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