Commit 6befb8d5 authored by verwaest@chromium.org's avatar verwaest@chromium.org

Also support smi in load-ICs.

BUG=
R=ulan@chromium.org

Review URL: https://chromiumcodereview.appspot.com/68523009

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17756 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 93f2ed48
......@@ -3054,18 +3054,26 @@ Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
GenerateNameCheck(name, this->name(), &miss);
}
__ JumpIfSmi(receiver(), &miss);
Label number_case;
Label* smi_target = HasHeapNumberMap(receiver_maps) ? &number_case : &miss;
__ JumpIfSmi(receiver(), smi_target);
Register map_reg = scratch1();
int receiver_count = receiver_maps->length();
int number_of_handled_maps = 0;
__ ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
for (int current = 0; current < receiver_count; ++current) {
Handle<Map> map = receiver_maps->at(current);
if (!map->is_deprecated()) {
number_of_handled_maps++;
__ mov(ip, Operand(receiver_maps->at(current)));
__ cmp(map_reg, ip);
if (map.is_identical_to(heap_number_map)) {
ASSERT(!number_case.is_unused());
__ bind(&number_case);
}
__ Jump(handlers->at(current), RelocInfo::CODE_TARGET, eq);
}
}
......
......@@ -3163,16 +3163,24 @@ Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
GenerateNameCheck(name, this->name(), &miss);
}
__ JumpIfSmi(receiver(), &miss);
Label number_case;
Label* smi_target = HasHeapNumberMap(receiver_maps) ? &number_case : &miss;
__ JumpIfSmi(receiver(), smi_target);
Register map_reg = scratch1();
__ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
int receiver_count = receiver_maps->length();
int number_of_handled_maps = 0;
Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
for (int current = 0; current < receiver_count; ++current) {
Handle<Map> map = receiver_maps->at(current);
if (!map->is_deprecated()) {
number_of_handled_maps++;
__ cmp(map_reg, map);
if (map.is_identical_to(heap_number_map)) {
ASSERT(!number_case.is_unused());
__ bind(&number_case);
}
__ j(equal, handlers->at(current));
}
}
......
......@@ -113,8 +113,9 @@ InlineCacheHolderFlag IC::GetCodeCacheForObject(Object* object) {
HeapObject* IC::GetCodeCacheHolder(Isolate* isolate,
Object* object,
InlineCacheHolderFlag holder) {
Object* map_owner =
holder == OWN_MAP ? object : object->GetPrototype(isolate);
if (object->IsSmi()) holder = PROTOTYPE_MAP;
Object* map_owner = holder == OWN_MAP
? object : object->GetPrototype(isolate);
return HeapObject::cast(map_owner);
}
......
......@@ -949,7 +949,7 @@ static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
}
bool IC::UpdatePolymorphicIC(Handle<HeapObject> receiver,
bool IC::UpdatePolymorphicIC(Handle<Object> receiver,
Handle<String> name,
Handle<Code> code) {
if (!code->is_handler()) return false;
......@@ -958,7 +958,7 @@ bool IC::UpdatePolymorphicIC(Handle<HeapObject> receiver,
int number_of_valid_maps;
int handler_to_overwrite = -1;
Handle<Map> new_receiver_map(receiver->map());
Handle<Map> new_receiver_map(receiver->GetMarkerMap(isolate()));
target()->FindAllMaps(&receiver_maps);
int number_of_maps = receiver_maps.length();
......@@ -1000,7 +1000,7 @@ bool IC::UpdatePolymorphicIC(Handle<HeapObject> receiver,
}
void IC::UpdateMonomorphicIC(Handle<HeapObject> receiver,
void IC::UpdateMonomorphicIC(Handle<Object> receiver,
Handle<Code> handler,
Handle<String> name) {
if (!handler->is_handler()) return set_target(*handler);
......@@ -1038,43 +1038,36 @@ bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) {
void IC::PatchCache(Handle<Object> object,
Handle<String> name,
Handle<Code> code) {
// TODO(verwaest): Handle smi here as well.
if (!object->IsHeapObject()) return;
Handle<HeapObject> receiver = Handle<HeapObject>::cast(object);
switch (state()) {
case UNINITIALIZED:
case PREMONOMORPHIC:
case MONOMORPHIC_PROTOTYPE_FAILURE:
UpdateMonomorphicIC(receiver, code, name);
UpdateMonomorphicIC(object, code, name);
break;
case MONOMORPHIC:
case MONOMORPHIC: {
// For now, call stubs are allowed to rewrite to the same stub. This
// happens e.g., when the field does not contain a function.
ASSERT(target()->is_call_stub() ||
target()->is_keyed_call_stub() ||
!target().is_identical_to(code));
if (!target()->is_keyed_stub()) {
bool is_same_handler = false;
Code* old_handler = target()->FindFirstHandler();
is_same_handler = old_handler == *code;
if (is_same_handler &&
IsTransitionedMapOfMonomorphicTarget(receiver->map())) {
UpdateMonomorphicIC(receiver, code, name);
break;
}
Code* old_handler = target()->FindFirstHandler();
if (old_handler == *code &&
IsTransitionedMapOfMonomorphicTarget(
object->GetMarkerMap(isolate()))) {
UpdateMonomorphicIC(object, code, name);
break;
}
// Fall through.
}
case POLYMORPHIC:
if (!target()->is_keyed_stub()) {
if (UpdatePolymorphicIC(receiver, name, code)) break;
if (UpdatePolymorphicIC(object, name, code)) break;
CopyICToMegamorphicCache(name);
}
set_target(*megamorphic_stub());
// Fall through.
case MEGAMORPHIC:
UpdateMegamorphicCache(receiver->map(), *name, *code);
UpdateMegamorphicCache(object->GetMarkerMap(isolate()), *name, *code);
break;
case DEBUG_STUB:
break;
......
......@@ -193,11 +193,11 @@ class IC {
UNREACHABLE();
return Handle<Code>::null();
}
void UpdateMonomorphicIC(Handle<HeapObject> receiver,
void UpdateMonomorphicIC(Handle<Object> receiver,
Handle<Code> handler,
Handle<String> name);
bool UpdatePolymorphicIC(Handle<HeapObject> receiver,
bool UpdatePolymorphicIC(Handle<Object> receiver,
Handle<String> name,
Handle<Code> code);
......
......@@ -1028,6 +1028,12 @@ Object* Object::GetPrototype(Isolate* isolate) {
}
Map* Object::GetMarkerMap(Isolate* isolate) {
if (IsSmi()) return isolate->heap()->heap_number_map();
return HeapObject::cast(this)->map();
}
Object* Object::GetHash() {
// The object is either a number, a name, an odd-ball,
// a real JS object, or a Harmony proxy.
......
......@@ -1494,6 +1494,7 @@ class Object : public MaybeObject {
// Return the object's prototype (might be Heap::null_value()).
Object* GetPrototype(Isolate* isolate);
Map* GetMarkerMap(Isolate* isolate);
// Returns the permanent hash code associated with this object. May return
// undefined if not yet created.
......
......@@ -134,7 +134,7 @@ Handle<Code> StubCache::FindHandler(Handle<Name> name,
Handle<Code> StubCache::ComputeMonomorphicIC(Handle<Name> name,
Handle<HeapObject> object,
Handle<Object> object,
Handle<Code> handler,
StrictModeFlag strict_mode) {
Code::Kind kind = handler->handler_kind();
......@@ -148,7 +148,7 @@ Handle<Code> StubCache::ComputeMonomorphicIC(Handle<Name> name,
name, stub_holder_map, kind, strict_mode, cache_holder);
if (!ic.is_null()) return ic;
Handle<Map> map(object->map());
Handle<Map> map(object->GetMarkerMap(isolate()));
if (kind == Code::LOAD_IC) {
LoadStubCompiler ic_compiler(isolate(), cache_holder);
ic = ic_compiler.CompileMonomorphicIC(map, handler, name);
......@@ -1181,6 +1181,17 @@ Register StoreStubCompiler::HandlerFrontendHeader(
}
bool BaseLoadStoreStubCompiler::HasHeapNumberMap(MapHandleList* receiver_maps) {
for (int i = 0; i < receiver_maps->length(); ++i) {
Handle<Map> map = receiver_maps->at(i);
if (map.is_identical_to(isolate()->factory()->heap_number_map())) {
return true;
}
}
return false;
}
Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<Object> object,
Register object_reg,
Handle<JSObject> holder,
......
......@@ -93,7 +93,7 @@ class StubCache {
StrictModeFlag strict_mode = kNonStrictMode);
Handle<Code> ComputeMonomorphicIC(Handle<Name> name,
Handle<HeapObject> receiver,
Handle<Object> receiver,
Handle<Code> handler,
StrictModeFlag strict_mode);
......@@ -608,6 +608,8 @@ class BaseLoadStoreStubCompiler: public StubCompiler {
void InitializeRegisters();
bool HasHeapNumberMap(MapHandleList* receiver_maps);
Code::Kind kind_;
InlineCacheHolderFlag cache_holder_;
Register* registers_;
......
......@@ -3071,17 +3071,25 @@ Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
GenerateNameCheck(name, this->name(), &miss);
}
__ JumpIfSmi(receiver(), &miss);
Label number_case;
Label* smi_target = HasHeapNumberMap(receiver_maps) ? &number_case : &miss;
__ JumpIfSmi(receiver(), smi_target);
Register map_reg = scratch1();
__ movq(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
int receiver_count = receiver_maps->length();
int number_of_handled_maps = 0;
Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
for (int current = 0; current < receiver_count; ++current) {
Handle<Map> map = receiver_maps->at(current);
if (!map->is_deprecated()) {
number_of_handled_maps++;
// Check map and tail call if there's a match
__ Cmp(map_reg, receiver_maps->at(current));
if (map.is_identical_to(heap_number_map)) {
ASSERT(!number_case.is_unused());
__ bind(&number_case);
}
__ j(equal, handlers->at(current), RelocInfo::CODE_TARGET);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment