Chromium Code Reviews

Unified Diff: src/ic/accessor-assembler.cc

Issue 2511603002: [ic] Support data handlers in LoadGlobalIC. (Closed)
Patch Set: Addressing comments and fix Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Index: src/ic/accessor-assembler.cc
diff --git a/src/ic/accessor-assembler.cc b/src/ic/accessor-assembler.cc
index 2f1a97ec172b571c1af7028eb8596f60a60540ad..dafb055cad70b79b076cc39b6834c436091ea5df 100644
--- a/src/ic/accessor-assembler.cc
+++ b/src/ic/accessor-assembler.cc
@@ -166,8 +166,8 @@ void AccessorAssemblerImpl::HandleLoadICHandlerCase(
Bind(&try_proto_handler);
{
GotoIf(IsCodeMap(LoadMap(handler)), &call_handler);
- HandleLoadICProtoHandler(p, handler, &var_holder, &var_smi_handler,
- &if_smi_handler, miss);
+ HandleLoadICProtoHandlerCase(p, handler, &var_holder, &var_smi_handler,
+ &if_smi_handler, miss, false);
}
Bind(&call_handler);
@@ -304,9 +304,10 @@ void AccessorAssemblerImpl::HandleLoadICSmiHandlerCase(
}
}
-void AccessorAssemblerImpl::HandleLoadICProtoHandler(
+void AccessorAssemblerImpl::HandleLoadICProtoHandlerCase(
const LoadICParameters* p, Node* handler, Variable* var_holder,
- Variable* var_smi_handler, Label* if_smi_handler, Label* miss) {
+ Variable* var_smi_handler, Label* if_smi_handler, Label* miss,
+ bool throw_reference_error_if_nonexistent) {
DCHECK_EQ(MachineRepresentation::kTagged, var_holder->rep());
DCHECK_EQ(MachineRepresentation::kTagged, var_smi_handler->rep());
@@ -339,6 +340,8 @@ void AccessorAssemblerImpl::HandleLoadICProtoHandler(
IsSetWord<LoadHandler::DoNegativeLookupOnReceiverBits>(handler_flags),
&check_prototypes);
{
+ CSA_ASSERT(this, Word32BinaryNot(
+ HasInstanceType(p->receiver, JS_GLOBAL_OBJECT_TYPE)));
Igor Sheludko 2016/11/17 11:32:08 The catcher.
// We have a dictionary receiver, do a negative lookup check.
NameDictionaryNegativeLookup(p->receiver, p->name, miss);
Goto(&check_prototypes);
@@ -355,7 +358,11 @@ void AccessorAssemblerImpl::HandleLoadICProtoHandler(
Label load_existent(this);
GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent);
// This is a handler for a load of a non-existent value.
- Return(UndefinedConstant());
+ if (throw_reference_error_if_nonexistent) {
+ TailCallRuntime(Runtime::kThrowReferenceError, p->context, p->name);
+ } else {
+ Return(UndefinedConstant());
+ }
Bind(&load_existent);
Node* holder = LoadWeakCellValue(maybe_holder_cell);
@@ -371,7 +378,7 @@ void AccessorAssemblerImpl::HandleLoadICProtoHandler(
Bind(&array_handler);
{
typedef LoadICProtoArrayDescriptor Descriptor;
- LoadICProtoArrayStub stub(isolate());
+ LoadICProtoArrayStub stub(isolate(), throw_reference_error_if_nonexistent);
Node* target = HeapConstant(stub.GetCode());
TailCallStub(Descriptor(isolate()), target, p->context,
Arg(Descriptor::kReceiver, p->receiver),
@@ -384,7 +391,8 @@ void AccessorAssemblerImpl::HandleLoadICProtoHandler(
Node* AccessorAssemblerImpl::EmitLoadICProtoArrayCheck(
const LoadICParameters* p, Node* handler, Node* handler_length,
- Node* handler_flags, Label* miss) {
+ Node* handler_flags, Label* miss,
+ bool throw_reference_error_if_nonexistent) {
Variable start_index(this, MachineType::PointerRepresentation());
start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex));
@@ -430,7 +438,11 @@ Node* AccessorAssemblerImpl::EmitLoadICProtoArrayCheck(
Label load_existent(this);
GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent);
// This is a handler for a load of a non-existent value.
- Return(UndefinedConstant());
+ if (throw_reference_error_if_nonexistent) {
+ TailCallRuntime(Runtime::kThrowReferenceError, p->context, p->name);
+ } else {
+ Return(UndefinedConstant());
+ }
Bind(&load_existent);
Node* holder = LoadWeakCellValue(maybe_holder_cell);
@@ -441,6 +453,25 @@ Node* AccessorAssemblerImpl::EmitLoadICProtoArrayCheck(
return holder;
}
+void AccessorAssemblerImpl::HandleLoadGlobalICHandlerCase(
+ const LoadICParameters* pp, Node* handler, Label* miss,
+ bool throw_reference_error_if_nonexistent) {
+ LoadICParameters p = *pp;
+ DCHECK_NULL(p.receiver);
+ Node* native_context = LoadNativeContext(p.context);
+ p.receiver = LoadContextElement(native_context, Context::EXTENSION_INDEX);
+
+ Variable var_holder(this, MachineRepresentation::kTagged);
+ Variable var_smi_handler(this, MachineRepresentation::kTagged);
+ Label if_smi_handler(this);
+ HandleLoadICProtoHandlerCase(&p, handler, &var_holder, &var_smi_handler,
+ &if_smi_handler, miss,
+ throw_reference_error_if_nonexistent);
+ Bind(&if_smi_handler);
+ HandleLoadICSmiHandlerCase(&p, var_holder.value(), var_smi_handler.value(),
+ miss, kOnlyProperties);
+}
+
void AccessorAssemblerImpl::HandleStoreICHandlerCase(const StoreICParameters* p,
Node* handler,
Label* miss) {
@@ -1120,8 +1151,9 @@ void AccessorAssemblerImpl::LoadIC(const LoadICParameters* p) {
}
}
-void AccessorAssemblerImpl::LoadICProtoArray(const LoadICParameters* p,
- Node* handler) {
+void AccessorAssemblerImpl::LoadICProtoArray(
+ const LoadICParameters* p, Node* handler,
+ bool throw_reference_error_if_nonexistent) {
Label miss(this);
CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(handler)));
CSA_ASSERT(this, IsFixedArrayMap(LoadMap(handler)));
@@ -1131,8 +1163,9 @@ void AccessorAssemblerImpl::LoadICProtoArray(const LoadICParameters* p,
Node* handler_length = LoadAndUntagFixedArrayBaseLength(handler);
- Node* holder = EmitLoadICProtoArrayCheck(p, handler, handler_length,
- handler_flags, &miss);
+ Node* holder =
+ EmitLoadICProtoArrayCheck(p, handler, handler_length, handler_flags,
+ &miss, throw_reference_error_if_nonexistent);
HandleLoadICSmiHandlerCase(p, holder, smi_handler, &miss, kOnlyProperties);
@@ -1143,8 +1176,9 @@ void AccessorAssemblerImpl::LoadICProtoArray(const LoadICParameters* p,
}
}
-void AccessorAssemblerImpl::LoadGlobalIC(const LoadICParameters* p) {
- Label try_handler(this), miss(this);
+void AccessorAssemblerImpl::LoadGlobalIC(const LoadICParameters* p,
+ TypeofMode typeof_mode) {
+ Label try_handler(this), call_handler(this), miss(this);
Node* weak_cell =
LoadFixedArrayElement(p->vector, p->slot, 0, SMI_PARAMETERS);
CSA_ASSERT(this, HasInstanceType(weak_cell, WEAK_CELL_TYPE));
@@ -1157,15 +1191,24 @@ void AccessorAssemblerImpl::LoadGlobalIC(const LoadICParameters* p) {
GotoIf(WordEqual(value, TheHoleConstant()), &miss);
Return(value);
+ Node* handler;
Bind(&try_handler);
{
- Node* handler =
+ handler =
LoadFixedArrayElement(p->vector, p->slot, kPointerSize, SMI_PARAMETERS);
+ CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(handler)));
GotoIf(WordEqual(handler, LoadRoot(Heap::kuninitialized_symbolRootIndex)),
&miss);
+ GotoIf(IsCodeMap(LoadMap(handler)), &call_handler);
- // In this case {handler} must be a Code object.
- CSA_ASSERT(this, HasInstanceType(handler, CODE_TYPE));
+ bool throw_reference_error_if_nonexistent =
+ typeof_mode == NOT_INSIDE_TYPEOF;
+ HandleLoadGlobalICHandlerCase(p, handler, &miss,
+ throw_reference_error_if_nonexistent);
+ }
+
+ Bind(&call_handler);
+ {
LoadWithVectorDescriptor descriptor(isolate());
Node* native_context = LoadNativeContext(p->context);
Node* receiver =
@@ -1551,7 +1594,8 @@ void AccessorAssemblerImpl::GenerateLoadICTrampoline() {
LoadIC(&p);
}
-void AccessorAssemblerImpl::GenerateLoadICProtoArray() {
+void AccessorAssemblerImpl::GenerateLoadICProtoArray(
+ bool throw_reference_error_if_nonexistent) {
typedef LoadICProtoArrayStub::Descriptor Descriptor;
Node* receiver = Parameter(Descriptor::kReceiver);
@@ -1562,10 +1606,10 @@ void AccessorAssemblerImpl::GenerateLoadICProtoArray() {
Node* context = Parameter(Descriptor::kContext);
LoadICParameters p(context, receiver, name, slot, vector);
- LoadICProtoArray(&p, handler);
+ LoadICProtoArray(&p, handler, throw_reference_error_if_nonexistent);
}
-void AccessorAssemblerImpl::GenerateLoadGlobalIC() {
+void AccessorAssemblerImpl::GenerateLoadGlobalIC(TypeofMode typeof_mode) {
typedef LoadGlobalICStub::Descriptor Descriptor;
Node* name = Parameter(Descriptor::kName);
@@ -1574,10 +1618,11 @@ void AccessorAssemblerImpl::GenerateLoadGlobalIC() {
Node* context = Parameter(Descriptor::kContext);
LoadICParameters p(context, nullptr, name, slot, vector);
- LoadGlobalIC(&p);
+ LoadGlobalIC(&p, typeof_mode);
}
-void AccessorAssemblerImpl::GenerateLoadGlobalICTrampoline() {
+void AccessorAssemblerImpl::GenerateLoadGlobalICTrampoline(
+ TypeofMode typeof_mode) {
typedef LoadGlobalICTrampolineStub::Descriptor Descriptor;
Node* name = Parameter(Descriptor::kName);
@@ -1586,7 +1631,7 @@ void AccessorAssemblerImpl::GenerateLoadGlobalICTrampoline() {
Node* vector = LoadTypeFeedbackVectorForStub();
LoadICParameters p(context, nullptr, name, slot, vector);
- LoadGlobalIC(&p);
+ LoadGlobalIC(&p, typeof_mode);
}
void AccessorAssemblerImpl::GenerateKeyedLoadICTF() {
@@ -1696,6 +1741,24 @@ void AccessorAssemblerImpl::GenerateKeyedStoreICTrampolineTF(
ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE(DISPATCH_TO_IMPL)
#undef DISPATCH_TO_IMPL
+void AccessorAssembler::GenerateLoadICProtoArray(
+ CodeAssemblerState* state, bool throw_reference_error_if_nonexistent) {
+ AccessorAssemblerImpl assembler(state);
+ assembler.GenerateLoadICProtoArray(throw_reference_error_if_nonexistent);
+}
+
+void AccessorAssembler::GenerateLoadGlobalIC(CodeAssemblerState* state,
+ TypeofMode typeof_mode) {
+ AccessorAssemblerImpl assembler(state);
+ assembler.GenerateLoadGlobalIC(typeof_mode);
+}
+
+void AccessorAssembler::GenerateLoadGlobalICTrampoline(
+ CodeAssemblerState* state, TypeofMode typeof_mode) {
+ AccessorAssemblerImpl assembler(state);
+ assembler.GenerateLoadGlobalICTrampoline(typeof_mode);
+}
+
void AccessorAssembler::GenerateKeyedStoreICTF(CodeAssemblerState* state,
LanguageMode language_mode) {
AccessorAssemblerImpl assembler(state);
« no previous file with comments | « src/ic/accessor-assembler.h ('k') | src/ic/accessor-assembler-impl.h » ('j') | src/ic/ic.cc » ('J')

Powered by Google App Engine