Commit 0db5bc23 authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[ic] Turn LoadIC_Normal and StoreIC_Normal into data handlers

This is mostly prework to also support prototype chain checks using data handlers

BUG=

Change-Id: I70aac1e86e45c78dfdc9f02d06b7e821494a4c9c
Reviewed-on: https://chromium-review.googlesource.com/447679
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43495}
parent 1c7f8398
......@@ -167,36 +167,6 @@ TF_BUILTIN(LoadIC_Miss, CodeStubAssembler) {
TailCallRuntime(Runtime::kLoadIC_Miss, context, receiver, name, slot, vector);
}
TF_BUILTIN(LoadIC_Normal, CodeStubAssembler) {
typedef LoadWithVectorDescriptor Descriptor;
Node* receiver = Parameter(Descriptor::kReceiver);
Node* name = Parameter(Descriptor::kName);
Node* context = Parameter(Descriptor::kContext);
Label slow(this);
{
Node* properties = LoadProperties(receiver);
Variable var_name_index(this, MachineType::PointerRepresentation());
Label found(this, &var_name_index);
NameDictionaryLookup<NameDictionary>(properties, name, &found,
&var_name_index, &slow);
Bind(&found);
{
Variable var_details(this, MachineRepresentation::kWord32);
Variable var_value(this, MachineRepresentation::kTagged);
LoadPropertyFromNameDictionary(properties, var_name_index.value(),
&var_details, &var_value);
Node* value = CallGetterIfAccessor(var_value.value(), var_details.value(),
context, receiver, &slow);
Return(value);
}
}
Bind(&slow);
TailCallRuntime(Runtime::kGetProperty, context, receiver, name);
}
TF_BUILTIN(LoadIC_Slow, CodeStubAssembler) {
typedef LoadWithVectorDescriptor Descriptor;
......@@ -221,43 +191,6 @@ TF_BUILTIN(StoreIC_Miss, CodeStubAssembler) {
receiver, name);
}
TF_BUILTIN(StoreIC_Normal, CodeStubAssembler) {
typedef StoreWithVectorDescriptor Descriptor;
Node* receiver = Parameter(Descriptor::kReceiver);
Node* name = Parameter(Descriptor::kName);
Node* value = Parameter(Descriptor::kValue);
Node* slot = Parameter(Descriptor::kSlot);
Node* vector = Parameter(Descriptor::kVector);
Node* context = Parameter(Descriptor::kContext);
Label slow(this);
{
Node* properties = LoadProperties(receiver);
Variable var_name_index(this, MachineType::PointerRepresentation());
Label found(this, &var_name_index);
NameDictionaryLookup<NameDictionary>(properties, name, &found,
&var_name_index, &slow);
Bind(&found);
{
Node* details = LoadDetailsByKeyIndex<NameDictionary>(
properties, var_name_index.value());
// Check that the property is a writable data property (no accessor).
const int kTypeAndReadOnlyMask = PropertyDetails::KindField::kMask |
PropertyDetails::kAttributesReadOnlyMask;
STATIC_ASSERT(kData == 0);
GotoIf(IsSetWord32(details, kTypeAndReadOnlyMask), &slow);
StoreValueByKeyIndex<NameDictionary>(properties, var_name_index.value(),
value);
Return(value);
}
}
Bind(&slow);
TailCallRuntime(Runtime::kStoreIC_Miss, context, value, slot, vector,
receiver, name);
}
void Builtins::Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) {
NamedStoreHandlerCompiler::GenerateStoreViaSetterForDeopt(masm);
}
......
......@@ -244,11 +244,9 @@ class Isolate;
TFS(LoadIC_FunctionPrototype, HANDLER, Code::LOAD_IC, LoadWithVector, 1) \
ASH(LoadIC_Getter_ForDeopt, BUILTIN, kNoExtraICState) \
TFS(LoadIC_Miss, BUILTIN, kNoExtraICState, LoadWithVector, 1) \
TFS(LoadIC_Normal, HANDLER, Code::LOAD_IC, LoadWithVector, 1) \
TFS(LoadIC_Slow, HANDLER, Code::LOAD_IC, LoadWithVector, 1) \
TFS(LoadIC_Uninitialized, BUILTIN, kNoExtraICState, LoadWithVector, 1) \
TFS(StoreIC_Miss, BUILTIN, kNoExtraICState, StoreWithVector, 1) \
TFS(StoreIC_Normal, HANDLER, Code::STORE_IC, StoreWithVector, 1) \
ASH(StoreIC_Setter_ForDeopt, BUILTIN, kNoExtraICState) \
\
/* Built-in functions for Javascript */ \
......
......@@ -789,7 +789,7 @@ class RuntimeCallTimer final {
V(LoadIC_LoadInterceptor) \
V(LoadIC_LoadNonexistentDH) \
V(LoadIC_LoadNonexistent) \
V(LoadIC_LoadNormal) \
V(LoadIC_LoadNormalDH) \
V(LoadIC_LoadScriptContextFieldStub) \
V(LoadIC_LoadViaGetter) \
V(LoadIC_NonReceiver) \
......@@ -814,7 +814,7 @@ class RuntimeCallTimer final {
V(StoreIC_StoreGlobal) \
V(StoreIC_StoreGlobalTransition) \
V(StoreIC_StoreInterceptorStub) \
V(StoreIC_StoreNormal) \
V(StoreIC_StoreNormalDH) \
V(StoreIC_StoreScriptContextFieldStub) \
V(StoreIC_StoreTransition) \
V(StoreIC_StoreTransitionDH) \
......
......@@ -179,6 +179,48 @@ void AccessorAssembler::HandleLoadICHandlerCase(
}
}
void AccessorAssembler::HandleLoadField(Node* holder, Node* handler_word,
Variable* var_double_value,
Label* rebox_double,
ExitPoint* exit_point) {
Comment("field_load");
Node* offset = DecodeWord<LoadHandler::FieldOffsetBits>(handler_word);
Label inobject(this), out_of_object(this);
Branch(IsSetWord<LoadHandler::IsInobjectBits>(handler_word), &inobject,
&out_of_object);
Bind(&inobject);
{
Label is_double(this);
GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double);
exit_point->Return(LoadObjectField(holder, offset));
Bind(&is_double);
if (FLAG_unbox_double_fields) {
var_double_value->Bind(
LoadObjectField(holder, offset, MachineType::Float64()));
} else {
Node* mutable_heap_number = LoadObjectField(holder, offset);
var_double_value->Bind(LoadHeapNumberValue(mutable_heap_number));
}
Goto(rebox_double);
}
Bind(&out_of_object);
{
Label is_double(this);
Node* properties = LoadProperties(holder);
Node* value = LoadObjectField(properties, offset);
GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double);
exit_point->Return(value);
Bind(&is_double);
var_double_value->Bind(LoadHeapNumberValue(value));
Goto(rebox_double);
}
}
void AccessorAssembler::HandleLoadICSmiHandlerCase(
const LoadICParameters* p, Node* holder, Node* smi_handler, Label* miss,
ExitPoint* exit_point, ElementSupport support_elements) {
......@@ -232,63 +274,32 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase(
Comment("property_load");
}
Label constant(this), field(this);
Branch(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForFields)),
&field, &constant);
Label constant(this), field(this), normal(this);
GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForFields)),
&field);
Bind(&field);
{
Comment("field_load");
Node* offset = DecodeWord<LoadHandler::FieldOffsetBits>(handler_word);
Branch(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForConstants)),
&constant, &normal);
Label inobject(this), out_of_object(this);
Branch(IsSetWord<LoadHandler::IsInobjectBits>(handler_word), &inobject,
&out_of_object);
Bind(&inobject);
{
Label is_double(this);
GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double);
exit_point->Return(LoadObjectField(holder, offset));
Bind(&is_double);
if (FLAG_unbox_double_fields) {
var_double_value.Bind(
LoadObjectField(holder, offset, MachineType::Float64()));
} else {
Node* mutable_heap_number = LoadObjectField(holder, offset);
var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number));
}
Goto(&rebox_double);
}
Bind(&out_of_object);
{
Label is_double(this);
Node* properties = LoadProperties(holder);
Node* value = LoadObjectField(properties, offset);
GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double);
exit_point->Return(value);
Bind(&is_double);
var_double_value.Bind(LoadHeapNumberValue(value));
Goto(&rebox_double);
}
Bind(&rebox_double);
exit_point->Return(AllocateHeapNumberWithValue(var_double_value.value()));
}
Bind(&field);
HandleLoadField(holder, handler_word, &var_double_value, &rebox_double,
exit_point);
Bind(&constant);
{
Comment("constant_load");
Node* descriptors = LoadMapDescriptors(LoadMap(holder));
Node* descriptor =
DecodeWord<LoadHandler::DescriptorValueIndexBits>(handler_word);
Node* descriptor = DecodeWord<LoadHandler::DescriptorBits>(handler_word);
Node* scaled_descriptor =
IntPtrMul(descriptor, IntPtrConstant(DescriptorArray::kEntrySize));
Node* value_index =
IntPtrAdd(scaled_descriptor,
IntPtrConstant(DescriptorArray::kFirstIndex +
DescriptorArray::kEntryValueIndex));
CSA_ASSERT(this,
UintPtrLessThan(descriptor,
LoadAndUntagFixedArrayBaseLength(descriptors)));
Node* value = LoadFixedArrayElement(descriptors, descriptor);
Node* value = LoadFixedArrayElement(descriptors, value_index);
Label if_accessor_info(this);
GotoIf(IsSetWord<LoadHandler::IsAccessorInfoBits>(handler_word),
......@@ -300,6 +311,29 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase(
exit_point->ReturnCallStub(callable, p->context, p->receiver, holder,
value);
}
Bind(&normal);
{
Comment("load_normal");
Node* properties = LoadProperties(holder);
Variable var_name_index(this, MachineType::PointerRepresentation());
Label found(this, &var_name_index);
NameDictionaryLookup<NameDictionary>(properties, p->name, &found,
&var_name_index, miss);
Bind(&found);
{
Variable var_details(this, MachineRepresentation::kWord32);
Variable var_value(this, MachineRepresentation::kTagged);
LoadPropertyFromNameDictionary(properties, var_name_index.value(),
&var_details, &var_value);
Node* value = CallGetterIfAccessor(var_value.value(), var_details.value(),
p->context, p->receiver, miss);
exit_point->Return(value);
}
}
Bind(&rebox_double);
exit_point->Return(AllocateHeapNumberWithValue(var_double_value.value()));
}
void AccessorAssembler::HandleLoadICProtoHandlerCase(
......@@ -464,6 +498,16 @@ void AccessorAssembler::HandleLoadGlobalICHandlerCase(
miss, exit_point, kOnlyProperties);
}
void AccessorAssembler::JumpIfDataProperty(Node* details, Label* writable,
Label* readonly) {
// Accessor properties never have the READ_ONLY attribute set.
GotoIf(IsSetWord32(details, PropertyDetails::kAttributesReadOnlyMask),
readonly);
Node* kind = DecodeWord32<PropertyDetails::KindField>(details);
GotoIf(Word32Equal(kind, Int32Constant(kData)), writable);
// Fall through if it's an accessor property.
}
void AccessorAssembler::HandleStoreICHandlerCase(
const StoreICParameters* p, Node* handler, Label* miss,
ElementSupport support_elements) {
......@@ -479,6 +523,33 @@ void AccessorAssembler::HandleStoreICHandlerCase(
Node* holder = p->receiver;
Node* handler_word = SmiUntag(handler);
Label if_fast_smi(this), slow(this);
GotoIfNot(
WordEqual(handler_word, IntPtrConstant(StoreHandler::kStoreNormal)),
&if_fast_smi);
Node* properties = LoadProperties(holder);
Variable var_name_index(this, MachineType::PointerRepresentation());
Label dictionary_found(this, &var_name_index);
NameDictionaryLookup<NameDictionary>(properties, p->name, &dictionary_found,
&var_name_index, miss);
Bind(&dictionary_found);
{
Node* details = LoadDetailsByKeyIndex<NameDictionary>(
properties, var_name_index.value());
// Check that the property is a writable data property (no accessor).
const int kTypeAndReadOnlyMask = PropertyDetails::KindField::kMask |
PropertyDetails::kAttributesReadOnlyMask;
STATIC_ASSERT(kData == 0);
GotoIf(IsSetWord32(details, kTypeAndReadOnlyMask), miss);
StoreValueByKeyIndex<NameDictionary>(properties, var_name_index.value(),
p->value);
Return(p->value);
}
Bind(&if_fast_smi);
// Handle non-transitioning field stores.
HandleStoreICSmiHandlerCase(handler_word, holder, p->value, nullptr, miss);
}
......@@ -606,11 +677,20 @@ void AccessorAssembler::HandleStoreICProtoHandler(const StoreICParameters* p,
Bind(&if_transition_to_constant);
{
// Check that constant matches value.
Node* value_index_in_descriptor =
DecodeWord<StoreHandler::DescriptorValueIndexBits>(handler_word);
Node* descriptor = DecodeWord<StoreHandler::DescriptorBits>(handler_word);
Node* scaled_descriptor =
IntPtrMul(descriptor, IntPtrConstant(DescriptorArray::kEntrySize));
Node* value_index =
IntPtrAdd(scaled_descriptor,
IntPtrConstant(DescriptorArray::kFirstIndex +
DescriptorArray::kEntryValueIndex));
Node* descriptors = LoadMapDescriptors(transition);
Node* constant =
LoadFixedArrayElement(descriptors, value_index_in_descriptor);
CSA_ASSERT(
this,
UintPtrLessThan(descriptor,
LoadAndUntagFixedArrayBaseLength(descriptors)));
Node* constant = LoadFixedArrayElement(descriptors, value_index);
GotoIf(WordNotEqual(p->value, constant), miss);
StoreMap(p->receiver, transition);
......@@ -761,12 +841,19 @@ Node* AccessorAssembler::PrepareValueForStore(Node* handler_word, Node* holder,
IntPtrConstant(StoreHandler::kStoreConstField)),
&done);
}
Node* value_index_in_descriptor =
DecodeWord<StoreHandler::DescriptorValueIndexBits>(handler_word);
Node* descriptor = DecodeWord<StoreHandler::DescriptorBits>(handler_word);
Node* scaled_descriptor =
IntPtrMul(descriptor, IntPtrConstant(DescriptorArray::kEntrySize));
Node* value_index =
IntPtrAdd(scaled_descriptor,
IntPtrConstant(DescriptorArray::kFirstIndex +
DescriptorArray::kEntryValueIndex));
Node* descriptors =
LoadMapDescriptors(transition ? transition : LoadMap(holder));
Node* maybe_field_type =
LoadFixedArrayElement(descriptors, value_index_in_descriptor);
CSA_ASSERT(this,
UintPtrLessThan(descriptor,
LoadAndUntagFixedArrayBaseLength(descriptors)));
Node* maybe_field_type = LoadFixedArrayElement(descriptors, value_index);
GotoIf(TaggedIsSmi(maybe_field_type), &done);
// Check that value type matches the field type.
......@@ -1977,8 +2064,16 @@ void AccessorAssembler::GenerateLoadField() {
ExitPoint direct_exit(this);
HandleLoadICSmiHandlerCase(&p, receiver, Parameter(Descriptor::kSmiHandler),
nullptr, &direct_exit, kOnlyProperties);
Variable var_double_value(this, MachineRepresentation::kFloat64);
Label rebox_double(this, &var_double_value);
Node* smi_handler = Parameter(Descriptor::kSmiHandler);
Node* handler_word = SmiUntag(smi_handler);
HandleLoadField(receiver, handler_word, &var_double_value, &rebox_double,
&direct_exit);
Bind(&rebox_double);
Return(AllocateHeapNumberWithValue(var_double_value.value()));
}
void AccessorAssembler::GenerateLoadGlobalIC(TypeofMode typeof_mode) {
......
......@@ -89,6 +89,7 @@ class AccessorAssembler : public CodeStubAssembler {
void HandleStoreICHandlerCase(
const StoreICParameters* p, Node* handler, Label* miss,
ElementSupport support_elements = kOnlyProperties);
void JumpIfDataProperty(Node* details, Label* writable, Label* readonly);
private:
// Stub generation entry points.
......@@ -136,6 +137,10 @@ class AccessorAssembler : public CodeStubAssembler {
ExitPoint* exit_point,
bool throw_reference_error_if_nonexistent);
void HandleLoadField(Node* holder, Node* handler_word,
Variable* var_double_value, Label* rebox_double,
ExitPoint* exit_point);
Node* EmitLoadICProtoArrayCheck(const LoadICParameters* p, Node* handler,
Node* handler_length, Node* handler_flags,
Label* miss,
......
......@@ -13,6 +13,11 @@
namespace v8 {
namespace internal {
Handle<Object> LoadHandler::LoadNormal(Isolate* isolate) {
int config = KindBits::encode(kForNormal);
return handle(Smi::FromInt(config), isolate);
}
Handle<Object> LoadHandler::LoadField(Isolate* isolate,
FieldIndex field_index) {
int config = KindBits::encode(kForFields) |
......@@ -25,16 +30,14 @@ Handle<Object> LoadHandler::LoadField(Isolate* isolate,
Handle<Object> LoadHandler::LoadConstant(Isolate* isolate, int descriptor) {
int config = KindBits::encode(kForConstants) |
IsAccessorInfoBits::encode(false) |
DescriptorValueIndexBits::encode(
DescriptorArray::ToValueIndex(descriptor));
DescriptorBits::encode(descriptor);
return handle(Smi::FromInt(config), isolate);
}
Handle<Object> LoadHandler::LoadApiGetter(Isolate* isolate, int descriptor) {
int config = KindBits::encode(kForConstants) |
IsAccessorInfoBits::encode(true) |
DescriptorValueIndexBits::encode(
DescriptorArray::ToValueIndex(descriptor));
DescriptorBits::encode(descriptor);
return handle(Smi::FromInt(config), isolate);
}
......@@ -79,6 +82,11 @@ Handle<Object> LoadHandler::LoadElement(Isolate* isolate,
return handle(Smi::FromInt(config), isolate);
}
Handle<Object> StoreHandler::StoreNormal(Isolate* isolate) {
int config = KindBits::encode(kStoreNormal);
return handle(Smi::FromInt(config), isolate);
}
Handle<Object> StoreHandler::StoreField(Isolate* isolate, Kind kind,
int descriptor, FieldIndex field_index,
Representation representation,
......@@ -101,7 +109,6 @@ Handle<Object> StoreHandler::StoreField(Isolate* isolate, Kind kind,
UNREACHABLE();
return Handle<Object>::null();
}
int value_index = DescriptorArray::ToValueIndex(descriptor);
DCHECK(kind == kStoreField || kind == kTransitionToField ||
(kind == kStoreConstField && FLAG_track_constant_fields));
......@@ -112,7 +119,7 @@ Handle<Object> StoreHandler::StoreField(Isolate* isolate, Kind kind,
StoreHandler::ExtendStorageBits::encode(extend_storage) |
StoreHandler::IsInobjectBits::encode(field_index.is_inobject()) |
StoreHandler::FieldRepresentationBits::encode(field_rep) |
StoreHandler::DescriptorValueIndexBits::encode(value_index) |
StoreHandler::DescriptorBits::encode(descriptor) |
StoreHandler::FieldOffsetBits::encode(field_index.offset());
return handle(Smi::FromInt(config), isolate);
}
......@@ -138,10 +145,9 @@ Handle<Object> StoreHandler::TransitionToField(Isolate* isolate, int descriptor,
Handle<Object> StoreHandler::TransitionToConstant(Isolate* isolate,
int descriptor) {
DCHECK(!FLAG_track_constant_fields);
int value_index = DescriptorArray::ToValueIndex(descriptor);
int config =
StoreHandler::KindBits::encode(StoreHandler::kTransitionToConstant) |
StoreHandler::DescriptorValueIndexBits::encode(value_index);
StoreHandler::DescriptorBits::encode(descriptor);
return handle(Smi::FromInt(config), isolate);
}
......
......@@ -16,8 +16,14 @@ namespace internal {
// A set of bit fields representing Smi handlers for loads.
class LoadHandler {
public:
enum Kind { kForElements, kForFields, kForConstants, kForNonExistent };
class KindBits : public BitField<Kind, 0, 2> {};
enum Kind {
kForElements,
kForNormal,
kForFields,
kForConstants,
kForNonExistent
};
class KindBits : public BitField<Kind, 0, 3> {};
// Defines whether access rights check should be done on receiver object.
// Applicable to kForFields, kForConstants and kForNonExistent kinds only when
......@@ -38,12 +44,10 @@ class LoadHandler {
class IsAccessorInfoBits
: public BitField<bool, DoNegativeLookupOnReceiverBits::kNext, 1> {};
// Index of a value entry in the descriptor array.
// +2 here is because each descriptor entry occupies 3 slots in array.
class DescriptorValueIndexBits
: public BitField<unsigned, IsAccessorInfoBits::kNext,
kDescriptorIndexBitCount + 2> {};
class DescriptorBits : public BitField<unsigned, IsAccessorInfoBits::kNext,
kDescriptorIndexBitCount> {};
// Make sure we don't overflow the smi.
STATIC_ASSERT(DescriptorValueIndexBits::kNext <= kSmiValueSize);
STATIC_ASSERT(DescriptorBits::kNext <= kSmiValueSize);
//
// Encoding when KindBits contains kForFields.
......@@ -83,6 +87,9 @@ class LoadHandler {
static const int kHolderCellIndex = 2;
static const int kFirstPrototypeIndex = 3;
// Creates a Smi-handler for loading a property from a slow object.
static inline Handle<Object> LoadNormal(Isolate* isolate);
// Creates a Smi-handler for loading a field from fast object.
static inline Handle<Object> LoadField(Isolate* isolate,
FieldIndex field_index);
......@@ -122,11 +129,12 @@ class StoreHandler {
kStoreElement,
kStoreField,
kStoreConstField,
kStoreNormal,
kTransitionToField,
// TODO(ishell): remove once constant field tracking is done.
kTransitionToConstant = kStoreConstField
};
class KindBits : public BitField<Kind, 0, 2> {};
class KindBits : public BitField<Kind, 0, 3> {};
enum FieldRepresentation { kSmi, kDouble, kHeapObject, kTagged };
......@@ -134,22 +142,19 @@ class StoreHandler {
// kinds.
// Index of a value entry in the descriptor array.
// +2 here is because each descriptor entry occupies 3 slots in array.
class DescriptorValueIndexBits
: public BitField<unsigned, KindBits::kNext,
kDescriptorIndexBitCount + 2> {};
class DescriptorBits
: public BitField<unsigned, KindBits::kNext, kDescriptorIndexBitCount> {};
//
// Encoding when KindBits contains kTransitionToConstant.
//
// Make sure we don't overflow the smi.
STATIC_ASSERT(DescriptorValueIndexBits::kNext <= kSmiValueSize);
STATIC_ASSERT(DescriptorBits::kNext <= kSmiValueSize);
//
// Encoding when KindBits contains kStoreField or kTransitionToField.
//
class ExtendStorageBits
: public BitField<bool, DescriptorValueIndexBits::kNext, 1> {};
class ExtendStorageBits : public BitField<bool, DescriptorBits::kNext, 1> {};
class IsInobjectBits : public BitField<bool, ExtendStorageBits::kNext, 1> {};
class FieldRepresentationBits
: public BitField<FieldRepresentation, IsInobjectBits::kNext, 2> {};
......@@ -180,6 +185,9 @@ class StoreHandler {
PropertyConstness constness,
Representation representation);
// Creates a Smi-handler for storing a property to a slow object.
static inline Handle<Object> StoreNormal(Isolate* isolate);
// Creates a Smi-handler for transitioning store to a field.
static inline Handle<Object> TransitionToField(Isolate* isolate,
int descriptor,
......
......@@ -1383,8 +1383,8 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
return slow_stub();
}
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormal);
return isolate()->builtins()->LoadIC_Normal();
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormalDH);
return LoadHandler::LoadNormal(isolate());
}
// -------------- Fields --------------
......@@ -2005,9 +2005,9 @@ Handle<Object> StoreIC::GetMapIndependentHandler(LookupIterator* lookup) {
if (holder->IsJSGlobalObject()) {
break; // Custom-compiled handler.
}
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNormal);
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNormalDH);
DCHECK(holder.is_identical_to(receiver));
return isolate()->builtins()->StoreIC_Normal();
return StoreHandler::StoreNormal(isolate());
}
// -------------- Fields --------------
......
......@@ -67,7 +67,6 @@ class KeyedStoreGenericAssembler : public AccessorAssembler {
ElementsKind packed_kind,
ElementsKind packed_kind_2, Label* bailout);
void JumpIfDataProperty(Node* details, Label* writable, Label* readonly);
void LookupPropertyOnPrototypeChain(Node* receiver_map, Node* name,
Label* accessor,
Variable* var_accessor_pair,
......@@ -506,17 +505,6 @@ void KeyedStoreGenericAssembler::EmitGenericElementStore(
}
}
void KeyedStoreGenericAssembler::JumpIfDataProperty(Node* details,
Label* writable,
Label* readonly) {
// Accessor properties never have the READ_ONLY attribute set.
GotoIf(IsSetWord32(details, PropertyDetails::kAttributesReadOnlyMask),
readonly);
Node* kind = DecodeWord32<PropertyDetails::KindField>(details);
GotoIf(Word32Equal(kind, Int32Constant(kData)), writable);
// Fall through if it's an accessor property.
}
void KeyedStoreGenericAssembler::LookupPropertyOnPrototypeChain(
Node* receiver_map, Node* name, Label* accessor,
Variable* var_accessor_pair, Variable* var_accessor_holder, Label* readonly,
......
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