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* global = BuildLoadGlobalObject(); | 3267 Node* global = BuildLoadGlobalObject(); |
3268 Handle<Name> name = variable->name(); | 3268 Handle<Name> name = variable->name(); |
3269 Node* value = BuildGlobalLoad(global, name, feedback, contextual_mode); | 3269 Node* value = BuildGlobalLoad(global, name, feedback, typeof_mode); |
3270 states.AddToNode(value, bailout_id, combine); | 3270 states.AddToNode(value, bailout_id, combine); |
3271 return value; | 3271 return value; |
3272 } | 3272 } |
3273 case VariableLocation::PARAMETER: | 3273 case VariableLocation::PARAMETER: |
3274 case VariableLocation::LOCAL: { | 3274 case VariableLocation::LOCAL: { |
3275 // Local var, const, or let variable. | 3275 // Local var, const, or let variable. |
3276 Node* value = environment()->Lookup(variable); | 3276 Node* value = environment()->Lookup(variable); |
3277 if (mode == CONST_LEGACY) { | 3277 if (mode == CONST_LEGACY) { |
3278 // Perform check for uninitialized legacy const variables. | 3278 // Perform check for uninitialized legacy const variables. |
3279 if (value->op() == the_hole->op()) { | 3279 if (value->op() == the_hole->op()) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3315 } | 3315 } |
3316 return value; | 3316 return value; |
3317 } | 3317 } |
3318 case VariableLocation::LOOKUP: { | 3318 case VariableLocation::LOOKUP: { |
3319 // Dynamic lookup of context variable (anywhere in the chain). | 3319 // Dynamic lookup of context variable (anywhere in the chain). |
3320 Node* value = jsgraph()->TheHoleConstant(); | 3320 Node* value = jsgraph()->TheHoleConstant(); |
3321 Handle<String> name = variable->name(); | 3321 Handle<String> name = variable->name(); |
3322 if (mode == DYNAMIC_GLOBAL) { | 3322 if (mode == DYNAMIC_GLOBAL) { |
3323 uint32_t check_bitset = ComputeBitsetForDynamicGlobal(variable); | 3323 uint32_t check_bitset = ComputeBitsetForDynamicGlobal(variable); |
3324 const Operator* op = javascript()->LoadDynamicGlobal( | 3324 const Operator* op = javascript()->LoadDynamicGlobal( |
3325 name, check_bitset, feedback, contextual_mode); | 3325 name, check_bitset, feedback, typeof_mode); |
3326 value = NewNode(op, BuildLoadFeedbackVector(), current_context()); | 3326 value = NewNode(op, BuildLoadFeedbackVector(), current_context()); |
3327 states.AddToNode(value, bailout_id, combine); | 3327 states.AddToNode(value, bailout_id, combine); |
3328 } else if (mode == DYNAMIC_LOCAL) { | 3328 } else if (mode == DYNAMIC_LOCAL) { |
3329 Variable* local = variable->local_if_not_shadowed(); | 3329 Variable* local = variable->local_if_not_shadowed(); |
3330 DCHECK(local->location() == | 3330 DCHECK(local->location() == |
3331 VariableLocation::CONTEXT); // Must be context. | 3331 VariableLocation::CONTEXT); // Must be context. |
3332 int depth = current_scope()->ContextChainLength(local->scope()); | 3332 int depth = current_scope()->ContextChainLength(local->scope()); |
3333 uint32_t check_bitset = ComputeBitsetForDynamicContext(variable); | 3333 uint32_t check_bitset = ComputeBitsetForDynamicContext(variable); |
3334 const Operator* op = javascript()->LoadDynamicContext( | 3334 const Operator* op = javascript()->LoadDynamicContext( |
3335 name, check_bitset, depth, local->index()); | 3335 name, check_bitset, depth, local->index()); |
3336 value = NewNode(op, current_context()); | 3336 value = NewNode(op, current_context()); |
3337 PrepareFrameState(value, bailout_id, combine); | 3337 PrepareFrameState(value, bailout_id, combine); |
3338 VariableMode local_mode = local->mode(); | 3338 VariableMode local_mode = local->mode(); |
3339 if (local_mode == CONST_LEGACY) { | 3339 if (local_mode == CONST_LEGACY) { |
3340 // Perform check for uninitialized legacy const variables. | 3340 // Perform check for uninitialized legacy const variables. |
3341 Node* undefined = jsgraph()->UndefinedConstant(); | 3341 Node* undefined = jsgraph()->UndefinedConstant(); |
3342 value = BuildHoleCheckSilent(value, undefined, value); | 3342 value = BuildHoleCheckSilent(value, undefined, value); |
3343 } else if (local_mode == LET || local_mode == CONST) { | 3343 } else if (local_mode == LET || local_mode == CONST) { |
3344 // Perform check for uninitialized let/const variables. | 3344 // Perform check for uninitialized let/const variables. |
3345 value = BuildHoleCheckThrow(value, local, value, bailout_id); | 3345 value = BuildHoleCheckThrow(value, local, value, bailout_id); |
3346 } | 3346 } |
3347 } else if (mode == DYNAMIC) { | 3347 } else if (mode == DYNAMIC) { |
3348 uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired; | 3348 uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired; |
3349 const Operator* op = javascript()->LoadDynamicGlobal( | 3349 const Operator* op = javascript()->LoadDynamicGlobal( |
3350 name, check_bitset, feedback, contextual_mode); | 3350 name, check_bitset, feedback, typeof_mode); |
3351 value = NewNode(op, BuildLoadFeedbackVector(), current_context()); | 3351 value = NewNode(op, BuildLoadFeedbackVector(), current_context()); |
3352 states.AddToNode(value, bailout_id, combine); | 3352 states.AddToNode(value, bailout_id, combine); |
3353 } | 3353 } |
3354 return value; | 3354 return value; |
3355 } | 3355 } |
3356 } | 3356 } |
3357 UNREACHABLE(); | 3357 UNREACHABLE(); |
3358 return NULL; | 3358 return NULL; |
3359 } | 3359 } |
3360 | 3360 |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3606 ? Runtime::kStoreToSuper_Strict | 3606 ? Runtime::kStoreToSuper_Strict |
3607 : Runtime::kStoreToSuper_Sloppy; | 3607 : Runtime::kStoreToSuper_Sloppy; |
3608 const Operator* op = javascript()->CallRuntime(function_id, 4); | 3608 const Operator* op = javascript()->CallRuntime(function_id, 4); |
3609 Node* node = NewNode(op, receiver, home_object, name_node, value); | 3609 Node* node = NewNode(op, receiver, home_object, name_node, value); |
3610 return Record(js_type_feedback_, node, id); | 3610 return Record(js_type_feedback_, node, id); |
3611 } | 3611 } |
3612 | 3612 |
3613 | 3613 |
3614 Node* AstGraphBuilder::BuildGlobalLoad(Node* object, Handle<Name> name, | 3614 Node* AstGraphBuilder::BuildGlobalLoad(Node* object, Handle<Name> name, |
3615 const VectorSlotPair& feedback, | 3615 const VectorSlotPair& feedback, |
3616 ContextualMode mode) { | 3616 TypeofMode typeof_mode) { |
3617 const Operator* op = | 3617 const Operator* op = |
3618 javascript()->LoadGlobal(MakeUnique(name), feedback, mode); | 3618 javascript()->LoadGlobal(MakeUnique(name), feedback, typeof_mode); |
3619 Node* node = NewNode(op, object, BuildLoadFeedbackVector()); | 3619 Node* node = NewNode(op, object, BuildLoadFeedbackVector()); |
3620 return Record(js_type_feedback_, node, feedback.slot()); | 3620 return Record(js_type_feedback_, node, feedback.slot()); |
3621 } | 3621 } |
3622 | 3622 |
3623 | 3623 |
3624 Node* AstGraphBuilder::BuildGlobalStore(Node* object, Handle<Name> name, | 3624 Node* AstGraphBuilder::BuildGlobalStore(Node* object, Handle<Name> name, |
3625 Node* value, | 3625 Node* value, |
3626 const VectorSlotPair& feedback, | 3626 const VectorSlotPair& feedback, |
3627 TypeFeedbackId id) { | 3627 TypeFeedbackId id) { |
3628 const Operator* op = | 3628 const Operator* op = |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4205 // Phi does not exist yet, introduce one. | 4205 // Phi does not exist yet, introduce one. |
4206 value = NewPhi(inputs, value, control); | 4206 value = NewPhi(inputs, value, control); |
4207 value->ReplaceInput(inputs - 1, other); | 4207 value->ReplaceInput(inputs - 1, other); |
4208 } | 4208 } |
4209 return value; | 4209 return value; |
4210 } | 4210 } |
4211 | 4211 |
4212 } // namespace compiler | 4212 } // namespace compiler |
4213 } // namespace internal | 4213 } // namespace internal |
4214 } // namespace v8 | 4214 } // namespace v8 |
OLD | NEW |