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/ic/accessor-assembler.h" | 5 #include "src/ic/accessor-assembler.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 var_handler->Bind(handler); | 73 var_handler->Bind(handler); |
74 Goto(if_handler); | 74 Goto(if_handler); |
75 | 75 |
76 Bind(&next_entry); | 76 Bind(&next_entry); |
77 } | 77 } |
78 | 78 |
79 // Loop from {unroll_count}*kEntrySize to {length}. | 79 // Loop from {unroll_count}*kEntrySize to {length}. |
80 Node* init = IntPtrConstant(unroll_count * kEntrySize); | 80 Node* init = IntPtrConstant(unroll_count * kEntrySize); |
81 Node* length = LoadAndUntagFixedArrayBaseLength(feedback); | 81 Node* length = LoadAndUntagFixedArrayBaseLength(feedback); |
82 BuildFastLoop( | 82 BuildFastLoop( |
83 MachineType::PointerRepresentation(), init, length, | 83 init, length, |
84 [this, receiver_map, feedback, if_handler, var_handler](Node* index) { | 84 [this, receiver_map, feedback, if_handler, var_handler](Node* index) { |
85 Node* cached_map = | 85 Node* cached_map = |
86 LoadWeakCellValue(LoadFixedArrayElement(feedback, index)); | 86 LoadWeakCellValue(LoadFixedArrayElement(feedback, index)); |
87 | 87 |
88 Label next_entry(this); | 88 Label next_entry(this); |
89 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); | 89 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); |
90 | 90 |
91 // Found, now call handler. | 91 // Found, now call handler. |
92 Node* handler = LoadFixedArrayElement(feedback, index, kPointerSize); | 92 Node* handler = LoadFixedArrayElement(feedback, index, kPointerSize); |
93 var_handler->Bind(handler); | 93 var_handler->Bind(handler); |
94 Goto(if_handler); | 94 Goto(if_handler); |
95 | 95 |
96 Bind(&next_entry); | 96 Bind(&next_entry); |
97 }, | 97 }, |
98 kEntrySize, IndexAdvanceMode::kPost); | 98 kEntrySize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); |
99 // The loop falls through if no handler was found. | 99 // The loop falls through if no handler was found. |
100 Goto(if_miss); | 100 Goto(if_miss); |
101 } | 101 } |
102 | 102 |
103 void AccessorAssembler::HandleKeyedStorePolymorphicCase( | 103 void AccessorAssembler::HandleKeyedStorePolymorphicCase( |
104 Node* receiver_map, Node* feedback, Label* if_handler, | 104 Node* receiver_map, Node* feedback, Label* if_handler, |
105 Variable* var_handler, Label* if_transition_handler, | 105 Variable* var_handler, Label* if_transition_handler, |
106 Variable* var_transition_map_cell, Label* if_miss) { | 106 Variable* var_transition_map_cell, Label* if_miss) { |
107 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); | 107 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); |
108 DCHECK_EQ(MachineRepresentation::kTagged, var_transition_map_cell->rep()); | 108 DCHECK_EQ(MachineRepresentation::kTagged, var_transition_map_cell->rep()); |
109 | 109 |
110 const int kEntrySize = 3; | 110 const int kEntrySize = 3; |
111 | 111 |
112 Node* init = IntPtrConstant(0); | 112 Node* init = IntPtrConstant(0); |
113 Node* length = LoadAndUntagFixedArrayBaseLength(feedback); | 113 Node* length = LoadAndUntagFixedArrayBaseLength(feedback); |
114 BuildFastLoop(MachineType::PointerRepresentation(), init, length, | 114 BuildFastLoop(init, length, |
115 [this, receiver_map, feedback, if_handler, var_handler, | 115 [this, receiver_map, feedback, if_handler, var_handler, |
116 if_transition_handler, var_transition_map_cell](Node* index) { | 116 if_transition_handler, var_transition_map_cell](Node* index) { |
117 Node* cached_map = | 117 Node* cached_map = |
118 LoadWeakCellValue(LoadFixedArrayElement(feedback, index)); | 118 LoadWeakCellValue(LoadFixedArrayElement(feedback, index)); |
119 Label next_entry(this); | 119 Label next_entry(this); |
120 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); | 120 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); |
121 | 121 |
122 Node* maybe_transition_map_cell = | 122 Node* maybe_transition_map_cell = |
123 LoadFixedArrayElement(feedback, index, kPointerSize); | 123 LoadFixedArrayElement(feedback, index, kPointerSize); |
124 | 124 |
125 var_handler->Bind( | 125 var_handler->Bind( |
126 LoadFixedArrayElement(feedback, index, 2 * kPointerSize)); | 126 LoadFixedArrayElement(feedback, index, 2 * kPointerSize)); |
127 GotoIf(WordEqual(maybe_transition_map_cell, | 127 GotoIf(WordEqual(maybe_transition_map_cell, |
128 LoadRoot(Heap::kUndefinedValueRootIndex)), | 128 LoadRoot(Heap::kUndefinedValueRootIndex)), |
129 if_handler); | 129 if_handler); |
130 var_transition_map_cell->Bind(maybe_transition_map_cell); | 130 var_transition_map_cell->Bind(maybe_transition_map_cell); |
131 Goto(if_transition_handler); | 131 Goto(if_transition_handler); |
132 | 132 |
133 Bind(&next_entry); | 133 Bind(&next_entry); |
134 }, | 134 }, |
135 kEntrySize, IndexAdvanceMode::kPost); | 135 kEntrySize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); |
136 // The loop falls through if no handler was found. | 136 // The loop falls through if no handler was found. |
137 Goto(if_miss); | 137 Goto(if_miss); |
138 } | 138 } |
139 | 139 |
140 void AccessorAssembler::HandleLoadICHandlerCase( | 140 void AccessorAssembler::HandleLoadICHandlerCase( |
141 const LoadICParameters* p, Node* handler, Label* miss, | 141 const LoadICParameters* p, Node* handler, Label* miss, |
142 ElementSupport support_elements) { | 142 ElementSupport support_elements) { |
143 Comment("have_handler"); | 143 Comment("have_handler"); |
144 Variable var_holder(this, MachineRepresentation::kTagged); | 144 Variable var_holder(this, MachineRepresentation::kTagged); |
145 var_holder.Bind(p->receiver); | 145 var_holder.Bind(p->receiver); |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 // For JSGlobalProxy receiver try to compare security tokens of current | 403 // For JSGlobalProxy receiver try to compare security tokens of current |
404 // and expected native contexts. | 404 // and expected native contexts. |
405 Node* expected_token = LoadContextElement(expected_native_context, | 405 Node* expected_token = LoadContextElement(expected_native_context, |
406 Context::SECURITY_TOKEN_INDEX); | 406 Context::SECURITY_TOKEN_INDEX); |
407 Node* current_token = | 407 Node* current_token = |
408 LoadContextElement(native_context, Context::SECURITY_TOKEN_INDEX); | 408 LoadContextElement(native_context, Context::SECURITY_TOKEN_INDEX); |
409 Branch(WordEqual(expected_token, current_token), &can_access, miss); | 409 Branch(WordEqual(expected_token, current_token), &can_access, miss); |
410 } | 410 } |
411 Bind(&can_access); | 411 Bind(&can_access); |
412 | 412 |
413 BuildFastLoop( | 413 BuildFastLoop(start_index.value(), handler_length, |
414 MachineType::PointerRepresentation(), start_index.value(), handler_length, | 414 [this, p, handler, miss](Node* current) { |
415 [this, p, handler, miss](Node* current) { | 415 Node* prototype_cell = |
416 Node* prototype_cell = LoadFixedArrayElement(handler, current); | 416 LoadFixedArrayElement(handler, current); |
417 CheckPrototype(prototype_cell, p->name, miss); | 417 CheckPrototype(prototype_cell, p->name, miss); |
418 }, | 418 }, |
419 1, IndexAdvanceMode::kPost); | 419 1, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); |
420 | 420 |
421 Node* maybe_holder_cell = | 421 Node* maybe_holder_cell = |
422 LoadFixedArrayElement(handler, LoadHandler::kHolderCellIndex); | 422 LoadFixedArrayElement(handler, LoadHandler::kHolderCellIndex); |
423 Label load_existent(this); | 423 Label load_existent(this); |
424 GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent); | 424 GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent); |
425 // This is a handler for a load of a non-existent value. | 425 // This is a handler for a load of a non-existent value. |
426 if (throw_reference_error_if_nonexistent) { | 426 if (throw_reference_error_if_nonexistent) { |
427 TailCallRuntime(Runtime::kThrowReferenceError, p->context, p->name); | 427 TailCallRuntime(Runtime::kThrowReferenceError, p->context, p->name); |
428 } else { | 428 } else { |
429 Return(UndefinedConstant()); | 429 Return(UndefinedConstant()); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 Bind(&tuple_handler); | 557 Bind(&tuple_handler); |
558 { | 558 { |
559 Node* transition = LoadWeakCellValue(maybe_transition_cell, miss); | 559 Node* transition = LoadWeakCellValue(maybe_transition_cell, miss); |
560 var_transition.Bind(transition); | 560 var_transition.Bind(transition); |
561 Goto(&if_transition); | 561 Goto(&if_transition); |
562 } | 562 } |
563 | 563 |
564 Bind(&array_handler); | 564 Bind(&array_handler); |
565 { | 565 { |
566 Node* length = SmiUntag(maybe_transition_cell); | 566 Node* length = SmiUntag(maybe_transition_cell); |
567 BuildFastLoop(MachineType::PointerRepresentation(), | 567 BuildFastLoop(IntPtrConstant(StoreHandler::kFirstPrototypeIndex), length, |
568 IntPtrConstant(StoreHandler::kFirstPrototypeIndex), length, | |
569 [this, p, handler, miss](Node* current) { | 568 [this, p, handler, miss](Node* current) { |
570 Node* prototype_cell = | 569 Node* prototype_cell = |
571 LoadFixedArrayElement(handler, current); | 570 LoadFixedArrayElement(handler, current); |
572 CheckPrototype(prototype_cell, p->name, miss); | 571 CheckPrototype(prototype_cell, p->name, miss); |
573 }, | 572 }, |
574 1, IndexAdvanceMode::kPost); | 573 1, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); |
575 | 574 |
576 Node* maybe_transition_cell = | 575 Node* maybe_transition_cell = |
577 LoadFixedArrayElement(handler, StoreHandler::kTransitionCellIndex); | 576 LoadFixedArrayElement(handler, StoreHandler::kTransitionCellIndex); |
578 Node* transition = LoadWeakCellValue(maybe_transition_cell, miss); | 577 Node* transition = LoadWeakCellValue(maybe_transition_cell, miss); |
579 var_transition.Bind(transition); | 578 var_transition.Bind(transition); |
580 Goto(&if_transition); | 579 Goto(&if_transition); |
581 } | 580 } |
582 | 581 |
583 Bind(&if_transition); | 582 Bind(&if_transition); |
584 { | 583 { |
(...skipping 1298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1883 Node* slot = Parameter(Descriptor::kSlot); | 1882 Node* slot = Parameter(Descriptor::kSlot); |
1884 Node* context = Parameter(Descriptor::kContext); | 1883 Node* context = Parameter(Descriptor::kContext); |
1885 Node* vector = LoadTypeFeedbackVectorForStub(); | 1884 Node* vector = LoadTypeFeedbackVectorForStub(); |
1886 | 1885 |
1887 StoreICParameters p(context, receiver, name, value, slot, vector); | 1886 StoreICParameters p(context, receiver, name, value, slot, vector); |
1888 KeyedStoreIC(&p, language_mode); | 1887 KeyedStoreIC(&p, language_mode); |
1889 } | 1888 } |
1890 | 1889 |
1891 } // namespace internal | 1890 } // namespace internal |
1892 } // namespace v8 | 1891 } // namespace v8 |
OLD | NEW |