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 2927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2938 void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) { | 2938 void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) { |
2939 Node* operand; | 2939 Node* operand; |
2940 if (expr->expression()->IsVariableProxy()) { | 2940 if (expr->expression()->IsVariableProxy()) { |
2941 // Typeof does not throw a reference error on global variables, hence we | 2941 // Typeof does not throw a reference error on global variables, hence we |
2942 // perform a non-contextual load in case the operand is a variable proxy. | 2942 // perform a non-contextual load in case the operand is a variable proxy. |
2943 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 2943 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
2944 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 2944 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
2945 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); | 2945 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); |
2946 operand = | 2946 operand = |
2947 BuildVariableLoad(proxy->var(), expr->expression()->id(), states, pair, | 2947 BuildVariableLoad(proxy->var(), expr->expression()->id(), states, pair, |
2948 OutputFrameStateCombine::Push(), NOT_CONTEXTUAL); | 2948 OutputFrameStateCombine::Push(), INSIDE_TYPEOF); |
2949 } else { | 2949 } else { |
2950 VisitForValue(expr->expression()); | 2950 VisitForValue(expr->expression()); |
2951 operand = environment()->Pop(); | 2951 operand = environment()->Pop(); |
2952 } | 2952 } |
2953 Node* value = NewNode(javascript()->TypeOf(), operand); | 2953 Node* value = NewNode(javascript()->TypeOf(), operand); |
2954 ast_context()->ProduceValue(value); | 2954 ast_context()->ProduceValue(value); |
2955 } | 2955 } |
2956 | 2956 |
2957 | 2957 |
2958 void AstGraphBuilder::VisitNot(UnaryOperation* expr) { | 2958 void AstGraphBuilder::VisitNot(UnaryOperation* expr) { |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3250 prototype_check.End(); | 3250 prototype_check.End(); |
3251 return environment()->Pop(); | 3251 return environment()->Pop(); |
3252 } | 3252 } |
3253 | 3253 |
3254 | 3254 |
3255 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, | 3255 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, |
3256 BailoutId bailout_id, | 3256 BailoutId bailout_id, |
3257 FrameStateBeforeAndAfter& states, | 3257 FrameStateBeforeAndAfter& states, |
3258 const VectorSlotPair& feedback, | 3258 const VectorSlotPair& feedback, |
3259 OutputFrameStateCombine combine, | 3259 OutputFrameStateCombine combine, |
3260 ContextualMode contextual_mode) { | 3260 TypeofMode typeof_mode) { |
3261 Node* the_hole = jsgraph()->TheHoleConstant(); | 3261 Node* the_hole = jsgraph()->TheHoleConstant(); |
3262 VariableMode mode = variable->mode(); | 3262 VariableMode mode = variable->mode(); |
3263 switch (variable->location()) { | 3263 switch (variable->location()) { |
3264 case VariableLocation::GLOBAL: | 3264 case VariableLocation::GLOBAL: |
3265 case VariableLocation::UNALLOCATED: { | 3265 case VariableLocation::UNALLOCATED: { |
3266 // Global var, const, or let variable. | 3266 // Global var, const, or let variable. |
3267 Node* script_context = current_context(); | 3267 Node* script_context = current_context(); |
3268 int slot_index = -1; | 3268 int slot_index = -1; |
3269 if (variable->index() > 0) { | 3269 if (variable->index() > 0) { |
3270 DCHECK(variable->IsStaticGlobalObjectProperty()); | 3270 DCHECK(variable->IsStaticGlobalObjectProperty()); |
3271 // Each var occupies two slots in the context: for reads and writes. | 3271 // Each var occupies two slots in the context: for reads and writes. |
3272 slot_index = variable->index(); | 3272 slot_index = variable->index(); |
3273 int depth = current_scope()->ContextChainLength(variable->scope()); | 3273 int depth = current_scope()->ContextChainLength(variable->scope()); |
3274 if (depth > 0) { | 3274 if (depth > 0) { |
3275 const Operator* op = javascript()->LoadContext( | 3275 const Operator* op = javascript()->LoadContext( |
3276 depth - 1, Context::PREVIOUS_INDEX, true); | 3276 depth - 1, Context::PREVIOUS_INDEX, true); |
3277 script_context = NewNode(op, current_context()); | 3277 script_context = NewNode(op, current_context()); |
3278 } | 3278 } |
3279 } | 3279 } |
3280 Node* global = BuildLoadGlobalObject(); | 3280 Node* global = BuildLoadGlobalObject(); |
3281 Handle<Name> name = variable->name(); | 3281 Handle<Name> name = variable->name(); |
3282 Node* value = BuildGlobalLoad(script_context, global, name, feedback, | 3282 Node* value = BuildGlobalLoad(script_context, global, name, feedback, |
3283 contextual_mode, slot_index); | 3283 typeof_mode, slot_index); |
3284 states.AddToNode(value, bailout_id, combine); | 3284 states.AddToNode(value, bailout_id, combine); |
3285 return value; | 3285 return value; |
3286 } | 3286 } |
3287 case VariableLocation::PARAMETER: | 3287 case VariableLocation::PARAMETER: |
3288 case VariableLocation::LOCAL: { | 3288 case VariableLocation::LOCAL: { |
3289 // Local var, const, or let variable. | 3289 // Local var, const, or let variable. |
3290 Node* value = environment()->Lookup(variable); | 3290 Node* value = environment()->Lookup(variable); |
3291 if (mode == CONST_LEGACY) { | 3291 if (mode == CONST_LEGACY) { |
3292 // Perform check for uninitialized legacy const variables. | 3292 // Perform check for uninitialized legacy const variables. |
3293 if (value->op() == the_hole->op()) { | 3293 if (value->op() == the_hole->op()) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3329 } | 3329 } |
3330 return value; | 3330 return value; |
3331 } | 3331 } |
3332 case VariableLocation::LOOKUP: { | 3332 case VariableLocation::LOOKUP: { |
3333 // Dynamic lookup of context variable (anywhere in the chain). | 3333 // Dynamic lookup of context variable (anywhere in the chain). |
3334 Node* value = jsgraph()->TheHoleConstant(); | 3334 Node* value = jsgraph()->TheHoleConstant(); |
3335 Handle<String> name = variable->name(); | 3335 Handle<String> name = variable->name(); |
3336 if (mode == DYNAMIC_GLOBAL) { | 3336 if (mode == DYNAMIC_GLOBAL) { |
3337 uint32_t check_bitset = ComputeBitsetForDynamicGlobal(variable); | 3337 uint32_t check_bitset = ComputeBitsetForDynamicGlobal(variable); |
3338 const Operator* op = javascript()->LoadDynamicGlobal( | 3338 const Operator* op = javascript()->LoadDynamicGlobal( |
3339 name, check_bitset, feedback, contextual_mode); | 3339 name, check_bitset, feedback, typeof_mode); |
3340 value = NewNode(op, BuildLoadFeedbackVector(), current_context()); | 3340 value = NewNode(op, BuildLoadFeedbackVector(), current_context()); |
3341 states.AddToNode(value, bailout_id, combine); | 3341 states.AddToNode(value, bailout_id, combine); |
3342 } else if (mode == DYNAMIC_LOCAL) { | 3342 } else if (mode == DYNAMIC_LOCAL) { |
3343 Variable* local = variable->local_if_not_shadowed(); | 3343 Variable* local = variable->local_if_not_shadowed(); |
3344 DCHECK(local->location() == | 3344 DCHECK(local->location() == |
3345 VariableLocation::CONTEXT); // Must be context. | 3345 VariableLocation::CONTEXT); // Must be context. |
3346 int depth = current_scope()->ContextChainLength(local->scope()); | 3346 int depth = current_scope()->ContextChainLength(local->scope()); |
3347 uint32_t check_bitset = ComputeBitsetForDynamicContext(variable); | 3347 uint32_t check_bitset = ComputeBitsetForDynamicContext(variable); |
3348 const Operator* op = javascript()->LoadDynamicContext( | 3348 const Operator* op = javascript()->LoadDynamicContext( |
3349 name, check_bitset, depth, local->index()); | 3349 name, check_bitset, depth, local->index()); |
3350 value = NewNode(op, current_context()); | 3350 value = NewNode(op, current_context()); |
3351 PrepareFrameState(value, bailout_id, combine); | 3351 PrepareFrameState(value, bailout_id, combine); |
3352 VariableMode local_mode = local->mode(); | 3352 VariableMode local_mode = local->mode(); |
3353 if (local_mode == CONST_LEGACY) { | 3353 if (local_mode == CONST_LEGACY) { |
3354 // Perform check for uninitialized legacy const variables. | 3354 // Perform check for uninitialized legacy const variables. |
3355 Node* undefined = jsgraph()->UndefinedConstant(); | 3355 Node* undefined = jsgraph()->UndefinedConstant(); |
3356 value = BuildHoleCheckSilent(value, undefined, value); | 3356 value = BuildHoleCheckSilent(value, undefined, value); |
3357 } else if (local_mode == LET || local_mode == CONST) { | 3357 } else if (local_mode == LET || local_mode == CONST) { |
3358 // Perform check for uninitialized let/const variables. | 3358 // Perform check for uninitialized let/const variables. |
3359 value = BuildHoleCheckThrow(value, local, value, bailout_id); | 3359 value = BuildHoleCheckThrow(value, local, value, bailout_id); |
3360 } | 3360 } |
3361 } else if (mode == DYNAMIC) { | 3361 } else if (mode == DYNAMIC) { |
3362 uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired; | 3362 uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired; |
3363 const Operator* op = javascript()->LoadDynamicGlobal( | 3363 const Operator* op = javascript()->LoadDynamicGlobal( |
3364 name, check_bitset, feedback, contextual_mode); | 3364 name, check_bitset, feedback, typeof_mode); |
3365 value = NewNode(op, BuildLoadFeedbackVector(), current_context()); | 3365 value = NewNode(op, BuildLoadFeedbackVector(), current_context()); |
3366 states.AddToNode(value, bailout_id, combine); | 3366 states.AddToNode(value, bailout_id, combine); |
3367 } | 3367 } |
3368 return value; | 3368 return value; |
3369 } | 3369 } |
3370 } | 3370 } |
3371 UNREACHABLE(); | 3371 UNREACHABLE(); |
3372 return NULL; | 3372 return NULL; |
3373 } | 3373 } |
3374 | 3374 |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3635 : Runtime::kStoreToSuper_Sloppy; | 3635 : Runtime::kStoreToSuper_Sloppy; |
3636 const Operator* op = javascript()->CallRuntime(function_id, 4); | 3636 const Operator* op = javascript()->CallRuntime(function_id, 4); |
3637 Node* node = NewNode(op, receiver, home_object, name_node, value); | 3637 Node* node = NewNode(op, receiver, home_object, name_node, value); |
3638 return Record(js_type_feedback_, node, id); | 3638 return Record(js_type_feedback_, node, id); |
3639 } | 3639 } |
3640 | 3640 |
3641 | 3641 |
3642 Node* AstGraphBuilder::BuildGlobalLoad(Node* script_context, Node* global, | 3642 Node* AstGraphBuilder::BuildGlobalLoad(Node* script_context, Node* global, |
3643 Handle<Name> name, | 3643 Handle<Name> name, |
3644 const VectorSlotPair& feedback, | 3644 const VectorSlotPair& feedback, |
3645 ContextualMode mode, int slot_index) { | 3645 TypeofMode typeof_mode, int slot_index) { |
3646 const Operator* op = | 3646 const Operator* op = javascript()->LoadGlobal(MakeUnique(name), feedback, |
3647 javascript()->LoadGlobal(MakeUnique(name), feedback, mode, slot_index); | 3647 typeof_mode, slot_index); |
3648 Node* node = NewNode(op, script_context, global, BuildLoadFeedbackVector()); | 3648 Node* node = NewNode(op, script_context, global, BuildLoadFeedbackVector()); |
3649 return Record(js_type_feedback_, node, feedback.slot()); | 3649 return Record(js_type_feedback_, node, feedback.slot()); |
3650 } | 3650 } |
3651 | 3651 |
3652 | 3652 |
3653 Node* AstGraphBuilder::BuildGlobalStore(Node* script_context, Node* global, | 3653 Node* AstGraphBuilder::BuildGlobalStore(Node* script_context, Node* global, |
3654 Handle<Name> name, Node* value, | 3654 Handle<Name> name, Node* value, |
3655 const VectorSlotPair& feedback, | 3655 const VectorSlotPair& feedback, |
3656 TypeFeedbackId id, int slot_index) { | 3656 TypeFeedbackId id, int slot_index) { |
3657 const Operator* op = javascript()->StoreGlobal( | 3657 const Operator* op = javascript()->StoreGlobal( |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4235 // Phi does not exist yet, introduce one. | 4235 // Phi does not exist yet, introduce one. |
4236 value = NewPhi(inputs, value, control); | 4236 value = NewPhi(inputs, value, control); |
4237 value->ReplaceInput(inputs - 1, other); | 4237 value->ReplaceInput(inputs - 1, other); |
4238 } | 4238 } |
4239 return value; | 4239 return value; |
4240 } | 4240 } |
4241 | 4241 |
4242 } // namespace compiler | 4242 } // namespace compiler |
4243 } // namespace internal | 4243 } // namespace internal |
4244 } // namespace v8 | 4244 } // namespace v8 |
OLD | NEW |