Commit 78751689 authored by verwaest's avatar verwaest Committed by Commit bot

Cleanup IC-related code

BUG=

Review URL: https://codereview.chromium.org/1865863003

Cr-Commit-Position: refs/heads/master@{#35297}
parent d16c3825
......@@ -265,8 +265,8 @@ void StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget(Heap* heap,
// when they might be keeping a Context alive, or when the heap is about
// to be serialized.
if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub() &&
!target->is_call_stub() && (heap->isolate()->serializer_enabled() ||
target->ic_age() != heap->global_ic_age())) {
(heap->isolate()->serializer_enabled() ||
target->ic_age() != heap->global_ic_age())) {
ICUtility::Clear(heap->isolate(), rinfo->pc(),
rinfo->host()->constant_pool());
target = Code::GetCodeFromTargetAddress(rinfo->target_address());
......
......@@ -87,42 +87,12 @@ void IC::SetTargetAtAddress(Address address, Code* target,
void IC::set_target(Code* code) {
SetTargetAtAddress(address(), code, constant_pool());
target_set_ = true;
}
void LoadIC::set_target(Code* code) {
// The contextual mode must be preserved across IC patching.
DCHECK(LoadICState::GetTypeofMode(code->extra_ic_state()) ==
LoadICState::GetTypeofMode(target()->extra_ic_state()));
IC::set_target(code);
}
void StoreIC::set_target(Code* code) {
// Language mode must be preserved across IC patching.
DCHECK(StoreICState::GetLanguageMode(code->extra_ic_state()) ==
StoreICState::GetLanguageMode(target()->extra_ic_state()));
IC::set_target(code);
}
void KeyedStoreIC::set_target(Code* code) {
// Language mode must be preserved across IC patching.
DCHECK(StoreICState::GetLanguageMode(code->extra_ic_state()) ==
language_mode());
IC::set_target(code);
}
Code* IC::raw_target() const {
Code* IC::target() const {
return GetTargetAtAddress(address(), constant_pool());
}
void IC::UpdateTarget() { target_ = handle(raw_target(), isolate_); }
Handle<Map> IC::GetHandlerCacheHolder(Handle<Map> receiver_map,
bool receiver_is_holder, Isolate* isolate,
CacheHolderFlag* flag) {
......
This diff is collapsed.
......@@ -47,14 +47,12 @@ class IC {
#ifdef DEBUG
bool IsLoadStub() const {
return target()->is_load_stub() || target()->is_keyed_load_stub();
return kind_ == Code::LOAD_IC || kind_ == Code::KEYED_LOAD_IC;
}
bool IsStoreStub() const {
return target()->is_store_stub() || target()->is_keyed_store_stub();
return kind_ == Code::STORE_IC || kind_ == Code::KEYED_STORE_IC;
}
bool IsCallStub() const { return target()->is_call_stub(); }
bool IsCallStub() const { return kind_ == Code::CALL_IC; }
#endif
static inline Handle<Map> GetHandlerCacheHolder(Handle<Map> receiver_map,
......@@ -82,9 +80,6 @@ class IC {
}
protected:
// Get the call-site target; used for determining the state.
Handle<Code> target() const { return target_; }
Address fp() const { return fp_; }
Address pc() const { return *pc_address_; }
Isolate* isolate() const { return isolate_; }
......@@ -101,13 +96,12 @@ class IC {
// Set the call-site target.
inline void set_target(Code* code);
bool is_target_set() { return target_set_; }
bool is_vector_set() { return vector_set_; }
bool UseVector() const {
bool use = ICUseVector(kind());
// If we are supposed to use the nexus, verify the nexus is non-null.
DCHECK(!use || nexus_ != NULL);
DCHECK(!use || nexus_ != nullptr);
return use;
}
......@@ -139,9 +133,6 @@ class IC {
Address constant_pool);
static inline void SetTargetAtAddress(Address address, Code* target,
Address constant_pool);
static void OnTypeFeedbackChanged(Isolate* isolate, Address address,
State old_state, State new_state,
bool target_remains_ic_stub);
// As a vector-based IC, type feedback must be updated differently.
static void OnTypeFeedbackChanged(Isolate* isolate, Code* host);
static void PostPatching(Address address, Code* target, Code* old_target);
......@@ -164,21 +155,18 @@ class IC {
bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map);
void PatchCache(Handle<Name> name, Handle<Code> code);
Code::Kind kind() const { return kind_; }
bool is_keyed() const {
return kind_ == Code::KEYED_LOAD_IC || kind_ == Code::KEYED_STORE_IC;
}
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_;
}
virtual Handle<Code> megamorphic_stub() {
UNREACHABLE();
return Handle<Code>::null();
}
bool ShouldRecomputeHandler(Handle<Object> receiver, Handle<String> name);
ExtraICState extra_ic_state() const { return extra_ic_state_; }
void set_extra_ic_state(ExtraICState state) { extra_ic_state_ = state; }
Handle<Map> receiver_map() { return receiver_map_; }
void update_receiver_map(Handle<Object> receiver) {
......@@ -201,8 +189,6 @@ class IC {
return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL;
}
inline void UpdateTarget();
Handle<TypeFeedbackVector> vector() const { return nexus()->vector_handle(); }
FeedbackVectorSlot slot() const { return nexus()->slot(); }
State saved_state() const {
......@@ -216,25 +202,17 @@ class IC {
FeedbackNexus* nexus() const { return nexus_; }
inline Code* get_host();
inline Code* target() const;
private:
inline Code* raw_target() const;
inline Address constant_pool() const;
inline Address raw_constant_pool() const;
void FindTargetMaps() {
if (target_maps_set_) return;
target_maps_set_ = true;
if (UseVector()) {
nexus()->ExtractMaps(&target_maps_);
} else {
if (state_ == MONOMORPHIC) {
Map* map = target_->FindFirstMap();
if (map != NULL) target_maps_.Add(handle(map));
} else if (state_ != UNINITIALIZED && state_ != PREMONOMORPHIC) {
target_->FindAllMaps(&target_maps_);
}
}
DCHECK(UseVector());
nexus()->ExtractMaps(&target_maps_);
}
// Frame pointer for the frame that uses (calls) the IC.
......@@ -252,9 +230,6 @@ class IC {
Isolate* isolate_;
// The original code target that missed.
Handle<Code> target_;
bool target_set_;
bool vector_set_;
State old_state_; // For saving if we marked as prototype failure.
State state_;
......@@ -330,8 +305,6 @@ class LoadIC : public IC {
static void Clear(Isolate* isolate, Code* host, LoadICNexus* nexus);
protected:
inline void set_target(Code* code);
Handle<Code> slow_stub() const {
if (kind() == Code::LOAD_IC) {
return isolate()->builtins()->LoadIC_Slow();
......@@ -341,8 +314,6 @@ class LoadIC : public IC {
}
}
Handle<Code> megamorphic_stub() override;
// Update the inline cache and the global stub cache based on the
// lookup result.
void UpdateCaches(LookupIterator* lookup);
......@@ -377,7 +348,6 @@ class KeyedLoadIC : public LoadIC {
KeyedLoadICNexus* nexus = NULL)
: LoadIC(depth, isolate, nexus) {
DCHECK(nexus != NULL);
DCHECK(target()->is_keyed_load_stub());
}
MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object,
......@@ -454,7 +424,6 @@ class StoreIC : public IC {
protected:
// Stub accessors.
Handle<Code> megamorphic_stub() override;
Handle<Code> slow_stub() const;
// Update the inline cache and the global stub cache based on the
......@@ -465,8 +434,6 @@ class StoreIC : public IC {
CacheHolderFlag cache_holder) override;
private:
inline void set_target(Code* code);
friend class IC;
};
......@@ -501,9 +468,7 @@ class KeyedStoreIC : public StoreIC {
KeyedStoreIC(FrameDepth depth, Isolate* isolate,
KeyedStoreICNexus* nexus = NULL)
: StoreIC(depth, isolate, nexus) {
DCHECK(target()->is_keyed_store_stub());
}
: StoreIC(depth, isolate, nexus) {}
MUST_USE_RESULT MaybeHandle<Object> Store(Handle<Object> object,
Handle<Object> name,
......@@ -531,8 +496,6 @@ class KeyedStoreIC : public StoreIC {
KeyedAccessStoreMode store_mode);
private:
inline void set_target(Code* code);
Handle<Map> ComputeTransitionedMap(Handle<Map> map,
KeyedAccessStoreMode store_mode);
......
......@@ -5025,18 +5025,8 @@ bool Code::is_inline_cache_stub() {
}
}
bool Code::is_keyed_stub() {
return is_keyed_load_stub() || is_keyed_store_stub();
}
bool Code::is_debug_stub() { return ic_state() == DEBUG_STUB; }
bool Code::is_handler() { return kind() == HANDLER; }
bool Code::is_load_stub() { return kind() == LOAD_IC; }
bool Code::is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; }
bool Code::is_store_stub() { return kind() == STORE_IC; }
bool Code::is_keyed_store_stub() { return kind() == KEYED_STORE_IC; }
bool Code::is_call_stub() { return kind() == CALL_IC; }
bool Code::is_binary_op_stub() { return kind() == BINARY_OP_IC; }
bool Code::is_compare_ic_stub() { return kind() == COMPARE_IC; }
......
......@@ -13792,126 +13792,14 @@ void Code::FindAndReplace(const FindAndReplacePattern& pattern) {
}
void Code::FindAllMaps(MapHandleList* maps) {
DCHECK(is_inline_cache_stub());
DisallowHeapAllocation no_allocation;
int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
for (RelocIterator it(this, mask); !it.done(); it.next()) {
RelocInfo* info = it.rinfo();
Object* object = info->target_object();
if (object->IsWeakCell()) object = WeakCell::cast(object)->value();
if (object->IsMap()) maps->Add(handle(Map::cast(object)));
}
}
Code* Code::FindFirstHandler() {
DCHECK(is_inline_cache_stub());
DisallowHeapAllocation no_allocation;
int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
bool skip_next_handler = false;
for (RelocIterator it(this, mask); !it.done(); it.next()) {
RelocInfo* info = it.rinfo();
if (info->rmode() == RelocInfo::EMBEDDED_OBJECT) {
Object* obj = info->target_object();
skip_next_handler |= obj->IsWeakCell() && WeakCell::cast(obj)->cleared();
} else {
Code* code = Code::GetCodeFromTargetAddress(info->target_address());
if (code->kind() == Code::HANDLER) {
if (!skip_next_handler) return code;
skip_next_handler = false;
}
}
}
return NULL;
}
bool Code::FindHandlers(CodeHandleList* code_list, int length) {
DCHECK(is_inline_cache_stub());
DisallowHeapAllocation no_allocation;
int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
bool skip_next_handler = false;
int i = 0;
for (RelocIterator it(this, mask); !it.done(); it.next()) {
if (i == length) return true;
RelocInfo* info = it.rinfo();
if (info->rmode() == RelocInfo::EMBEDDED_OBJECT) {
Object* obj = info->target_object();
skip_next_handler |= obj->IsWeakCell() && WeakCell::cast(obj)->cleared();
} else {
Code* code = Code::GetCodeFromTargetAddress(info->target_address());
// IC stubs with handlers never contain non-handler code objects before
// handler targets.
if (code->kind() != Code::HANDLER) break;
if (!skip_next_handler) {
code_list->Add(Handle<Code>(code));
i++;
}
skip_next_handler = false;
}
}
return i == length;
}
MaybeHandle<Code> Code::FindHandlerForMap(Map* map) {
DCHECK(is_inline_cache_stub());
int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
bool return_next = false;
for (RelocIterator it(this, mask); !it.done(); it.next()) {
RelocInfo* info = it.rinfo();
if (info->rmode() == RelocInfo::EMBEDDED_OBJECT) {
Object* object = info->target_object();
if (object->IsWeakCell()) object = WeakCell::cast(object)->value();
if (object == map) return_next = true;
} else if (return_next) {
Code* code = Code::GetCodeFromTargetAddress(info->target_address());
DCHECK(code->kind() == Code::HANDLER);
return handle(code);
}
}
return MaybeHandle<Code>();
}
Name* Code::FindFirstName() {
DCHECK(is_inline_cache_stub());
DisallowHeapAllocation no_allocation;
int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
for (RelocIterator it(this, mask); !it.done(); it.next()) {
RelocInfo* info = it.rinfo();
Object* object = info->target_object();
if (object->IsName()) return Name::cast(object);
}
return NULL;
}
void Code::ClearInlineCaches() {
ClearInlineCaches(NULL);
}
void Code::ClearInlineCaches(Code::Kind kind) {
ClearInlineCaches(&kind);
}
void Code::ClearInlineCaches(Code::Kind* kind) {
int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID);
for (RelocIterator it(this, mask); !it.done(); it.next()) {
RelocInfo* info = it.rinfo();
Code* target(Code::GetCodeFromTargetAddress(info->target_address()));
if (target->is_inline_cache_stub()) {
if (kind == NULL || *kind == target->kind()) {
IC::Clear(this->GetIsolate(), info->pc(),
info->host()->constant_pool());
}
IC::Clear(this->GetIsolate(), info->pc(), info->host()->constant_pool());
}
}
}
......
......@@ -5012,15 +5012,10 @@ class Code: public HeapObject {
inline bool is_inline_cache_stub();
inline bool is_debug_stub();
inline bool is_handler();
inline bool is_load_stub();
inline bool is_keyed_load_stub();
inline bool is_store_stub();
inline bool is_keyed_store_stub();
inline bool is_call_stub();
inline bool is_binary_op_stub();
inline bool is_compare_ic_stub();
inline bool is_to_boolean_ic_stub();
inline bool is_keyed_stub();
inline bool is_optimized_code();
inline bool is_wasm_code();
inline bool embeds_maps_weakly();
......@@ -5127,20 +5122,6 @@ class Code: public HeapObject {
// Find the first map in an IC stub.
Map* FindFirstMap();
void FindAllMaps(MapHandleList* maps);
// Find the first handler in an IC stub.
Code* FindFirstHandler();
// Find |length| handlers and put them into |code_list|. Returns false if not
// enough handlers can be found.
bool FindHandlers(CodeHandleList* code_list, int length = -1);
// Find the handler for |map|.
MaybeHandle<Code> FindHandlerForMap(Map* map);
// Find the first name in an IC stub.
Name* FindFirstName();
class FindAndReplacePattern;
// For each (map-to-find, object-to-replace) pair in the pattern, this
......@@ -5234,7 +5215,6 @@ class Code: public HeapObject {
DECLARE_VERIFIER(Code)
void ClearInlineCaches();
void ClearInlineCaches(Kind kind);
BailoutId TranslatePcOffsetToAstId(uint32_t pc_offset);
uint32_t TranslateAstIdToPcOffset(BailoutId ast_id);
......@@ -5403,8 +5383,6 @@ class Code: public HeapObject {
friend class RelocIterator;
friend class Deoptimizer; // For FindCodeAgeSequence.
void ClearInlineCaches(Kind* kind);
// Code aging
byte* FindCodeAgeSequence();
static void GetCodeAgeAndParity(Code* code, Age* age,
......
......@@ -295,7 +295,7 @@ void TypeFeedbackOracle::KeyedPropertyReceiverTypes(
*key_type = ELEMENT;
} else {
KeyedLoadICNexus nexus(feedback_vector_, slot);
CollectReceiverTypes<FeedbackNexus>(&nexus, receiver_types);
CollectReceiverTypes(&nexus, receiver_types);
*is_string = HasOnlyStringMaps(receiver_types);
*key_type = nexus.FindFirstName() != NULL ? PROPERTY : ELEMENT;
}
......@@ -332,21 +332,20 @@ void TypeFeedbackOracle::CollectReceiverTypes(FeedbackVectorSlot slot,
Code::Flags flags,
SmallMapList* types) {
StoreICNexus nexus(feedback_vector_, slot);
CollectReceiverTypes<FeedbackNexus>(&nexus, name, flags, types);
CollectReceiverTypes(&nexus, name, flags, types);
}
template <class T>
void TypeFeedbackOracle::CollectReceiverTypes(T* obj, Handle<Name> name,
void TypeFeedbackOracle::CollectReceiverTypes(FeedbackNexus* nexus,
Handle<Name> name,
Code::Flags flags,
SmallMapList* types) {
if (FLAG_collect_megamorphic_maps_from_stub_cache &&
obj->ic_state() == MEGAMORPHIC) {
nexus->ic_state() == MEGAMORPHIC) {
types->Reserve(4, zone());
isolate()->stub_cache()->CollectMatchingMaps(
types, name, flags, native_context_, zone());
} else {
CollectReceiverTypes<T>(obj, types);
CollectReceiverTypes(nexus, types);
}
}
......@@ -356,23 +355,22 @@ void TypeFeedbackOracle::CollectReceiverTypes(FeedbackVectorSlot slot,
FeedbackVectorSlotKind kind = feedback_vector_->GetKind(slot);
if (kind == FeedbackVectorSlotKind::STORE_IC) {
StoreICNexus nexus(feedback_vector_, slot);
CollectReceiverTypes<FeedbackNexus>(&nexus, types);
CollectReceiverTypes(&nexus, types);
} else {
DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, kind);
KeyedStoreICNexus nexus(feedback_vector_, slot);
CollectReceiverTypes<FeedbackNexus>(&nexus, types);
CollectReceiverTypes(&nexus, types);
}
}
template <class T>
void TypeFeedbackOracle::CollectReceiverTypes(T* obj, SmallMapList* types) {
void TypeFeedbackOracle::CollectReceiverTypes(FeedbackNexus* nexus,
SmallMapList* types) {
MapHandleList maps;
if (obj->ic_state() == MONOMORPHIC) {
Map* map = obj->FindFirstMap();
if (nexus->ic_state() == MONOMORPHIC) {
Map* map = nexus->FindFirstMap();
if (map != NULL) maps.Add(handle(map));
} else if (obj->ic_state() == POLYMORPHIC) {
obj->FindAllMaps(&maps);
} else if (nexus->ic_state() == POLYMORPHIC) {
nexus->FindAllMaps(&maps);
} else {
return;
}
......
......@@ -17,7 +17,7 @@ namespace internal {
// Forward declarations.
class SmallMapList;
class FeedbackNexus;
class TypeFeedbackOracle: public ZoneObject {
public:
......@@ -56,8 +56,7 @@ class TypeFeedbackOracle: public ZoneObject {
SmallMapList* receiver_types);
void CollectReceiverTypes(FeedbackVectorSlot slot, SmallMapList* types);
template <class T>
void CollectReceiverTypes(T* obj, SmallMapList* types);
void CollectReceiverTypes(FeedbackNexus* nexus, SmallMapList* types);
static bool IsRelevantFeedback(Map* map, Context* native_context) {
Object* constructor = map->GetConstructor();
......@@ -98,9 +97,8 @@ class TypeFeedbackOracle: public ZoneObject {
private:
void CollectReceiverTypes(FeedbackVectorSlot slot, Handle<Name> name,
Code::Flags flags, SmallMapList* types);
template <class T>
void CollectReceiverTypes(T* obj, Handle<Name> name, Code::Flags flags,
SmallMapList* types);
void CollectReceiverTypes(FeedbackNexus* nexus, Handle<Name> name,
Code::Flags flags, SmallMapList* types);
// Returns true if there is at least one string map and if
// all maps are string maps.
......
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