| Index: src/ic/ic.cc
|
| diff --git a/src/ic/ic.cc b/src/ic/ic.cc
|
| index 045c4593e15ffe7337dc94d82d03cafe8541e93c..f8ffc5e2a1e52dd27285cdd2e533b82ef0bd890d 100644
|
| --- a/src/ic/ic.cc
|
| +++ b/src/ic/ic.cc
|
| @@ -95,8 +95,8 @@ const char* GetTransitionMarkModifier(KeyedAccessStoreMode mode) {
|
| void IC::TraceIC(const char* type, Handle<Object> name) {
|
| if (FLAG_trace_ic) {
|
| if (AddressIsDeoptimizedCode()) return;
|
| - State new_state =
|
| - UseVector() ? nexus()->StateFromFeedback() : raw_target()->ic_state();
|
| + DCHECK(UseVector());
|
| + State new_state = nexus()->StateFromFeedback();
|
| TraceIC(type, name, state(), new_state);
|
| }
|
| }
|
| @@ -105,8 +105,7 @@ void IC::TraceIC(const char* type, Handle<Object> name) {
|
| void IC::TraceIC(const char* type, Handle<Object> name, State old_state,
|
| State new_state) {
|
| if (FLAG_trace_ic) {
|
| - Code* new_target = raw_target();
|
| - PrintF("[%s%s in ", new_target->is_keyed_stub() ? "Keyed" : "", type);
|
| + PrintF("[%s%s in ", is_keyed() ? "Keyed" : "", type);
|
|
|
| // TODO(jkummerow): Add support for "apply". The logic is roughly:
|
| // marker = [fp_ + kMarkerOffset];
|
| @@ -123,7 +122,7 @@ void IC::TraceIC(const char* type, Handle<Object> name, State old_state,
|
| }
|
|
|
| const char* modifier = "";
|
| - if (new_target->kind() == Code::KEYED_STORE_IC) {
|
| + if (kind() == Code::KEYED_STORE_IC) {
|
| KeyedAccessStoreMode mode =
|
| casted_nexus<KeyedStoreICNexus>()->GetKeyedAccessStoreMode();
|
| modifier = GetTransitionMarkModifier(mode);
|
| @@ -146,7 +145,6 @@ void IC::TraceIC(const char* type, Handle<Object> name, State old_state,
|
|
|
| IC::IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus)
|
| : isolate_(isolate),
|
| - target_set_(false),
|
| vector_set_(false),
|
| target_maps_set_(false),
|
| nexus_(nexus) {
|
| @@ -185,11 +183,11 @@ IC::IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus)
|
| constant_pool_address_ = constant_pool;
|
| }
|
| pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address);
|
| - target_ = handle(raw_target(), isolate);
|
| - kind_ = target_->kind();
|
| - state_ = UseVector() ? nexus->StateFromFeedback() : target_->ic_state();
|
| + Code* target = this->target();
|
| + kind_ = target->kind();
|
| + state_ = UseVector() ? nexus->StateFromFeedback() : target->ic_state();
|
| old_state_ = state_;
|
| - extra_ic_state_ = target_->extra_ic_state();
|
| + extra_ic_state_ = target->extra_ic_state();
|
| }
|
|
|
|
|
| @@ -260,11 +258,8 @@ static void LookupForRead(LookupIterator* it) {
|
|
|
| bool IC::ShouldRecomputeHandler(Handle<Object> receiver, Handle<String> name) {
|
| if (!RecomputeHandlerForName(name)) return false;
|
| - if (UseVector()) {
|
| - maybe_handler_ = nexus()->FindHandlerForMap(receiver_map());
|
| - } else {
|
| - maybe_handler_ = target()->FindHandlerForMap(*receiver_map());
|
| - }
|
| + DCHECK(UseVector());
|
| + maybe_handler_ = nexus()->FindHandlerForMap(receiver_map());
|
|
|
| // The current map wasn't handled yet. There's no reason to stay monomorphic,
|
| // *unless* we're moving from a deprecated map to its replacement, or
|
| @@ -293,11 +288,11 @@ bool IC::ShouldRecomputeHandler(Handle<Object> receiver, Handle<String> name) {
|
| }
|
|
|
| bool IC::RecomputeHandlerForName(Handle<Object> name) {
|
| - if (target()->is_keyed_stub()) {
|
| + if (is_keyed()) {
|
| // Determine whether the failure is due to a name failure.
|
| if (!name->IsName()) return false;
|
| - Name* stub_name =
|
| - UseVector() ? nexus()->FindFirstName() : target()->FindFirstName();
|
| + DCHECK(UseVector());
|
| + Name* stub_name = nexus()->FindFirstName();
|
| if (*name != stub_name) return false;
|
| }
|
|
|
| @@ -369,37 +364,6 @@ static void ComputeTypeInfoCountDelta(IC::State old_state, IC::State new_state,
|
| }
|
| }
|
|
|
| -
|
| -void IC::OnTypeFeedbackChanged(Isolate* isolate, Address address,
|
| - State old_state, State new_state,
|
| - bool target_remains_ic_stub) {
|
| - Code* host =
|
| - isolate->inner_pointer_to_code_cache()->GetCacheEntry(address)->code;
|
| - if (host->kind() != Code::FUNCTION) return;
|
| -
|
| - if (FLAG_type_info_threshold > 0 && target_remains_ic_stub &&
|
| - // Not all Code objects have TypeFeedbackInfo.
|
| - host->type_feedback_info()->IsTypeFeedbackInfo()) {
|
| - int polymorphic_delta = 0; // "Polymorphic" here includes monomorphic.
|
| - int generic_delta = 0; // "Generic" here includes megamorphic.
|
| - ComputeTypeInfoCountDelta(old_state, new_state, &polymorphic_delta,
|
| - &generic_delta);
|
| - TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info());
|
| - info->change_ic_with_type_info_count(polymorphic_delta);
|
| - info->change_ic_generic_count(generic_delta);
|
| - }
|
| - if (host->type_feedback_info()->IsTypeFeedbackInfo()) {
|
| - TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info());
|
| - info->change_own_type_change_checksum();
|
| - }
|
| - host->set_profiler_ticks(0);
|
| - isolate->runtime_profiler()->NotifyICChanged();
|
| - // TODO(2029): When an optimized function is patched, it would
|
| - // be nice to propagate the corresponding type information to its
|
| - // unoptimized version for the benefit of later inlining.
|
| -}
|
| -
|
| -
|
| // static
|
| void IC::OnTypeFeedbackChanged(Isolate* isolate, Code* host) {
|
| if (host->kind() != Code::FUNCTION) return;
|
| @@ -413,26 +377,42 @@ void IC::OnTypeFeedbackChanged(Isolate* isolate, Code* host) {
|
| // unoptimized version for the benefit of later inlining.
|
| }
|
|
|
| -
|
| void IC::PostPatching(Address address, Code* target, Code* old_target) {
|
| // Type vector based ICs update these statistics at a different time because
|
| // they don't always patch on state change.
|
| if (ICUseVector(target->kind())) return;
|
|
|
| - Isolate* isolate = target->GetHeap()->isolate();
|
| - State old_state = UNINITIALIZED;
|
| - State new_state = UNINITIALIZED;
|
| - bool target_remains_ic_stub = false;
|
| - if (old_target->is_inline_cache_stub() && target->is_inline_cache_stub()) {
|
| - old_state = old_target->ic_state();
|
| - new_state = target->ic_state();
|
| - target_remains_ic_stub = true;
|
| - }
|
| + DCHECK(old_target->is_inline_cache_stub());
|
| + DCHECK(target->is_inline_cache_stub());
|
| + State old_state = old_target->ic_state();
|
| + State new_state = target->ic_state();
|
|
|
| - OnTypeFeedbackChanged(isolate, address, old_state, new_state,
|
| - target_remains_ic_stub);
|
| -}
|
| + Isolate* isolate = target->GetIsolate();
|
| + Code* host =
|
| + isolate->inner_pointer_to_code_cache()->GetCacheEntry(address)->code;
|
| + if (host->kind() != Code::FUNCTION) return;
|
|
|
| + // Not all Code objects have TypeFeedbackInfo.
|
| + if (host->type_feedback_info()->IsTypeFeedbackInfo()) {
|
| + if (FLAG_type_info_threshold > 0) {
|
| + int polymorphic_delta = 0; // "Polymorphic" here includes monomorphic.
|
| + int generic_delta = 0; // "Generic" here includes megamorphic.
|
| + ComputeTypeInfoCountDelta(old_state, new_state, &polymorphic_delta,
|
| + &generic_delta);
|
| + TypeFeedbackInfo* info =
|
| + TypeFeedbackInfo::cast(host->type_feedback_info());
|
| + info->change_ic_with_type_info_count(polymorphic_delta);
|
| + info->change_ic_generic_count(generic_delta);
|
| + }
|
| + TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info());
|
| + info->change_own_type_change_checksum();
|
| + }
|
| + host->set_profiler_ticks(0);
|
| + isolate->runtime_profiler()->NotifyICChanged();
|
| + // TODO(2029): When an optimized function is patched, it would
|
| + // be nice to propagate the corresponding type information to its
|
| + // unoptimized version for the benefit of later inlining.
|
| +}
|
|
|
| void IC::Clear(Isolate* isolate, Address address, Address constant_pool) {
|
| Code* target = GetTargetAtAddress(address, constant_pool);
|
| @@ -440,21 +420,8 @@ void IC::Clear(Isolate* isolate, Address address, Address constant_pool) {
|
| // Don't clear debug break inline cache as it will remove the break point.
|
| if (target->is_debug_stub()) return;
|
|
|
| - switch (target->kind()) {
|
| - case Code::COMPARE_IC:
|
| - return CompareIC::Clear(isolate, address, target, constant_pool);
|
| - case Code::BINARY_OP_IC:
|
| - case Code::CALL_IC: // CallICs are vector-based and cleared differently.
|
| - case Code::KEYED_LOAD_IC:
|
| - case Code::KEYED_STORE_IC:
|
| - case Code::LOAD_IC:
|
| - case Code::STORE_IC:
|
| - case Code::TO_BOOLEAN_IC:
|
| - // Clearing these is tricky and does not
|
| - // make any performance difference.
|
| - return;
|
| - default:
|
| - UNREACHABLE();
|
| + if (target->kind() == Code::COMPARE_IC) {
|
| + CompareIC::Clear(isolate, address, target, constant_pool);
|
| }
|
| }
|
|
|
| @@ -704,7 +671,7 @@ static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
|
|
|
| bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) {
|
| if (!code->is_handler()) return false;
|
| - if (target()->is_keyed_stub() && state() != RECOMPUTE_HANDLER) return false;
|
| + if (is_keyed() && state() != RECOMPUTE_HANDLER) return false;
|
| Handle<Map> map = receiver_map();
|
| MapHandleList maps;
|
| CodeHandleList handlers;
|
| @@ -737,14 +704,11 @@ bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) {
|
| if (number_of_maps == 0 && state() != MONOMORPHIC && state() != POLYMORPHIC) {
|
| return false;
|
| }
|
| - if (UseVector()) {
|
| - if (!nexus()->FindHandlers(&handlers, maps.length())) return false;
|
| - } else {
|
| - if (!target()->FindHandlers(&handlers, maps.length())) return false;
|
| - }
|
| + DCHECK(UseVector());
|
| + if (!nexus()->FindHandlers(&handlers, maps.length())) return false;
|
|
|
| number_of_valid_maps++;
|
| - if (number_of_valid_maps > 1 && target()->is_keyed_stub()) return false;
|
| + if (number_of_valid_maps > 1 && is_keyed()) return false;
|
| Handle<Code> ic;
|
| if (number_of_valid_maps == 1) {
|
| ConfigureVectorState(name, receiver_map(), code);
|
| @@ -762,7 +726,6 @@ bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) {
|
| ConfigureVectorState(name, &maps, &handlers);
|
| }
|
|
|
| - if (!UseVector()) set_target(*ic);
|
| return true;
|
| }
|
|
|
| @@ -777,7 +740,7 @@ void IC::CopyICToMegamorphicCache(Handle<Name> name) {
|
| MapHandleList maps;
|
| CodeHandleList handlers;
|
| TargetMaps(&maps);
|
| - if (!target()->FindHandlers(&handlers, maps.length())) return;
|
| + if (!nexus()->FindHandlers(&handlers, maps.length())) return;
|
| for (int i = 0; i < maps.length(); i++) {
|
| UpdateMegamorphicCache(*maps.at(i), *name, *handlers.at(i));
|
| }
|
| @@ -808,26 +771,20 @@ void IC::PatchCache(Handle<Name> name, Handle<Code> code) {
|
| case RECOMPUTE_HANDLER:
|
| case MONOMORPHIC:
|
| case POLYMORPHIC:
|
| - if (!target()->is_keyed_stub() || state() == RECOMPUTE_HANDLER) {
|
| + if (!is_keyed() || state() == RECOMPUTE_HANDLER) {
|
| if (UpdatePolymorphicIC(name, code)) break;
|
| // For keyed stubs, we can't know whether old handlers were for the
|
| // same key.
|
| CopyICToMegamorphicCache(name);
|
| }
|
| - if (UseVector()) {
|
| - ConfigureVectorState(MEGAMORPHIC);
|
| - } else {
|
| - set_target(*megamorphic_stub());
|
| - }
|
| + DCHECK(UseVector());
|
| + ConfigureVectorState(MEGAMORPHIC);
|
| // Fall through.
|
| case MEGAMORPHIC:
|
| UpdateMegamorphicCache(*receiver_map(), *name, *code);
|
| // Indicate that we've handled this case.
|
| - if (UseVector()) {
|
| - vector_set_ = true;
|
| - } else {
|
| - target_set_ = true;
|
| - }
|
| + DCHECK(UseVector());
|
| + vector_set_ = true;
|
| break;
|
| case DEBUG_STUB:
|
| break;
|
| @@ -912,12 +869,6 @@ Handle<Code> KeyedStoreIC::ChooseMegamorphicStub(Isolate* isolate,
|
| }
|
|
|
|
|
| -Handle<Code> LoadIC::megamorphic_stub() {
|
| - DCHECK_EQ(Code::KEYED_LOAD_IC, kind());
|
| - return KeyedLoadIC::ChooseMegamorphicStub(isolate(), extra_ic_state());
|
| -}
|
| -
|
| -
|
| Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) {
|
| LoadFieldStub stub(isolate(), index);
|
| return stub.GetCode();
|
| @@ -1239,7 +1190,6 @@ static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) {
|
|
|
|
|
| Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
|
| - Handle<Code> null_handle;
|
| Handle<Map> receiver_map(receiver->map(), isolate());
|
| DCHECK(receiver_map->instance_type() != JS_VALUE_TYPE); // Checked by caller.
|
| MapHandleList target_receiver_maps;
|
| @@ -1250,14 +1200,14 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
|
| PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
|
| receiver_map, extra_ic_state());
|
| ConfigureVectorState(Handle<Name>::null(), receiver_map, handler);
|
| - return null_handle;
|
| + return Handle<Code>();
|
| }
|
|
|
| for (int i = 0; i < target_receiver_maps.length(); i++) {
|
| if (!target_receiver_maps.at(i).is_null() &&
|
| target_receiver_maps.at(i)->instance_type() == JS_VALUE_TYPE) {
|
| TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "JSValue");
|
| - return megamorphic_stub();
|
| + return Handle<Code>();
|
| }
|
| }
|
|
|
| @@ -1276,7 +1226,7 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
|
| PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
|
| receiver_map, extra_ic_state());
|
| ConfigureVectorState(Handle<Name>::null(), receiver_map, handler);
|
| - return null_handle;
|
| + return Handle<Code>();
|
| }
|
|
|
| DCHECK(state() != GENERIC);
|
| @@ -1287,21 +1237,21 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
|
| // If the miss wasn't due to an unseen map, a polymorphic stub
|
| // won't help, use the generic stub.
|
| TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "same map added twice");
|
| - return megamorphic_stub();
|
| + return Handle<Code>();
|
| }
|
|
|
| // If the maximum number of receiver maps has been exceeded, use the generic
|
| // version of the IC.
|
| if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
|
| TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "max polymorph exceeded");
|
| - return megamorphic_stub();
|
| + return Handle<Code>();
|
| }
|
|
|
| CodeHandleList handlers(target_receiver_maps.length());
|
| ElementHandlerCompiler compiler(isolate());
|
| compiler.CompileElementHandlers(&target_receiver_maps, &handlers);
|
| ConfigureVectorState(Handle<Name>::null(), &target_receiver_maps, &handlers);
|
| - return null_handle;
|
| + return Handle<Code>();
|
| }
|
|
|
|
|
| @@ -1316,7 +1266,7 @@ MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
|
| }
|
|
|
| Handle<Object> load_handle;
|
| - Handle<Code> stub = megamorphic_stub();
|
| + Handle<Code> stub;
|
|
|
| // Check for non-string values that can be converted into an
|
| // internalized string directly or is representable as a smi.
|
| @@ -1335,9 +1285,8 @@ MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
|
| }
|
|
|
| DCHECK(UseVector());
|
| - if (!is_vector_set() || stub.is_null()) {
|
| - Code* generic = *megamorphic_stub();
|
| - if (!stub.is_null() && *stub == generic) {
|
| + if (!is_vector_set()) {
|
| + if (stub.is_null()) {
|
| ConfigureVectorState(MEGAMORPHIC);
|
| TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic");
|
| }
|
| @@ -1431,11 +1380,8 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
|
| if (kind() == Code::KEYED_STORE_IC && name->AsArrayIndex(&index)) {
|
| // Rewrite to the generic keyed store stub.
|
| if (FLAG_use_ic) {
|
| - if (UseVector()) {
|
| - ConfigureVectorState(MEGAMORPHIC);
|
| - } else if (!AddressIsDeoptimizedCode()) {
|
| - set_target(*megamorphic_stub());
|
| - }
|
| + DCHECK(UseVector());
|
| + ConfigureVectorState(MEGAMORPHIC);
|
| TRACE_IC("StoreIC", name);
|
| TRACE_GENERIC_IC(isolate(), "StoreIC", "name as array index");
|
| }
|
| @@ -1534,15 +1480,6 @@ Handle<Code> CallIC::initialize_stub_in_optimized_code(
|
| }
|
|
|
|
|
| -static Handle<Code> StoreICInitializeStubHelper(
|
| - Isolate* isolate, ExtraICState extra_state,
|
| - InlineCacheState initialization_state) {
|
| - Handle<Code> ic = PropertyICCompiler::ComputeStore(
|
| - isolate, initialization_state, extra_state);
|
| - return ic;
|
| -}
|
| -
|
| -
|
| Handle<Code> StoreIC::initialize_stub(Isolate* isolate,
|
| LanguageMode language_mode,
|
| State initialization_state) {
|
| @@ -1564,26 +1501,10 @@ Handle<Code> StoreIC::initialize_stub_in_optimized_code(
|
| return stub.GetCode();
|
| }
|
|
|
| - return StoreICInitializeStubHelper(
|
| - isolate, ComputeExtraICState(language_mode), initialization_state);
|
| -}
|
| -
|
| -
|
| -Handle<Code> StoreIC::megamorphic_stub() {
|
| - if (kind() == Code::STORE_IC) {
|
| - return PropertyICCompiler::ComputeStore(isolate(), MEGAMORPHIC,
|
| - extra_ic_state());
|
| - } else {
|
| - DCHECK(kind() == Code::KEYED_STORE_IC);
|
| - if (is_strict(language_mode())) {
|
| - return isolate()->builtins()->KeyedStoreIC_Megamorphic_Strict();
|
| - } else {
|
| - return isolate()->builtins()->KeyedStoreIC_Megamorphic();
|
| - }
|
| - }
|
| + return PropertyICCompiler::ComputeStore(isolate, initialization_state,
|
| + ComputeExtraICState(language_mode));
|
| }
|
|
|
| -
|
| Handle<Code> StoreIC::slow_stub() const {
|
| if (kind() == Code::STORE_IC) {
|
| return isolate()->builtins()->StoreIC_Slow();
|
| @@ -1845,13 +1766,13 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
|
| // If the miss wasn't due to an unseen map, a polymorphic stub
|
| // won't help, use the megamorphic stub which can handle everything.
|
| TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "same map added twice");
|
| - return megamorphic_stub();
|
| + return Handle<Code>();
|
| }
|
|
|
| // If the maximum number of receiver maps has been exceeded, use the
|
| // megamorphic version of the IC.
|
| if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
|
| - return megamorphic_stub();
|
| + return Handle<Code>();
|
| }
|
|
|
| // Make sure all polymorphic handlers have the same store mode, otherwise the
|
| @@ -1862,7 +1783,7 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
|
| store_mode = old_store_mode;
|
| } else if (store_mode != old_store_mode) {
|
| TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "store mode mismatch");
|
| - return megamorphic_stub();
|
| + return Handle<Code>();
|
| }
|
| }
|
|
|
| @@ -1880,7 +1801,7 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
|
| external_arrays != target_receiver_maps.length()) {
|
| TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
|
| "unsupported combination of external and normal arrays");
|
| - return megamorphic_stub();
|
| + return Handle<Code>();
|
| }
|
| }
|
|
|
| @@ -2003,7 +1924,6 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
|
| key = TryConvertKey(key, isolate());
|
|
|
| Handle<Object> store_handle;
|
| - Handle<Code> stub = megamorphic_stub();
|
|
|
| uint32_t index;
|
| if ((key->IsInternalizedString() &&
|
| @@ -2064,6 +1984,7 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
|
| value, language_mode()),
|
| Object);
|
|
|
| + Handle<Code> stub;
|
| if (use_ic) {
|
| if (!old_receiver_map.is_null()) {
|
| if (sloppy_arguments_elements) {
|
| @@ -2087,12 +2008,11 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
|
| }
|
| }
|
|
|
| - if (!is_vector_set() || stub.is_null()) {
|
| - Code* megamorphic = *megamorphic_stub();
|
| - if (!stub.is_null() && (*stub == megamorphic || *stub == *slow_stub())) {
|
| + if (!is_vector_set()) {
|
| + if (stub.is_null() || *stub == *slow_stub()) {
|
| ConfigureVectorState(MEGAMORPHIC);
|
| TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
|
| - *stub == megamorphic ? "set generic" : "slow stub");
|
| + stub.is_null() ? "set generic" : "slow stub");
|
| }
|
| }
|
| TRACE_IC("StoreIC", key);
|
| @@ -2438,7 +2358,7 @@ RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) {
|
| MaybeHandle<Object> BinaryOpIC::Transition(
|
| Handle<AllocationSite> allocation_site, Handle<Object> left,
|
| Handle<Object> right) {
|
| - BinaryOpICState state(isolate(), target()->extra_ic_state());
|
| + BinaryOpICState state(isolate(), extra_ic_state());
|
|
|
| // Compute the actual result using the builtin for the binary operation.
|
| Handle<Object> result;
|
| @@ -2502,12 +2422,8 @@ MaybeHandle<Object> BinaryOpIC::Transition(
|
| return result;
|
| }
|
|
|
| - // Execution::Call can execute arbitrary JavaScript, hence potentially
|
| - // update the state of this very IC, so we must update the stored state.
|
| - UpdateTarget();
|
| -
|
| // Compute the new state.
|
| - BinaryOpICState old_state(isolate(), target()->extra_ic_state());
|
| + BinaryOpICState old_state(isolate(), extra_ic_state());
|
| state.Update(left, right, result);
|
|
|
| // Check if we have a string operation here.
|
| @@ -2665,7 +2581,7 @@ RUNTIME_FUNCTION(Runtime_Unreachable) {
|
|
|
|
|
| Handle<Object> ToBooleanIC::ToBoolean(Handle<Object> object) {
|
| - ToBooleanICStub stub(isolate(), target()->extra_ic_state());
|
| + ToBooleanICStub stub(isolate(), extra_ic_state());
|
| bool to_boolean_value = stub.UpdateStatus(object);
|
| Handle<Code> code = stub.GetCode();
|
| set_target(*code);
|
|
|