| 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 |