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 |