Index: src/compiler/bytecode-graph-builder.cc |
diff --git a/src/compiler/bytecode-graph-builder.cc b/src/compiler/bytecode-graph-builder.cc |
index e6ed264672f6d5a8230f90d849c8866408f4b4fe..05ec6b5afb8526fe7c4b6b4f0ca4f861c848bb20 100644 |
--- a/src/compiler/bytecode-graph-builder.cc |
+++ b/src/compiler/bytecode-graph-builder.cc |
@@ -786,9 +786,10 @@ void BytecodeGraphBuilder::VisitMov() { |
environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), value); |
} |
-Node* BytecodeGraphBuilder::BuildLoadGlobal(TypeofMode typeof_mode) { |
- VectorSlotPair feedback = |
- CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(0)); |
+Node* BytecodeGraphBuilder::BuildLoadGlobal(int feedback_slot_operand, |
Michael Starzinger
2016/09/29 14:52:25
nit: Could we instead of passing the operand index
Leszek Swirski
2016/09/29 15:40:18
Done. I was on the fence about this too, thanks!
|
+ TypeofMode typeof_mode) { |
+ VectorSlotPair feedback = CreateVectorSlotPair( |
+ bytecode_iterator().GetIndexOperand(feedback_slot_operand)); |
DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC, |
feedback_vector()->GetKind(feedback.slot())); |
Handle<Name> name(feedback_vector()->GetName(feedback.slot())); |
@@ -798,20 +799,20 @@ Node* BytecodeGraphBuilder::BuildLoadGlobal(TypeofMode typeof_mode) { |
void BytecodeGraphBuilder::VisitLdaGlobal() { |
FrameStateBeforeAndAfter states(this); |
- Node* node = BuildLoadGlobal(TypeofMode::NOT_INSIDE_TYPEOF); |
+ Node* node = BuildLoadGlobal(0, TypeofMode::NOT_INSIDE_TYPEOF); |
environment()->BindAccumulator(node, &states); |
} |
void BytecodeGraphBuilder::VisitLdrGlobal() { |
FrameStateBeforeAndAfter states(this); |
- Node* node = BuildLoadGlobal(TypeofMode::NOT_INSIDE_TYPEOF); |
+ Node* node = BuildLoadGlobal(0, TypeofMode::NOT_INSIDE_TYPEOF); |
environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), node, |
&states); |
} |
void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() { |
FrameStateBeforeAndAfter states(this); |
- Node* node = BuildLoadGlobal(TypeofMode::INSIDE_TYPEOF); |
+ Node* node = BuildLoadGlobal(0, TypeofMode::INSIDE_TYPEOF); |
environment()->BindAccumulator(node, &states); |
} |
@@ -888,12 +889,13 @@ void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() { |
BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF); |
} |
-void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) { |
- uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2); |
- |
- // Check if any context in the depth has an extension. |
+BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::CheckContextExtensions( |
+ uint32_t depth) { |
+ // Output environment where the context has an extension |
Environment* slow_environment = nullptr; |
+ DCHECK_GT(depth, 0u); |
+ |
// We only need to check up to the last-but-one depth, because the an eval in |
// the same scope as the variable itself has no way of shadowing it. |
for (uint32_t d = 0; d < depth; d++) { |
@@ -927,6 +929,17 @@ void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) { |
} |
} |
+ DCHECK(slow_environment != nullptr); |
Michael Starzinger
2016/09/29 14:52:25
nit: DCHECK_NOT_NULL
Leszek Swirski
2016/09/29 15:40:18
Done.
|
+ |
+ return slow_environment; |
+} |
+ |
+void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) { |
+ uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2); |
+ |
+ // Check if any context in the depth has an extension. |
+ Environment* slow_environment = CheckContextExtensions(depth); |
+ |
// Fast path, do a context load. |
{ |
uint32_t slot_index = bytecode_iterator().GetIndexOperand(1); |
@@ -967,9 +980,23 @@ void BytecodeGraphBuilder::VisitLdaLookupContextSlotInsideTypeof() { |
} |
void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) { |
- // TODO(leszeks): Build the fast path here. |
+ uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2); |
+ |
+ // Check if any context in the depth has an extension. |
+ Environment* slow_environment = CheckContextExtensions(depth); |
+ |
+ // Fast path, do a global load. |
+ { |
+ FrameStateBeforeAndAfter states(this); |
+ Node* node = BuildLoadGlobal(1, typeof_mode); |
+ environment()->BindAccumulator(node, &states); |
+ |
+ NewMerge(); |
+ } |
+ Environment* fast_environment = environment(); |
// Slow path, do a runtime load lookup. |
+ set_environment(slow_environment); |
{ |
FrameStateBeforeAndAfter states(this); |
@@ -983,6 +1010,9 @@ void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) { |
Node* value = NewNode(op, name); |
environment()->BindAccumulator(value, &states); |
} |
+ |
+ fast_environment->Merge(environment()); |
+ set_environment(fast_environment); |
} |
void BytecodeGraphBuilder::VisitLdaLookupGlobalSlot() { |