| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
| 6 | 6 |
| 7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
| 8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
| 9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
| 10 #include "src/compiler/js-type-feedback.h" | 10 #include "src/compiler/js-type-feedback.h" |
| (...skipping 2754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2765 } | 2765 } |
| 2766 return check_depths.ToIntegral(); | 2766 return check_depths.ToIntegral(); |
| 2767 } | 2767 } |
| 2768 | 2768 |
| 2769 | 2769 |
| 2770 uint32_t AstGraphBuilder::ComputeBitsetForDynamicContext(Variable* variable) { | 2770 uint32_t AstGraphBuilder::ComputeBitsetForDynamicContext(Variable* variable) { |
| 2771 DCHECK_EQ(DYNAMIC_LOCAL, variable->mode()); | 2771 DCHECK_EQ(DYNAMIC_LOCAL, variable->mode()); |
| 2772 EnumSet<int, uint32_t> check_depths; | 2772 EnumSet<int, uint32_t> check_depths; |
| 2773 for (Scope* s = current_scope(); s != nullptr; s = s->outer_scope()) { | 2773 for (Scope* s = current_scope(); s != nullptr; s = s->outer_scope()) { |
| 2774 if (s->num_heap_slots() <= 0) continue; | 2774 if (s->num_heap_slots() <= 0) continue; |
| 2775 if (!s->calls_sloppy_eval()) continue; | 2775 if (!s->calls_sloppy_eval() && s != variable->scope()) continue; |
| 2776 int depth = current_scope()->ContextChainLength(s); | 2776 int depth = current_scope()->ContextChainLength(s); |
| 2777 if (depth > DynamicContextAccess::kMaxCheckDepth) { | 2777 if (depth > DynamicContextAccess::kMaxCheckDepth) { |
| 2778 return DynamicContextAccess::kFullCheckRequired; | 2778 return DynamicContextAccess::kFullCheckRequired; |
| 2779 } | 2779 } |
| 2780 check_depths.Add(depth); | 2780 check_depths.Add(depth); |
| 2781 if (s == variable->scope()) break; | 2781 if (s == variable->scope()) break; |
| 2782 } | 2782 } |
| 2783 return check_depths.ToIntegral(); | 2783 return check_depths.ToIntegral(); |
| 2784 } | 2784 } |
| 2785 | 2785 |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3033 states.AddToNode(value, bailout_id, combine); | 3033 states.AddToNode(value, bailout_id, combine); |
| 3034 } else if (mode == DYNAMIC_LOCAL) { | 3034 } else if (mode == DYNAMIC_LOCAL) { |
| 3035 Variable* local = variable->local_if_not_shadowed(); | 3035 Variable* local = variable->local_if_not_shadowed(); |
| 3036 DCHECK(local->location() == Variable::CONTEXT); // Must be context. | 3036 DCHECK(local->location() == Variable::CONTEXT); // Must be context. |
| 3037 int depth = current_scope()->ContextChainLength(local->scope()); | 3037 int depth = current_scope()->ContextChainLength(local->scope()); |
| 3038 uint32_t check_bitset = ComputeBitsetForDynamicContext(variable); | 3038 uint32_t check_bitset = ComputeBitsetForDynamicContext(variable); |
| 3039 const Operator* op = javascript()->LoadDynamicContext( | 3039 const Operator* op = javascript()->LoadDynamicContext( |
| 3040 name, check_bitset, depth, local->index()); | 3040 name, check_bitset, depth, local->index()); |
| 3041 value = NewNode(op, current_context()); | 3041 value = NewNode(op, current_context()); |
| 3042 PrepareFrameState(value, bailout_id, combine); | 3042 PrepareFrameState(value, bailout_id, combine); |
| 3043 // TODO(mstarzinger): Hole checks are missing here when optimized. | 3043 VariableMode local_mode = local->mode(); |
| 3044 if (local_mode == CONST_LEGACY) { |
| 3045 // Perform check for uninitialized legacy const variables. |
| 3046 Node* undefined = jsgraph()->UndefinedConstant(); |
| 3047 value = BuildHoleCheckSilent(value, undefined, value); |
| 3048 } else if (local_mode == LET || local_mode == CONST) { |
| 3049 // Perform check for uninitialized let/const variables. |
| 3050 value = BuildHoleCheckThrow(value, local, value, bailout_id); |
| 3051 } |
| 3044 } else if (mode == DYNAMIC) { | 3052 } else if (mode == DYNAMIC) { |
| 3045 uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired; | 3053 uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired; |
| 3046 const Operator* op = javascript()->LoadDynamicGlobal( | 3054 const Operator* op = javascript()->LoadDynamicGlobal( |
| 3047 name, check_bitset, feedback, contextual_mode); | 3055 name, check_bitset, feedback, contextual_mode); |
| 3048 value = NewNode(op, current_context()); | 3056 value = NewNode(op, current_context()); |
| 3049 states.AddToNode(value, bailout_id, combine); | 3057 states.AddToNode(value, bailout_id, combine); |
| 3050 } | 3058 } |
| 3051 return value; | 3059 return value; |
| 3052 } | 3060 } |
| 3053 } | 3061 } |
| (...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3779 // Phi does not exist yet, introduce one. | 3787 // Phi does not exist yet, introduce one. |
| 3780 value = NewPhi(inputs, value, control); | 3788 value = NewPhi(inputs, value, control); |
| 3781 value->ReplaceInput(inputs - 1, other); | 3789 value->ReplaceInput(inputs - 1, other); |
| 3782 } | 3790 } |
| 3783 return value; | 3791 return value; |
| 3784 } | 3792 } |
| 3785 | 3793 |
| 3786 } // namespace compiler | 3794 } // namespace compiler |
| 3787 } // namespace internal | 3795 } // namespace internal |
| 3788 } // namespace v8 | 3796 } // namespace v8 |
| OLD | NEW |