[ic] Use FeedbackSlotKind instead of Code::Kind in IC class and friends.
Now we can inline vector-based IC dispatchers to bytecode handlers. BUG=v8:5917 Change-Id: Ie81750f252a730240097e514e69b348f410a48b7 Reviewed-on: https://chromium-review.googlesource.com/439265 Reviewed-by: Michael Stanton <mvstanton@chromium.org> Commit-Queue: Igor Sheludko <ishell@chromium.org> Cr-Commit-Position: refs/heads/master@{#43028}
This commit is contained in:
parent
72bad21c8b
commit
45adc5f836
@ -51,6 +51,7 @@ int FeedbackMetadata::GetSlotSize(FeedbackSlotKind kind) {
|
||||
case FeedbackSlotKind::GENERAL:
|
||||
case FeedbackSlotKind::INTERPRETER_COMPARE_IC:
|
||||
case FeedbackSlotKind::INTERPRETER_BINARYOP_IC:
|
||||
case FeedbackSlotKind::TO_BOOLEAN_IC:
|
||||
case FeedbackSlotKind::LITERAL:
|
||||
case FeedbackSlotKind::CREATE_CLOSURE:
|
||||
return 1;
|
||||
@ -225,6 +226,7 @@ void FeedbackVector::ComputeCounts(int* with_type_info, int* generic,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FeedbackSlotKind::TO_BOOLEAN_IC:
|
||||
case FeedbackSlotKind::CREATE_CLOSURE:
|
||||
case FeedbackSlotKind::GENERAL:
|
||||
case FeedbackSlotKind::LITERAL:
|
||||
|
@ -139,6 +139,8 @@ const char* FeedbackMetadata::Kind2String(FeedbackSlotKind kind) {
|
||||
return "INTERPRETER_BINARYOP_IC";
|
||||
case FeedbackSlotKind::INTERPRETER_COMPARE_IC:
|
||||
return "INTERPRETER_COMPARE_IC";
|
||||
case FeedbackSlotKind::TO_BOOLEAN_IC:
|
||||
return "TO_BOOLEAN_IC";
|
||||
case FeedbackSlotKind::STORE_DATA_PROPERTY_IN_LITERAL_IC:
|
||||
return "STORE_DATA_PROPERTY_IN_LITERAL_IC";
|
||||
case FeedbackSlotKind::CREATE_CLOSURE:
|
||||
@ -191,6 +193,7 @@ Handle<FeedbackVector> FeedbackVector::New(Isolate* isolate,
|
||||
break;
|
||||
case FeedbackSlotKind::INTERPRETER_COMPARE_IC:
|
||||
case FeedbackSlotKind::INTERPRETER_BINARYOP_IC:
|
||||
case FeedbackSlotKind::TO_BOOLEAN_IC:
|
||||
array->set(index, Smi::kZero, SKIP_WRITE_BARRIER);
|
||||
break;
|
||||
case FeedbackSlotKind::CREATE_CLOSURE: {
|
||||
@ -327,6 +330,7 @@ void FeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared,
|
||||
nexus.Clear(shared->code());
|
||||
break;
|
||||
}
|
||||
case FeedbackSlotKind::TO_BOOLEAN_IC:
|
||||
case FeedbackSlotKind::INVALID:
|
||||
case FeedbackSlotKind::KINDS_NUMBER:
|
||||
UNREACHABLE();
|
||||
|
@ -33,6 +33,7 @@ enum class FeedbackSlotKind {
|
||||
KEYED_STORE_STRICT_IC,
|
||||
INTERPRETER_BINARYOP_IC,
|
||||
INTERPRETER_COMPARE_IC,
|
||||
TO_BOOLEAN_IC,
|
||||
STORE_DATA_PROPERTY_IN_LITERAL_IC,
|
||||
CREATE_CLOSURE,
|
||||
LITERAL,
|
||||
|
@ -45,7 +45,10 @@ Code* IC::GetTargetAtAddress(Address address, Address constant_pool) {
|
||||
// Convert target address to the code object. Code::GetCodeFromTargetAddress
|
||||
// is safe for use during GC where the map might be marked.
|
||||
Code* result = Code::GetCodeFromTargetAddress(target);
|
||||
DCHECK(result->is_inline_cache_stub());
|
||||
// The result can be an IC dispatcher (for vector-based ICs), an IC handler
|
||||
// (for old-style patching ICs) or CEntryStub (for IC dispatchers inlined to
|
||||
// bytecode handlers).
|
||||
DCHECK(result->is_inline_cache_stub() || result->is_stub());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
112
src/ic/ic.cc
112
src/ic/ic.cc
@ -143,7 +143,7 @@ void IC::TraceIC(const char* type, Handle<Object> name, State old_state,
|
||||
}
|
||||
|
||||
const char* modifier = "";
|
||||
if (kind() == Code::KEYED_STORE_IC) {
|
||||
if (IsKeyedStoreIC()) {
|
||||
KeyedAccessStoreMode mode =
|
||||
casted_nexus<KeyedStoreICNexus>()->GetKeyedAccessStoreMode();
|
||||
modifier = GetTransitionMarkModifier(mode);
|
||||
@ -196,10 +196,10 @@ void IC::TraceIC(const char* type, Handle<Object> name, State old_state,
|
||||
|
||||
#define TRACE_IC(type, name) TraceIC(type, name)
|
||||
|
||||
|
||||
IC::IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus)
|
||||
: isolate_(isolate),
|
||||
vector_set_(false),
|
||||
kind_(FeedbackSlotKind::INVALID),
|
||||
target_maps_set_(false),
|
||||
nexus_(nexus) {
|
||||
// To improve the performance of the (much used) IC code, we unfold a few
|
||||
@ -247,11 +247,29 @@ IC::IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus)
|
||||
constant_pool_address_ = constant_pool;
|
||||
}
|
||||
pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address);
|
||||
Code* target = this->target();
|
||||
kind_ = target->kind();
|
||||
state_ = UseVector() ? nexus->StateFromFeedback() : StateFromCode(target);
|
||||
if (nexus) {
|
||||
kind_ = nexus->kind();
|
||||
DCHECK(UseVector());
|
||||
state_ = nexus->StateFromFeedback();
|
||||
extra_ic_state_ = kNoExtraICState;
|
||||
} else {
|
||||
Code* target = this->target();
|
||||
Code::Kind kind = target->kind();
|
||||
if (kind == Code::BINARY_OP_IC) {
|
||||
kind_ = FeedbackSlotKind::INTERPRETER_BINARYOP_IC;
|
||||
} else if (kind == Code::COMPARE_IC) {
|
||||
kind_ = FeedbackSlotKind::INTERPRETER_COMPARE_IC;
|
||||
} else if (kind == Code::TO_BOOLEAN_IC) {
|
||||
kind_ = FeedbackSlotKind::TO_BOOLEAN_IC;
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
kind_ = FeedbackSlotKind::INVALID;
|
||||
}
|
||||
DCHECK(!UseVector());
|
||||
state_ = StateFromCode(target);
|
||||
extra_ic_state_ = target->extra_ic_state();
|
||||
}
|
||||
old_state_ = state_;
|
||||
extra_ic_state_ = target->extra_ic_state();
|
||||
}
|
||||
|
||||
// The ICs that don't pass slot and vector through the stack have to
|
||||
@ -350,7 +368,7 @@ bool IC::ShouldRecomputeHandler(Handle<String> name) {
|
||||
|
||||
// This is a contextual access, always just update the handler and stay
|
||||
// monomorphic.
|
||||
if (kind() == Code::LOAD_GLOBAL_IC) return true;
|
||||
if (IsLoadGlobalIC()) return true;
|
||||
|
||||
// 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
|
||||
@ -462,6 +480,7 @@ void IC::OnTypeFeedbackChanged(Isolate* isolate, Code* host) {
|
||||
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.
|
||||
// TODO(ishell): DCHECK
|
||||
if (ICUseVector(target->kind())) return;
|
||||
|
||||
DCHECK(old_target->is_inline_cache_stub());
|
||||
@ -583,13 +602,13 @@ void IC::ConfigureVectorState(IC::State new_state, Handle<Object> key) {
|
||||
if (new_state == PREMONOMORPHIC) {
|
||||
nexus()->ConfigurePremonomorphic();
|
||||
} else if (new_state == MEGAMORPHIC) {
|
||||
if (kind() == Code::LOAD_IC || kind() == Code::STORE_IC) {
|
||||
if (IsLoadIC() || IsStoreIC()) {
|
||||
nexus()->ConfigureMegamorphic();
|
||||
} else if (kind() == Code::KEYED_LOAD_IC) {
|
||||
} else if (IsKeyedLoadIC()) {
|
||||
KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
|
||||
nexus->ConfigureMegamorphicKeyed(key->IsName() ? PROPERTY : ELEMENT);
|
||||
} else {
|
||||
DCHECK(kind() == Code::KEYED_STORE_IC);
|
||||
DCHECK(IsKeyedStoreIC());
|
||||
KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
|
||||
nexus->ConfigureMegamorphicKeyed(key->IsName() ? PROPERTY : ELEMENT);
|
||||
}
|
||||
@ -604,20 +623,20 @@ void IC::ConfigureVectorState(IC::State new_state, Handle<Object> key) {
|
||||
void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
|
||||
Handle<Object> handler) {
|
||||
DCHECK(UseVector());
|
||||
if (kind() == Code::LOAD_IC) {
|
||||
if (IsLoadIC()) {
|
||||
LoadICNexus* nexus = casted_nexus<LoadICNexus>();
|
||||
nexus->ConfigureMonomorphic(map, handler);
|
||||
} else if (kind() == Code::LOAD_GLOBAL_IC) {
|
||||
} else if (IsLoadGlobalIC()) {
|
||||
LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>();
|
||||
nexus->ConfigureHandlerMode(handler);
|
||||
} else if (kind() == Code::KEYED_LOAD_IC) {
|
||||
} else if (IsKeyedLoadIC()) {
|
||||
KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
|
||||
nexus->ConfigureMonomorphic(name, map, handler);
|
||||
} else if (kind() == Code::STORE_IC) {
|
||||
} else if (IsStoreIC()) {
|
||||
StoreICNexus* nexus = casted_nexus<StoreICNexus>();
|
||||
nexus->ConfigureMonomorphic(map, handler);
|
||||
} else {
|
||||
DCHECK(kind() == Code::KEYED_STORE_IC);
|
||||
DCHECK(IsKeyedStoreIC());
|
||||
KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
|
||||
nexus->ConfigureMonomorphic(name, map, handler);
|
||||
}
|
||||
@ -629,17 +648,17 @@ void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
|
||||
void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps,
|
||||
List<Handle<Object>>* handlers) {
|
||||
DCHECK(UseVector());
|
||||
if (kind() == Code::LOAD_IC) {
|
||||
if (IsLoadIC()) {
|
||||
LoadICNexus* nexus = casted_nexus<LoadICNexus>();
|
||||
nexus->ConfigurePolymorphic(maps, handlers);
|
||||
} else if (kind() == Code::KEYED_LOAD_IC) {
|
||||
} else if (IsKeyedLoadIC()) {
|
||||
KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
|
||||
nexus->ConfigurePolymorphic(name, maps, handlers);
|
||||
} else if (kind() == Code::STORE_IC) {
|
||||
} else if (IsStoreIC()) {
|
||||
StoreICNexus* nexus = casted_nexus<StoreICNexus>();
|
||||
nexus->ConfigurePolymorphic(maps, handlers);
|
||||
} else {
|
||||
DCHECK(kind() == Code::KEYED_STORE_IC);
|
||||
DCHECK(IsKeyedStoreIC());
|
||||
KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
|
||||
nexus->ConfigurePolymorphic(name, maps, handlers);
|
||||
}
|
||||
@ -652,7 +671,7 @@ void IC::ConfigureVectorState(MapHandleList* maps,
|
||||
MapHandleList* transitioned_maps,
|
||||
List<Handle<Object>>* handlers) {
|
||||
DCHECK(UseVector());
|
||||
DCHECK(kind() == Code::KEYED_STORE_IC);
|
||||
DCHECK(IsKeyedStoreIC());
|
||||
KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
|
||||
nexus->ConfigurePolymorphic(maps, transitioned_maps, handlers);
|
||||
|
||||
@ -843,12 +862,8 @@ bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) {
|
||||
|
||||
void IC::PatchCache(Handle<Name> name, Handle<Object> handler) {
|
||||
DCHECK(IsHandler(*handler));
|
||||
// Currently only LoadIC and KeyedLoadIC support non-code handlers.
|
||||
DCHECK_IMPLIES(!handler->IsCode(), kind() == Code::LOAD_IC ||
|
||||
kind() == Code::LOAD_GLOBAL_IC ||
|
||||
kind() == Code::KEYED_LOAD_IC ||
|
||||
kind() == Code::STORE_IC ||
|
||||
kind() == Code::KEYED_STORE_IC);
|
||||
// Currently only load and store ICs support non-code handlers.
|
||||
DCHECK_IMPLIES(!handler->IsCode(), IsAnyLoad() || IsAnyStore());
|
||||
switch (state()) {
|
||||
case UNINITIALIZED:
|
||||
case PREMONOMORPHIC:
|
||||
@ -856,7 +871,7 @@ void IC::PatchCache(Handle<Name> name, Handle<Object> handler) {
|
||||
break;
|
||||
case RECOMPUTE_HANDLER:
|
||||
case MONOMORPHIC:
|
||||
if (kind() == Code::LOAD_GLOBAL_IC) {
|
||||
if (IsLoadGlobalIC()) {
|
||||
UpdateMonomorphicIC(handler, name);
|
||||
break;
|
||||
}
|
||||
@ -1101,7 +1116,7 @@ bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) {
|
||||
|
||||
|
||||
void LoadIC::UpdateCaches(LookupIterator* lookup) {
|
||||
if (state() == UNINITIALIZED && kind() != Code::LOAD_GLOBAL_IC) {
|
||||
if (state() == UNINITIALIZED && !IsLoadGlobalIC()) {
|
||||
// This is the first time we execute this inline cache. Set the target to
|
||||
// the pre monomorphic stub to delay setting the monomorphic state.
|
||||
TRACE_HANDLER_STATS(isolate(), LoadIC_Premonomorphic);
|
||||
@ -1115,15 +1130,14 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) {
|
||||
lookup->state() == LookupIterator::ACCESS_CHECK) {
|
||||
code = slow_stub();
|
||||
} else if (!lookup->IsFound()) {
|
||||
if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC) {
|
||||
if (IsLoadIC() || IsLoadGlobalIC()) {
|
||||
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNonexistentDH);
|
||||
code = LoadNonExistent(receiver_map(), lookup->name());
|
||||
} else {
|
||||
code = slow_stub();
|
||||
}
|
||||
} else {
|
||||
if (kind() == Code::LOAD_GLOBAL_IC &&
|
||||
lookup->state() == LookupIterator::DATA &&
|
||||
if (IsLoadGlobalIC() && lookup->state() == LookupIterator::DATA &&
|
||||
lookup->GetReceiver().is_identical_to(lookup->GetHolder<Object>())) {
|
||||
DCHECK(lookup->GetReceiver()->IsJSGlobalObject());
|
||||
// Now update the cell in the feedback vector.
|
||||
@ -1156,20 +1170,12 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) {
|
||||
}
|
||||
|
||||
StubCache* IC::stub_cache() {
|
||||
switch (kind()) {
|
||||
case Code::LOAD_IC:
|
||||
case Code::KEYED_LOAD_IC:
|
||||
return isolate()->load_stub_cache();
|
||||
|
||||
case Code::STORE_IC:
|
||||
case Code::KEYED_STORE_IC:
|
||||
return isolate()->store_stub_cache();
|
||||
|
||||
default:
|
||||
break;
|
||||
if (IsAnyLoad()) {
|
||||
return isolate()->load_stub_cache();
|
||||
} else {
|
||||
DCHECK(IsAnyStore());
|
||||
return isolate()->store_stub_cache();
|
||||
}
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void IC::UpdateMegamorphicCache(Map* map, Name* name, Object* handler) {
|
||||
@ -1179,8 +1185,7 @@ void IC::UpdateMegamorphicCache(Map* map, Name* name, Object* handler) {
|
||||
void IC::TraceHandlerCacheHitStats(LookupIterator* lookup) {
|
||||
if (!FLAG_runtime_call_stats) return;
|
||||
|
||||
if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC ||
|
||||
kind() == Code::KEYED_LOAD_IC) {
|
||||
if (IsAnyLoad()) {
|
||||
switch (lookup->state()) {
|
||||
case LookupIterator::ACCESS_CHECK:
|
||||
TRACE_HANDLER_STATS(isolate(), LoadIC_HandlerCacheHit_AccessCheck);
|
||||
@ -1207,7 +1212,7 @@ void IC::TraceHandlerCacheHitStats(LookupIterator* lookup) {
|
||||
TRACE_HANDLER_STATS(isolate(), LoadIC_HandlerCacheHit_Transition);
|
||||
break;
|
||||
}
|
||||
} else if (kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC) {
|
||||
} else if (IsAnyStore()) {
|
||||
switch (lookup->state()) {
|
||||
case LookupIterator::ACCESS_CHECK:
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_HandlerCacheHit_AccessCheck);
|
||||
@ -1254,19 +1259,18 @@ Handle<Object> IC::ComputeHandler(LookupIterator* lookup,
|
||||
lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>());
|
||||
CacheHolderFlag flag;
|
||||
Handle<Map> stub_holder_map;
|
||||
if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC ||
|
||||
kind() == Code::KEYED_LOAD_IC) {
|
||||
if (IsAnyLoad()) {
|
||||
stub_holder_map = IC::GetHandlerCacheHolder(
|
||||
receiver_map(), receiver_is_holder, isolate(), &flag);
|
||||
} else {
|
||||
DCHECK(kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC);
|
||||
DCHECK(IsAnyStore());
|
||||
// Store handlers cannot be cached on prototypes.
|
||||
flag = kCacheOnReceiver;
|
||||
stub_holder_map = receiver_map();
|
||||
}
|
||||
|
||||
Handle<Object> handler = PropertyHandlerCompiler::Find(
|
||||
lookup->name(), stub_holder_map, kind(), flag);
|
||||
lookup->name(), stub_holder_map, handler_kind(), flag);
|
||||
// Use the cached value if it exists, and if it is different from the
|
||||
// handler that just missed.
|
||||
if (!handler.is_null()) {
|
||||
@ -1384,7 +1388,7 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
|
||||
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadApiGetterDH);
|
||||
return smi_handler;
|
||||
}
|
||||
if (kind() != Code::LOAD_GLOBAL_IC) {
|
||||
if (!IsLoadGlobalIC()) {
|
||||
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadApiGetterFromPrototypeDH);
|
||||
return LoadFromPrototype(map, holder, lookup->name(), smi_handler);
|
||||
}
|
||||
@ -1398,7 +1402,7 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
|
||||
case LookupIterator::DATA: {
|
||||
DCHECK_EQ(kData, lookup->property_details().kind());
|
||||
if (lookup->is_dictionary_holder()) {
|
||||
if (kind() != Code::LOAD_IC && kind() != Code::LOAD_GLOBAL_IC) {
|
||||
if (!IsLoadIC() && !IsLoadGlobalIC()) { // IsKeyedLoadIC()?
|
||||
TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
|
||||
return slow_stub();
|
||||
}
|
||||
@ -1542,7 +1546,7 @@ Handle<Object> LoadIC::CompileHandler(LookupIterator* lookup,
|
||||
|
||||
case LookupIterator::DATA: {
|
||||
DCHECK(lookup->is_dictionary_holder());
|
||||
DCHECK(kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC);
|
||||
DCHECK(IsLoadIC() || IsLoadGlobalIC());
|
||||
DCHECK(holder->IsJSGlobalObject());
|
||||
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadGlobal);
|
||||
NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
|
||||
|
43
src/ic/ic.h
43
src/ic/ic.h
@ -45,15 +45,10 @@ class IC {
|
||||
// Clear the inline cache to initial state.
|
||||
static void Clear(Isolate* isolate, Address address, Address constant_pool);
|
||||
|
||||
#ifdef DEBUG
|
||||
bool IsLoadStub() const {
|
||||
return kind_ == Code::LOAD_IC || kind_ == Code::LOAD_GLOBAL_IC ||
|
||||
kind_ == Code::KEYED_LOAD_IC;
|
||||
bool IsAnyLoad() const {
|
||||
return IsLoadIC() || IsLoadGlobalIC() || IsKeyedLoadIC();
|
||||
}
|
||||
bool IsStoreStub() const {
|
||||
return kind_ == Code::STORE_IC || kind_ == Code::KEYED_STORE_IC;
|
||||
}
|
||||
#endif
|
||||
bool IsAnyStore() const { return IsStoreIC() || IsKeyedStoreIC(); }
|
||||
|
||||
static inline Handle<Map> GetHandlerCacheHolder(Handle<Map> receiver_map,
|
||||
bool receiver_is_holder,
|
||||
@ -73,6 +68,11 @@ class IC {
|
||||
kind == Code::KEYED_LOAD_IC || kind == Code::STORE_IC ||
|
||||
kind == Code::KEYED_STORE_IC;
|
||||
}
|
||||
static bool ICUseVector(FeedbackSlotKind kind) {
|
||||
return IsLoadICKind(kind) || IsLoadGlobalICKind(kind) ||
|
||||
IsKeyedLoadICKind(kind) || IsStoreICKind(kind) ||
|
||||
IsKeyedStoreICKind(kind);
|
||||
}
|
||||
|
||||
// The ICs that don't pass slot and vector through the stack have to
|
||||
// save/restore them in the dispatcher.
|
||||
@ -164,15 +164,17 @@ class IC {
|
||||
void CopyICToMegamorphicCache(Handle<Name> name);
|
||||
bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map);
|
||||
void PatchCache(Handle<Name> name, Handle<Object> code);
|
||||
Code::Kind kind() const { return kind_; }
|
||||
bool is_keyed() const {
|
||||
return kind_ == Code::KEYED_LOAD_IC || kind_ == Code::KEYED_STORE_IC;
|
||||
}
|
||||
FeedbackSlotKind kind() const { return kind_; }
|
||||
bool IsLoadIC() const { return IsLoadICKind(kind_); }
|
||||
bool IsLoadGlobalIC() const { return IsLoadGlobalICKind(kind_); }
|
||||
bool IsKeyedLoadIC() const { return IsKeyedLoadICKind(kind_); }
|
||||
bool IsStoreIC() const { return IsStoreICKind(kind_); }
|
||||
bool IsKeyedStoreIC() const { return IsKeyedStoreICKind(kind_); }
|
||||
bool is_keyed() const { return IsKeyedLoadIC() || IsKeyedStoreIC(); }
|
||||
Code::Kind handler_kind() const {
|
||||
if (kind_ == Code::KEYED_LOAD_IC) return Code::LOAD_IC;
|
||||
DCHECK(kind_ == Code::LOAD_IC || kind_ == Code::STORE_IC ||
|
||||
kind_ == Code::KEYED_STORE_IC);
|
||||
return kind_;
|
||||
if (IsAnyLoad()) return Code::LOAD_IC;
|
||||
DCHECK(IsAnyStore());
|
||||
return Code::STORE_IC;
|
||||
}
|
||||
bool ShouldRecomputeHandler(Handle<String> name);
|
||||
|
||||
@ -243,7 +245,7 @@ class IC {
|
||||
bool vector_set_;
|
||||
State old_state_; // For saving if we marked as prototype failure.
|
||||
State state_;
|
||||
Code::Kind kind_;
|
||||
FeedbackSlotKind kind_;
|
||||
Handle<Map> receiver_map_;
|
||||
MaybeHandle<Object> maybe_handler_;
|
||||
|
||||
@ -273,7 +275,7 @@ class LoadIC : public IC {
|
||||
LoadIC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL)
|
||||
: IC(depth, isolate, nexus) {
|
||||
DCHECK(nexus != NULL);
|
||||
DCHECK(IsLoadStub());
|
||||
DCHECK(IsAnyLoad());
|
||||
}
|
||||
|
||||
static bool ShouldThrowReferenceError(FeedbackSlotKind kind) {
|
||||
@ -281,8 +283,7 @@ class LoadIC : public IC {
|
||||
}
|
||||
|
||||
bool ShouldThrowReferenceError() const {
|
||||
return UseVector() && ShouldThrowReferenceError(
|
||||
nexus()->vector()->GetKind(nexus()->slot()));
|
||||
return ShouldThrowReferenceError(kind());
|
||||
}
|
||||
|
||||
MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object,
|
||||
@ -363,7 +364,7 @@ class StoreIC : public IC {
|
||||
public:
|
||||
StoreIC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL)
|
||||
: IC(depth, isolate, nexus) {
|
||||
DCHECK(IsStoreStub());
|
||||
DCHECK(IsAnyStore());
|
||||
}
|
||||
|
||||
LanguageMode language_mode() const {
|
||||
|
@ -4982,7 +4982,8 @@ bool Code::IsCodeStubOrIC() {
|
||||
}
|
||||
|
||||
ExtraICState Code::extra_ic_state() {
|
||||
DCHECK(is_inline_cache_stub() || is_debug_stub());
|
||||
DCHECK(is_binary_op_stub() || is_compare_ic_stub() ||
|
||||
is_to_boolean_ic_stub() || is_debug_stub());
|
||||
return ExtractExtraICStateFromFlags(flags());
|
||||
}
|
||||
|
||||
@ -5279,6 +5280,7 @@ bool Code::is_debug_stub() {
|
||||
return false;
|
||||
}
|
||||
bool Code::is_handler() { return kind() == HANDLER; }
|
||||
bool Code::is_stub() { return kind() == STUB; }
|
||||
bool Code::is_binary_op_stub() { return kind() == BINARY_OP_IC; }
|
||||
bool Code::is_compare_ic_stub() { return kind() == COMPARE_IC; }
|
||||
bool Code::is_to_boolean_ic_stub() { return kind() == TO_BOOLEAN_IC; }
|
||||
|
@ -804,6 +804,7 @@ void FeedbackVector::FeedbackVectorPrint(std::ostream& os) { // NOLINT
|
||||
case FeedbackSlotKind::LITERAL:
|
||||
case FeedbackSlotKind::GENERAL:
|
||||
break;
|
||||
case FeedbackSlotKind::TO_BOOLEAN_IC:
|
||||
case FeedbackSlotKind::INVALID:
|
||||
case FeedbackSlotKind::KINDS_NUMBER:
|
||||
UNREACHABLE();
|
||||
|
@ -5059,6 +5059,7 @@ class Code: public HeapObject {
|
||||
inline bool is_inline_cache_stub();
|
||||
inline bool is_debug_stub();
|
||||
inline bool is_handler();
|
||||
inline bool is_stub();
|
||||
inline bool is_binary_op_stub();
|
||||
inline bool is_compare_ic_stub();
|
||||
inline bool is_to_boolean_ic_stub();
|
||||
|
Loading…
Reference in New Issue
Block a user