diff --git a/src/ic.cc b/src/ic.cc index 5792b0e3ba..1ad61222cc 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -1736,9 +1736,8 @@ MaybeObject* KeyedStoreIC::Store(State state, // Check if the given name is an array index. uint32_t index; if (name->AsArrayIndex(&index)) { - HandleScope scope(isolate()); Handle result = SetElement(receiver, index, value, strict_mode); - if (result.is_null()) return Failure::Exception(); + RETURN_IF_EMPTY_HANDLE(isolate(), result); return *value; } @@ -1761,17 +1760,16 @@ MaybeObject* KeyedStoreIC::Store(State state, ASSERT(!(use_ic && object->IsJSGlobalProxy())); if (use_ic) { - Code* stub = (strict_mode == kStrictMode) + Handle stub = (strict_mode == kStrictMode) ? generic_stub_strict() : generic_stub(); if (object->IsJSObject()) { - JSObject* receiver = JSObject::cast(*object); - Heap* heap = Handle::cast(object)->GetHeap(); - Map* elements_map = Handle::cast(object)->elements()->map(); - if (elements_map == heap->non_strict_arguments_elements_map()) { + Handle receiver = Handle::cast(object); + if (receiver->elements()->map() == + isolate()->heap()->non_strict_arguments_elements_map()) { stub = non_strict_arguments_stub(); } else if (!force_generic) { - if (key->IsSmi() && (target() != non_strict_arguments_stub())) { + if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { StubKind stub_kind = STORE_NO_TRANSITION; if (receiver->GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) { if (value->IsHeapNumber()) { @@ -1784,17 +1782,11 @@ MaybeObject* KeyedStoreIC::Store(State state, stub_kind = STORE_TRANSITION_DOUBLE_TO_OBJECT; } } - HandleScope scope(isolate()); - MaybeObject* maybe_stub = ComputeStub(receiver, - stub_kind, - strict_mode, - stub); - stub = maybe_stub->IsFailure() ? - NULL : Code::cast(maybe_stub->ToObjectUnchecked()); + stub = ComputeStub(receiver, stub_kind, strict_mode, stub); } } } - if (stub != NULL) set_target(stub); + if (!stub.is_null()) set_target(*stub); } #ifdef DEBUG @@ -1831,50 +1823,44 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup, // Compute the code stub for this store; used for rewriting to // monomorphic state and making sure that the code stub is in the // stub cache. - MaybeObject* maybe_code = NULL; - Object* code = NULL; + Handle code; switch (type) { - case FIELD: { - maybe_code = isolate()->stub_cache()->ComputeKeyedStoreField( - *name, *receiver, lookup->GetFieldIndex(), NULL, strict_mode); + case FIELD: + code = isolate()->stub_cache()->ComputeKeyedStoreField( + name, receiver, lookup->GetFieldIndex(), + Handle::null(), strict_mode); break; - } - case MAP_TRANSITION: { + case MAP_TRANSITION: if (lookup->GetAttributes() == NONE) { - HandleScope scope(isolate()); ASSERT(type == MAP_TRANSITION); Handle transition(lookup->GetTransitionMap()); int index = transition->PropertyIndexFor(*name); - maybe_code = isolate()->stub_cache()->ComputeKeyedStoreField( - *name, *receiver, index, *transition, strict_mode); + code = isolate()->stub_cache()->ComputeKeyedStoreField( + name, receiver, index, transition, strict_mode); break; } // fall through. - } - default: { + default: // Always rewrite to the generic case so that we do not // repeatedly try to rewrite. - maybe_code = (strict_mode == kStrictMode) + code = (strict_mode == kStrictMode) ? generic_stub_strict() : generic_stub(); break; - } } - // If we're unable to compute the stub (not enough memory left), we - // simply avoid updating the caches. - if (maybe_code == NULL || !maybe_code->ToObject(&code)) return; + ASSERT(!code.is_null()); // Patch the call site depending on the state of the cache. Make // sure to always rewrite from monomorphic to megamorphic. ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); if (state == UNINITIALIZED || state == PREMONOMORPHIC) { - set_target(Code::cast(code)); + set_target(*code); } else if (state == MONOMORPHIC) { set_target((strict_mode == kStrictMode) - ? megamorphic_stub_strict() - : megamorphic_stub()); + ? *megamorphic_stub_strict() + : *megamorphic_stub()); } #ifdef DEBUG @@ -2035,7 +2021,7 @@ RUNTIME_FUNCTION(MaybeObject*, SharedStoreIC_ExtendStorage) { // Used from ic-.cc. RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) { - NoHandleAllocation na; + HandleScope scope(isolate); ASSERT(args.length() == 3); KeyedStoreIC ic(isolate); IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); @@ -2069,7 +2055,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Slow) { RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) { - NoHandleAllocation na; + HandleScope scope(isolate); ASSERT(args.length() == 3); KeyedStoreIC ic(isolate); IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); diff --git a/src/ic.h b/src/ic.h index 6d5f321e6a..efef44a3b1 100644 --- a/src/ic.h +++ b/src/ic.h @@ -603,29 +603,24 @@ class KeyedStoreIC: public KeyedIC { return Isolate::Current()->builtins()->builtin( Builtins::kKeyedStoreIC_Initialize); } - Code* megamorphic_stub() { - return isolate()->builtins()->builtin( - Builtins::kKeyedStoreIC_Generic); - } static Code* initialize_stub_strict() { return Isolate::Current()->builtins()->builtin( Builtins::kKeyedStoreIC_Initialize_Strict); } - Code* megamorphic_stub_strict() { - return isolate()->builtins()->builtin( - Builtins::kKeyedStoreIC_Generic_Strict); + Handle megamorphic_stub() { + return isolate()->builtins()->KeyedStoreIC_Generic(); } - Code* generic_stub() { - return isolate()->builtins()->builtin( - Builtins::kKeyedStoreIC_Generic); + Handle megamorphic_stub_strict() { + return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); } - Code* generic_stub_strict() { - return isolate()->builtins()->builtin( - Builtins::kKeyedStoreIC_Generic_Strict); + Handle generic_stub() { + return isolate()->builtins()->KeyedStoreIC_Generic(); } - Code* non_strict_arguments_stub() { - return isolate()->builtins()->builtin( - Builtins::kKeyedStoreIC_NonStrictArguments); + Handle generic_stub_strict() { + return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); + } + Handle non_strict_arguments_stub() { + return isolate()->builtins()->KeyedStoreIC_NonStrictArguments(); } static void Clear(Address address, Code* target); diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 19fbbd925b..4a337baf72 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -687,36 +687,40 @@ Handle StubCache::ComputeStoreInterceptor(Handle name, return code; } +Handle KeyedStoreStubCompiler::CompileStoreField(Handle object, + int index, + Handle transition, + Handle name) { + CALL_HEAP_FUNCTION(isolate(), + CompileStoreField(*object, index, + (transition.is_null() + ? NULL + : *transition), + *name), + Code); +} -MaybeObject* StubCache::ComputeKeyedStoreField(String* name, - JSObject* receiver, +Handle StubCache::ComputeKeyedStoreField(Handle name, + Handle receiver, int field_index, - Map* transition, + Handle transition, StrictModeFlag strict_mode) { - PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION; + PropertyType type = (transition.is_null()) ? FIELD : MAP_TRANSITION; Code::Flags flags = Code::ComputeMonomorphicFlags( Code::KEYED_STORE_IC, type, strict_mode); - Object* code = receiver->map()->FindInCodeCache(name, flags); - if (code->IsUndefined()) { - HandleScope scope(isolate()); - KeyedStoreStubCompiler compiler(isolate(), strict_mode); - { MaybeObject* maybe_code = - compiler.CompileStoreField(receiver, field_index, transition, name); - if (!maybe_code->ToObject(&code)) return maybe_code; - } - PROFILE(isolate(), - CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, - Code::cast(code), name)); - GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, name, Code::cast(code))); - Object* result; - { MaybeObject* maybe_result = - receiver->UpdateMapCodeCache(name, Code::cast(code)); - if (!maybe_result->ToObject(&result)) return maybe_result; - } - } + Handle probe(receiver->map()->FindInCodeCache(*name, flags)); + if (probe->IsCode()) return Handle::cast(probe); + + KeyedStoreStubCompiler compiler(isolate(), strict_mode); + Handle code = + compiler.CompileStoreField(receiver, field_index, transition, name); + PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name)); + GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code)); + JSObject::UpdateMapCodeCache(isolate_, receiver, name, code); return code; } + #define CALL_LOGGER_TAG(kind, type) \ (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) diff --git a/src/stub-cache.h b/src/stub-cache.h index 1ce4ef5984..a6f40a789c 100644 --- a/src/stub-cache.h +++ b/src/stub-cache.h @@ -162,12 +162,11 @@ class StubCache { // --- - MUST_USE_RESULT MaybeObject* ComputeKeyedStoreField( - String* name, - JSObject* receiver, - int field_index, - Map* transition, - StrictModeFlag strict_mode); + Handle ComputeKeyedStoreField(Handle name, + Handle receiver, + int field_index, + Handle transition, + StrictModeFlag strict_mode); MUST_USE_RESULT MaybeObject* ComputeKeyedLoadOrStoreElement( JSObject* receiver, @@ -755,6 +754,11 @@ class KeyedStoreStubCompiler: public StubCompiler { KeyedStoreStubCompiler(Isolate* isolate, StrictModeFlag strict_mode) : StubCompiler(isolate), strict_mode_(strict_mode) { } + Handle CompileStoreField(Handle object, + int index, + Handle transition, + Handle name); + MUST_USE_RESULT MaybeObject* CompileStoreField(JSObject* object, int index, Map* transition,