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 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 if (!function_closure_.is_set()) { | 472 if (!function_closure_.is_set()) { |
473 const Operator* op = common()->Parameter( | 473 const Operator* op = common()->Parameter( |
474 Linkage::kJSFunctionCallClosureParamIndex, "%closure"); | 474 Linkage::kJSFunctionCallClosureParamIndex, "%closure"); |
475 Node* node = NewNode(op, graph()->start()); | 475 Node* node = NewNode(op, graph()->start()); |
476 function_closure_.set(node); | 476 function_closure_.set(node); |
477 } | 477 } |
478 return function_closure_.get(); | 478 return function_closure_.get(); |
479 } | 479 } |
480 | 480 |
481 | 481 |
482 Node* AstGraphBuilder::GetFeedbackVector() { | |
483 if (!feedback_vector_.is_set()) { | |
484 Node* vector = | |
485 jsgraph()->Constant(handle(info()->shared_info()->feedback_vector())); | |
486 feedback_vector_.set(vector); | |
487 } | |
488 return feedback_vector_.get(); | |
489 } | |
490 | |
491 | |
492 void AstGraphBuilder::CreateFunctionContext(bool constant_context) { | 482 void AstGraphBuilder::CreateFunctionContext(bool constant_context) { |
493 function_context_.set(constant_context | 483 function_context_.set(constant_context |
494 ? jsgraph()->HeapConstant(info()->context()) | 484 ? jsgraph()->HeapConstant(info()->context()) |
495 : NewOuterContextParam()); | 485 : NewOuterContextParam()); |
496 } | 486 } |
497 | 487 |
498 | 488 |
499 Node* AstGraphBuilder::NewOuterContextParam() { | 489 Node* AstGraphBuilder::NewOuterContextParam() { |
500 // Parameter (arity + 1) is special for the outer context of the function | 490 // Parameter (arity + 1) is special for the outer context of the function |
501 const Operator* op = | 491 const Operator* op = |
(...skipping 2784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3286 return value; | 3276 return value; |
3287 } | 3277 } |
3288 case Variable::LOOKUP: { | 3278 case Variable::LOOKUP: { |
3289 // Dynamic lookup of context variable (anywhere in the chain). | 3279 // Dynamic lookup of context variable (anywhere in the chain). |
3290 Node* value = jsgraph()->TheHoleConstant(); | 3280 Node* value = jsgraph()->TheHoleConstant(); |
3291 Handle<String> name = variable->name(); | 3281 Handle<String> name = variable->name(); |
3292 if (mode == DYNAMIC_GLOBAL) { | 3282 if (mode == DYNAMIC_GLOBAL) { |
3293 uint32_t check_bitset = ComputeBitsetForDynamicGlobal(variable); | 3283 uint32_t check_bitset = ComputeBitsetForDynamicGlobal(variable); |
3294 const Operator* op = javascript()->LoadDynamicGlobal( | 3284 const Operator* op = javascript()->LoadDynamicGlobal( |
3295 name, check_bitset, feedback, contextual_mode); | 3285 name, check_bitset, feedback, contextual_mode); |
3296 value = NewNode(op, GetFeedbackVector(), current_context()); | 3286 value = NewNode(op, BuildLoadFeedbackVector(), current_context()); |
3297 states.AddToNode(value, bailout_id, combine); | 3287 states.AddToNode(value, bailout_id, combine); |
3298 } else if (mode == DYNAMIC_LOCAL) { | 3288 } else if (mode == DYNAMIC_LOCAL) { |
3299 Variable* local = variable->local_if_not_shadowed(); | 3289 Variable* local = variable->local_if_not_shadowed(); |
3300 DCHECK(local->location() == Variable::CONTEXT); // Must be context. | 3290 DCHECK(local->location() == Variable::CONTEXT); // Must be context. |
3301 int depth = current_scope()->ContextChainLength(local->scope()); | 3291 int depth = current_scope()->ContextChainLength(local->scope()); |
3302 uint32_t check_bitset = ComputeBitsetForDynamicContext(variable); | 3292 uint32_t check_bitset = ComputeBitsetForDynamicContext(variable); |
3303 const Operator* op = javascript()->LoadDynamicContext( | 3293 const Operator* op = javascript()->LoadDynamicContext( |
3304 name, check_bitset, depth, local->index()); | 3294 name, check_bitset, depth, local->index()); |
3305 value = NewNode(op, current_context()); | 3295 value = NewNode(op, current_context()); |
3306 PrepareFrameState(value, bailout_id, combine); | 3296 PrepareFrameState(value, bailout_id, combine); |
3307 VariableMode local_mode = local->mode(); | 3297 VariableMode local_mode = local->mode(); |
3308 if (local_mode == CONST_LEGACY) { | 3298 if (local_mode == CONST_LEGACY) { |
3309 // Perform check for uninitialized legacy const variables. | 3299 // Perform check for uninitialized legacy const variables. |
3310 Node* undefined = jsgraph()->UndefinedConstant(); | 3300 Node* undefined = jsgraph()->UndefinedConstant(); |
3311 value = BuildHoleCheckSilent(value, undefined, value); | 3301 value = BuildHoleCheckSilent(value, undefined, value); |
3312 } else if (local_mode == LET || local_mode == CONST) { | 3302 } else if (local_mode == LET || local_mode == CONST) { |
3313 // Perform check for uninitialized let/const variables. | 3303 // Perform check for uninitialized let/const variables. |
3314 value = BuildHoleCheckThrow(value, local, value, bailout_id); | 3304 value = BuildHoleCheckThrow(value, local, value, bailout_id); |
3315 } | 3305 } |
3316 } else if (mode == DYNAMIC) { | 3306 } else if (mode == DYNAMIC) { |
3317 uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired; | 3307 uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired; |
3318 const Operator* op = javascript()->LoadDynamicGlobal( | 3308 const Operator* op = javascript()->LoadDynamicGlobal( |
3319 name, check_bitset, feedback, contextual_mode); | 3309 name, check_bitset, feedback, contextual_mode); |
3320 value = NewNode(op, GetFeedbackVector(), current_context()); | 3310 value = NewNode(op, BuildLoadFeedbackVector(), current_context()); |
3321 states.AddToNode(value, bailout_id, combine); | 3311 states.AddToNode(value, bailout_id, combine); |
3322 } | 3312 } |
3323 return value; | 3313 return value; |
3324 } | 3314 } |
3325 } | 3315 } |
3326 UNREACHABLE(); | 3316 UNREACHABLE(); |
3327 return NULL; | 3317 return NULL; |
3328 } | 3318 } |
3329 | 3319 |
3330 | 3320 |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3484 if (js_type_feedback) { | 3474 if (js_type_feedback) { |
3485 js_type_feedback->Record(node, id); | 3475 js_type_feedback->Record(node, id); |
3486 } | 3476 } |
3487 return node; | 3477 return node; |
3488 } | 3478 } |
3489 | 3479 |
3490 | 3480 |
3491 Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key, | 3481 Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key, |
3492 const VectorSlotPair& feedback) { | 3482 const VectorSlotPair& feedback) { |
3493 const Operator* op = javascript()->LoadProperty(feedback); | 3483 const Operator* op = javascript()->LoadProperty(feedback); |
3494 return Record(js_type_feedback_, | 3484 Node* node = NewNode(op, object, key, BuildLoadFeedbackVector()); |
3495 NewNode(op, object, key, GetFeedbackVector()), feedback.slot()); | 3485 return Record(js_type_feedback_, node, feedback.slot()); |
3496 } | 3486 } |
3497 | 3487 |
3498 | 3488 |
3499 Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name, | 3489 Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name, |
3500 const VectorSlotPair& feedback, | 3490 const VectorSlotPair& feedback, |
3501 ContextualMode mode) { | 3491 ContextualMode mode) { |
3502 const Operator* op = | 3492 const Operator* op = |
3503 javascript()->LoadNamed(MakeUnique(name), feedback, mode); | 3493 javascript()->LoadNamed(MakeUnique(name), feedback, mode); |
3504 return Record(js_type_feedback_, NewNode(op, object, GetFeedbackVector()), | 3494 Node* node = NewNode(op, object, BuildLoadFeedbackVector()); |
3505 feedback.slot()); | 3495 return Record(js_type_feedback_, node, feedback.slot()); |
3506 } | 3496 } |
3507 | 3497 |
3508 | 3498 |
3509 Node* AstGraphBuilder::BuildKeyedStore(Node* object, Node* key, Node* value, | 3499 Node* AstGraphBuilder::BuildKeyedStore(Node* object, Node* key, Node* value, |
3510 const VectorSlotPair& feedback, | 3500 const VectorSlotPair& feedback, |
3511 TypeFeedbackId id) { | 3501 TypeFeedbackId id) { |
3512 const Operator* op = javascript()->StoreProperty(language_mode(), feedback); | 3502 const Operator* op = javascript()->StoreProperty(language_mode(), feedback); |
3513 return Record(js_type_feedback_, NewNode(op, object, key, value), id); | 3503 Node* node = NewNode(op, object, key, value); |
| 3504 return Record(js_type_feedback_, node, id); |
3514 } | 3505 } |
3515 | 3506 |
3516 | 3507 |
3517 Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name, | 3508 Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name, |
3518 Node* value, | 3509 Node* value, |
3519 const VectorSlotPair& feedback, | 3510 const VectorSlotPair& feedback, |
3520 TypeFeedbackId id) { | 3511 TypeFeedbackId id) { |
3521 const Operator* op = | 3512 const Operator* op = |
3522 javascript()->StoreNamed(language_mode(), MakeUnique(name), feedback); | 3513 javascript()->StoreNamed(language_mode(), MakeUnique(name), feedback); |
3523 return Record(js_type_feedback_, NewNode(op, object, value), id); | 3514 Node* node = NewNode(op, object, value); |
| 3515 return Record(js_type_feedback_, node, id); |
3524 } | 3516 } |
3525 | 3517 |
3526 | 3518 |
3527 Node* AstGraphBuilder::BuildNamedSuperLoad(Node* receiver, Node* home_object, | 3519 Node* AstGraphBuilder::BuildNamedSuperLoad(Node* receiver, Node* home_object, |
3528 Handle<Name> name, | 3520 Handle<Name> name, |
3529 const VectorSlotPair& feedback) { | 3521 const VectorSlotPair& feedback) { |
3530 Node* name_node = jsgraph()->Constant(name); | 3522 Node* name_node = jsgraph()->Constant(name); |
3531 const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper, 3); | 3523 const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper, 3); |
3532 Node* value = NewNode(op, receiver, home_object, name_node); | 3524 Node* node = NewNode(op, receiver, home_object, name_node); |
3533 return Record(js_type_feedback_, value, feedback.slot()); | 3525 return Record(js_type_feedback_, node, feedback.slot()); |
3534 } | 3526 } |
3535 | 3527 |
3536 | 3528 |
3537 Node* AstGraphBuilder::BuildKeyedSuperLoad(Node* receiver, Node* home_object, | 3529 Node* AstGraphBuilder::BuildKeyedSuperLoad(Node* receiver, Node* home_object, |
3538 Node* key, | 3530 Node* key, |
3539 const VectorSlotPair& feedback) { | 3531 const VectorSlotPair& feedback) { |
3540 const Operator* op = | 3532 const Operator* op = |
3541 javascript()->CallRuntime(Runtime::kLoadKeyedFromSuper, 3); | 3533 javascript()->CallRuntime(Runtime::kLoadKeyedFromSuper, 3); |
3542 Node* value = NewNode(op, receiver, home_object, key); | 3534 Node* node = NewNode(op, receiver, home_object, key); |
3543 return Record(js_type_feedback_, value, feedback.slot()); | 3535 return Record(js_type_feedback_, node, feedback.slot()); |
3544 } | 3536 } |
3545 | 3537 |
3546 | 3538 |
3547 Node* AstGraphBuilder::BuildKeyedSuperStore(Node* receiver, Node* home_object, | 3539 Node* AstGraphBuilder::BuildKeyedSuperStore(Node* receiver, Node* home_object, |
3548 Node* key, Node* value, | 3540 Node* key, Node* value, |
3549 TypeFeedbackId id) { | 3541 TypeFeedbackId id) { |
3550 Runtime::FunctionId function_id = is_strict(language_mode()) | 3542 Runtime::FunctionId function_id = is_strict(language_mode()) |
3551 ? Runtime::kStoreKeyedToSuper_Strict | 3543 ? Runtime::kStoreKeyedToSuper_Strict |
3552 : Runtime::kStoreKeyedToSuper_Sloppy; | 3544 : Runtime::kStoreKeyedToSuper_Sloppy; |
3553 const Operator* op = javascript()->CallRuntime(function_id, 4); | 3545 const Operator* op = javascript()->CallRuntime(function_id, 4); |
3554 Node* result = NewNode(op, receiver, home_object, key, value); | 3546 Node* node = NewNode(op, receiver, home_object, key, value); |
3555 return Record(js_type_feedback_, result, id); | 3547 return Record(js_type_feedback_, node, id); |
3556 } | 3548 } |
3557 | 3549 |
3558 | 3550 |
3559 Node* AstGraphBuilder::BuildNamedSuperStore(Node* receiver, Node* home_object, | 3551 Node* AstGraphBuilder::BuildNamedSuperStore(Node* receiver, Node* home_object, |
3560 Handle<Name> name, Node* value, | 3552 Handle<Name> name, Node* value, |
3561 TypeFeedbackId id) { | 3553 TypeFeedbackId id) { |
3562 Node* name_node = jsgraph()->Constant(name); | 3554 Node* name_node = jsgraph()->Constant(name); |
3563 Runtime::FunctionId function_id = is_strict(language_mode()) | 3555 Runtime::FunctionId function_id = is_strict(language_mode()) |
3564 ? Runtime::kStoreToSuper_Strict | 3556 ? Runtime::kStoreToSuper_Strict |
3565 : Runtime::kStoreToSuper_Sloppy; | 3557 : Runtime::kStoreToSuper_Sloppy; |
3566 const Operator* op = javascript()->CallRuntime(function_id, 4); | 3558 const Operator* op = javascript()->CallRuntime(function_id, 4); |
3567 Node* result = NewNode(op, receiver, home_object, name_node, value); | 3559 Node* node = NewNode(op, receiver, home_object, name_node, value); |
3568 return Record(js_type_feedback_, result, id); | 3560 return Record(js_type_feedback_, node, id); |
3569 } | 3561 } |
3570 | 3562 |
3571 | 3563 |
3572 Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) { | 3564 Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) { |
3573 return NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object, | 3565 return NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object, |
3574 jsgraph()->IntPtrConstant(offset - kHeapObjectTag)); | 3566 jsgraph()->IntPtrConstant(offset - kHeapObjectTag)); |
3575 } | 3567 } |
3576 | 3568 |
3577 | 3569 |
| 3570 Node* AstGraphBuilder::BuildLoadImmutableObjectField(Node* object, int offset) { |
| 3571 return graph()->NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object, |
| 3572 jsgraph()->IntPtrConstant(offset - kHeapObjectTag), |
| 3573 graph()->start(), graph()->start()); |
| 3574 } |
| 3575 |
| 3576 |
3578 Node* AstGraphBuilder::BuildLoadBuiltinsObject() { | 3577 Node* AstGraphBuilder::BuildLoadBuiltinsObject() { |
3579 Node* global = BuildLoadGlobalObject(); | 3578 Node* global = BuildLoadGlobalObject(); |
3580 Node* builtins = | 3579 Node* builtins = |
3581 BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset); | 3580 BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset); |
3582 return builtins; | 3581 return builtins; |
3583 } | 3582 } |
3584 | 3583 |
3585 | 3584 |
3586 Node* AstGraphBuilder::BuildLoadGlobalObject() { | 3585 Node* AstGraphBuilder::BuildLoadGlobalObject() { |
3587 const Operator* load_op = | 3586 const Operator* load_op = |
3588 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true); | 3587 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true); |
3589 return NewNode(load_op, function_context_.get()); | 3588 return NewNode(load_op, function_context_.get()); |
3590 } | 3589 } |
3591 | 3590 |
3592 | 3591 |
3593 Node* AstGraphBuilder::BuildLoadGlobalProxy() { | 3592 Node* AstGraphBuilder::BuildLoadGlobalProxy() { |
3594 Node* global = BuildLoadGlobalObject(); | 3593 Node* global = BuildLoadGlobalObject(); |
3595 Node* proxy = | 3594 Node* proxy = |
3596 BuildLoadObjectField(global, JSGlobalObject::kGlobalProxyOffset); | 3595 BuildLoadObjectField(global, JSGlobalObject::kGlobalProxyOffset); |
3597 return proxy; | 3596 return proxy; |
3598 } | 3597 } |
3599 | 3598 |
3600 | 3599 |
| 3600 Node* AstGraphBuilder::BuildLoadFeedbackVector() { |
| 3601 if (!feedback_vector_.is_set()) { |
| 3602 Node* closure = GetFunctionClosure(); |
| 3603 Node* shared = BuildLoadImmutableObjectField( |
| 3604 closure, JSFunction::kSharedFunctionInfoOffset); |
| 3605 Node* vector = BuildLoadImmutableObjectField( |
| 3606 shared, SharedFunctionInfo::kFeedbackVectorOffset); |
| 3607 feedback_vector_.set(vector); |
| 3608 } |
| 3609 return feedback_vector_.get(); |
| 3610 } |
| 3611 |
| 3612 |
3601 Node* AstGraphBuilder::BuildLoadExternal(ExternalReference reference, | 3613 Node* AstGraphBuilder::BuildLoadExternal(ExternalReference reference, |
3602 MachineType type) { | 3614 MachineType type) { |
3603 return NewNode(jsgraph()->machine()->Load(type), | 3615 return NewNode(jsgraph()->machine()->Load(type), |
3604 jsgraph()->ExternalConstant(reference), | 3616 jsgraph()->ExternalConstant(reference), |
3605 jsgraph()->IntPtrConstant(0)); | 3617 jsgraph()->IntPtrConstant(0)); |
3606 } | 3618 } |
3607 | 3619 |
3608 | 3620 |
3609 Node* AstGraphBuilder::BuildStoreExternal(ExternalReference reference, | 3621 Node* AstGraphBuilder::BuildStoreExternal(ExternalReference reference, |
3610 MachineType type, Node* value) { | 3622 MachineType type, Node* value) { |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4112 // Phi does not exist yet, introduce one. | 4124 // Phi does not exist yet, introduce one. |
4113 value = NewPhi(inputs, value, control); | 4125 value = NewPhi(inputs, value, control); |
4114 value->ReplaceInput(inputs - 1, other); | 4126 value->ReplaceInput(inputs - 1, other); |
4115 } | 4127 } |
4116 return value; | 4128 return value; |
4117 } | 4129 } |
4118 | 4130 |
4119 } // namespace compiler | 4131 } // namespace compiler |
4120 } // namespace internal | 4132 } // namespace internal |
4121 } // namespace v8 | 4133 } // namespace v8 |
OLD | NEW |