Index: src/ic.cc |
diff --git a/src/ic.cc b/src/ic.cc |
index 5f779b1c942f0a59ac29e7abae4bb95d143af612..55d2d0b42c173cafe3daf7faac40f1bbf7894bc2 100644 |
--- a/src/ic.cc |
+++ b/src/ic.cc |
@@ -971,36 +971,30 @@ void LoadIC::UpdateCaches(LookupResult* lookup, |
} |
-MaybeObject* KeyedLoadIC::GetElementStubWithoutMapCheck( |
+Handle<Code> KeyedLoadIC::GetElementStubWithoutMapCheck( |
bool is_js_array, |
ElementsKind elements_kind) { |
- return KeyedLoadElementStub(elements_kind).TryGetCode(); |
+ return KeyedLoadElementStub(elements_kind).GetCode(); |
} |
-MaybeObject* KeyedLoadIC::ComputePolymorphicStub( |
- MapList* receiver_maps, |
+Handle<Code> KeyedLoadIC::ComputePolymorphicStub( |
+ MapHandleList* receiver_maps, |
StrictModeFlag strict_mode) { |
- CodeList handler_ics(receiver_maps->length()); |
+ CodeHandleList handler_ics(receiver_maps->length()); |
for (int i = 0; i < receiver_maps->length(); ++i) { |
- Map* receiver_map(receiver_maps->at(i)); |
- MaybeObject* maybe_cached_stub = ComputeMonomorphicStubWithoutMapCheck( |
+ Handle<Map> receiver_map = receiver_maps->at(i); |
+ Handle<Code> cached_stub = ComputeMonomorphicStubWithoutMapCheck( |
receiver_map, strict_mode); |
- Code* cached_stub; |
- if (!maybe_cached_stub->To(&cached_stub)) return maybe_cached_stub; |
handler_ics.Add(cached_stub); |
} |
- Object* object; |
- HandleScope scope(isolate()); |
KeyedLoadStubCompiler compiler(isolate()); |
- MaybeObject* maybe_code = compiler.CompileLoadPolymorphic(receiver_maps, |
- &handler_ics); |
- if (!maybe_code->ToObject(&object)) return maybe_code; |
+ Handle<Code> code = compiler.CompileLoadPolymorphic( |
+ receiver_maps, &handler_ics); |
isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); |
- PROFILE(isolate(), CodeCreateEvent( |
- Logger::KEYED_LOAD_MEGAMORPHIC_IC_TAG, |
- Code::cast(object), 0)); |
- return object; |
+ PROFILE(isolate(), |
+ CodeCreateEvent(Logger::KEYED_LOAD_MEGAMORPHIC_IC_TAG, *code, 0)); |
+ return code; |
} |
@@ -1034,8 +1028,7 @@ MaybeObject* KeyedLoadIC::Load(State state, |
name->Equals(isolate()->heap()->length_symbol())) { |
Handle<String> string = Handle<String>::cast(object); |
Handle<Code> code = |
- isolate()->stub_cache()->ComputeKeyedLoadStringLength(name, |
- string); |
+ isolate()->stub_cache()->ComputeKeyedLoadStringLength(name, string); |
ASSERT(!code.is_null()); |
set_target(*code); |
TRACE_IC("KeyedLoadIC", name, state, target()); |
@@ -1420,10 +1413,12 @@ void StoreIC::UpdateCaches(LookupResult* lookup, |
} |
-static bool AddOneReceiverMapIfMissing(MapList* receiver_maps, |
- Map* new_receiver_map) { |
+static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, |
+ Handle<Map> new_receiver_map) { |
+ ASSERT(!new_receiver_map.is_null()); |
for (int current = 0; current < receiver_maps->length(); ++current) { |
- if (receiver_maps->at(current) == new_receiver_map) { |
+ if (!receiver_maps->at(current).is_null() && |
+ receiver_maps->at(current).is_identical_to(new_receiver_map)) { |
return false; |
} |
} |
@@ -1432,22 +1427,23 @@ static bool AddOneReceiverMapIfMissing(MapList* receiver_maps, |
} |
-void KeyedIC::GetReceiverMapsForStub(Code* stub, MapList* result) { |
+void KeyedIC::GetReceiverMapsForStub(Handle<Code> stub, |
+ MapHandleList* result) { |
ASSERT(stub->is_inline_cache_stub()); |
- if (!string_stub().is_null() && stub == *string_stub()) { |
- return result->Add(isolate()->heap()->string_map()); |
+ if (!string_stub().is_null() && stub.is_identical_to(string_stub())) { |
+ return result->Add(isolate()->factory()->string_map()); |
} else if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) { |
if (stub->ic_state() == MONOMORPHIC) { |
- result->Add(Map::cast(stub->FindFirstMap())); |
+ result->Add(Handle<Map>(stub->FindFirstMap())); |
} else { |
ASSERT(stub->ic_state() == MEGAMORPHIC); |
AssertNoAllocation no_allocation; |
int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
- for (RelocIterator it(stub, mask); !it.done(); it.next()) { |
+ for (RelocIterator it(*stub, mask); !it.done(); it.next()) { |
RelocInfo* info = it.rinfo(); |
- Object* object = info->target_object(); |
+ Handle<Object> object(info->target_object()); |
ASSERT(object->IsMap()); |
- AddOneReceiverMapIfMissing(result, Map::cast(object)); |
+ AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object)); |
} |
} |
} |
@@ -1458,33 +1454,13 @@ Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver, |
StubKind stub_kind, |
StrictModeFlag strict_mode, |
Handle<Code> generic_stub) { |
- CALL_HEAP_FUNCTION(isolate(), |
- ComputeStub(*receiver, |
- stub_kind, |
- strict_mode, |
- *generic_stub), |
- Code); |
-} |
- |
- |
- |
-MaybeObject* KeyedIC::ComputeStub(JSObject* receiver, |
- StubKind stub_kind, |
- StrictModeFlag strict_mode, |
- Code* generic_stub) { |
State ic_state = target()->ic_state(); |
if ((ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) && |
!IsTransitionStubKind(stub_kind)) { |
- Code* monomorphic_stub; |
- MaybeObject* maybe_stub = ComputeMonomorphicStub(receiver, |
- stub_kind, |
- strict_mode, |
- generic_stub); |
- if (!maybe_stub->To(&monomorphic_stub)) return maybe_stub; |
- |
- return monomorphic_stub; |
+ return ComputeMonomorphicStub( |
+ receiver, stub_kind, strict_mode, generic_stub); |
} |
- ASSERT(target() != generic_stub); |
+ ASSERT(target() != *generic_stub); |
// Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS |
// via megamorphic stubs, since they don't have a map in their relocation info |
@@ -1495,18 +1471,17 @@ MaybeObject* KeyedIC::ComputeStub(JSObject* receiver, |
// Determine the list of receiver maps that this call site has seen, |
// adding the map that was just encountered. |
- MapList target_receiver_maps; |
+ MapHandleList target_receiver_maps; |
+ Handle<Map> receiver_map(receiver->map()); |
if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { |
- target_receiver_maps.Add(receiver->map()); |
+ target_receiver_maps.Add(receiver_map); |
} else { |
- GetReceiverMapsForStub(target(), &target_receiver_maps); |
+ GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps); |
} |
bool map_added = |
- AddOneReceiverMapIfMissing(&target_receiver_maps, receiver->map()); |
+ AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); |
if (IsTransitionStubKind(stub_kind)) { |
- MaybeObject* maybe_map = ComputeTransitionedMap(receiver, stub_kind); |
- Map* new_map = NULL; |
- if (!maybe_map->To(&new_map)) return maybe_map; |
+ Handle<Map> new_map = ComputeTransitionedMap(receiver, stub_kind); |
map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map); |
} |
if (!map_added) { |
@@ -1521,32 +1496,25 @@ MaybeObject* KeyedIC::ComputeStub(JSObject* receiver, |
return generic_stub; |
} |
- PolymorphicCodeCache* cache = isolate()->heap()->polymorphic_code_cache(); |
- Code::Flags flags = Code::ComputeFlags(this->kind(), |
- MEGAMORPHIC, |
- strict_mode); |
- Object* maybe_cached_stub = cache->Lookup(&target_receiver_maps, flags); |
- // If there is a cached stub, use it. |
- if (!maybe_cached_stub->IsUndefined()) { |
- ASSERT(maybe_cached_stub->IsCode()); |
- return Code::cast(maybe_cached_stub); |
- } |
- MaybeObject* maybe_stub = |
+ Handle<PolymorphicCodeCache> cache = |
+ isolate()->factory()->polymorphic_code_cache(); |
+ Code::Flags flags = Code::ComputeFlags(kind(), MEGAMORPHIC, strict_mode); |
+ Handle<Object> probe = cache->Lookup(&target_receiver_maps, flags); |
+ if (probe->IsCode()) return Handle<Code>::cast(probe); |
+ |
+ Handle<Code> stub = |
ComputePolymorphicStub(&target_receiver_maps, strict_mode); |
- Code* stub; |
- if (!maybe_stub->To(&stub)) return maybe_stub; |
- MaybeObject* maybe_update = cache->Update(&target_receiver_maps, flags, stub); |
- if (maybe_update->IsFailure()) return maybe_update; |
+ PolymorphicCodeCache::Update(cache, &target_receiver_maps, flags, stub); |
return stub; |
} |
-MaybeObject* KeyedIC::ComputeMonomorphicStubWithoutMapCheck( |
- Map* receiver_map, |
+Handle<Code> KeyedIC::ComputeMonomorphicStubWithoutMapCheck( |
+ Handle<Map> receiver_map, |
StrictModeFlag strict_mode) { |
if ((receiver_map->instance_type() & kNotStringTag) == 0) { |
ASSERT(!string_stub().is_null()); |
- return *string_stub(); |
+ return string_stub(); |
} else { |
ASSERT(receiver_map->has_dictionary_elements() || |
receiver_map->has_fast_elements() || |
@@ -1560,85 +1528,78 @@ MaybeObject* KeyedIC::ComputeMonomorphicStubWithoutMapCheck( |
} |
-MaybeObject* KeyedIC::ComputeMonomorphicStub(JSObject* receiver, |
+Handle<Code> KeyedIC::ComputeMonomorphicStub(Handle<JSObject> receiver, |
StubKind stub_kind, |
StrictModeFlag strict_mode, |
- Code* generic_stub) { |
- Code* result = NULL; |
+ Handle<Code> generic_stub) { |
if (receiver->HasFastElements() || |
receiver->HasFastSmiOnlyElements() || |
receiver->HasExternalArrayElements() || |
receiver->HasFastDoubleElements() || |
receiver->HasDictionaryElements()) { |
- MaybeObject* maybe_stub = |
- isolate()->stub_cache()->ComputeKeyedLoadOrStoreElement( |
- receiver, stub_kind, strict_mode); |
- if (!maybe_stub->To(&result)) return maybe_stub; |
+ return isolate()->stub_cache()->ComputeKeyedLoadOrStoreElement( |
+ receiver, stub_kind, strict_mode); |
} else { |
- result = generic_stub; |
+ return generic_stub; |
} |
- return result; |
} |
-MaybeObject* KeyedIC::ComputeTransitionedMap(JSObject* receiver, |
- StubKind stub_kind) { |
+Handle<Map> KeyedIC::ComputeTransitionedMap(Handle<JSObject> receiver, |
+ StubKind stub_kind) { |
switch (stub_kind) { |
case KeyedIC::STORE_TRANSITION_SMI_TO_OBJECT: |
case KeyedIC::STORE_TRANSITION_DOUBLE_TO_OBJECT: |
- return receiver->GetElementsTransitionMap(FAST_ELEMENTS); |
+ return JSObject::GetElementsTransitionMap(receiver, FAST_ELEMENTS); |
+ break; |
case KeyedIC::STORE_TRANSITION_SMI_TO_DOUBLE: |
- return receiver->GetElementsTransitionMap(FAST_DOUBLE_ELEMENTS); |
+ return JSObject::GetElementsTransitionMap(receiver, FAST_DOUBLE_ELEMENTS); |
+ break; |
default: |
UNREACHABLE(); |
- return NULL; |
+ return Handle<Map>::null(); |
} |
} |
-MaybeObject* KeyedStoreIC::GetElementStubWithoutMapCheck( |
+Handle<Code> KeyedStoreIC::GetElementStubWithoutMapCheck( |
bool is_js_array, |
ElementsKind elements_kind) { |
- return KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode(); |
+ return KeyedStoreElementStub(is_js_array, elements_kind).GetCode(); |
} |
-MaybeObject* KeyedStoreIC::ComputePolymorphicStub( |
- MapList* receiver_maps, |
- StrictModeFlag strict_mode) { |
+Handle<Code> KeyedStoreIC::ComputePolymorphicStub(MapHandleList* receiver_maps, |
+ StrictModeFlag strict_mode) { |
// Collect MONOMORPHIC stubs for all target_receiver_maps. |
- CodeList handler_ics(receiver_maps->length()); |
- MapList transitioned_maps(receiver_maps->length()); |
+ CodeHandleList handler_ics(receiver_maps->length()); |
+ MapHandleList transitioned_maps(receiver_maps->length()); |
for (int i = 0; i < receiver_maps->length(); ++i) { |
- Map* receiver_map(receiver_maps->at(i)); |
- MaybeObject* maybe_cached_stub = NULL; |
- Map* transitioned_map = receiver_map->FindTransitionedMap(receiver_maps); |
- if (transitioned_map != NULL) { |
- maybe_cached_stub = ElementsTransitionAndStoreStub( |
+ Handle<Map> receiver_map(receiver_maps->at(i)); |
+ Handle<Code> cached_stub; |
+ Handle<Map> transitioned_map = |
+ receiver_map->FindTransitionedMap(receiver_maps); |
+ if (!transitioned_map.is_null()) { |
+ cached_stub = ElementsTransitionAndStoreStub( |
receiver_map->elements_kind(), // original elements_kind |
transitioned_map->elements_kind(), |
receiver_map->instance_type() == JS_ARRAY_TYPE, // is_js_array |
- strict_mode).TryGetCode(); |
+ strict_mode).GetCode(); |
} else { |
- maybe_cached_stub = ComputeMonomorphicStubWithoutMapCheck( |
- receiver_map, strict_mode); |
+ cached_stub = ComputeMonomorphicStubWithoutMapCheck(receiver_map, |
+ strict_mode); |
} |
- Code* cached_stub; |
- if (!maybe_cached_stub->To(&cached_stub)) return maybe_cached_stub; |
+ ASSERT(!cached_stub.is_null()); |
handler_ics.Add(cached_stub); |
transitioned_maps.Add(transitioned_map); |
} |
- Object* object; |
- HandleScope scope(isolate()); |
KeyedStoreStubCompiler compiler(isolate(), strict_mode); |
- MaybeObject* maybe_code = compiler.CompileStorePolymorphic( |
+ Handle<Code> code = compiler.CompileStorePolymorphic( |
receiver_maps, &handler_ics, &transitioned_maps); |
- if (!maybe_code->ToObject(&object)) return maybe_code; |
isolate()->counters()->keyed_store_polymorphic_stubs()->Increment(); |
- PROFILE(isolate(), CodeCreateEvent( |
- Logger::KEYED_STORE_MEGAMORPHIC_IC_TAG, |
- Code::cast(object), 0)); |
- return object; |
+ PROFILE(isolate(), |
+ CodeCreateEvent(Logger::KEYED_STORE_MEGAMORPHIC_IC_TAG, *code, 0)); |
+ return code; |
} |