Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: src/code-stub-assembler.cc

Issue 2362453004: [stubs] KeyedLoadIC_Megamorphic: support getters (Closed)
Patch Set: rebase Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/code-stub-assembler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698