Index: src/interpreter/interpreter.cc |
diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc |
index 0c1f945d0fd3322f146bc3449409ec5a5734fbb9..999a795a56fbcb37406055a31491d347b5bf6efa 100644 |
--- a/src/interpreter/interpreter.cc |
+++ b/src/interpreter/interpreter.cc |
@@ -421,16 +421,14 @@ void Interpreter::DoMov(InterpreterAssembler* assembler) { |
__ Dispatch(); |
} |
-Node* Interpreter::BuildLoadGlobal(Callable ic, |
+Node* Interpreter::BuildLoadGlobal(Callable ic, Node* context, |
+ Node* feedback_slot, |
InterpreterAssembler* assembler) { |
typedef LoadGlobalWithVectorDescriptor Descriptor; |
- // Get the global object. |
- Node* context = __ GetContext(); |
// Load the global via the LoadGlobalIC. |
Node* code_target = __ HeapConstant(ic.code()); |
- Node* raw_slot = __ BytecodeOperandIdx(0); |
- Node* smi_slot = __ SmiTag(raw_slot); |
+ Node* smi_slot = __ SmiTag(feedback_slot); |
Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
return __ CallStub(ic.descriptor(), code_target, context, |
Arg(Descriptor::kSlot, smi_slot), |
@@ -444,7 +442,11 @@ Node* Interpreter::BuildLoadGlobal(Callable ic, |
void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) { |
Callable ic = |
CodeFactory::LoadGlobalICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF); |
- Node* result = BuildLoadGlobal(ic, assembler); |
+ |
+ Node* context = __ GetContext(); |
+ |
+ Node* raw_slot = __ BytecodeOperandIdx(0); |
+ Node* result = BuildLoadGlobal(ic, context, raw_slot, assembler); |
__ SetAccumulator(result); |
__ Dispatch(); |
} |
@@ -456,7 +458,11 @@ void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) { |
void Interpreter::DoLdrGlobal(InterpreterAssembler* assembler) { |
Callable ic = |
CodeFactory::LoadGlobalICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF); |
- Node* result = BuildLoadGlobal(ic, assembler); |
+ |
+ Node* context = __ GetContext(); |
+ |
+ Node* raw_slot = __ BytecodeOperandIdx(0); |
+ Node* result = BuildLoadGlobal(ic, context, raw_slot, assembler); |
Node* destination = __ BytecodeOperandReg(1); |
__ StoreRegister(result, destination); |
__ Dispatch(); |
@@ -469,7 +475,11 @@ void Interpreter::DoLdrGlobal(InterpreterAssembler* assembler) { |
void Interpreter::DoLdaGlobalInsideTypeof(InterpreterAssembler* assembler) { |
Callable ic = |
CodeFactory::LoadGlobalICInOptimizedCode(isolate_, INSIDE_TYPEOF); |
- Node* result = BuildLoadGlobal(ic, assembler); |
+ |
+ Node* context = __ GetContext(); |
+ |
+ Node* raw_slot = __ BytecodeOperandIdx(0); |
+ Node* result = BuildLoadGlobal(ic, context, raw_slot, assembler); |
__ SetAccumulator(result); |
__ Dispatch(); |
} |
@@ -563,8 +573,8 @@ void Interpreter::DoStaContextSlot(InterpreterAssembler* assembler) { |
void Interpreter::DoLdaLookupSlot(Runtime::FunctionId function_id, |
InterpreterAssembler* assembler) { |
- Node* index = __ BytecodeOperandIdx(0); |
- Node* name = __ LoadConstantPoolEntry(index); |
+ Node* name_index = __ BytecodeOperandIdx(0); |
+ Node* name = __ LoadConstantPoolEntry(name_index); |
Node* context = __ GetContext(); |
Node* result = __ CallRuntime(function_id, context, name); |
__ SetAccumulator(result); |
@@ -634,6 +644,56 @@ void Interpreter::DoLdaLookupContextSlotInsideTypeof( |
DoLdaLookupContextSlot(Runtime::kLoadLookupSlotInsideTypeof, assembler); |
} |
+void Interpreter::DoLdaLookupGlobalSlot(Runtime::FunctionId function_id, |
+ InterpreterAssembler* assembler) { |
+ Node* context = __ GetContext(); |
+ Node* name_index = __ BytecodeOperandIdx(0); |
+ Node* feedback_slot = __ BytecodeOperandIdx(1); |
+ Node* depth = __ BytecodeOperandUImm(2); |
+ |
+ Label slowpath(assembler, Label::kDeferred); |
+ |
+ // Check for context extensions to allow the fast path |
+ __ GotoIfHasContextExtensionUpToDepth(context, depth, &slowpath); |
+ |
+ // Fast path does a normal load global |
+ { |
+ Callable ic = CodeFactory::LoadGlobalICInOptimizedCode( |
+ isolate_, function_id == Runtime::kLoadLookupSlotInsideTypeof |
+ ? INSIDE_TYPEOF |
+ : NOT_INSIDE_TYPEOF); |
+ Node* result = BuildLoadGlobal(ic, context, feedback_slot, assembler); |
+ __ SetAccumulator(result); |
+ __ Dispatch(); |
+ } |
+ |
+ // Slow path when we have to call out to the runtime |
+ __ Bind(&slowpath); |
+ { |
+ Node* name = __ LoadConstantPoolEntry(name_index); |
+ Node* result = __ CallRuntime(function_id, context, name); |
+ __ SetAccumulator(result); |
+ __ Dispatch(); |
+ } |
+} |
+ |
+// LdaLookupGlobalSlot <name_index> <feedback_slot> <depth> |
+// |
+// Lookup the object with the name in constant pool entry |name_index| |
+// dynamically. |
+void Interpreter::DoLdaLookupGlobalSlot(InterpreterAssembler* assembler) { |
+ DoLdaLookupGlobalSlot(Runtime::kLoadLookupSlot, assembler); |
+} |
+ |
+// LdaLookupGlobalSlotInsideTypeof <name_index> <feedback_slot> <depth> |
+// |
+// Lookup the object with the name in constant pool entry |name_index| |
+// dynamically without causing a NoReferenceError. |
+void Interpreter::DoLdaLookupGlobalSlotInsideTypeof( |
+ InterpreterAssembler* assembler) { |
+ DoLdaLookupGlobalSlot(Runtime::kLoadLookupSlotInsideTypeof, assembler); |
+} |
+ |
void Interpreter::DoStaLookupSlot(LanguageMode language_mode, |
InterpreterAssembler* assembler) { |
Node* value = __ GetAccumulator(); |