Commit 45adc5f8 authored by ishell@chromium.org's avatar ishell@chromium.org Committed by Commit Bot

[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/439265Reviewed-by: 's avatarMichael Stanton <mvstanton@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43028}
parent 72bad21c
...@@ -51,6 +51,7 @@ int FeedbackMetadata::GetSlotSize(FeedbackSlotKind kind) { ...@@ -51,6 +51,7 @@ int FeedbackMetadata::GetSlotSize(FeedbackSlotKind kind) {
case FeedbackSlotKind::GENERAL: case FeedbackSlotKind::GENERAL:
case FeedbackSlotKind::INTERPRETER_COMPARE_IC: case FeedbackSlotKind::INTERPRETER_COMPARE_IC:
case FeedbackSlotKind::INTERPRETER_BINARYOP_IC: case FeedbackSlotKind::INTERPRETER_BINARYOP_IC:
case FeedbackSlotKind::TO_BOOLEAN_IC:
case FeedbackSlotKind::LITERAL: case FeedbackSlotKind::LITERAL:
case FeedbackSlotKind::CREATE_CLOSURE: case FeedbackSlotKind::CREATE_CLOSURE:
return 1; return 1;
...@@ -225,6 +226,7 @@ void FeedbackVector::ComputeCounts(int* with_type_info, int* generic, ...@@ -225,6 +226,7 @@ void FeedbackVector::ComputeCounts(int* with_type_info, int* generic,
} }
break; break;
} }
case FeedbackSlotKind::TO_BOOLEAN_IC:
case FeedbackSlotKind::CREATE_CLOSURE: case FeedbackSlotKind::CREATE_CLOSURE:
case FeedbackSlotKind::GENERAL: case FeedbackSlotKind::GENERAL:
case FeedbackSlotKind::LITERAL: case FeedbackSlotKind::LITERAL:
......
...@@ -139,6 +139,8 @@ const char* FeedbackMetadata::Kind2String(FeedbackSlotKind kind) { ...@@ -139,6 +139,8 @@ const char* FeedbackMetadata::Kind2String(FeedbackSlotKind kind) {
return "INTERPRETER_BINARYOP_IC"; return "INTERPRETER_BINARYOP_IC";
case FeedbackSlotKind::INTERPRETER_COMPARE_IC: case FeedbackSlotKind::INTERPRETER_COMPARE_IC:
return "INTERPRETER_COMPARE_IC"; return "INTERPRETER_COMPARE_IC";
case FeedbackSlotKind::TO_BOOLEAN_IC:
return "TO_BOOLEAN_IC";
case FeedbackSlotKind::STORE_DATA_PROPERTY_IN_LITERAL_IC: case FeedbackSlotKind::STORE_DATA_PROPERTY_IN_LITERAL_IC:
return "STORE_DATA_PROPERTY_IN_LITERAL_IC"; return "STORE_DATA_PROPERTY_IN_LITERAL_IC";
case FeedbackSlotKind::CREATE_CLOSURE: case FeedbackSlotKind::CREATE_CLOSURE:
...@@ -191,6 +193,7 @@ Handle<FeedbackVector> FeedbackVector::New(Isolate* isolate, ...@@ -191,6 +193,7 @@ Handle<FeedbackVector> FeedbackVector::New(Isolate* isolate,
break; break;
case FeedbackSlotKind::INTERPRETER_COMPARE_IC: case FeedbackSlotKind::INTERPRETER_COMPARE_IC:
case FeedbackSlotKind::INTERPRETER_BINARYOP_IC: case FeedbackSlotKind::INTERPRETER_BINARYOP_IC:
case FeedbackSlotKind::TO_BOOLEAN_IC:
array->set(index, Smi::kZero, SKIP_WRITE_BARRIER); array->set(index, Smi::kZero, SKIP_WRITE_BARRIER);
break; break;
case FeedbackSlotKind::CREATE_CLOSURE: { case FeedbackSlotKind::CREATE_CLOSURE: {
...@@ -327,6 +330,7 @@ void FeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared, ...@@ -327,6 +330,7 @@ void FeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared,
nexus.Clear(shared->code()); nexus.Clear(shared->code());
break; break;
} }
case FeedbackSlotKind::TO_BOOLEAN_IC:
case FeedbackSlotKind::INVALID: case FeedbackSlotKind::INVALID:
case FeedbackSlotKind::KINDS_NUMBER: case FeedbackSlotKind::KINDS_NUMBER:
UNREACHABLE(); UNREACHABLE();
......
...@@ -33,6 +33,7 @@ enum class FeedbackSlotKind { ...@@ -33,6 +33,7 @@ enum class FeedbackSlotKind {
KEYED_STORE_STRICT_IC, KEYED_STORE_STRICT_IC,
INTERPRETER_BINARYOP_IC, INTERPRETER_BINARYOP_IC,
INTERPRETER_COMPARE_IC, INTERPRETER_COMPARE_IC,
TO_BOOLEAN_IC,
STORE_DATA_PROPERTY_IN_LITERAL_IC, STORE_DATA_PROPERTY_IN_LITERAL_IC,
CREATE_CLOSURE, CREATE_CLOSURE,
LITERAL, LITERAL,
......
...@@ -45,7 +45,10 @@ Code* IC::GetTargetAtAddress(Address address, Address constant_pool) { ...@@ -45,7 +45,10 @@ Code* IC::GetTargetAtAddress(Address address, Address constant_pool) {
// Convert target address to the code object. Code::GetCodeFromTargetAddress // Convert target address to the code object. Code::GetCodeFromTargetAddress
// is safe for use during GC where the map might be marked. // is safe for use during GC where the map might be marked.
Code* result = Code::GetCodeFromTargetAddress(target); 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; return result;
} }
......
This diff is collapsed.
...@@ -45,15 +45,10 @@ class IC { ...@@ -45,15 +45,10 @@ class IC {
// Clear the inline cache to initial state. // Clear the inline cache to initial state.
static void Clear(Isolate* isolate, Address address, Address constant_pool); static void Clear(Isolate* isolate, Address address, Address constant_pool);
#ifdef DEBUG bool IsAnyLoad() const {
bool IsLoadStub() const { return IsLoadIC() || IsLoadGlobalIC() || IsKeyedLoadIC();
return kind_ == Code::LOAD_IC || kind_ == Code::LOAD_GLOBAL_IC ||
kind_ == Code::KEYED_LOAD_IC;
} }
bool IsStoreStub() const { bool IsAnyStore() const { return IsStoreIC() || IsKeyedStoreIC(); }
return kind_ == Code::STORE_IC || kind_ == Code::KEYED_STORE_IC;
}
#endif
static inline Handle<Map> GetHandlerCacheHolder(Handle<Map> receiver_map, static inline Handle<Map> GetHandlerCacheHolder(Handle<Map> receiver_map,
bool receiver_is_holder, bool receiver_is_holder,
...@@ -73,6 +68,11 @@ class IC { ...@@ -73,6 +68,11 @@ class IC {
kind == Code::KEYED_LOAD_IC || kind == Code::STORE_IC || kind == Code::KEYED_LOAD_IC || kind == Code::STORE_IC ||
kind == Code::KEYED_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 // The ICs that don't pass slot and vector through the stack have to
// save/restore them in the dispatcher. // save/restore them in the dispatcher.
...@@ -164,15 +164,17 @@ class IC { ...@@ -164,15 +164,17 @@ class IC {
void CopyICToMegamorphicCache(Handle<Name> name); void CopyICToMegamorphicCache(Handle<Name> name);
bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map); bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map);
void PatchCache(Handle<Name> name, Handle<Object> code); void PatchCache(Handle<Name> name, Handle<Object> code);
Code::Kind kind() const { return kind_; } FeedbackSlotKind kind() const { return kind_; }
bool is_keyed() const { bool IsLoadIC() const { return IsLoadICKind(kind_); }
return kind_ == Code::KEYED_LOAD_IC || kind_ == Code::KEYED_STORE_IC; 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 { Code::Kind handler_kind() const {
if (kind_ == Code::KEYED_LOAD_IC) return Code::LOAD_IC; if (IsAnyLoad()) return Code::LOAD_IC;
DCHECK(kind_ == Code::LOAD_IC || kind_ == Code::STORE_IC || DCHECK(IsAnyStore());
kind_ == Code::KEYED_STORE_IC); return Code::STORE_IC;
return kind_;
} }
bool ShouldRecomputeHandler(Handle<String> name); bool ShouldRecomputeHandler(Handle<String> name);
...@@ -243,7 +245,7 @@ class IC { ...@@ -243,7 +245,7 @@ class IC {
bool vector_set_; bool vector_set_;
State old_state_; // For saving if we marked as prototype failure. State old_state_; // For saving if we marked as prototype failure.
State state_; State state_;
Code::Kind kind_; FeedbackSlotKind kind_;
Handle<Map> receiver_map_; Handle<Map> receiver_map_;
MaybeHandle<Object> maybe_handler_; MaybeHandle<Object> maybe_handler_;
...@@ -273,7 +275,7 @@ class LoadIC : public IC { ...@@ -273,7 +275,7 @@ class LoadIC : public IC {
LoadIC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL) LoadIC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL)
: IC(depth, isolate, nexus) { : IC(depth, isolate, nexus) {
DCHECK(nexus != NULL); DCHECK(nexus != NULL);
DCHECK(IsLoadStub()); DCHECK(IsAnyLoad());
} }
static bool ShouldThrowReferenceError(FeedbackSlotKind kind) { static bool ShouldThrowReferenceError(FeedbackSlotKind kind) {
...@@ -281,8 +283,7 @@ class LoadIC : public IC { ...@@ -281,8 +283,7 @@ class LoadIC : public IC {
} }
bool ShouldThrowReferenceError() const { bool ShouldThrowReferenceError() const {
return UseVector() && ShouldThrowReferenceError( return ShouldThrowReferenceError(kind());
nexus()->vector()->GetKind(nexus()->slot()));
} }
MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object,
...@@ -363,7 +364,7 @@ class StoreIC : public IC { ...@@ -363,7 +364,7 @@ class StoreIC : public IC {
public: public:
StoreIC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL) StoreIC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL)
: IC(depth, isolate, nexus) { : IC(depth, isolate, nexus) {
DCHECK(IsStoreStub()); DCHECK(IsAnyStore());
} }
LanguageMode language_mode() const { LanguageMode language_mode() const {
......
...@@ -4982,7 +4982,8 @@ bool Code::IsCodeStubOrIC() { ...@@ -4982,7 +4982,8 @@ bool Code::IsCodeStubOrIC() {
} }
ExtraICState Code::extra_ic_state() { 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()); return ExtractExtraICStateFromFlags(flags());
} }
...@@ -5279,6 +5280,7 @@ bool Code::is_debug_stub() { ...@@ -5279,6 +5280,7 @@ bool Code::is_debug_stub() {
return false; return false;
} }
bool Code::is_handler() { return kind() == HANDLER; } 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_binary_op_stub() { return kind() == BINARY_OP_IC; }
bool Code::is_compare_ic_stub() { return kind() == COMPARE_IC; } bool Code::is_compare_ic_stub() { return kind() == COMPARE_IC; }
bool Code::is_to_boolean_ic_stub() { return kind() == TO_BOOLEAN_IC; } bool Code::is_to_boolean_ic_stub() { return kind() == TO_BOOLEAN_IC; }
......
...@@ -804,6 +804,7 @@ void FeedbackVector::FeedbackVectorPrint(std::ostream& os) { // NOLINT ...@@ -804,6 +804,7 @@ void FeedbackVector::FeedbackVectorPrint(std::ostream& os) { // NOLINT
case FeedbackSlotKind::LITERAL: case FeedbackSlotKind::LITERAL:
case FeedbackSlotKind::GENERAL: case FeedbackSlotKind::GENERAL:
break; break;
case FeedbackSlotKind::TO_BOOLEAN_IC:
case FeedbackSlotKind::INVALID: case FeedbackSlotKind::INVALID:
case FeedbackSlotKind::KINDS_NUMBER: case FeedbackSlotKind::KINDS_NUMBER:
UNREACHABLE(); UNREACHABLE();
......
...@@ -5059,6 +5059,7 @@ class Code: public HeapObject { ...@@ -5059,6 +5059,7 @@ class Code: public HeapObject {
inline bool is_inline_cache_stub(); inline bool is_inline_cache_stub();
inline bool is_debug_stub(); inline bool is_debug_stub();
inline bool is_handler(); inline bool is_handler();
inline bool is_stub();
inline bool is_binary_op_stub(); inline bool is_binary_op_stub();
inline bool is_compare_ic_stub(); inline bool is_compare_ic_stub();
inline bool is_to_boolean_ic_stub(); inline bool is_to_boolean_ic_stub();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment