Commit ccca1739 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[ic] Use Load/StoreHandlerStruct objects instead of Tuple3/FixedArray.

This CL also removes LoadICProtoArray* builtins which are no longer necessary.

Bug: v8:7206, v8:5561
Change-Id: Ic5d9a3d4d21c4bd5e5e1cd110bd029ced157a000
Reviewed-on: https://chromium-review.googlesource.com/819252
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50104}
parent 674402ff
...@@ -45,8 +45,6 @@ const Register LoadDescriptor::SlotRegister() { return r0; } ...@@ -45,8 +45,6 @@ const Register LoadDescriptor::SlotRegister() { return r0; }
const Register LoadWithVectorDescriptor::VectorRegister() { return r3; } const Register LoadWithVectorDescriptor::VectorRegister() { return r3; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return r4; }
const Register StoreDescriptor::ReceiverRegister() { return r1; } const Register StoreDescriptor::ReceiverRegister() { return r1; }
const Register StoreDescriptor::NameRegister() { return r2; } const Register StoreDescriptor::NameRegister() { return r2; }
const Register StoreDescriptor::ValueRegister() { return r0; } const Register StoreDescriptor::ValueRegister() { return r0; }
......
...@@ -45,8 +45,6 @@ const Register LoadDescriptor::SlotRegister() { return x0; } ...@@ -45,8 +45,6 @@ const Register LoadDescriptor::SlotRegister() { return x0; }
const Register LoadWithVectorDescriptor::VectorRegister() { return x3; } const Register LoadWithVectorDescriptor::VectorRegister() { return x3; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return x4; }
const Register StoreDescriptor::ReceiverRegister() { return x1; } const Register StoreDescriptor::ReceiverRegister() { return x1; }
const Register StoreDescriptor::NameRegister() { return x2; } const Register StoreDescriptor::NameRegister() { return x2; }
const Register StoreDescriptor::ValueRegister() { return x0; } const Register StoreDescriptor::ValueRegister() { return x0; }
......
...@@ -199,8 +199,6 @@ namespace internal { ...@@ -199,8 +199,6 @@ namespace internal {
TFC(ToBooleanLazyDeoptContinuation, TypeConversionStackParameter, 1) \ TFC(ToBooleanLazyDeoptContinuation, TypeConversionStackParameter, 1) \
\ \
/* Handlers */ \ /* Handlers */ \
TFH(LoadICProtoArray, LoadICProtoArray) \
TFH(LoadICProtoArrayThrowIfNonexistent, LoadICProtoArray) \
TFH(KeyedLoadIC_Megamorphic, LoadWithVector) \ TFH(KeyedLoadIC_Megamorphic, LoadWithVector) \
TFH(KeyedLoadIC_Miss, LoadWithVector) \ TFH(KeyedLoadIC_Miss, LoadWithVector) \
TFH(KeyedLoadIC_PolymorphicName, LoadWithVector) \ TFH(KeyedLoadIC_PolymorphicName, LoadWithVector) \
......
...@@ -42,8 +42,6 @@ IC_BUILTIN_PARAM(LoadGlobalICTrampoline, LoadGlobalICTrampoline, ...@@ -42,8 +42,6 @@ IC_BUILTIN_PARAM(LoadGlobalICTrampoline, LoadGlobalICTrampoline,
NOT_INSIDE_TYPEOF) NOT_INSIDE_TYPEOF)
IC_BUILTIN_PARAM(LoadGlobalICInsideTypeofTrampoline, LoadGlobalICTrampoline, IC_BUILTIN_PARAM(LoadGlobalICInsideTypeofTrampoline, LoadGlobalICTrampoline,
INSIDE_TYPEOF) INSIDE_TYPEOF)
IC_BUILTIN_PARAM(LoadICProtoArray, LoadICProtoArray, false)
IC_BUILTIN_PARAM(LoadICProtoArrayThrowIfNonexistent, LoadICProtoArray, true)
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -29,16 +29,6 @@ Handle<Code> CodeFactory::RuntimeCEntry(Isolate* isolate, int result_size) { ...@@ -29,16 +29,6 @@ Handle<Code> CodeFactory::RuntimeCEntry(Isolate* isolate, int result_size) {
return stub.GetCode(); return stub.GetCode();
} }
// static
Callable CodeFactory::LoadICProtoArray(Isolate* isolate,
bool throw_if_nonexistent) {
return Callable(
throw_if_nonexistent
? BUILTIN_CODE(isolate, LoadICProtoArrayThrowIfNonexistent)
: BUILTIN_CODE(isolate, LoadICProtoArray),
LoadICProtoArrayDescriptor(isolate));
}
// static // static
Callable CodeFactory::ApiGetter(Isolate* isolate) { Callable CodeFactory::ApiGetter(Isolate* isolate) {
CallApiGetterStub stub(isolate); CallApiGetterStub stub(isolate);
......
...@@ -24,7 +24,6 @@ class V8_EXPORT_PRIVATE CodeFactory final { ...@@ -24,7 +24,6 @@ class V8_EXPORT_PRIVATE CodeFactory final {
static Handle<Code> RuntimeCEntry(Isolate* isolate, int result_size = 1); static Handle<Code> RuntimeCEntry(Isolate* isolate, int result_size = 1);
// Initial states for ICs. // Initial states for ICs.
static Callable LoadICProtoArray(Isolate* isolate, bool throw_if_nonexistent);
static Callable LoadGlobalIC(Isolate* isolate, TypeofMode typeof_mode); static Callable LoadGlobalIC(Isolate* isolate, TypeofMode typeof_mode);
static Callable LoadGlobalICInOptimizedCode(Isolate* isolate, static Callable LoadGlobalICInOptimizedCode(Isolate* isolate,
TypeofMode typeof_mode); TypeofMode typeof_mode);
......
...@@ -957,10 +957,11 @@ KeyedAccessStoreMode KeyedStoreICNexus::GetKeyedAccessStoreMode() const { ...@@ -957,10 +957,11 @@ KeyedAccessStoreMode KeyedStoreICNexus::GetKeyedAccessStoreMode() const {
for (const Handle<Object>& maybe_code_handler : handlers) { for (const Handle<Object>& maybe_code_handler : handlers) {
// 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; Handle<Code> handler;
if (maybe_code_handler->IsTuple3()) { if (maybe_code_handler->IsStoreHandler()) {
// Elements transition. // Elements transition.
Handle<Tuple3> data_handler = Handle<Tuple3>::cast(maybe_code_handler); Handle<StoreHandler> data_handler =
handler = handle(Code::cast(data_handler->value2())); Handle<StoreHandler>::cast(maybe_code_handler);
handler = handle(Code::cast(data_handler->smi_handler()));
} else if (maybe_code_handler->IsTuple2()) { } else if (maybe_code_handler->IsTuple2()) {
// Element store with prototype chain check. // Element store with prototype chain check.
Handle<Tuple2> data_handler = Handle<Tuple2>::cast(maybe_code_handler); Handle<Tuple2> data_handler = Handle<Tuple2>::cast(maybe_code_handler);
......
...@@ -44,8 +44,6 @@ const Register LoadDescriptor::SlotRegister() { return eax; } ...@@ -44,8 +44,6 @@ const Register LoadDescriptor::SlotRegister() { return eax; }
const Register LoadWithVectorDescriptor::VectorRegister() { return ebx; } const Register LoadWithVectorDescriptor::VectorRegister() { return ebx; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return edi; }
const Register StoreDescriptor::ReceiverRegister() { return edx; } const Register StoreDescriptor::ReceiverRegister() { return edx; }
const Register StoreDescriptor::NameRegister() { return ecx; } const Register StoreDescriptor::NameRegister() { return ecx; }
const Register StoreDescriptor::ValueRegister() { return eax; } const Register StoreDescriptor::ValueRegister() { return eax; }
......
This diff is collapsed.
...@@ -37,8 +37,6 @@ class AccessorAssembler : public CodeStubAssembler { ...@@ -37,8 +37,6 @@ class AccessorAssembler : public CodeStubAssembler {
void GenerateStoreGlobalIC(); void GenerateStoreGlobalIC();
void GenerateStoreGlobalICTrampoline(); void GenerateStoreGlobalICTrampoline();
void GenerateLoadICProtoArray(bool throw_reference_error_if_nonexistent);
void GenerateLoadGlobalIC(TypeofMode typeof_mode); void GenerateLoadGlobalIC(TypeofMode typeof_mode);
void GenerateLoadGlobalICTrampoline(TypeofMode typeof_mode); void GenerateLoadGlobalICTrampoline(TypeofMode typeof_mode);
...@@ -116,8 +114,6 @@ class AccessorAssembler : public CodeStubAssembler { ...@@ -116,8 +114,6 @@ class AccessorAssembler : public CodeStubAssembler {
Node* LoadDescriptorValue(Node* map, Node* descriptor); Node* LoadDescriptorValue(Node* map, Node* descriptor);
void LoadIC_Uninitialized(const LoadICParameters* p); void LoadIC_Uninitialized(const LoadICParameters* p);
void LoadICProtoArray(const LoadICParameters* p, Node* handler,
bool throw_reference_error_if_nonexistent);
void LoadGlobalIC(const LoadICParameters* p, TypeofMode typeof_mode); void LoadGlobalIC(const LoadICParameters* p, TypeofMode typeof_mode);
void KeyedLoadIC(const LoadICParameters* p); void KeyedLoadIC(const LoadICParameters* p);
void KeyedLoadICGeneric(const LoadICParameters* p); void KeyedLoadICGeneric(const LoadICParameters* p);
...@@ -140,9 +136,11 @@ class AccessorAssembler : public CodeStubAssembler { ...@@ -140,9 +136,11 @@ class AccessorAssembler : public CodeStubAssembler {
// LoadIC implementation. // LoadIC implementation.
enum class ICMode { kNonGlobalIC, kGlobalIC };
void HandleLoadICHandlerCase( void HandleLoadICHandlerCase(
const LoadICParameters* p, Node* handler, Label* miss, const LoadICParameters* p, Node* handler, Label* miss,
ExitPoint* exit_point, ElementSupport support_elements = kOnlyProperties); ExitPoint* exit_point, ICMode ic_mode = ICMode::kNonGlobalIC,
ElementSupport support_elements = kOnlyProperties);
void HandleLoadICSmiHandlerCase(const LoadICParameters* p, Node* holder, void HandleLoadICSmiHandlerCase(const LoadICParameters* p, Node* holder,
Node* smi_handler, Label* miss, Node* smi_handler, Label* miss,
...@@ -155,7 +153,8 @@ class AccessorAssembler : public CodeStubAssembler { ...@@ -155,7 +153,8 @@ class AccessorAssembler : public CodeStubAssembler {
Variable* var_smi_handler, Variable* var_smi_handler,
Label* if_smi_handler, Label* miss, Label* if_smi_handler, Label* miss,
ExitPoint* exit_point, ExitPoint* exit_point,
bool throw_reference_error_if_nonexistent); bool throw_reference_error_if_nonexistent,
ICMode ic_mode);
void HandleLoadField(Node* holder, Node* handler_word, void HandleLoadField(Node* holder, Node* handler_word,
Variable* var_double_value, Label* rebox_double, Variable* var_double_value, Label* rebox_double,
...@@ -164,10 +163,6 @@ class AccessorAssembler : public CodeStubAssembler { ...@@ -164,10 +163,6 @@ class AccessorAssembler : public CodeStubAssembler {
void EmitAccessCheck(Node* expected_native_context, Node* context, void EmitAccessCheck(Node* expected_native_context, Node* context,
Node* receiver, Label* can_access, Label* miss); Node* receiver, Label* can_access, Label* miss);
Node* EmitLoadICProtoArrayCheck(const LoadICParameters* p, Node* handler,
Node* handler_length, Node* handler_flags,
Label* miss);
// LoadGlobalIC implementation. // LoadGlobalIC implementation.
void HandleLoadGlobalICHandlerCase(const LoadICParameters* p, Node* handler, void HandleLoadGlobalICHandlerCase(const LoadICParameters* p, Node* handler,
......
...@@ -240,22 +240,15 @@ Handle<Smi> StoreHandler::StoreApiSetter(Isolate* isolate, ...@@ -240,22 +240,15 @@ Handle<Smi> StoreHandler::StoreApiSetter(Isolate* isolate,
// static // static
WeakCell* StoreHandler::GetTransitionCell(Object* handler) { WeakCell* StoreHandler::GetTransitionCell(Object* handler) {
if (handler->IsTuple3()) { DCHECK(handler->IsStoreHandler());
STATIC_ASSERT(kDataOffset == Tuple3::kValue1Offset); WeakCell* cell = WeakCell::cast(StoreHandler::cast(handler)->data1());
WeakCell* cell = WeakCell::cast(Tuple3::cast(handler)->value1());
DCHECK(!cell->cleared());
return cell;
}
DCHECK(handler->IsFixedArrayExact());
WeakCell* cell = WeakCell::cast(FixedArray::cast(handler)->get(kDataIndex));
DCHECK(!cell->cleared()); DCHECK(!cell->cleared());
return cell; return cell;
} }
// static // static
bool StoreHandler::IsHandler(Object* maybe_handler) { bool StoreHandler::IsHandler(Object* maybe_handler) {
return maybe_handler->IsFixedArrayExact() || maybe_handler->IsTuple3(); return maybe_handler->IsStoreHandler();
} }
} // namespace internal } // namespace internal
......
...@@ -16,7 +16,7 @@ namespace { ...@@ -16,7 +16,7 @@ namespace {
template <bool fill_array = true> template <bool fill_array = true>
int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map, int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map,
Handle<JSReceiver> holder, Handle<Name> name, Handle<JSReceiver> holder, Handle<Name> name,
Handle<FixedArray> array, int first_index) { Handle<DataHandler> handler) {
if (!holder.is_null() && holder->map() == *receiver_map) return 0; if (!holder.is_null() && holder->map() == *receiver_map) return 0;
HandleScope scope(isolate); HandleScope scope(isolate);
...@@ -31,7 +31,7 @@ int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map, ...@@ -31,7 +31,7 @@ int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map,
// corresponds. // corresponds.
if (fill_array) { if (fill_array) {
Handle<Context> native_context = isolate->native_context(); Handle<Context> native_context = isolate->native_context();
array->set(first_index + checks_count, native_context->self_weak_cell()); handler->set_data2(native_context->self_weak_cell());
} }
checks_count++; checks_count++;
} }
...@@ -47,7 +47,7 @@ int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map, ...@@ -47,7 +47,7 @@ int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map,
int GetPrototypeCheckCount(Isolate* isolate, Handle<Map> receiver_map, int GetPrototypeCheckCount(Isolate* isolate, Handle<Map> receiver_map,
Handle<JSReceiver> holder, Handle<Name> name) { Handle<JSReceiver> holder, Handle<Name> name) {
return InitPrototypeChecks<false>(isolate, receiver_map, holder, name, return InitPrototypeChecks<false>(isolate, receiver_map, holder, name,
Handle<FixedArray>(), 0); Handle<DataHandler>());
} }
} // namespace } // namespace
...@@ -62,11 +62,12 @@ Handle<Object> LoadHandler::LoadFromPrototype(Isolate* isolate, ...@@ -62,11 +62,12 @@ Handle<Object> LoadHandler::LoadFromPrototype(Isolate* isolate,
int checks_count = int checks_count =
GetPrototypeCheckCount(isolate, receiver_map, holder, name); GetPrototypeCheckCount(isolate, receiver_map, holder, name);
DCHECK_LE(0, checks_count); DCHECK_LE(0, checks_count);
DCHECK_LE(checks_count, 1);
if (receiver_map->IsPrimitiveMap() || if (receiver_map->IsPrimitiveMap() ||
receiver_map->is_access_check_needed()) { receiver_map->is_access_check_needed()) {
DCHECK(!receiver_map->is_dictionary_map()); DCHECK(!receiver_map->is_dictionary_map());
DCHECK_LE(1, checks_count); // For native context. DCHECK_EQ(1, checks_count); // For native context.
smi_handler = EnableAccessCheckOnReceiver(isolate, smi_handler); smi_handler = EnableAccessCheckOnReceiver(isolate, smi_handler);
} else if (receiver_map->is_dictionary_map() && } else if (receiver_map->is_dictionary_map() &&
!receiver_map->IsJSGlobalObjectMap()) { !receiver_map->IsJSGlobalObjectMap()) {
...@@ -82,18 +83,14 @@ Handle<Object> LoadHandler::LoadFromPrototype(Isolate* isolate, ...@@ -82,18 +83,14 @@ Handle<Object> LoadHandler::LoadFromPrototype(Isolate* isolate,
data = Map::GetOrCreatePrototypeWeakCell(holder, isolate); data = Map::GetOrCreatePrototypeWeakCell(holder, isolate);
} }
if (checks_count == 0) { int data_count = 1 + checks_count;
return isolate->factory()->NewTuple3(data, smi_handler, validity_cell, Handle<LoadHandler> handler = isolate->factory()->NewLoadHandler(data_count);
TENURED);
} handler->set_smi_handler(*smi_handler);
Handle<FixedArray> handler_array(isolate->factory()->NewFixedArray( handler->set_validity_cell(*validity_cell);
kFirstPrototypeIndex + checks_count, TENURED)); handler->set_data1(*data);
handler_array->set(kSmiHandlerIndex, *smi_handler); InitPrototypeChecks(isolate, receiver_map, holder, name, handler);
handler_array->set(kValidityCellIndex, *validity_cell); return handler;
handler_array->set(kDataIndex, *data);
InitPrototypeChecks(isolate, receiver_map, holder, name, handler_array,
kFirstPrototypeIndex);
return handler_array;
} }
// static // static
...@@ -105,11 +102,12 @@ Handle<Object> LoadHandler::LoadFullChain(Isolate* isolate, ...@@ -105,11 +102,12 @@ Handle<Object> LoadHandler::LoadFullChain(Isolate* isolate,
Handle<JSReceiver> end; // null handle Handle<JSReceiver> end; // null handle
int checks_count = GetPrototypeCheckCount(isolate, receiver_map, end, name); int checks_count = GetPrototypeCheckCount(isolate, receiver_map, end, name);
DCHECK_LE(0, checks_count); DCHECK_LE(0, checks_count);
DCHECK_LE(checks_count, 1);
if (receiver_map->IsPrimitiveMap() || if (receiver_map->IsPrimitiveMap() ||
receiver_map->is_access_check_needed()) { receiver_map->is_access_check_needed()) {
DCHECK(!receiver_map->is_dictionary_map()); DCHECK(!receiver_map->is_dictionary_map());
DCHECK_LE(1, checks_count); // For native context. DCHECK_EQ(1, checks_count); // For native context.
smi_handler = EnableAccessCheckOnReceiver(isolate, smi_handler); smi_handler = EnableAccessCheckOnReceiver(isolate, smi_handler);
} else if (receiver_map->is_dictionary_map() && } else if (receiver_map->is_dictionary_map() &&
!receiver_map->IsJSGlobalObjectMap()) { !receiver_map->IsJSGlobalObjectMap()) {
...@@ -125,18 +123,14 @@ Handle<Object> LoadHandler::LoadFullChain(Isolate* isolate, ...@@ -125,18 +123,14 @@ Handle<Object> LoadHandler::LoadFullChain(Isolate* isolate,
validity_cell = handle(Smi::kZero, isolate); validity_cell = handle(Smi::kZero, isolate);
} }
Factory* factory = isolate->factory(); int data_count = 1 + checks_count;
if (checks_count == 0) { Handle<LoadHandler> handler = isolate->factory()->NewLoadHandler(data_count);
return factory->NewTuple3(holder, smi_handler, validity_cell, TENURED);
} handler->set_smi_handler(*smi_handler);
Handle<FixedArray> handler_array(factory->NewFixedArray( handler->set_validity_cell(*validity_cell);
LoadHandler::kFirstPrototypeIndex + checks_count, TENURED)); handler->set_data1(*holder);
handler_array->set(kSmiHandlerIndex, *smi_handler); InitPrototypeChecks(isolate, receiver_map, end, name, handler);
handler_array->set(kValidityCellIndex, *validity_cell); return handler;
handler_array->set(kDataIndex, *holder);
InitPrototypeChecks(isolate, receiver_map, end, name, handler_array,
kFirstPrototypeIndex);
return handler_array;
} }
// static // static
...@@ -169,7 +163,11 @@ Handle<Object> StoreHandler::StoreElementTransition( ...@@ -169,7 +163,11 @@ Handle<Object> StoreHandler::StoreElementTransition(
validity_cell = handle(Smi::kZero, isolate); validity_cell = handle(Smi::kZero, isolate);
} }
Handle<WeakCell> cell = Map::WeakCellForMap(transition); Handle<WeakCell> cell = Map::WeakCellForMap(transition);
return isolate->factory()->NewTuple3(cell, stub, validity_cell, TENURED); Handle<StoreHandler> handler = isolate->factory()->NewStoreHandler(1);
handler->set_smi_handler(*stub);
handler->set_validity_cell(*validity_cell);
handler->set_data1(*cell);
return handler;
} }
Handle<Smi> StoreHandler::StoreTransition(Isolate* isolate, Handle<Smi> StoreHandler::StoreTransition(Isolate* isolate,
...@@ -224,18 +222,15 @@ Handle<Object> StoreHandler::StoreThroughPrototype( ...@@ -224,18 +222,15 @@ Handle<Object> StoreHandler::StoreThroughPrototype(
data = Map::GetOrCreatePrototypeWeakCell(holder, isolate); data = Map::GetOrCreatePrototypeWeakCell(holder, isolate);
} }
Factory* factory = isolate->factory(); int data_count = 1 + checks_count;
if (checks_count == 0) { Handle<StoreHandler> handler =
return factory->NewTuple3(data, smi_handler, validity_cell, TENURED); isolate->factory()->NewStoreHandler(data_count);
}
Handle<FixedArray> handler_array( handler->set_smi_handler(*smi_handler);
factory->NewFixedArray(kFirstPrototypeIndex + checks_count, TENURED)); handler->set_validity_cell(*validity_cell);
handler_array->set(kSmiHandlerIndex, *smi_handler); handler->set_data1(*data);
handler_array->set(kValidityCellIndex, *validity_cell); InitPrototypeChecks(isolate, receiver_map, holder, name, handler);
handler_array->set(kDataIndex, *data); return handler;
InitPrototypeChecks(isolate, receiver_map, holder, name, handler_array,
kFirstPrototypeIndex);
return handler_array;
} }
// static // static
...@@ -259,57 +254,25 @@ Handle<Object> StoreHandler::StoreProxy(Isolate* isolate, ...@@ -259,57 +254,25 @@ Handle<Object> StoreHandler::StoreProxy(Isolate* isolate,
Object* StoreHandler::ValidHandlerOrNull(Object* raw_handler, Name* name, Object* StoreHandler::ValidHandlerOrNull(Object* raw_handler, Name* name,
Handle<Map>* out_transition) { Handle<Map>* out_transition) {
STATIC_ASSERT(kValidityCellOffset == Tuple3::kValue3Offset);
Smi* valid = Smi::FromInt(Map::kPrototypeChainValid); Smi* valid = Smi::FromInt(Map::kPrototypeChainValid);
if (raw_handler->IsTuple3()) { DCHECK(raw_handler->IsStoreHandler());
// Check validity cell.
Tuple3* handler = Tuple3::cast(raw_handler);
Object* raw_validity_cell = handler->value3(); // Check validity cell.
// |raw_valitity_cell| can be Smi::kZero if no validity cell is required StoreHandler* handler = StoreHandler::cast(raw_handler);
// (which counts as valid).
if (raw_validity_cell->IsCell() &&
Cell::cast(raw_validity_cell)->value() != valid) {
return nullptr;
}
} else { Object* raw_validity_cell = handler->validity_cell();
DCHECK(raw_handler->IsFixedArrayExact()); // |raw_valitity_cell| can be Smi::kZero if no validity cell is required
FixedArray* handler = FixedArray::cast(raw_handler); // (which counts as valid).
if (raw_validity_cell->IsCell() &&
// Check validity cell. Cell::cast(raw_validity_cell)->value() != valid) {
Object* value = Cell::cast(handler->get(kValidityCellIndex))->value(); return nullptr;
if (value != valid) return nullptr;
// Check prototypes.
Heap* heap = handler->GetHeap();
Isolate* isolate = heap->isolate();
Handle<Name> name_handle(name, isolate);
for (int i = kFirstPrototypeIndex; i < handler->length(); i++) {
// This mirrors AccessorAssembler::CheckPrototype.
WeakCell* prototype_cell = WeakCell::cast(handler->get(i));
if (prototype_cell->cleared()) return nullptr;
HeapObject* maybe_prototype = HeapObject::cast(prototype_cell->value());
if (maybe_prototype->IsPropertyCell()) {
Object* value = PropertyCell::cast(maybe_prototype)->value();
if (value != heap->the_hole_value()) return nullptr;
} else {
DCHECK(maybe_prototype->map()->is_dictionary_map());
// Do a negative dictionary lookup.
NameDictionary* dict =
JSObject::cast(maybe_prototype)->property_dictionary();
int number = dict->FindEntry(isolate, name_handle);
if (number != NameDictionary::kNotFound) {
PropertyDetails details = dict->DetailsAt(number);
if (details.IsReadOnly()) return nullptr;
if (details.kind() == PropertyKind::kAccessor) return nullptr;
break;
}
}
}
} }
// We use this ValidHandlerOrNull() function only for transitioning store
// handlers which are not applicable to receivers that require access checks.
DCHECK(handler->smi_handler()->IsSmi());
DCHECK(
!DoAccessCheckOnReceiverBits::decode(Smi::ToInt(handler->smi_handler())));
// Check if the transition target is deprecated. // Check if the transition target is deprecated.
WeakCell* target_cell = GetTransitionCell(raw_handler); WeakCell* target_cell = GetTransitionCell(raw_handler);
......
...@@ -102,21 +102,6 @@ class LoadHandler final : public DataHandler { ...@@ -102,21 +102,6 @@ class LoadHandler final : public DataHandler {
class ExportsIndexBits : public BitField<unsigned, KindBits::kNext, class ExportsIndexBits : public BitField<unsigned, KindBits::kNext,
kSmiValueSize - KindBits::kNext> {}; kSmiValueSize - KindBits::kNext> {};
// The layout of an Tuple3 handler representing a load of a field from
// prototype when prototype chain checks do not include non-existing lookups
// or access checks.
static const int kDataOffset = Tuple3::kValue1Offset;
static const int kSmiHandlerOffset = Tuple3::kValue2Offset;
static const int kValidityCellOffset = Tuple3::kValue3Offset;
// The layout of an array handler representing a load of a field from
// prototype when prototype chain checks include non-existing lookups and
// access checks.
static const int kSmiHandlerIndex = 0;
static const int kValidityCellIndex = 1;
static const int kDataIndex = 2;
static const int kFirstPrototypeIndex = 3;
// Decodes kind from Smi-handler. // Decodes kind from Smi-handler.
static inline Kind GetHandlerKind(Smi* smi_handler); static inline Kind GetHandlerKind(Smi* smi_handler);
...@@ -267,24 +252,10 @@ class StoreHandler final : public DataHandler { ...@@ -267,24 +252,10 @@ class StoreHandler final : public DataHandler {
// Make sure we don't overflow the smi. // Make sure we don't overflow the smi.
STATIC_ASSERT(FieldIndexBits::kNext <= kSmiValueSize); STATIC_ASSERT(FieldIndexBits::kNext <= kSmiValueSize);
// The layout of an Tuple3 handler representing a transitioning store
// when prototype chain checks do not include non-existing lookups or access
// checks.
static const int kDataOffset = Tuple3::kValue1Offset;
static const int kSmiHandlerOffset = Tuple3::kValue2Offset;
static const int kValidityCellOffset = Tuple3::kValue3Offset;
static inline WeakCell* GetTransitionCell(Object* handler); static inline WeakCell* GetTransitionCell(Object* handler);
static Object* ValidHandlerOrNull(Object* handler, Name* name, static Object* ValidHandlerOrNull(Object* handler, Name* name,
Handle<Map>* out_transition); Handle<Map>* out_transition);
// The layout of an array handler representing a transitioning store
// when prototype chain checks include non-existing lookups and access checks.
static const int kSmiHandlerIndex = 0;
static const int kValidityCellIndex = 1;
static const int kDataIndex = 2;
static const int kFirstPrototypeIndex = 3;
// Creates a Smi-handler for storing a field to fast object. // Creates a Smi-handler for storing a field to fast object.
static inline Handle<Smi> StoreField(Isolate* isolate, int descriptor, static inline Handle<Smi> StoreField(Isolate* isolate, int descriptor,
FieldIndex field_index, FieldIndex field_index,
......
...@@ -42,8 +42,7 @@ Address IC::raw_constant_pool() const { ...@@ -42,8 +42,7 @@ Address IC::raw_constant_pool() const {
bool IC::IsHandler(Object* object) { bool IC::IsHandler(Object* object) {
return (object->IsSmi() && (object != nullptr)) || object->IsTuple2() || return (object->IsSmi() && (object != nullptr)) || object->IsTuple2() ||
object->IsTuple3() || object->IsFixedArrayExact() || object->IsDataHandler() || object->IsWeakCell() || object->IsCode();
object->IsWeakCell() || object->IsCode();
} }
bool IC::AddressIsDeoptimizedCode() const { bool IC::AddressIsDeoptimizedCode() const {
......
...@@ -795,36 +795,20 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( ...@@ -795,36 +795,20 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
{ {
Comment("lookup transition"); Comment("lookup transition");
VARIABLE(var_handler, MachineRepresentation::kTagged); VARIABLE(var_handler, MachineRepresentation::kTagged);
Label tuple3(this), fixedarray(this), found_handler(this, &var_handler); Label check_key(this), found_handler(this, &var_handler);
Node* maybe_handler = Node* maybe_handler =
LoadObjectField(receiver_map, Map::kTransitionsOrPrototypeInfoOffset); LoadObjectField(receiver_map, Map::kTransitionsOrPrototypeInfoOffset);
GotoIf(TaggedIsSmi(maybe_handler), notfound); GotoIf(TaggedIsSmi(maybe_handler), notfound);
Node* handler_map = LoadMap(maybe_handler); GotoIf(HasInstanceType(maybe_handler, STORE_HANDLER_TYPE), &check_key);
GotoIf(WordEqual(handler_map, Tuple3MapConstant()), &tuple3);
GotoIf(WordEqual(handler_map, FixedArrayMapConstant()), &fixedarray);
// TODO(jkummerow): Consider implementing TransitionArray search. // TODO(jkummerow): Consider implementing TransitionArray search.
Goto(notfound); Goto(notfound);
VARIABLE(var_transition_cell, MachineRepresentation::kTagged);
Label check_key(this, &var_transition_cell);
BIND(&tuple3);
{
var_transition_cell.Bind(
LoadObjectField(maybe_handler, StoreHandler::kDataOffset));
Goto(&check_key);
}
BIND(&fixedarray);
{
var_transition_cell.Bind(
LoadFixedArrayElement(maybe_handler, StoreHandler::kDataIndex));
Goto(&check_key);
}
BIND(&check_key); BIND(&check_key);
{ {
Node* transition = LoadWeakCellValue(var_transition_cell.value(), slow); Node* transition_cell =
LoadObjectField(maybe_handler, StoreHandler::kData1Offset);
Node* transition = LoadWeakCellValue(transition_cell, slow);
Node* transition_bitfield3 = LoadMapBitField3(transition); Node* transition_bitfield3 = LoadMapBitField3(transition);
GotoIf(IsSetWord32<Map::IsDeprecatedBit>(transition_bitfield3), slow); GotoIf(IsSetWord32<Map::IsDeprecatedBit>(transition_bitfield3), slow);
Node* nof = Node* nof =
......
...@@ -356,24 +356,6 @@ void LoadWithVectorDescriptor::InitializePlatformSpecific( ...@@ -356,24 +356,6 @@ void LoadWithVectorDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void LoadICProtoArrayDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) {
// kReceiver, kName, kSlot, kVector, kHandler
MachineType machine_types[] = {
MachineType::AnyTagged(), MachineType::AnyTagged(),
MachineType::TaggedSigned(), MachineType::AnyTagged(),
MachineType::AnyTagged()};
data->InitializePlatformIndependent(arraysize(machine_types), 0,
machine_types);
}
void LoadICProtoArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister(),
VectorRegister(), HandlerRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void StoreWithVectorDescriptor::InitializePlatformIndependent( void StoreWithVectorDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
// kReceiver, kName, kValue, kSlot, kVector // kReceiver, kName, kValue, kSlot, kVector
......
...@@ -22,7 +22,6 @@ class PlatformInterfaceDescriptor; ...@@ -22,7 +22,6 @@ class PlatformInterfaceDescriptor;
V(Load) \ V(Load) \
V(LoadWithVector) \ V(LoadWithVector) \
V(LoadField) \ V(LoadField) \
V(LoadICProtoArray) \
V(LoadGlobal) \ V(LoadGlobal) \
V(LoadGlobalWithVector) \ V(LoadGlobalWithVector) \
V(Store) \ V(Store) \
...@@ -504,15 +503,6 @@ class LoadWithVectorDescriptor : public LoadDescriptor { ...@@ -504,15 +503,6 @@ class LoadWithVectorDescriptor : public LoadDescriptor {
static const Register VectorRegister(); static const Register VectorRegister();
}; };
class LoadICProtoArrayDescriptor : public LoadWithVectorDescriptor {
public:
DEFINE_PARAMETERS(kReceiver, kName, kSlot, kVector, kHandler)
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadICProtoArrayDescriptor,
LoadWithVectorDescriptor)
static const Register HandlerRegister();
};
class LoadGlobalWithVectorDescriptor : public LoadGlobalDescriptor { class LoadGlobalWithVectorDescriptor : public LoadGlobalDescriptor {
public: public:
DEFINE_PARAMETERS(kName, kSlot, kVector) DEFINE_PARAMETERS(kName, kSlot, kVector)
......
...@@ -43,8 +43,6 @@ const Register LoadDescriptor::SlotRegister() { return a0; } ...@@ -43,8 +43,6 @@ const Register LoadDescriptor::SlotRegister() { return a0; }
const Register LoadWithVectorDescriptor::VectorRegister() { return a3; } const Register LoadWithVectorDescriptor::VectorRegister() { return a3; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return t0; }
const Register StoreDescriptor::ReceiverRegister() { return a1; } const Register StoreDescriptor::ReceiverRegister() { return a1; }
const Register StoreDescriptor::NameRegister() { return a2; } const Register StoreDescriptor::NameRegister() { return a2; }
const Register StoreDescriptor::ValueRegister() { return a0; } const Register StoreDescriptor::ValueRegister() { return a0; }
......
...@@ -43,8 +43,6 @@ const Register LoadDescriptor::SlotRegister() { return a0; } ...@@ -43,8 +43,6 @@ const Register LoadDescriptor::SlotRegister() { return a0; }
const Register LoadWithVectorDescriptor::VectorRegister() { return a3; } const Register LoadWithVectorDescriptor::VectorRegister() { return a3; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return a4; }
const Register StoreDescriptor::ReceiverRegister() { return a1; } const Register StoreDescriptor::ReceiverRegister() { return a1; }
const Register StoreDescriptor::NameRegister() { return a2; } const Register StoreDescriptor::NameRegister() { return a2; }
const Register StoreDescriptor::ValueRegister() { return a0; } const Register StoreDescriptor::ValueRegister() { return a0; }
......
...@@ -43,8 +43,6 @@ const Register LoadDescriptor::SlotRegister() { return r3; } ...@@ -43,8 +43,6 @@ const Register LoadDescriptor::SlotRegister() { return r3; }
const Register LoadWithVectorDescriptor::VectorRegister() { return r6; } const Register LoadWithVectorDescriptor::VectorRegister() { return r6; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return r7; }
const Register StoreDescriptor::ReceiverRegister() { return r4; } const Register StoreDescriptor::ReceiverRegister() { return r4; }
const Register StoreDescriptor::NameRegister() { return r5; } const Register StoreDescriptor::NameRegister() { return r5; }
const Register StoreDescriptor::ValueRegister() { return r3; } const Register StoreDescriptor::ValueRegister() { return r3; }
......
...@@ -43,8 +43,6 @@ const Register LoadDescriptor::SlotRegister() { return r2; } ...@@ -43,8 +43,6 @@ const Register LoadDescriptor::SlotRegister() { return r2; }
const Register LoadWithVectorDescriptor::VectorRegister() { return r5; } const Register LoadWithVectorDescriptor::VectorRegister() { return r5; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return r6; }
const Register StoreDescriptor::ReceiverRegister() { return r3; } const Register StoreDescriptor::ReceiverRegister() { return r3; }
const Register StoreDescriptor::NameRegister() { return r4; } const Register StoreDescriptor::NameRegister() { return r4; }
const Register StoreDescriptor::ValueRegister() { return r2; } const Register StoreDescriptor::ValueRegister() { return r2; }
......
...@@ -44,8 +44,6 @@ const Register LoadDescriptor::SlotRegister() { return rax; } ...@@ -44,8 +44,6 @@ const Register LoadDescriptor::SlotRegister() { return rax; }
const Register LoadWithVectorDescriptor::VectorRegister() { return rbx; } const Register LoadWithVectorDescriptor::VectorRegister() { return rbx; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return rdi; }
const Register StoreDescriptor::ReceiverRegister() { return rdx; } const Register StoreDescriptor::ReceiverRegister() { return rdx; }
const Register StoreDescriptor::NameRegister() { return rcx; } const Register StoreDescriptor::NameRegister() { return rcx; }
const Register StoreDescriptor::ValueRegister() { return rax; } const Register StoreDescriptor::ValueRegister() { return rax; }
......
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