OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/code-stub-assembler.h" | 5 #include "src/code-stub-assembler.h" |
6 #include "src/code-factory.h" | 6 #include "src/code-factory.h" |
7 #include "src/frames-inl.h" | 7 #include "src/frames-inl.h" |
8 #include "src/frames.h" | 8 #include "src/frames.h" |
9 #include "src/ic/handler-configuration.h" | 9 #include "src/ic/handler-configuration.h" |
10 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
(...skipping 3547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3558 | 3558 |
3559 var_value->Bind(value); | 3559 var_value->Bind(value); |
3560 | 3560 |
3561 Node* details = LoadAndUntagToWord32ObjectField(property_cell, | 3561 Node* details = LoadAndUntagToWord32ObjectField(property_cell, |
3562 PropertyCell::kDetailsOffset); | 3562 PropertyCell::kDetailsOffset); |
3563 var_details->Bind(details); | 3563 var_details->Bind(details); |
3564 | 3564 |
3565 Comment("] LoadPropertyFromGlobalDictionary"); | 3565 Comment("] LoadPropertyFromGlobalDictionary"); |
3566 } | 3566 } |
3567 | 3567 |
| 3568 // |value| is the property backing store's contents, which is either a value |
| 3569 // or an accessor pair, as specified by |details|. |
| 3570 // Returns either the original value, or the result of the getter call. |
| 3571 Node* CodeStubAssembler::CallGetterIfAccessor(Node* value, Node* details, |
| 3572 Node* context, Node* receiver, |
| 3573 Label* if_bailout) { |
| 3574 Variable var_value(this, MachineRepresentation::kTagged); |
| 3575 var_value.Bind(value); |
| 3576 Label done(this); |
| 3577 |
| 3578 Node* kind = BitFieldDecode<PropertyDetails::KindField>(details); |
| 3579 GotoIf(Word32Equal(kind, Int32Constant(kData)), &done); |
| 3580 |
| 3581 // Accessor case. |
| 3582 { |
| 3583 Node* accessor_pair = value; |
| 3584 GotoIf(Word32Equal(LoadInstanceType(accessor_pair), |
| 3585 Int32Constant(ACCESSOR_INFO_TYPE)), |
| 3586 if_bailout); |
| 3587 AssertInstanceType(accessor_pair, ACCESSOR_PAIR_TYPE); |
| 3588 Node* getter = LoadObjectField(accessor_pair, AccessorPair::kGetterOffset); |
| 3589 Node* getter_map = LoadMap(getter); |
| 3590 Node* instance_type = LoadMapInstanceType(getter_map); |
| 3591 // FunctionTemplateInfo getters are not supported yet. |
| 3592 GotoIf( |
| 3593 Word32Equal(instance_type, Int32Constant(FUNCTION_TEMPLATE_INFO_TYPE)), |
| 3594 if_bailout); |
| 3595 |
| 3596 // Return undefined if the {getter} is not callable. |
| 3597 var_value.Bind(UndefinedConstant()); |
| 3598 GotoIf(Word32Equal(Word32And(LoadMapBitField(getter_map), |
| 3599 Int32Constant(1 << Map::kIsCallable)), |
| 3600 Int32Constant(0)), |
| 3601 &done); |
| 3602 |
| 3603 // Call the accessor. |
| 3604 Callable callable = CodeFactory::Call(isolate()); |
| 3605 Node* result = CallJS(callable, context, getter, receiver); |
| 3606 var_value.Bind(result); |
| 3607 Goto(&done); |
| 3608 } |
| 3609 |
| 3610 Bind(&done); |
| 3611 return var_value.value(); |
| 3612 } |
| 3613 |
3568 void CodeStubAssembler::TryGetOwnProperty( | 3614 void CodeStubAssembler::TryGetOwnProperty( |
3569 Node* context, Node* receiver, Node* object, Node* map, Node* instance_type, | 3615 Node* context, Node* receiver, Node* object, Node* map, Node* instance_type, |
3570 Node* unique_name, Label* if_found_value, Variable* var_value, | 3616 Node* unique_name, Label* if_found_value, Variable* var_value, |
3571 Label* if_not_found, Label* if_bailout) { | 3617 Label* if_not_found, Label* if_bailout) { |
3572 DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep()); | 3618 DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep()); |
3573 Comment("TryGetOwnProperty"); | 3619 Comment("TryGetOwnProperty"); |
3574 | 3620 |
3575 Variable var_meta_storage(this, MachineRepresentation::kTagged); | 3621 Variable var_meta_storage(this, MachineRepresentation::kTagged); |
3576 Variable var_entry(this, MachineType::PointerRepresentation()); | 3622 Variable var_entry(this, MachineType::PointerRepresentation()); |
3577 | 3623 |
(...skipping 27 matching lines...) Expand all Loading... |
3605 Node* dictionary = var_meta_storage.value(); | 3651 Node* dictionary = var_meta_storage.value(); |
3606 Node* entry = var_entry.value(); | 3652 Node* entry = var_entry.value(); |
3607 | 3653 |
3608 LoadPropertyFromGlobalDictionary(dictionary, entry, &var_details, var_value, | 3654 LoadPropertyFromGlobalDictionary(dictionary, entry, &var_details, var_value, |
3609 if_not_found); | 3655 if_not_found); |
3610 Goto(&if_found); | 3656 Goto(&if_found); |
3611 } | 3657 } |
3612 // Here we have details and value which could be an accessor. | 3658 // Here we have details and value which could be an accessor. |
3613 Bind(&if_found); | 3659 Bind(&if_found); |
3614 { | 3660 { |
3615 Node* details = var_details.value(); | 3661 Node* value = CallGetterIfAccessor(var_value->value(), var_details.value(), |
3616 Node* kind = BitFieldDecode<PropertyDetails::KindField>(details); | 3662 context, receiver, if_bailout); |
3617 | 3663 var_value->Bind(value); |
3618 Label if_accessor(this); | 3664 Goto(if_found_value); |
3619 Branch(Word32Equal(kind, Int32Constant(kData)), if_found_value, | |
3620 &if_accessor); | |
3621 Bind(&if_accessor); | |
3622 { | |
3623 Node* accessor_pair = var_value->value(); | |
3624 GotoIf(Word32Equal(LoadInstanceType(accessor_pair), | |
3625 Int32Constant(ACCESSOR_INFO_TYPE)), | |
3626 if_bailout); | |
3627 AssertInstanceType(accessor_pair, ACCESSOR_PAIR_TYPE); | |
3628 Node* getter = | |
3629 LoadObjectField(accessor_pair, AccessorPair::kGetterOffset); | |
3630 Node* getter_map = LoadMap(getter); | |
3631 Node* instance_type = LoadMapInstanceType(getter_map); | |
3632 // FunctionTemplateInfo getters are not supported yet. | |
3633 GotoIf(Word32Equal(instance_type, | |
3634 Int32Constant(FUNCTION_TEMPLATE_INFO_TYPE)), | |
3635 if_bailout); | |
3636 | |
3637 // Return undefined if the {getter} is not callable. | |
3638 var_value->Bind(UndefinedConstant()); | |
3639 GotoIf(Word32Equal(Word32And(LoadMapBitField(getter_map), | |
3640 Int32Constant(1 << Map::kIsCallable)), | |
3641 Int32Constant(0)), | |
3642 if_found_value); | |
3643 | |
3644 // Call the accessor. | |
3645 Callable callable = CodeFactory::Call(isolate()); | |
3646 Node* result = CallJS(callable, context, getter, receiver); | |
3647 var_value->Bind(result); | |
3648 Goto(if_found_value); | |
3649 } | |
3650 } | 3665 } |
3651 } | 3666 } |
3652 | 3667 |
3653 void CodeStubAssembler::TryLookupElement(Node* object, Node* map, | 3668 void CodeStubAssembler::TryLookupElement(Node* object, Node* map, |
3654 Node* instance_type, | 3669 Node* instance_type, |
3655 Node* intptr_index, Label* if_found, | 3670 Node* intptr_index, Label* if_found, |
3656 Label* if_not_found, | 3671 Label* if_not_found, |
3657 Label* if_bailout) { | 3672 Label* if_bailout) { |
3658 // Handle special objects in runtime. | 3673 // Handle special objects in runtime. |
3659 GotoIf(Int32LessThanOrEqual(instance_type, | 3674 GotoIf(Int32LessThanOrEqual(instance_type, |
(...skipping 1217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4877 Bind(&dictionary_found); | 4892 Bind(&dictionary_found); |
4878 { | 4893 { |
4879 LoadPropertyFromNameDictionary(properties, var_name_index.value(), | 4894 LoadPropertyFromNameDictionary(properties, var_name_index.value(), |
4880 &var_details, &var_value); | 4895 &var_details, &var_value); |
4881 Goto(&if_found_on_receiver); | 4896 Goto(&if_found_on_receiver); |
4882 } | 4897 } |
4883 } | 4898 } |
4884 | 4899 |
4885 Bind(&if_found_on_receiver); | 4900 Bind(&if_found_on_receiver); |
4886 { | 4901 { |
4887 Node* kind = | 4902 Node* value = CallGetterIfAccessor(var_value.value(), var_details.value(), |
4888 BitFieldDecode<PropertyDetails::KindField>(var_details.value()); | 4903 p->context, receiver, &slow); |
4889 // TODO(jkummerow): Support accessors without missing? | |
4890 GotoUnless(Word32Equal(kind, Int32Constant(kData)), &slow); | |
4891 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_symbol(), 1); | 4904 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_symbol(), 1); |
4892 Return(var_value.value()); | 4905 Return(value); |
4893 } | 4906 } |
4894 | 4907 |
4895 Bind(&slow); | 4908 Bind(&slow); |
4896 { | 4909 { |
4897 Comment("KeyedLoadGeneric_slow"); | 4910 Comment("KeyedLoadGeneric_slow"); |
4898 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_slow(), 1); | 4911 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_slow(), 1); |
4899 // TODO(jkummerow): Should we use the GetProperty TF stub instead? | 4912 // TODO(jkummerow): Should we use the GetProperty TF stub instead? |
4900 TailCallRuntime(Runtime::kKeyedGetProperty, p->context, p->receiver, | 4913 TailCallRuntime(Runtime::kKeyedGetProperty, p->context, p->receiver, |
4901 p->name); | 4914 p->name); |
4902 } | 4915 } |
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5626 Heap::kTheHoleValueRootIndex); | 5639 Heap::kTheHoleValueRootIndex); |
5627 | 5640 |
5628 // Store the WeakCell in the feedback vector. | 5641 // Store the WeakCell in the feedback vector. |
5629 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, | 5642 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, |
5630 CodeStubAssembler::SMI_PARAMETERS); | 5643 CodeStubAssembler::SMI_PARAMETERS); |
5631 return cell; | 5644 return cell; |
5632 } | 5645 } |
5633 | 5646 |
5634 } // namespace internal | 5647 } // namespace internal |
5635 } // namespace v8 | 5648 } // namespace v8 |
OLD | NEW |