Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(642)

Unified Diff: src/ic/ic.cc

Issue 1865863003: Cleanup IC-related code (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ic/ic.h ('k') | src/ic/ic-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
« no previous file with comments | « src/ic/ic.h ('k') | src/ic/ic-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698