Commit 9c59539f authored by jkummerow's avatar jkummerow Committed by Commit bot

[LoadIC] Handle simple field loads in the dispatcher

No compiled handlers required! Instead, the type feedback vector
contains a Smi encoding the field index.

Review-Url: https://codereview.chromium.org/2133233002
Cr-Commit-Position: refs/heads/master@{#37803}
parent 7e1d1fc7
...@@ -2143,8 +2143,7 @@ void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map, ...@@ -2143,8 +2143,7 @@ void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map,
Bind(&rebox_double); Bind(&rebox_double);
{ {
Comment("rebox_double"); Comment("rebox_double");
Node* heap_number = AllocateHeapNumber(); Node* heap_number = AllocateHeapNumberWithValue(var_double_value.value());
StoreHeapNumberValue(heap_number, var_double_value.value());
var_value->Bind(heap_number); var_value->Bind(heap_number);
Goto(&done); Goto(&done);
} }
...@@ -2940,14 +2939,69 @@ void CodeStubAssembler::LoadIC(const LoadICParameters* p) { ...@@ -2940,14 +2939,69 @@ void CodeStubAssembler::LoadIC(const LoadICParameters* p) {
&var_handler, &try_polymorphic); &var_handler, &try_polymorphic);
Bind(&if_handler); Bind(&if_handler);
{ {
Comment("LoadIC_if_handler");
Label call_handler(this);
Node* handler = var_handler.value();
GotoUnless(WordIsSmi(handler), &call_handler);
// |handler| is a Smi. It encodes a field index as obtained by
// FieldIndex.GetLoadByFieldOffset().
{
Label inobject_double(this), out_of_object(this),
out_of_object_double(this);
Variable var_double_value(this, MachineRepresentation::kFloat64);
Label rebox_double(this, &var_double_value);
Node* handler_word = SmiToWord32(handler);
// handler == (offset << 1) | is_double.
Node* double_bit = Word32And(handler_word, Int32Constant(1));
Node* offset = Word32Sar(handler_word, Int32Constant(1));
// Negative index -> out of object.
GotoIf(Int32LessThan(offset, Int32Constant(0)), &out_of_object);
Node* offset_ptr = ChangeInt32ToIntPtr(offset);
GotoUnless(Word32Equal(double_bit, Int32Constant(0)), &inobject_double);
Return(LoadObjectField(p->receiver, offset_ptr));
Bind(&inobject_double);
if (FLAG_unbox_double_fields) {
var_double_value.Bind(
LoadObjectField(p->receiver, offset_ptr, MachineType::Float64()));
} else {
Node* mutable_heap_number = LoadObjectField(p->receiver, offset_ptr);
var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number));
}
Goto(&rebox_double);
Bind(&out_of_object);
// |offset| == -actual_offset
offset_ptr = ChangeInt32ToIntPtr(Int32Sub(Int32Constant(0), offset));
Node* properties = LoadProperties(p->receiver);
Node* value = LoadObjectField(properties, offset_ptr);
GotoUnless(Word32Equal(double_bit, Int32Constant(0)),
&out_of_object_double);
Return(value);
Bind(&out_of_object_double);
var_double_value.Bind(LoadHeapNumberValue(value));
Goto(&rebox_double);
Bind(&rebox_double);
Return(AllocateHeapNumberWithValue(var_double_value.value()));
}
// |handler| is a heap object. Must be code, call it.
Bind(&call_handler);
LoadWithVectorDescriptor descriptor(isolate()); LoadWithVectorDescriptor descriptor(isolate());
TailCallStub(descriptor, var_handler.value(), p->context, p->receiver, TailCallStub(descriptor, handler, p->context, p->receiver, p->name, p->slot,
p->name, p->slot, p->vector); p->vector);
} }
Bind(&try_polymorphic); Bind(&try_polymorphic);
{ {
// Check polymorphic case. // Check polymorphic case.
Comment("LoadIC_try_polymorphic");
GotoUnless( GotoUnless(
WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)), WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)),
&try_megamorphic); &try_megamorphic);
......
...@@ -39,8 +39,7 @@ inline FieldIndex FieldIndex::ForPropertyIndex(Map* map, ...@@ -39,8 +39,7 @@ inline FieldIndex FieldIndex::ForPropertyIndex(Map* map,
is_double, inobject_properties, first_inobject_offset); is_double, inobject_properties, first_inobject_offset);
} }
// Takes an index as computed by GetLoadByFieldIndex and reconstructs a
// Takes an index as computed by GetLoadFieldByIndex and reconstructs a
// FieldIndex object from it. // FieldIndex object from it.
inline FieldIndex FieldIndex::ForLoadByFieldIndex(Map* map, int orig_index) { inline FieldIndex FieldIndex::ForLoadByFieldIndex(Map* map, int orig_index) {
int field_index = orig_index; int field_index = orig_index;
...@@ -85,6 +84,42 @@ inline int FieldIndex::GetLoadByFieldIndex() const { ...@@ -85,6 +84,42 @@ inline int FieldIndex::GetLoadByFieldIndex() const {
return is_double() ? (result | 1) : result; return is_double() ? (result | 1) : result;
} }
// Takes an offset as computed by GetLoadByFieldOffset and reconstructs a
// FieldIndex object from it.
inline FieldIndex FieldIndex::ForLoadByFieldOffset(Map* map, int offset) {
bool is_double = offset & 1;
int field_index = (offset >> 1) / kPointerSize;
int is_inobject = true;
int first_inobject_offset = 0;
if (field_index < 0) {
field_index = -field_index;
is_inobject = false;
first_inobject_offset = FixedArray::kHeaderSize;
} else {
first_inobject_offset =
map->IsJSObjectMap() ? map->GetInObjectPropertyOffset(0) : 0;
}
int inobject_properties =
map->IsJSObjectMap() ? map->GetInObjectProperties() : 0;
FieldIndex result(is_inobject, field_index, is_double, inobject_properties,
first_inobject_offset);
DCHECK(result.GetLoadByFieldOffset() == offset);
return result;
}
// Returns the offset format consumed by TurboFan stubs:
// In-object: zero-based from object start,
// out-of-object: zero-based from FixedArray start.
inline int FieldIndex::GetLoadByFieldOffset() const {
// For efficiency, stubs consume an offset that is optimized for quick
// access. If the property is in-object, the offset is positive.
// If it's out-of-object, the encoded offset is -raw_offset.
// In either case, the offset itself is shifted up by one bit, the lower-most
// bit signifying if the field is a mutable double box (1) or not (0).
int result = index() << kPointerSizeLog2;
if (!is_inobject()) result = -result;
return (result << 1) | (is_double() ? 1 : 0);
}
inline FieldIndex FieldIndex::ForDescriptor(Map* map, int descriptor_index) { inline FieldIndex FieldIndex::ForDescriptor(Map* map, int descriptor_index) {
PropertyDetails details = PropertyDetails details =
......
...@@ -27,10 +27,12 @@ class FieldIndex final { ...@@ -27,10 +27,12 @@ class FieldIndex final {
static FieldIndex ForInObjectOffset(int offset, Map* map = NULL); static FieldIndex ForInObjectOffset(int offset, Map* map = NULL);
static FieldIndex ForDescriptor(Map* map, int descriptor_index); static FieldIndex ForDescriptor(Map* map, int descriptor_index);
static FieldIndex ForLoadByFieldIndex(Map* map, int index); static FieldIndex ForLoadByFieldIndex(Map* map, int index);
static FieldIndex ForLoadByFieldOffset(Map* map, int index);
static FieldIndex ForKeyedLookupCacheIndex(Map* map, int index); static FieldIndex ForKeyedLookupCacheIndex(Map* map, int index);
static FieldIndex FromFieldAccessStubKey(int key); static FieldIndex FromFieldAccessStubKey(int key);
int GetLoadByFieldIndex() const; int GetLoadByFieldIndex() const;
int GetLoadByFieldOffset() const;
bool is_inobject() const { bool is_inobject() const {
return IsInObjectBits::decode(bit_field_); return IsInObjectBits::decode(bit_field_);
......
...@@ -173,6 +173,7 @@ void FullCodeGenerator::PrepareForBailout(Expression* node, ...@@ -173,6 +173,7 @@ void FullCodeGenerator::PrepareForBailout(Expression* node,
void FullCodeGenerator::CallLoadIC(TypeFeedbackId id) { void FullCodeGenerator::CallLoadIC(TypeFeedbackId id) {
Handle<Code> ic = CodeFactory::LoadIC(isolate()).code(); Handle<Code> ic = CodeFactory::LoadIC(isolate()).code();
CallIC(ic, id); CallIC(ic, id);
if (FLAG_tf_load_ic_stub) RestoreContext();
} }
void FullCodeGenerator::CallLoadGlobalIC(TypeofMode typeof_mode, void FullCodeGenerator::CallLoadGlobalIC(TypeofMode typeof_mode,
......
...@@ -577,7 +577,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( ...@@ -577,7 +577,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
#undef __ #undef __
void ElementHandlerCompiler::CompileElementHandlers( void ElementHandlerCompiler::CompileElementHandlers(
MapHandleList* receiver_maps, CodeHandleList* handlers) { MapHandleList* receiver_maps, List<Handle<Object>>* handlers) {
for (int i = 0; i < receiver_maps->length(); ++i) { for (int i = 0; i < receiver_maps->length(); ++i) {
Handle<Map> receiver_map = receiver_maps->at(i); Handle<Map> receiver_map = receiver_maps->at(i);
Handle<Code> cached_stub; Handle<Code> cached_stub;
......
...@@ -280,7 +280,7 @@ class ElementHandlerCompiler : public PropertyHandlerCompiler { ...@@ -280,7 +280,7 @@ class ElementHandlerCompiler : public PropertyHandlerCompiler {
virtual ~ElementHandlerCompiler() {} virtual ~ElementHandlerCompiler() {}
void CompileElementHandlers(MapHandleList* receiver_maps, void CompileElementHandlers(MapHandleList* receiver_maps,
CodeHandleList* handlers); List<Handle<Object>>* handlers);
static void GenerateStoreSlow(MacroAssembler* masm); static void GenerateStoreSlow(MacroAssembler* masm);
}; };
......
...@@ -541,35 +541,33 @@ void IC::ConfigureVectorState(IC::State new_state, Handle<Object> key) { ...@@ -541,35 +541,33 @@ void IC::ConfigureVectorState(IC::State new_state, Handle<Object> key) {
OnTypeFeedbackChanged(isolate(), get_host()); OnTypeFeedbackChanged(isolate(), get_host());
} }
void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map, void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
Handle<Code> handler) { Handle<Object> handler) {
DCHECK(UseVector()); DCHECK(UseVector());
if (kind() == Code::LOAD_IC) { if (kind() == Code::LOAD_IC) {
LoadICNexus* nexus = casted_nexus<LoadICNexus>(); LoadICNexus* nexus = casted_nexus<LoadICNexus>();
nexus->ConfigureMonomorphic(map, handler); nexus->ConfigureMonomorphic(map, handler);
} else if (kind() == Code::LOAD_GLOBAL_IC) { } else if (kind() == Code::LOAD_GLOBAL_IC) {
LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>(); LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>();
nexus->ConfigureHandlerMode(handler); nexus->ConfigureHandlerMode(Handle<Code>::cast(handler));
} else if (kind() == Code::KEYED_LOAD_IC) { } else if (kind() == Code::KEYED_LOAD_IC) {
KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
nexus->ConfigureMonomorphic(name, map, handler); nexus->ConfigureMonomorphic(name, map, Handle<Code>::cast(handler));
} else if (kind() == Code::STORE_IC) { } else if (kind() == Code::STORE_IC) {
StoreICNexus* nexus = casted_nexus<StoreICNexus>(); StoreICNexus* nexus = casted_nexus<StoreICNexus>();
nexus->ConfigureMonomorphic(map, handler); nexus->ConfigureMonomorphic(map, Handle<Code>::cast(handler));
} else { } else {
DCHECK(kind() == Code::KEYED_STORE_IC); DCHECK(kind() == Code::KEYED_STORE_IC);
KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>(); KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
nexus->ConfigureMonomorphic(name, map, handler); nexus->ConfigureMonomorphic(name, map, Handle<Code>::cast(handler));
} }
vector_set_ = true; vector_set_ = true;
OnTypeFeedbackChanged(isolate(), get_host()); OnTypeFeedbackChanged(isolate(), get_host());
} }
void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps, void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps,
CodeHandleList* handlers) { List<Handle<Object>>* handlers) {
DCHECK(UseVector()); DCHECK(UseVector());
if (kind() == Code::LOAD_IC) { if (kind() == Code::LOAD_IC) {
LoadICNexus* nexus = casted_nexus<LoadICNexus>(); LoadICNexus* nexus = casted_nexus<LoadICNexus>();
...@@ -686,13 +684,15 @@ static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, ...@@ -686,13 +684,15 @@ static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
return true; return true;
} }
bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Object> code) {
bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) { DCHECK(code->IsSmi() || code->IsCode());
if (!code->is_handler()) return false; if (!code->IsSmi() && !Code::cast(*code)->is_handler()) {
return false;
}
if (is_keyed() && state() != RECOMPUTE_HANDLER) return false; if (is_keyed() && state() != RECOMPUTE_HANDLER) return false;
Handle<Map> map = receiver_map(); Handle<Map> map = receiver_map();
MapHandleList maps; MapHandleList maps;
CodeHandleList handlers; List<Handle<Object>> handlers;
TargetMaps(&maps); TargetMaps(&maps);
int number_of_maps = maps.length(); int number_of_maps = maps.length();
...@@ -747,16 +747,16 @@ bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) { ...@@ -747,16 +747,16 @@ bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) {
return true; return true;
} }
void IC::UpdateMonomorphicIC(Handle<Object> handler, Handle<Name> name) {
void IC::UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name) { DCHECK(handler->IsSmi() ||
DCHECK(handler->is_handler()); (handler->IsCode() && Handle<Code>::cast(handler)->is_handler()));
ConfigureVectorState(name, receiver_map(), handler); ConfigureVectorState(name, receiver_map(), handler);
} }
void IC::CopyICToMegamorphicCache(Handle<Name> name) { void IC::CopyICToMegamorphicCache(Handle<Name> name) {
MapHandleList maps; MapHandleList maps;
CodeHandleList handlers; List<Handle<Object>> handlers;
TargetMaps(&maps); TargetMaps(&maps);
if (!nexus()->FindHandlers(&handlers, maps.length())) return; if (!nexus()->FindHandlers(&handlers, maps.length())) return;
for (int i = 0; i < maps.length(); i++) { for (int i = 0; i < maps.length(); i++) {
...@@ -780,8 +780,8 @@ bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) { ...@@ -780,8 +780,8 @@ bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) {
return transitioned_map == target_map; return transitioned_map == target_map;
} }
void IC::PatchCache(Handle<Name> name, Handle<Object> code) {
void IC::PatchCache(Handle<Name> name, Handle<Code> code) { DCHECK(code->IsCode() || (kind() == Code::LOAD_IC && code->IsSmi()));
switch (state()) { switch (state()) {
case UNINITIALIZED: case UNINITIALIZED:
case PREMONOMORPHIC: case PREMONOMORPHIC:
...@@ -849,8 +849,11 @@ Handle<Code> KeyedStoreIC::ChooseMegamorphicStub(Isolate* isolate, ...@@ -849,8 +849,11 @@ Handle<Code> KeyedStoreIC::ChooseMegamorphicStub(Isolate* isolate,
: isolate->builtins()->KeyedStoreIC_Megamorphic(); : isolate->builtins()->KeyedStoreIC_Megamorphic();
} }
Handle<Object> LoadIC::SimpleFieldLoad(FieldIndex index) {
Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) { if (kind() == Code::LOAD_IC && FLAG_tf_load_ic_stub) {
return handle(Smi::FromInt(index.GetLoadByFieldOffset()), isolate());
}
DCHECK(kind() == Code::KEYED_LOAD_IC || !FLAG_tf_load_ic_stub);
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldStub); TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldStub);
LoadFieldStub stub(isolate(), index); LoadFieldStub stub(isolate(), index);
return stub.GetCode(); return stub.GetCode();
...@@ -905,7 +908,7 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) { ...@@ -905,7 +908,7 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) {
return; return;
} }
Handle<Code> code; Handle<Object> code;
if (lookup->state() == LookupIterator::JSPROXY || if (lookup->state() == LookupIterator::JSPROXY ||
lookup->state() == LookupIterator::ACCESS_CHECK) { lookup->state() == LookupIterator::ACCESS_CHECK) {
code = slow_stub(); code = slow_stub();
...@@ -980,15 +983,31 @@ StubCache* IC::stub_cache() { ...@@ -980,15 +983,31 @@ StubCache* IC::stub_cache() {
return nullptr; return nullptr;
} }
void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) { void IC::UpdateMegamorphicCache(Map* map, Name* name, Object* code) {
stub_cache()->Set(name, map, code); if (code->IsSmi()) {
// TODO(jkummerow): Support Smis in the code cache.
Handle<Map> map_handle(map, isolate());
Handle<Name> name_handle(name, isolate());
FieldIndex index =
FieldIndex::ForLoadByFieldOffset(map, Smi::cast(code)->value());
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldStub);
LoadFieldStub stub(isolate(), index);
Code* handler = *stub.GetCode();
stub_cache()->Set(*name_handle, *map_handle, handler);
return;
}
DCHECK(code->IsCode());
stub_cache()->Set(name, map, Code::cast(code));
} }
Handle<Object> IC::ComputeHandler(LookupIterator* lookup,
Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) { Handle<Object> value) {
// Try to find a globally shared handler stub. // Try to find a globally shared handler stub.
Handle<Code> code = GetMapIndependentHandler(lookup); Handle<Object> handler_or_index = GetMapIndependentHandler(lookup);
if (!code.is_null()) return code; if (!handler_or_index.is_null()) {
DCHECK(handler_or_index->IsCode() || handler_or_index->IsSmi());
return handler_or_index;
}
// Otherwise check the map's handler cache for a map-specific handler, and // Otherwise check the map's handler cache for a map-specific handler, and
// compile one if the cache comes up empty. // compile one if the cache comes up empty.
...@@ -1007,12 +1026,12 @@ Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) { ...@@ -1007,12 +1026,12 @@ Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) {
stub_holder_map = receiver_map(); stub_holder_map = receiver_map();
} }
code = PropertyHandlerCompiler::Find(lookup->name(), stub_holder_map, kind(), Handle<Code> code = PropertyHandlerCompiler::Find(
flag); lookup->name(), stub_holder_map, kind(), flag);
// Use the cached value if it exists, and if it is different from the // Use the cached value if it exists, and if it is different from the
// handler that just missed. // handler that just missed.
if (!code.is_null()) { if (!code.is_null()) {
Handle<Code> handler; Handle<Object> handler;
if (maybe_handler_.ToHandle(&handler)) { if (maybe_handler_.ToHandle(&handler)) {
if (!handler.is_identical_to(code)) { if (!handler.is_identical_to(code)) {
TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit); TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit);
...@@ -1045,7 +1064,7 @@ Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) { ...@@ -1045,7 +1064,7 @@ Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) {
return code; return code;
} }
Handle<Code> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) { Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
Handle<Object> receiver = lookup->GetReceiver(); Handle<Object> receiver = lookup->GetReceiver();
if (receiver->IsString() && if (receiver->IsString() &&
Name::Equals(isolate()->factory()->length_string(), lookup->name())) { Name::Equals(isolate()->factory()->length_string(), lookup->name())) {
...@@ -1389,7 +1408,7 @@ void KeyedLoadIC::UpdateLoadElement(Handle<HeapObject> receiver) { ...@@ -1389,7 +1408,7 @@ void KeyedLoadIC::UpdateLoadElement(Handle<HeapObject> receiver) {
return; return;
} }
CodeHandleList handlers(target_receiver_maps.length()); List<Handle<Object>> handlers(target_receiver_maps.length());
TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_PolymorphicElement); TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_PolymorphicElement);
ElementHandlerCompiler compiler(isolate()); ElementHandlerCompiler compiler(isolate());
compiler.CompileElementHandlers(&target_receiver_maps, &handlers); compiler.CompileElementHandlers(&target_receiver_maps, &handlers);
...@@ -1606,7 +1625,8 @@ void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value, ...@@ -1606,7 +1625,8 @@ void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value,
if (!use_ic) { if (!use_ic) {
TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'");
} }
Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub(); Handle<Code> code =
use_ic ? Handle<Code>::cast(ComputeHandler(lookup, value)) : slow_stub();
PatchCache(lookup->name(), code); PatchCache(lookup->name(), code);
TRACE_IC("StoreIC", lookup->name()); TRACE_IC("StoreIC", lookup->name());
...@@ -1628,7 +1648,7 @@ static Handle<Code> PropertyCellStoreHandler( ...@@ -1628,7 +1648,7 @@ static Handle<Code> PropertyCellStoreHandler(
return code; return code;
} }
Handle<Code> StoreIC::GetMapIndependentHandler(LookupIterator* lookup) { Handle<Object> StoreIC::GetMapIndependentHandler(LookupIterator* lookup) {
DCHECK_NE(LookupIterator::JSPROXY, lookup->state()); DCHECK_NE(LookupIterator::JSPROXY, lookup->state());
// This is currently guaranteed by checks in StoreIC::Store. // This is currently guaranteed by checks in StoreIC::Store.
......
...@@ -107,10 +107,10 @@ class IC { ...@@ -107,10 +107,10 @@ class IC {
void ConfigureVectorState(IC::State new_state, Handle<Object> key); void ConfigureVectorState(IC::State new_state, Handle<Object> key);
// Configure the vector for MONOMORPHIC. // Configure the vector for MONOMORPHIC.
void ConfigureVectorState(Handle<Name> name, Handle<Map> map, void ConfigureVectorState(Handle<Name> name, Handle<Map> map,
Handle<Code> handler); Handle<Object> handler);
// Configure the vector for POLYMORPHIC. // Configure the vector for POLYMORPHIC.
void ConfigureVectorState(Handle<Name> name, MapHandleList* maps, void ConfigureVectorState(Handle<Name> name, MapHandleList* maps,
CodeHandleList* handlers); List<Handle<Object>>* handlers);
// Configure the vector for POLYMORPHIC with transitions (only for element // Configure the vector for POLYMORPHIC with transitions (only for element
// keyed stores). // keyed stores).
void ConfigureVectorState(MapHandleList* maps, void ConfigureVectorState(MapHandleList* maps,
...@@ -136,9 +136,9 @@ class IC { ...@@ -136,9 +136,9 @@ class IC {
static void PostPatching(Address address, Code* target, Code* old_target); static void PostPatching(Address address, Code* target, Code* old_target);
// Compute the handler either by compiling or by retrieving a cached version. // Compute the handler either by compiling or by retrieving a cached version.
Handle<Code> ComputeHandler(LookupIterator* lookup, Handle<Object> ComputeHandler(LookupIterator* lookup,
Handle<Object> value = Handle<Code>::null()); Handle<Object> value = Handle<Code>::null());
virtual Handle<Code> GetMapIndependentHandler(LookupIterator* lookup) { virtual Handle<Object> GetMapIndependentHandler(LookupIterator* lookup) {
UNREACHABLE(); UNREACHABLE();
return Handle<Code>::null(); return Handle<Code>::null();
} }
...@@ -149,15 +149,15 @@ class IC { ...@@ -149,15 +149,15 @@ class IC {
return Handle<Code>::null(); return Handle<Code>::null();
} }
void UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name); void UpdateMonomorphicIC(Handle<Object> handler, Handle<Name> name);
bool UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code); bool UpdatePolymorphicIC(Handle<Name> name, Handle<Object> code);
void UpdateMegamorphicCache(Map* map, Name* name, Code* code); void UpdateMegamorphicCache(Map* map, Name* name, Object* code);
StubCache* stub_cache(); StubCache* stub_cache();
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<Code> code); void PatchCache(Handle<Name> name, Handle<Object> code);
Code::Kind kind() const { return kind_; } Code::Kind kind() const { return kind_; }
bool is_keyed() const { bool is_keyed() const {
return kind_ == Code::KEYED_LOAD_IC || kind_ == Code::KEYED_STORE_IC; return kind_ == Code::KEYED_LOAD_IC || kind_ == Code::KEYED_STORE_IC;
...@@ -239,7 +239,7 @@ class IC { ...@@ -239,7 +239,7 @@ class IC {
State state_; State state_;
Code::Kind kind_; Code::Kind kind_;
Handle<Map> receiver_map_; Handle<Map> receiver_map_;
MaybeHandle<Code> maybe_handler_; MaybeHandle<Object> maybe_handler_;
ExtraICState extra_ic_state_; ExtraICState extra_ic_state_;
MapHandleList target_maps_; MapHandleList target_maps_;
...@@ -305,13 +305,13 @@ class LoadIC : public IC { ...@@ -305,13 +305,13 @@ class LoadIC : public IC {
// lookup result. // lookup result.
void UpdateCaches(LookupIterator* lookup); void UpdateCaches(LookupIterator* lookup);
Handle<Code> GetMapIndependentHandler(LookupIterator* lookup) override; Handle<Object> GetMapIndependentHandler(LookupIterator* lookup) override;
Handle<Code> CompileHandler(LookupIterator* lookup, Handle<Object> unused, Handle<Code> CompileHandler(LookupIterator* lookup, Handle<Object> unused,
CacheHolderFlag cache_holder) override; CacheHolderFlag cache_holder) override;
private: private:
Handle<Code> SimpleFieldLoad(FieldIndex index); Handle<Object> SimpleFieldLoad(FieldIndex index);
friend class IC; friend class IC;
}; };
...@@ -418,7 +418,7 @@ class StoreIC : public IC { ...@@ -418,7 +418,7 @@ class StoreIC : public IC {
// lookup result. // lookup result.
void UpdateCaches(LookupIterator* lookup, Handle<Object> value, void UpdateCaches(LookupIterator* lookup, Handle<Object> value,
JSReceiver::StoreFromKeyed store_mode); JSReceiver::StoreFromKeyed store_mode);
Handle<Code> GetMapIndependentHandler(LookupIterator* lookup) override; Handle<Object> GetMapIndependentHandler(LookupIterator* lookup) override;
Handle<Code> CompileHandler(LookupIterator* lookup, Handle<Object> value, Handle<Code> CompileHandler(LookupIterator* lookup, Handle<Object> value,
CacheHolderFlag cache_holder) override; CacheHolderFlag cache_holder) override;
......
...@@ -427,10 +427,9 @@ Handle<FixedArray> FeedbackNexus::EnsureExtraArrayOfSize(int length) { ...@@ -427,10 +427,9 @@ Handle<FixedArray> FeedbackNexus::EnsureExtraArrayOfSize(int length) {
return Handle<FixedArray>::cast(feedback_extra); return Handle<FixedArray>::cast(feedback_extra);
} }
void FeedbackNexus::InstallHandlers(Handle<FixedArray> array, void FeedbackNexus::InstallHandlers(Handle<FixedArray> array,
MapHandleList* maps, MapHandleList* maps,
CodeHandleList* handlers) { List<Handle<Object>>* handlers) {
int receiver_count = maps->length(); int receiver_count = maps->length();
for (int current = 0; current < receiver_count; ++current) { for (int current = 0; current < receiver_count; ++current) {
Handle<Map> map = maps->at(current); Handle<Map> map = maps->at(current);
...@@ -656,9 +655,8 @@ void CallICNexus::ConfigureMegamorphic(int call_count) { ...@@ -656,9 +655,8 @@ void CallICNexus::ConfigureMegamorphic(int call_count) {
SetFeedbackExtra(Smi::FromInt(call_count), SKIP_WRITE_BARRIER); SetFeedbackExtra(Smi::FromInt(call_count), SKIP_WRITE_BARRIER);
} }
void LoadICNexus::ConfigureMonomorphic(Handle<Map> receiver_map, void LoadICNexus::ConfigureMonomorphic(Handle<Map> receiver_map,
Handle<Code> handler) { Handle<Object> handler) {
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
SetFeedback(*cell); SetFeedback(*cell);
SetFeedbackExtra(*handler); SetFeedbackExtra(*handler);
...@@ -722,9 +720,8 @@ void KeyedStoreICNexus::ConfigureMonomorphic(Handle<Name> name, ...@@ -722,9 +720,8 @@ void KeyedStoreICNexus::ConfigureMonomorphic(Handle<Name> name,
} }
} }
void LoadICNexus::ConfigurePolymorphic(MapHandleList* maps, void LoadICNexus::ConfigurePolymorphic(MapHandleList* maps,
CodeHandleList* handlers) { List<Handle<Object>>* handlers) {
Isolate* isolate = GetIsolate(); Isolate* isolate = GetIsolate();
int receiver_count = maps->length(); int receiver_count = maps->length();
Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 2); Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 2);
...@@ -735,7 +732,7 @@ void LoadICNexus::ConfigurePolymorphic(MapHandleList* maps, ...@@ -735,7 +732,7 @@ void LoadICNexus::ConfigurePolymorphic(MapHandleList* maps,
void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name, void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name,
MapHandleList* maps, MapHandleList* maps,
CodeHandleList* handlers) { List<Handle<Object>>* handlers) {
int receiver_count = maps->length(); int receiver_count = maps->length();
DCHECK(receiver_count > 1); DCHECK(receiver_count > 1);
Handle<FixedArray> array; Handle<FixedArray> array;
...@@ -751,9 +748,8 @@ void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name, ...@@ -751,9 +748,8 @@ void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name,
InstallHandlers(array, maps, handlers); InstallHandlers(array, maps, handlers);
} }
void StoreICNexus::ConfigurePolymorphic(MapHandleList* maps, void StoreICNexus::ConfigurePolymorphic(MapHandleList* maps,
CodeHandleList* handlers) { List<Handle<Object>>* handlers) {
Isolate* isolate = GetIsolate(); Isolate* isolate = GetIsolate();
int receiver_count = maps->length(); int receiver_count = maps->length();
Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 2); Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 2);
...@@ -762,10 +758,9 @@ void StoreICNexus::ConfigurePolymorphic(MapHandleList* maps, ...@@ -762,10 +758,9 @@ void StoreICNexus::ConfigurePolymorphic(MapHandleList* maps,
SKIP_WRITE_BARRIER); SKIP_WRITE_BARRIER);
} }
void KeyedStoreICNexus::ConfigurePolymorphic(Handle<Name> name, void KeyedStoreICNexus::ConfigurePolymorphic(Handle<Name> name,
MapHandleList* maps, MapHandleList* maps,
CodeHandleList* handlers) { List<Handle<Object>>* handlers) {
int receiver_count = maps->length(); int receiver_count = maps->length();
DCHECK(receiver_count > 1); DCHECK(receiver_count > 1);
Handle<FixedArray> array; Handle<FixedArray> array;
...@@ -807,6 +802,30 @@ void KeyedStoreICNexus::ConfigurePolymorphic(MapHandleList* maps, ...@@ -807,6 +802,30 @@ void KeyedStoreICNexus::ConfigurePolymorphic(MapHandleList* maps,
} }
} }
namespace {
int GetStepSize(FixedArray* array, Isolate* isolate) {
// The array should be of the form
// [map, handler, map, handler, ...]
// or
// [map, map, handler, map, map, handler, ...]
// where "map" is either a WeakCell or |undefined|,
// and "handler" is either a Code object or a Smi.
DCHECK(array->length() >= 2);
Object* second = array->get(1);
if (second->IsWeakCell() || second->IsUndefined(isolate)) return 3;
DCHECK(second->IsCode() || second->IsSmi());
return 2;
}
#ifdef DEBUG // Only used by DCHECKs below.
bool IsHandler(Object* object) {
return object->IsSmi() ||
(object->IsCode() && Code::cast(object)->is_handler());
}
#endif
} // namespace
int FeedbackNexus::ExtractMaps(MapHandleList* maps) const { int FeedbackNexus::ExtractMaps(MapHandleList* maps) const {
Isolate* isolate = GetIsolate(); Isolate* isolate = GetIsolate();
...@@ -818,12 +837,7 @@ int FeedbackNexus::ExtractMaps(MapHandleList* maps) const { ...@@ -818,12 +837,7 @@ int FeedbackNexus::ExtractMaps(MapHandleList* maps) const {
feedback = GetFeedbackExtra(); feedback = GetFeedbackExtra();
} }
FixedArray* array = FixedArray::cast(feedback); FixedArray* array = FixedArray::cast(feedback);
// The array should be of the form int increment = GetStepSize(array, isolate);
// [map, handler, map, handler, ...]
// or
// [map, map, handler, map, map, handler, ...]
DCHECK(array->length() >= 2);
int increment = array->get(1)->IsCode() ? 2 : 3;
for (int i = 0; i < array->length(); i += increment) { for (int i = 0; i < array->length(); i += increment) {
DCHECK(array->get(i)->IsWeakCell()); DCHECK(array->get(i)->IsWeakCell());
WeakCell* cell = WeakCell::cast(array->get(i)); WeakCell* cell = WeakCell::cast(array->get(i));
...@@ -846,26 +860,25 @@ int FeedbackNexus::ExtractMaps(MapHandleList* maps) const { ...@@ -846,26 +860,25 @@ int FeedbackNexus::ExtractMaps(MapHandleList* maps) const {
return 0; return 0;
} }
MaybeHandle<Object> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
Object* feedback = GetFeedback(); Object* feedback = GetFeedback();
Isolate* isolate = GetIsolate();
bool is_named_feedback = IsPropertyNameFeedback(feedback); bool is_named_feedback = IsPropertyNameFeedback(feedback);
if (feedback->IsFixedArray() || is_named_feedback) { if (feedback->IsFixedArray() || is_named_feedback) {
if (is_named_feedback) { if (is_named_feedback) {
feedback = GetFeedbackExtra(); feedback = GetFeedbackExtra();
} }
FixedArray* array = FixedArray::cast(feedback); FixedArray* array = FixedArray::cast(feedback);
DCHECK(array->length() >= 2); int increment = GetStepSize(array, isolate);
int increment = array->get(1)->IsCode() ? 2 : 3;
for (int i = 0; i < array->length(); i += increment) { for (int i = 0; i < array->length(); i += increment) {
DCHECK(array->get(i)->IsWeakCell()); DCHECK(array->get(i)->IsWeakCell());
WeakCell* cell = WeakCell::cast(array->get(i)); WeakCell* cell = WeakCell::cast(array->get(i));
if (!cell->cleared()) { if (!cell->cleared()) {
Map* array_map = Map::cast(cell->value()); Map* array_map = Map::cast(cell->value());
if (array_map == *map) { if (array_map == *map) {
Code* code = Code::cast(array->get(i + increment - 1)); Object* code = array->get(i + increment - 1);
DCHECK(code->kind() == Code::HANDLER); DCHECK(IsHandler(code));
return handle(code); return handle(code, isolate);
} }
} }
} }
...@@ -874,9 +887,9 @@ MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const { ...@@ -874,9 +887,9 @@ MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
if (!cell->cleared()) { if (!cell->cleared()) {
Map* cell_map = Map::cast(cell->value()); Map* cell_map = Map::cast(cell->value());
if (cell_map == *map) { if (cell_map == *map) {
Code* code = Code::cast(GetFeedbackExtra()); Object* code = GetFeedbackExtra();
DCHECK(code->kind() == Code::HANDLER); DCHECK(IsHandler(code));
return handle(code); return handle(code, isolate);
} }
} }
} }
...@@ -884,9 +897,10 @@ MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const { ...@@ -884,9 +897,10 @@ MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
return MaybeHandle<Code>(); return MaybeHandle<Code>();
} }
bool FeedbackNexus::FindHandlers(List<Handle<Object>>* code_list,
bool FeedbackNexus::FindHandlers(CodeHandleList* code_list, int length) const { int length) const {
Object* feedback = GetFeedback(); Object* feedback = GetFeedback();
Isolate* isolate = GetIsolate();
int count = 0; int count = 0;
bool is_named_feedback = IsPropertyNameFeedback(feedback); bool is_named_feedback = IsPropertyNameFeedback(feedback);
if (feedback->IsFixedArray() || is_named_feedback) { if (feedback->IsFixedArray() || is_named_feedback) {
...@@ -894,29 +908,24 @@ bool FeedbackNexus::FindHandlers(CodeHandleList* code_list, int length) const { ...@@ -894,29 +908,24 @@ bool FeedbackNexus::FindHandlers(CodeHandleList* code_list, int length) const {
feedback = GetFeedbackExtra(); feedback = GetFeedbackExtra();
} }
FixedArray* array = FixedArray::cast(feedback); FixedArray* array = FixedArray::cast(feedback);
// The array should be of the form int increment = GetStepSize(array, isolate);
// [map, handler, map, handler, ...]
// or
// [map, map, handler, map, map, handler, ...]
// Be sure to skip handlers whose maps have been cleared.
DCHECK(array->length() >= 2);
int increment = array->get(1)->IsCode() ? 2 : 3;
for (int i = 0; i < array->length(); i += increment) { for (int i = 0; i < array->length(); i += increment) {
DCHECK(array->get(i)->IsWeakCell()); DCHECK(array->get(i)->IsWeakCell());
WeakCell* cell = WeakCell::cast(array->get(i)); WeakCell* cell = WeakCell::cast(array->get(i));
// Be sure to skip handlers whose maps have been cleared.
if (!cell->cleared()) { if (!cell->cleared()) {
Code* code = Code::cast(array->get(i + increment - 1)); Object* code = array->get(i + increment - 1);
DCHECK(code->kind() == Code::HANDLER); DCHECK(IsHandler(code));
code_list->Add(handle(code)); code_list->Add(handle(code, isolate));
count++; count++;
} }
} }
} else if (feedback->IsWeakCell()) { } else if (feedback->IsWeakCell()) {
WeakCell* cell = WeakCell::cast(feedback); WeakCell* cell = WeakCell::cast(feedback);
if (!cell->cleared()) { if (!cell->cleared()) {
Code* code = Code::cast(GetFeedbackExtra()); Object* code = GetFeedbackExtra();
DCHECK(code->kind() == Code::HANDLER); DCHECK(IsHandler(code));
code_list->Add(handle(code)); code_list->Add(handle(code, isolate));
count++; count++;
} }
} }
...@@ -966,7 +975,7 @@ void KeyedStoreICNexus::Clear(Code* host) { ...@@ -966,7 +975,7 @@ void KeyedStoreICNexus::Clear(Code* host) {
KeyedAccessStoreMode KeyedStoreICNexus::GetKeyedAccessStoreMode() const { KeyedAccessStoreMode KeyedStoreICNexus::GetKeyedAccessStoreMode() const {
KeyedAccessStoreMode mode = STANDARD_STORE; KeyedAccessStoreMode mode = STANDARD_STORE;
MapHandleList maps; MapHandleList maps;
CodeHandleList handlers; List<Handle<Object>> handlers;
if (GetKeyType() == PROPERTY) return mode; if (GetKeyType() == PROPERTY) return mode;
...@@ -974,7 +983,7 @@ KeyedAccessStoreMode KeyedStoreICNexus::GetKeyedAccessStoreMode() const { ...@@ -974,7 +983,7 @@ KeyedAccessStoreMode KeyedStoreICNexus::GetKeyedAccessStoreMode() const {
FindHandlers(&handlers, maps.length()); FindHandlers(&handlers, maps.length());
for (int i = 0; i < handlers.length(); i++) { for (int i = 0; i < handlers.length(); i++) {
// The first handler that isn't the slow handler will have the bits we need. // The first handler that isn't the slow handler will have the bits we need.
Handle<Code> handler = handlers.at(i); Handle<Code> handler = Handle<Code>::cast(handlers.at(i));
CodeStub::Major major_key = CodeStub::MajorKeyFromKey(handler->stub_key()); CodeStub::Major major_key = CodeStub::MajorKeyFromKey(handler->stub_key());
uint32_t minor_key = CodeStub::MinorKeyFromKey(handler->stub_key()); uint32_t minor_key = CodeStub::MinorKeyFromKey(handler->stub_key());
CHECK(major_key == CodeStub::KeyedStoreSloppyArguments || CHECK(major_key == CodeStub::KeyedStoreSloppyArguments ||
......
...@@ -412,8 +412,9 @@ class FeedbackNexus { ...@@ -412,8 +412,9 @@ class FeedbackNexus {
virtual InlineCacheState StateFromFeedback() const = 0; virtual InlineCacheState StateFromFeedback() const = 0;
virtual int ExtractMaps(MapHandleList* maps) const; virtual int ExtractMaps(MapHandleList* maps) const;
virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const; virtual MaybeHandle<Object> FindHandlerForMap(Handle<Map> map) const;
virtual bool FindHandlers(CodeHandleList* code_list, int length = -1) const; virtual bool FindHandlers(List<Handle<Object>>* code_list,
int length = -1) const;
virtual Name* FindFirstName() const { return NULL; } virtual Name* FindFirstName() const { return NULL; }
virtual void ConfigureUninitialized(); virtual void ConfigureUninitialized();
...@@ -434,7 +435,7 @@ class FeedbackNexus { ...@@ -434,7 +435,7 @@ class FeedbackNexus {
Handle<FixedArray> EnsureArrayOfSize(int length); Handle<FixedArray> EnsureArrayOfSize(int length);
Handle<FixedArray> EnsureExtraArrayOfSize(int length); Handle<FixedArray> EnsureExtraArrayOfSize(int length);
void InstallHandlers(Handle<FixedArray> array, MapHandleList* maps, void InstallHandlers(Handle<FixedArray> array, MapHandleList* maps,
CodeHandleList* handlers); List<Handle<Object>>* handlers);
private: private:
// The reason for having a vector handle and a raw pointer is that we can and // The reason for having a vector handle and a raw pointer is that we can and
...@@ -471,10 +472,11 @@ class CallICNexus final : public FeedbackNexus { ...@@ -471,10 +472,11 @@ class CallICNexus final : public FeedbackNexus {
// CallICs don't record map feedback. // CallICs don't record map feedback.
return 0; return 0;
} }
MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const final { MaybeHandle<Object> FindHandlerForMap(Handle<Map> map) const final {
return MaybeHandle<Code>(); return MaybeHandle<Code>();
} }
bool FindHandlers(CodeHandleList* code_list, int length = -1) const final { bool FindHandlers(List<Handle<Object>>* code_list,
int length = -1) const final {
return length == 0; return length == 0;
} }
...@@ -499,9 +501,10 @@ class LoadICNexus : public FeedbackNexus { ...@@ -499,9 +501,10 @@ class LoadICNexus : public FeedbackNexus {
void Clear(Code* host); void Clear(Code* host);
void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler); void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Object> handler);
void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers); void ConfigurePolymorphic(MapHandleList* maps,
List<Handle<Object>>* handlers);
InlineCacheState StateFromFeedback() const override; InlineCacheState StateFromFeedback() const override;
}; };
...@@ -521,10 +524,11 @@ class LoadGlobalICNexus : public FeedbackNexus { ...@@ -521,10 +524,11 @@ class LoadGlobalICNexus : public FeedbackNexus {
// LoadGlobalICs don't record map feedback. // LoadGlobalICs don't record map feedback.
return 0; return 0;
} }
MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const final { MaybeHandle<Object> FindHandlerForMap(Handle<Map> map) const final {
return MaybeHandle<Code>(); return MaybeHandle<Code>();
} }
bool FindHandlers(CodeHandleList* code_list, int length = -1) const final { bool FindHandlers(List<Handle<Object>>* code_list,
int length = -1) const final {
return length == 0; return length == 0;
} }
...@@ -556,7 +560,7 @@ class KeyedLoadICNexus : public FeedbackNexus { ...@@ -556,7 +560,7 @@ class KeyedLoadICNexus : public FeedbackNexus {
Handle<Code> handler); Handle<Code> handler);
// name can be null. // name can be null.
void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps, void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
CodeHandleList* handlers); List<Handle<Object>>* handlers);
void ConfigureMegamorphicKeyed(IcCheckType property_type); void ConfigureMegamorphicKeyed(IcCheckType property_type);
...@@ -585,7 +589,8 @@ class StoreICNexus : public FeedbackNexus { ...@@ -585,7 +589,8 @@ class StoreICNexus : public FeedbackNexus {
void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler); void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler);
void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers); void ConfigurePolymorphic(MapHandleList* maps,
List<Handle<Object>>* handlers);
InlineCacheState StateFromFeedback() const override; InlineCacheState StateFromFeedback() const override;
}; };
...@@ -613,7 +618,7 @@ class KeyedStoreICNexus : public FeedbackNexus { ...@@ -613,7 +618,7 @@ class KeyedStoreICNexus : public FeedbackNexus {
Handle<Code> handler); Handle<Code> handler);
// name can be null. // name can be null.
void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps, void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
CodeHandleList* handlers); List<Handle<Object>>* handlers);
void ConfigurePolymorphic(MapHandleList* maps, void ConfigurePolymorphic(MapHandleList* maps,
MapHandleList* transitioned_maps, MapHandleList* transitioned_maps,
CodeHandleList* handlers); CodeHandleList* handlers);
......
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