Chromium Code Reviews| 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() { |