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 #include "src/ic/accessor-assembler-impl.h" | |
7 | 6 |
8 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
9 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
10 #include "src/ic/handler-configuration.h" | 9 #include "src/ic/handler-configuration.h" |
11 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
12 | 11 |
13 namespace v8 { | 12 namespace v8 { |
14 namespace internal { | 13 namespace internal { |
15 | 14 |
16 using compiler::CodeAssemblerState; | 15 using compiler::CodeAssemblerState; |
| 16 using compiler::Node; |
17 | 17 |
18 //////////////////// Private helpers. | 18 //////////////////// Private helpers. |
19 | 19 |
20 Node* AccessorAssemblerImpl::TryMonomorphicCase(Node* slot, Node* vector, | 20 Node* AccessorAssembler::TryMonomorphicCase(Node* slot, Node* vector, |
21 Node* receiver_map, | 21 Node* receiver_map, |
22 Label* if_handler, | 22 Label* if_handler, |
23 Variable* var_handler, | 23 Variable* var_handler, |
24 Label* if_miss) { | 24 Label* if_miss) { |
25 Comment("TryMonomorphicCase"); | 25 Comment("TryMonomorphicCase"); |
26 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); | 26 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); |
27 | 27 |
28 // TODO(ishell): add helper class that hides offset computations for a series | 28 // TODO(ishell): add helper class that hides offset computations for a series |
29 // of loads. | 29 // of loads. |
30 int32_t header_size = FixedArray::kHeaderSize - kHeapObjectTag; | 30 int32_t header_size = FixedArray::kHeaderSize - kHeapObjectTag; |
31 // Adding |header_size| with a separate IntPtrAdd rather than passing it | 31 // Adding |header_size| with a separate IntPtrAdd rather than passing it |
32 // into ElementOffsetFromIndex() allows it to be folded into a single | 32 // into ElementOffsetFromIndex() allows it to be folded into a single |
33 // [base, index, offset] indirect memory access on x64. | 33 // [base, index, offset] indirect memory access on x64. |
34 Node* offset = | 34 Node* offset = |
35 ElementOffsetFromIndex(slot, FAST_HOLEY_ELEMENTS, SMI_PARAMETERS); | 35 ElementOffsetFromIndex(slot, FAST_HOLEY_ELEMENTS, SMI_PARAMETERS); |
36 Node* feedback = Load(MachineType::AnyTagged(), vector, | 36 Node* feedback = Load(MachineType::AnyTagged(), vector, |
37 IntPtrAdd(offset, IntPtrConstant(header_size))); | 37 IntPtrAdd(offset, IntPtrConstant(header_size))); |
38 | 38 |
39 // Try to quickly handle the monomorphic case without knowing for sure | 39 // Try to quickly handle the monomorphic case without knowing for sure |
40 // if we have a weak cell in feedback. We do know it's safe to look | 40 // if we have a weak cell in feedback. We do know it's safe to look |
41 // at WeakCell::kValueOffset. | 41 // at WeakCell::kValueOffset. |
42 GotoIf(WordNotEqual(receiver_map, LoadWeakCellValueUnchecked(feedback)), | 42 GotoIf(WordNotEqual(receiver_map, LoadWeakCellValueUnchecked(feedback)), |
43 if_miss); | 43 if_miss); |
44 | 44 |
45 Node* handler = | 45 Node* handler = |
46 Load(MachineType::AnyTagged(), vector, | 46 Load(MachineType::AnyTagged(), vector, |
47 IntPtrAdd(offset, IntPtrConstant(header_size + kPointerSize))); | 47 IntPtrAdd(offset, IntPtrConstant(header_size + kPointerSize))); |
48 | 48 |
49 var_handler->Bind(handler); | 49 var_handler->Bind(handler); |
50 Goto(if_handler); | 50 Goto(if_handler); |
51 return feedback; | 51 return feedback; |
52 } | 52 } |
53 | 53 |
54 void AccessorAssemblerImpl::HandlePolymorphicCase( | 54 void AccessorAssembler::HandlePolymorphicCase(Node* receiver_map, |
55 Node* receiver_map, Node* feedback, Label* if_handler, | 55 Node* feedback, Label* if_handler, |
56 Variable* var_handler, Label* if_miss, int unroll_count) { | 56 Variable* var_handler, |
| 57 Label* if_miss, |
| 58 int unroll_count) { |
57 Comment("HandlePolymorphicCase"); | 59 Comment("HandlePolymorphicCase"); |
58 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); | 60 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); |
59 | 61 |
60 // Iterate {feedback} array. | 62 // Iterate {feedback} array. |
61 const int kEntrySize = 2; | 63 const int kEntrySize = 2; |
62 | 64 |
63 for (int i = 0; i < unroll_count; i++) { | 65 for (int i = 0; i < unroll_count; i++) { |
64 Label next_entry(this); | 66 Label next_entry(this); |
65 Node* cached_map = | 67 Node* cached_map = |
66 LoadWeakCellValue(LoadFixedArrayElement(feedback, i * kEntrySize)); | 68 LoadWeakCellValue(LoadFixedArrayElement(feedback, i * kEntrySize)); |
(...skipping 24 matching lines...) Expand all Loading... |
91 var_handler->Bind(handler); | 93 var_handler->Bind(handler); |
92 Goto(if_handler); | 94 Goto(if_handler); |
93 | 95 |
94 Bind(&next_entry); | 96 Bind(&next_entry); |
95 }, | 97 }, |
96 kEntrySize, IndexAdvanceMode::kPost); | 98 kEntrySize, IndexAdvanceMode::kPost); |
97 // The loop falls through if no handler was found. | 99 // The loop falls through if no handler was found. |
98 Goto(if_miss); | 100 Goto(if_miss); |
99 } | 101 } |
100 | 102 |
101 void AccessorAssemblerImpl::HandleKeyedStorePolymorphicCase( | 103 void AccessorAssembler::HandleKeyedStorePolymorphicCase( |
102 Node* receiver_map, Node* feedback, Label* if_handler, | 104 Node* receiver_map, Node* feedback, Label* if_handler, |
103 Variable* var_handler, Label* if_transition_handler, | 105 Variable* var_handler, Label* if_transition_handler, |
104 Variable* var_transition_map_cell, Label* if_miss) { | 106 Variable* var_transition_map_cell, Label* if_miss) { |
105 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); | 107 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); |
106 DCHECK_EQ(MachineRepresentation::kTagged, var_transition_map_cell->rep()); | 108 DCHECK_EQ(MachineRepresentation::kTagged, var_transition_map_cell->rep()); |
107 | 109 |
108 const int kEntrySize = 3; | 110 const int kEntrySize = 3; |
109 | 111 |
110 Node* init = IntPtrConstant(0); | 112 Node* init = IntPtrConstant(0); |
111 Node* length = LoadAndUntagFixedArrayBaseLength(feedback); | 113 Node* length = LoadAndUntagFixedArrayBaseLength(feedback); |
(...skipping 16 matching lines...) Expand all Loading... |
128 var_transition_map_cell->Bind(maybe_transition_map_cell); | 130 var_transition_map_cell->Bind(maybe_transition_map_cell); |
129 Goto(if_transition_handler); | 131 Goto(if_transition_handler); |
130 | 132 |
131 Bind(&next_entry); | 133 Bind(&next_entry); |
132 }, | 134 }, |
133 kEntrySize, IndexAdvanceMode::kPost); | 135 kEntrySize, IndexAdvanceMode::kPost); |
134 // The loop falls through if no handler was found. | 136 // The loop falls through if no handler was found. |
135 Goto(if_miss); | 137 Goto(if_miss); |
136 } | 138 } |
137 | 139 |
138 void AccessorAssemblerImpl::HandleLoadICHandlerCase( | 140 void AccessorAssembler::HandleLoadICHandlerCase( |
139 const LoadICParameters* p, Node* handler, Label* miss, | 141 const LoadICParameters* p, Node* handler, Label* miss, |
140 ElementSupport support_elements) { | 142 ElementSupport support_elements) { |
141 Comment("have_handler"); | 143 Comment("have_handler"); |
142 Variable var_holder(this, MachineRepresentation::kTagged); | 144 Variable var_holder(this, MachineRepresentation::kTagged); |
143 var_holder.Bind(p->receiver); | 145 var_holder.Bind(p->receiver); |
144 Variable var_smi_handler(this, MachineRepresentation::kTagged); | 146 Variable var_smi_handler(this, MachineRepresentation::kTagged); |
145 var_smi_handler.Bind(handler); | 147 var_smi_handler.Bind(handler); |
146 | 148 |
147 Variable* vars[] = {&var_holder, &var_smi_handler}; | 149 Variable* vars[] = {&var_holder, &var_smi_handler}; |
148 Label if_smi_handler(this, 2, vars); | 150 Label if_smi_handler(this, 2, vars); |
(...skipping 17 matching lines...) Expand all Loading... |
166 } | 168 } |
167 | 169 |
168 Bind(&call_handler); | 170 Bind(&call_handler); |
169 { | 171 { |
170 typedef LoadWithVectorDescriptor Descriptor; | 172 typedef LoadWithVectorDescriptor Descriptor; |
171 TailCallStub(Descriptor(isolate()), handler, p->context, p->receiver, | 173 TailCallStub(Descriptor(isolate()), handler, p->context, p->receiver, |
172 p->name, p->slot, p->vector); | 174 p->name, p->slot, p->vector); |
173 } | 175 } |
174 } | 176 } |
175 | 177 |
176 void AccessorAssemblerImpl::HandleLoadICSmiHandlerCase( | 178 void AccessorAssembler::HandleLoadICSmiHandlerCase( |
177 const LoadICParameters* p, Node* holder, Node* smi_handler, Label* miss, | 179 const LoadICParameters* p, Node* holder, Node* smi_handler, Label* miss, |
178 ElementSupport support_elements) { | 180 ElementSupport support_elements) { |
179 Variable var_double_value(this, MachineRepresentation::kFloat64); | 181 Variable var_double_value(this, MachineRepresentation::kFloat64); |
180 Label rebox_double(this, &var_double_value); | 182 Label rebox_double(this, &var_double_value); |
181 | 183 |
182 Node* handler_word = SmiUntag(smi_handler); | 184 Node* handler_word = SmiUntag(smi_handler); |
183 Node* handler_kind = DecodeWord<LoadHandler::KindBits>(handler_word); | 185 Node* handler_kind = DecodeWord<LoadHandler::KindBits>(handler_word); |
184 if (support_elements == kSupportElements) { | 186 if (support_elements == kSupportElements) { |
185 Label property(this); | 187 Label property(this); |
186 GotoUnless( | 188 GotoUnless( |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 GotoIf(IsSetWord<LoadHandler::IsAccessorInfoBits>(handler_word), | 290 GotoIf(IsSetWord<LoadHandler::IsAccessorInfoBits>(handler_word), |
289 &if_accessor_info); | 291 &if_accessor_info); |
290 Return(value); | 292 Return(value); |
291 | 293 |
292 Bind(&if_accessor_info); | 294 Bind(&if_accessor_info); |
293 Callable callable = CodeFactory::ApiGetter(isolate()); | 295 Callable callable = CodeFactory::ApiGetter(isolate()); |
294 TailCallStub(callable, p->context, p->receiver, holder, value); | 296 TailCallStub(callable, p->context, p->receiver, holder, value); |
295 } | 297 } |
296 } | 298 } |
297 | 299 |
298 void AccessorAssemblerImpl::HandleLoadICProtoHandlerCase( | 300 void AccessorAssembler::HandleLoadICProtoHandlerCase( |
299 const LoadICParameters* p, Node* handler, Variable* var_holder, | 301 const LoadICParameters* p, Node* handler, Variable* var_holder, |
300 Variable* var_smi_handler, Label* if_smi_handler, Label* miss, | 302 Variable* var_smi_handler, Label* if_smi_handler, Label* miss, |
301 bool throw_reference_error_if_nonexistent) { | 303 bool throw_reference_error_if_nonexistent) { |
302 DCHECK_EQ(MachineRepresentation::kTagged, var_holder->rep()); | 304 DCHECK_EQ(MachineRepresentation::kTagged, var_holder->rep()); |
303 DCHECK_EQ(MachineRepresentation::kTagged, var_smi_handler->rep()); | 305 DCHECK_EQ(MachineRepresentation::kTagged, var_smi_handler->rep()); |
304 | 306 |
305 // IC dispatchers rely on these assumptions to be held. | 307 // IC dispatchers rely on these assumptions to be held. |
306 STATIC_ASSERT(FixedArray::kLengthOffset == LoadHandler::kHolderCellOffset); | 308 STATIC_ASSERT(FixedArray::kLengthOffset == LoadHandler::kHolderCellOffset); |
307 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kSmiHandlerIndex), | 309 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kSmiHandlerIndex), |
308 LoadHandler::kSmiHandlerOffset); | 310 LoadHandler::kSmiHandlerOffset); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 // both the receiver map check and the validity cell check. | 363 // both the receiver map check and the validity cell check. |
362 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0))); | 364 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0))); |
363 | 365 |
364 var_holder->Bind(holder); | 366 var_holder->Bind(holder); |
365 var_smi_handler->Bind(smi_handler); | 367 var_smi_handler->Bind(smi_handler); |
366 Goto(if_smi_handler); | 368 Goto(if_smi_handler); |
367 } | 369 } |
368 | 370 |
369 Bind(&array_handler); | 371 Bind(&array_handler); |
370 { | 372 { |
371 typedef LoadICProtoArrayDescriptor Descriptor; | 373 TailCallStub(CodeFactory::LoadICProtoArray( |
372 LoadICProtoArrayStub stub(isolate(), throw_reference_error_if_nonexistent); | 374 isolate(), throw_reference_error_if_nonexistent), |
373 Node* target = HeapConstant(stub.GetCode()); | 375 p->context, p->receiver, p->name, p->slot, p->vector, handler); |
374 TailCallStub(Descriptor(isolate()), target, p->context, p->receiver, | |
375 p->name, p->slot, p->vector, handler); | |
376 } | 376 } |
377 } | 377 } |
378 | 378 |
379 Node* AccessorAssemblerImpl::EmitLoadICProtoArrayCheck( | 379 Node* AccessorAssembler::EmitLoadICProtoArrayCheck( |
380 const LoadICParameters* p, Node* handler, Node* handler_length, | 380 const LoadICParameters* p, Node* handler, Node* handler_length, |
381 Node* handler_flags, Label* miss, | 381 Node* handler_flags, Label* miss, |
382 bool throw_reference_error_if_nonexistent) { | 382 bool throw_reference_error_if_nonexistent) { |
383 Variable start_index(this, MachineType::PointerRepresentation()); | 383 Variable start_index(this, MachineType::PointerRepresentation()); |
384 start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex)); | 384 start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex)); |
385 | 385 |
386 Label can_access(this); | 386 Label can_access(this); |
387 GotoUnless(IsSetWord<LoadHandler::DoAccessCheckOnReceiverBits>(handler_flags), | 387 GotoUnless(IsSetWord<LoadHandler::DoAccessCheckOnReceiverBits>(handler_flags), |
388 &can_access); | 388 &can_access); |
389 { | 389 { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 | 431 |
432 Bind(&load_existent); | 432 Bind(&load_existent); |
433 Node* holder = LoadWeakCellValue(maybe_holder_cell); | 433 Node* holder = LoadWeakCellValue(maybe_holder_cell); |
434 // The |holder| is guaranteed to be alive at this point since we passed | 434 // The |holder| is guaranteed to be alive at this point since we passed |
435 // the receiver map check, the validity cell check and the prototype chain | 435 // the receiver map check, the validity cell check and the prototype chain |
436 // check. | 436 // check. |
437 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0))); | 437 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0))); |
438 return holder; | 438 return holder; |
439 } | 439 } |
440 | 440 |
441 void AccessorAssemblerImpl::HandleLoadGlobalICHandlerCase( | 441 void AccessorAssembler::HandleLoadGlobalICHandlerCase( |
442 const LoadICParameters* pp, Node* handler, Label* miss, | 442 const LoadICParameters* pp, Node* handler, Label* miss, |
443 bool throw_reference_error_if_nonexistent) { | 443 bool throw_reference_error_if_nonexistent) { |
444 LoadICParameters p = *pp; | 444 LoadICParameters p = *pp; |
445 DCHECK_NULL(p.receiver); | 445 DCHECK_NULL(p.receiver); |
446 Node* native_context = LoadNativeContext(p.context); | 446 Node* native_context = LoadNativeContext(p.context); |
447 p.receiver = LoadContextElement(native_context, Context::EXTENSION_INDEX); | 447 p.receiver = LoadContextElement(native_context, Context::EXTENSION_INDEX); |
448 | 448 |
449 Variable var_holder(this, MachineRepresentation::kTagged); | 449 Variable var_holder(this, MachineRepresentation::kTagged); |
450 Variable var_smi_handler(this, MachineRepresentation::kTagged); | 450 Variable var_smi_handler(this, MachineRepresentation::kTagged); |
451 Label if_smi_handler(this); | 451 Label if_smi_handler(this); |
452 HandleLoadICProtoHandlerCase(&p, handler, &var_holder, &var_smi_handler, | 452 HandleLoadICProtoHandlerCase(&p, handler, &var_holder, &var_smi_handler, |
453 &if_smi_handler, miss, | 453 &if_smi_handler, miss, |
454 throw_reference_error_if_nonexistent); | 454 throw_reference_error_if_nonexistent); |
455 Bind(&if_smi_handler); | 455 Bind(&if_smi_handler); |
456 HandleLoadICSmiHandlerCase(&p, var_holder.value(), var_smi_handler.value(), | 456 HandleLoadICSmiHandlerCase(&p, var_holder.value(), var_smi_handler.value(), |
457 miss, kOnlyProperties); | 457 miss, kOnlyProperties); |
458 } | 458 } |
459 | 459 |
460 void AccessorAssemblerImpl::HandleStoreICHandlerCase( | 460 void AccessorAssembler::HandleStoreICHandlerCase( |
461 const StoreICParameters* p, Node* handler, Label* miss, | 461 const StoreICParameters* p, Node* handler, Label* miss, |
462 ElementSupport support_elements) { | 462 ElementSupport support_elements) { |
463 Label if_smi_handler(this), if_nonsmi_handler(this); | 463 Label if_smi_handler(this), if_nonsmi_handler(this); |
464 Label if_proto_handler(this), if_element_handler(this), call_handler(this); | 464 Label if_proto_handler(this), if_element_handler(this), call_handler(this); |
465 | 465 |
466 Branch(TaggedIsSmi(handler), &if_smi_handler, &if_nonsmi_handler); | 466 Branch(TaggedIsSmi(handler), &if_smi_handler, &if_nonsmi_handler); |
467 | 467 |
468 // |handler| is a Smi, encoding what to do. See SmiHandler methods | 468 // |handler| is a Smi, encoding what to do. See SmiHandler methods |
469 // for the encoding format. | 469 // for the encoding format. |
470 Bind(&if_smi_handler); | 470 Bind(&if_smi_handler); |
(...skipping 26 matching lines...) Expand all Loading... |
497 | 497 |
498 // |handler| is a heap object. Must be code, call it. | 498 // |handler| is a heap object. Must be code, call it. |
499 Bind(&call_handler); | 499 Bind(&call_handler); |
500 { | 500 { |
501 StoreWithVectorDescriptor descriptor(isolate()); | 501 StoreWithVectorDescriptor descriptor(isolate()); |
502 TailCallStub(descriptor, handler, p->context, p->receiver, p->name, | 502 TailCallStub(descriptor, handler, p->context, p->receiver, p->name, |
503 p->value, p->slot, p->vector); | 503 p->value, p->slot, p->vector); |
504 } | 504 } |
505 } | 505 } |
506 | 506 |
507 void AccessorAssemblerImpl::HandleStoreICElementHandlerCase( | 507 void AccessorAssembler::HandleStoreICElementHandlerCase( |
508 const StoreICParameters* p, Node* handler, Label* miss) { | 508 const StoreICParameters* p, Node* handler, Label* miss) { |
509 Comment("HandleStoreICElementHandlerCase"); | 509 Comment("HandleStoreICElementHandlerCase"); |
510 Node* validity_cell = LoadObjectField(handler, Tuple2::kValue1Offset); | 510 Node* validity_cell = LoadObjectField(handler, Tuple2::kValue1Offset); |
511 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset); | 511 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset); |
512 GotoIf(WordNotEqual(cell_value, | 512 GotoIf(WordNotEqual(cell_value, |
513 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))), | 513 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))), |
514 miss); | 514 miss); |
515 | 515 |
516 Node* code_handler = LoadObjectField(handler, Tuple2::kValue2Offset); | 516 Node* code_handler = LoadObjectField(handler, Tuple2::kValue2Offset); |
517 CSA_ASSERT(this, IsCodeMap(LoadMap(code_handler))); | 517 CSA_ASSERT(this, IsCodeMap(LoadMap(code_handler))); |
518 | 518 |
519 StoreWithVectorDescriptor descriptor(isolate()); | 519 StoreWithVectorDescriptor descriptor(isolate()); |
520 TailCallStub(descriptor, code_handler, p->context, p->receiver, p->name, | 520 TailCallStub(descriptor, code_handler, p->context, p->receiver, p->name, |
521 p->value, p->slot, p->vector); | 521 p->value, p->slot, p->vector); |
522 } | 522 } |
523 | 523 |
524 void AccessorAssemblerImpl::HandleStoreICProtoHandler( | 524 void AccessorAssembler::HandleStoreICProtoHandler(const StoreICParameters* p, |
525 const StoreICParameters* p, Node* handler, Label* miss) { | 525 Node* handler, Label* miss) { |
526 // IC dispatchers rely on these assumptions to be held. | 526 // IC dispatchers rely on these assumptions to be held. |
527 STATIC_ASSERT(FixedArray::kLengthOffset == | 527 STATIC_ASSERT(FixedArray::kLengthOffset == |
528 StoreHandler::kTransitionCellOffset); | 528 StoreHandler::kTransitionCellOffset); |
529 DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kSmiHandlerIndex), | 529 DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kSmiHandlerIndex), |
530 StoreHandler::kSmiHandlerOffset); | 530 StoreHandler::kSmiHandlerOffset); |
531 DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kValidityCellIndex), | 531 DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kValidityCellIndex), |
532 StoreHandler::kValidityCellOffset); | 532 StoreHandler::kValidityCellOffset); |
533 | 533 |
534 // Both FixedArray and Tuple3 handlers have validity cell at the same offset. | 534 // Both FixedArray and Tuple3 handlers have validity cell at the same offset. |
535 Label validity_cell_check_done(this); | 535 Label validity_cell_check_done(this); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 Node* constant = | 606 Node* constant = |
607 LoadFixedArrayElement(descriptors, value_index_in_descriptor); | 607 LoadFixedArrayElement(descriptors, value_index_in_descriptor); |
608 GotoIf(WordNotEqual(p->value, constant), miss); | 608 GotoIf(WordNotEqual(p->value, constant), miss); |
609 | 609 |
610 StoreMap(p->receiver, transition); | 610 StoreMap(p->receiver, transition); |
611 Return(p->value); | 611 Return(p->value); |
612 } | 612 } |
613 } | 613 } |
614 } | 614 } |
615 | 615 |
616 void AccessorAssemblerImpl::HandleStoreICSmiHandlerCase(Node* handler_word, | 616 void AccessorAssembler::HandleStoreICSmiHandlerCase(Node* handler_word, |
617 Node* holder, | 617 Node* holder, Node* value, |
618 Node* value, | 618 Node* transition, |
619 Node* transition, | 619 Label* miss) { |
620 Label* miss) { | |
621 Comment(transition ? "transitioning field store" : "field store"); | 620 Comment(transition ? "transitioning field store" : "field store"); |
622 | 621 |
623 #ifdef DEBUG | 622 #ifdef DEBUG |
624 Node* handler_kind = DecodeWord<StoreHandler::KindBits>(handler_word); | 623 Node* handler_kind = DecodeWord<StoreHandler::KindBits>(handler_word); |
625 if (transition) { | 624 if (transition) { |
626 CSA_ASSERT( | 625 CSA_ASSERT( |
627 this, | 626 this, |
628 Word32Or( | 627 Word32Or( |
629 WordEqual(handler_kind, | 628 WordEqual(handler_kind, |
630 IntPtrConstant(StoreHandler::kTransitionToField)), | 629 IntPtrConstant(StoreHandler::kTransitionToField)), |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 } | 675 } |
677 | 676 |
678 Bind(&if_smi_field); | 677 Bind(&if_smi_field); |
679 { | 678 { |
680 Comment("store smi field"); | 679 Comment("store smi field"); |
681 HandleStoreFieldAndReturn(handler_word, holder, Representation::Smi(), | 680 HandleStoreFieldAndReturn(handler_word, holder, Representation::Smi(), |
682 value, transition, miss); | 681 value, transition, miss); |
683 } | 682 } |
684 } | 683 } |
685 | 684 |
686 void AccessorAssemblerImpl::HandleStoreFieldAndReturn( | 685 void AccessorAssembler::HandleStoreFieldAndReturn(Node* handler_word, |
687 Node* handler_word, Node* holder, Representation representation, | 686 Node* holder, |
688 Node* value, Node* transition, Label* miss) { | 687 Representation representation, |
| 688 Node* value, Node* transition, |
| 689 Label* miss) { |
689 bool transition_to_field = transition != nullptr; | 690 bool transition_to_field = transition != nullptr; |
690 Node* prepared_value = PrepareValueForStore( | 691 Node* prepared_value = PrepareValueForStore( |
691 handler_word, holder, representation, transition, value, miss); | 692 handler_word, holder, representation, transition, value, miss); |
692 | 693 |
693 Label if_inobject(this), if_out_of_object(this); | 694 Label if_inobject(this), if_out_of_object(this); |
694 Branch(IsSetWord<StoreHandler::IsInobjectBits>(handler_word), &if_inobject, | 695 Branch(IsSetWord<StoreHandler::IsInobjectBits>(handler_word), &if_inobject, |
695 &if_out_of_object); | 696 &if_out_of_object); |
696 | 697 |
697 Bind(&if_inobject); | 698 Bind(&if_inobject); |
698 { | 699 { |
(...skipping 21 matching lines...) Expand all Loading... |
720 | 721 |
721 StoreNamedField(handler_word, holder, false, representation, prepared_value, | 722 StoreNamedField(handler_word, holder, false, representation, prepared_value, |
722 transition_to_field); | 723 transition_to_field); |
723 if (transition_to_field) { | 724 if (transition_to_field) { |
724 StoreMap(holder, transition); | 725 StoreMap(holder, transition); |
725 } | 726 } |
726 Return(value); | 727 Return(value); |
727 } | 728 } |
728 } | 729 } |
729 | 730 |
730 Node* AccessorAssemblerImpl::PrepareValueForStore(Node* handler_word, | 731 Node* AccessorAssembler::PrepareValueForStore(Node* handler_word, Node* holder, |
731 Node* holder, | 732 Representation representation, |
732 Representation representation, | 733 Node* transition, Node* value, |
733 Node* transition, Node* value, | 734 Label* bailout) { |
734 Label* bailout) { | |
735 if (representation.IsDouble()) { | 735 if (representation.IsDouble()) { |
736 value = TryTaggedToFloat64(value, bailout); | 736 value = TryTaggedToFloat64(value, bailout); |
737 | 737 |
738 } else if (representation.IsHeapObject()) { | 738 } else if (representation.IsHeapObject()) { |
739 GotoIf(TaggedIsSmi(value), bailout); | 739 GotoIf(TaggedIsSmi(value), bailout); |
740 Node* value_index_in_descriptor = | 740 Node* value_index_in_descriptor = |
741 DecodeWord<StoreHandler::DescriptorValueIndexBits>(handler_word); | 741 DecodeWord<StoreHandler::DescriptorValueIndexBits>(handler_word); |
742 Node* descriptors = | 742 Node* descriptors = |
743 LoadMapDescriptors(transition ? transition : LoadMap(holder)); | 743 LoadMapDescriptors(transition ? transition : LoadMap(holder)); |
744 Node* maybe_field_type = | 744 Node* maybe_field_type = |
(...skipping 10 matching lines...) Expand all Loading... |
755 | 755 |
756 } else if (representation.IsSmi()) { | 756 } else if (representation.IsSmi()) { |
757 GotoUnless(TaggedIsSmi(value), bailout); | 757 GotoUnless(TaggedIsSmi(value), bailout); |
758 | 758 |
759 } else { | 759 } else { |
760 DCHECK(representation.IsTagged()); | 760 DCHECK(representation.IsTagged()); |
761 } | 761 } |
762 return value; | 762 return value; |
763 } | 763 } |
764 | 764 |
765 void AccessorAssemblerImpl::ExtendPropertiesBackingStore(Node* object) { | 765 void AccessorAssembler::ExtendPropertiesBackingStore(Node* object) { |
766 Node* properties = LoadProperties(object); | 766 Node* properties = LoadProperties(object); |
767 Node* length = LoadFixedArrayBaseLength(properties); | 767 Node* length = LoadFixedArrayBaseLength(properties); |
768 | 768 |
769 ParameterMode mode = OptimalParameterMode(); | 769 ParameterMode mode = OptimalParameterMode(); |
770 length = TaggedToParameter(length, mode); | 770 length = TaggedToParameter(length, mode); |
771 | 771 |
772 Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode); | 772 Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode); |
773 Node* new_capacity = IntPtrOrSmiAdd(length, delta, mode); | 773 Node* new_capacity = IntPtrOrSmiAdd(length, delta, mode); |
774 | 774 |
775 // Grow properties array. | 775 // Grow properties array. |
(...skipping 15 matching lines...) Expand all Loading... |
791 Heap::kUndefinedValueRootIndex, mode); | 791 Heap::kUndefinedValueRootIndex, mode); |
792 | 792 |
793 // |new_properties| is guaranteed to be in new space, so we can skip | 793 // |new_properties| is guaranteed to be in new space, so we can skip |
794 // the write barrier. | 794 // the write barrier. |
795 CopyFixedArrayElements(kind, properties, new_properties, length, | 795 CopyFixedArrayElements(kind, properties, new_properties, length, |
796 SKIP_WRITE_BARRIER, mode); | 796 SKIP_WRITE_BARRIER, mode); |
797 | 797 |
798 StoreObjectField(object, JSObject::kPropertiesOffset, new_properties); | 798 StoreObjectField(object, JSObject::kPropertiesOffset, new_properties); |
799 } | 799 } |
800 | 800 |
801 void AccessorAssemblerImpl::StoreNamedField(Node* handler_word, Node* object, | 801 void AccessorAssembler::StoreNamedField(Node* handler_word, Node* object, |
802 bool is_inobject, | 802 bool is_inobject, |
803 Representation representation, | 803 Representation representation, |
804 Node* value, | 804 Node* value, bool transition_to_field) { |
805 bool transition_to_field) { | |
806 bool store_value_as_double = representation.IsDouble(); | 805 bool store_value_as_double = representation.IsDouble(); |
807 Node* property_storage = object; | 806 Node* property_storage = object; |
808 if (!is_inobject) { | 807 if (!is_inobject) { |
809 property_storage = LoadProperties(object); | 808 property_storage = LoadProperties(object); |
810 } | 809 } |
811 | 810 |
812 Node* offset = DecodeWord<StoreHandler::FieldOffsetBits>(handler_word); | 811 Node* offset = DecodeWord<StoreHandler::FieldOffsetBits>(handler_word); |
813 if (representation.IsDouble()) { | 812 if (representation.IsDouble()) { |
814 if (!FLAG_unbox_double_fields || !is_inobject) { | 813 if (!FLAG_unbox_double_fields || !is_inobject) { |
815 if (transition_to_field) { | 814 if (transition_to_field) { |
(...skipping 13 matching lines...) Expand all Loading... |
829 if (store_value_as_double) { | 828 if (store_value_as_double) { |
830 StoreObjectFieldNoWriteBarrier(property_storage, offset, value, | 829 StoreObjectFieldNoWriteBarrier(property_storage, offset, value, |
831 MachineRepresentation::kFloat64); | 830 MachineRepresentation::kFloat64); |
832 } else if (representation.IsSmi()) { | 831 } else if (representation.IsSmi()) { |
833 StoreObjectFieldNoWriteBarrier(property_storage, offset, value); | 832 StoreObjectFieldNoWriteBarrier(property_storage, offset, value); |
834 } else { | 833 } else { |
835 StoreObjectField(property_storage, offset, value); | 834 StoreObjectField(property_storage, offset, value); |
836 } | 835 } |
837 } | 836 } |
838 | 837 |
839 void AccessorAssemblerImpl::EmitFastElementsBoundsCheck( | 838 void AccessorAssembler::EmitFastElementsBoundsCheck(Node* object, |
840 Node* object, Node* elements, Node* intptr_index, | 839 Node* elements, |
841 Node* is_jsarray_condition, Label* miss) { | 840 Node* intptr_index, |
| 841 Node* is_jsarray_condition, |
| 842 Label* miss) { |
842 Variable var_length(this, MachineType::PointerRepresentation()); | 843 Variable var_length(this, MachineType::PointerRepresentation()); |
843 Comment("Fast elements bounds check"); | 844 Comment("Fast elements bounds check"); |
844 Label if_array(this), length_loaded(this, &var_length); | 845 Label if_array(this), length_loaded(this, &var_length); |
845 GotoIf(is_jsarray_condition, &if_array); | 846 GotoIf(is_jsarray_condition, &if_array); |
846 { | 847 { |
847 var_length.Bind(SmiUntag(LoadFixedArrayBaseLength(elements))); | 848 var_length.Bind(SmiUntag(LoadFixedArrayBaseLength(elements))); |
848 Goto(&length_loaded); | 849 Goto(&length_loaded); |
849 } | 850 } |
850 Bind(&if_array); | 851 Bind(&if_array); |
851 { | 852 { |
852 var_length.Bind(SmiUntag(LoadJSArrayLength(object))); | 853 var_length.Bind(SmiUntag(LoadJSArrayLength(object))); |
853 Goto(&length_loaded); | 854 Goto(&length_loaded); |
854 } | 855 } |
855 Bind(&length_loaded); | 856 Bind(&length_loaded); |
856 GotoUnless(UintPtrLessThan(intptr_index, var_length.value()), miss); | 857 GotoUnless(UintPtrLessThan(intptr_index, var_length.value()), miss); |
857 } | 858 } |
858 | 859 |
859 void AccessorAssemblerImpl::EmitElementLoad( | 860 void AccessorAssembler::EmitElementLoad(Node* object, Node* elements, |
860 Node* object, Node* elements, Node* elements_kind, Node* intptr_index, | 861 Node* elements_kind, Node* intptr_index, |
861 Node* is_jsarray_condition, Label* if_hole, Label* rebox_double, | 862 Node* is_jsarray_condition, |
862 Variable* var_double_value, Label* unimplemented_elements_kind, | 863 Label* if_hole, Label* rebox_double, |
863 Label* out_of_bounds, Label* miss) { | 864 Variable* var_double_value, |
| 865 Label* unimplemented_elements_kind, |
| 866 Label* out_of_bounds, Label* miss) { |
864 Label if_typed_array(this), if_fast_packed(this), if_fast_holey(this), | 867 Label if_typed_array(this), if_fast_packed(this), if_fast_holey(this), |
865 if_fast_double(this), if_fast_holey_double(this), if_nonfast(this), | 868 if_fast_double(this), if_fast_holey_double(this), if_nonfast(this), |
866 if_dictionary(this); | 869 if_dictionary(this); |
867 GotoIf( | 870 GotoIf( |
868 Int32GreaterThan(elements_kind, Int32Constant(LAST_FAST_ELEMENTS_KIND)), | 871 Int32GreaterThan(elements_kind, Int32Constant(LAST_FAST_ELEMENTS_KIND)), |
869 &if_nonfast); | 872 &if_nonfast); |
870 | 873 |
871 EmitFastElementsBoundsCheck(object, elements, intptr_index, | 874 EmitFastElementsBoundsCheck(object, elements, intptr_index, |
872 is_jsarray_condition, out_of_bounds); | 875 is_jsarray_condition, out_of_bounds); |
873 int32_t kinds[] = {// Handled by if_fast_packed. | 876 int32_t kinds[] = {// Handled by if_fast_packed. |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1046 { | 1049 { |
1047 Comment("FLOAT64_ELEMENTS"); | 1050 Comment("FLOAT64_ELEMENTS"); |
1048 Node* index = WordShl(intptr_index, IntPtrConstant(3)); | 1051 Node* index = WordShl(intptr_index, IntPtrConstant(3)); |
1049 Node* element = Load(MachineType::Float64(), backing_store, index); | 1052 Node* element = Load(MachineType::Float64(), backing_store, index); |
1050 var_double_value->Bind(element); | 1053 var_double_value->Bind(element); |
1051 Goto(rebox_double); | 1054 Goto(rebox_double); |
1052 } | 1055 } |
1053 } | 1056 } |
1054 } | 1057 } |
1055 | 1058 |
1056 void AccessorAssemblerImpl::CheckPrototype(Node* prototype_cell, Node* name, | 1059 void AccessorAssembler::CheckPrototype(Node* prototype_cell, Node* name, |
1057 Label* miss) { | 1060 Label* miss) { |
1058 Node* maybe_prototype = LoadWeakCellValue(prototype_cell, miss); | 1061 Node* maybe_prototype = LoadWeakCellValue(prototype_cell, miss); |
1059 | 1062 |
1060 Label done(this); | 1063 Label done(this); |
1061 Label if_property_cell(this), if_dictionary_object(this); | 1064 Label if_property_cell(this), if_dictionary_object(this); |
1062 | 1065 |
1063 // |maybe_prototype| is either a PropertyCell or a slow-mode prototype. | 1066 // |maybe_prototype| is either a PropertyCell or a slow-mode prototype. |
1064 Branch(WordEqual(LoadMap(maybe_prototype), | 1067 Branch(WordEqual(LoadMap(maybe_prototype), |
1065 LoadRoot(Heap::kGlobalPropertyCellMapRootIndex)), | 1068 LoadRoot(Heap::kGlobalPropertyCellMapRootIndex)), |
1066 &if_property_cell, &if_dictionary_object); | 1069 &if_property_cell, &if_dictionary_object); |
1067 | 1070 |
1068 Bind(&if_dictionary_object); | 1071 Bind(&if_dictionary_object); |
1069 { | 1072 { |
1070 CSA_ASSERT(this, IsDictionaryMap(LoadMap(maybe_prototype))); | 1073 CSA_ASSERT(this, IsDictionaryMap(LoadMap(maybe_prototype))); |
1071 NameDictionaryNegativeLookup(maybe_prototype, name, miss); | 1074 NameDictionaryNegativeLookup(maybe_prototype, name, miss); |
1072 Goto(&done); | 1075 Goto(&done); |
1073 } | 1076 } |
1074 | 1077 |
1075 Bind(&if_property_cell); | 1078 Bind(&if_property_cell); |
1076 { | 1079 { |
1077 // Ensure the property cell still contains the hole. | 1080 // Ensure the property cell still contains the hole. |
1078 Node* value = LoadObjectField(maybe_prototype, PropertyCell::kValueOffset); | 1081 Node* value = LoadObjectField(maybe_prototype, PropertyCell::kValueOffset); |
1079 GotoIf(WordNotEqual(value, LoadRoot(Heap::kTheHoleValueRootIndex)), miss); | 1082 GotoIf(WordNotEqual(value, LoadRoot(Heap::kTheHoleValueRootIndex)), miss); |
1080 Goto(&done); | 1083 Goto(&done); |
1081 } | 1084 } |
1082 | 1085 |
1083 Bind(&done); | 1086 Bind(&done); |
1084 } | 1087 } |
1085 | 1088 |
1086 void AccessorAssemblerImpl::NameDictionaryNegativeLookup(Node* object, | 1089 void AccessorAssembler::NameDictionaryNegativeLookup(Node* object, Node* name, |
1087 Node* name, | 1090 Label* miss) { |
1088 Label* miss) { | |
1089 CSA_ASSERT(this, IsDictionaryMap(LoadMap(object))); | 1091 CSA_ASSERT(this, IsDictionaryMap(LoadMap(object))); |
1090 Node* properties = LoadProperties(object); | 1092 Node* properties = LoadProperties(object); |
1091 // Ensure the property does not exist in a dictionary-mode object. | 1093 // Ensure the property does not exist in a dictionary-mode object. |
1092 Variable var_name_index(this, MachineType::PointerRepresentation()); | 1094 Variable var_name_index(this, MachineType::PointerRepresentation()); |
1093 Label done(this); | 1095 Label done(this); |
1094 NameDictionaryLookup<NameDictionary>(properties, name, miss, &var_name_index, | 1096 NameDictionaryLookup<NameDictionary>(properties, name, miss, &var_name_index, |
1095 &done); | 1097 &done); |
1096 Bind(&done); | 1098 Bind(&done); |
1097 } | 1099 } |
1098 | 1100 |
1099 //////////////////// Stub cache access helpers. | 1101 //////////////////// Stub cache access helpers. |
1100 | 1102 |
1101 enum AccessorAssemblerImpl::StubCacheTable : int { | 1103 enum AccessorAssembler::StubCacheTable : int { |
1102 kPrimary = static_cast<int>(StubCache::kPrimary), | 1104 kPrimary = static_cast<int>(StubCache::kPrimary), |
1103 kSecondary = static_cast<int>(StubCache::kSecondary) | 1105 kSecondary = static_cast<int>(StubCache::kSecondary) |
1104 }; | 1106 }; |
1105 | 1107 |
1106 Node* AccessorAssemblerImpl::StubCachePrimaryOffset(Node* name, Node* map) { | 1108 Node* AccessorAssembler::StubCachePrimaryOffset(Node* name, Node* map) { |
1107 // See v8::internal::StubCache::PrimaryOffset(). | 1109 // See v8::internal::StubCache::PrimaryOffset(). |
1108 STATIC_ASSERT(StubCache::kCacheIndexShift == Name::kHashShift); | 1110 STATIC_ASSERT(StubCache::kCacheIndexShift == Name::kHashShift); |
1109 // Compute the hash of the name (use entire hash field). | 1111 // Compute the hash of the name (use entire hash field). |
1110 Node* hash_field = LoadNameHashField(name); | 1112 Node* hash_field = LoadNameHashField(name); |
1111 CSA_ASSERT(this, | 1113 CSA_ASSERT(this, |
1112 Word32Equal(Word32And(hash_field, | 1114 Word32Equal(Word32And(hash_field, |
1113 Int32Constant(Name::kHashNotComputedMask)), | 1115 Int32Constant(Name::kHashNotComputedMask)), |
1114 Int32Constant(0))); | 1116 Int32Constant(0))); |
1115 | 1117 |
1116 // Using only the low bits in 64-bit mode is unlikely to increase the | 1118 // Using only the low bits in 64-bit mode is unlikely to increase the |
1117 // risk of collision even if the heap is spread over an area larger than | 1119 // risk of collision even if the heap is spread over an area larger than |
1118 // 4Gb (and not at all if it isn't). | 1120 // 4Gb (and not at all if it isn't). |
1119 Node* map32 = TruncateWordToWord32(BitcastTaggedToWord(map)); | 1121 Node* map32 = TruncateWordToWord32(BitcastTaggedToWord(map)); |
1120 Node* hash = Int32Add(hash_field, map32); | 1122 Node* hash = Int32Add(hash_field, map32); |
1121 // Base the offset on a simple combination of name and map. | 1123 // Base the offset on a simple combination of name and map. |
1122 hash = Word32Xor(hash, Int32Constant(StubCache::kPrimaryMagic)); | 1124 hash = Word32Xor(hash, Int32Constant(StubCache::kPrimaryMagic)); |
1123 uint32_t mask = (StubCache::kPrimaryTableSize - 1) | 1125 uint32_t mask = (StubCache::kPrimaryTableSize - 1) |
1124 << StubCache::kCacheIndexShift; | 1126 << StubCache::kCacheIndexShift; |
1125 return ChangeUint32ToWord(Word32And(hash, Int32Constant(mask))); | 1127 return ChangeUint32ToWord(Word32And(hash, Int32Constant(mask))); |
1126 } | 1128 } |
1127 | 1129 |
1128 Node* AccessorAssemblerImpl::StubCacheSecondaryOffset(Node* name, Node* seed) { | 1130 Node* AccessorAssembler::StubCacheSecondaryOffset(Node* name, Node* seed) { |
1129 // See v8::internal::StubCache::SecondaryOffset(). | 1131 // See v8::internal::StubCache::SecondaryOffset(). |
1130 | 1132 |
1131 // Use the seed from the primary cache in the secondary cache. | 1133 // Use the seed from the primary cache in the secondary cache. |
1132 Node* name32 = TruncateWordToWord32(BitcastTaggedToWord(name)); | 1134 Node* name32 = TruncateWordToWord32(BitcastTaggedToWord(name)); |
1133 Node* hash = Int32Sub(TruncateWordToWord32(seed), name32); | 1135 Node* hash = Int32Sub(TruncateWordToWord32(seed), name32); |
1134 hash = Int32Add(hash, Int32Constant(StubCache::kSecondaryMagic)); | 1136 hash = Int32Add(hash, Int32Constant(StubCache::kSecondaryMagic)); |
1135 int32_t mask = (StubCache::kSecondaryTableSize - 1) | 1137 int32_t mask = (StubCache::kSecondaryTableSize - 1) |
1136 << StubCache::kCacheIndexShift; | 1138 << StubCache::kCacheIndexShift; |
1137 return ChangeUint32ToWord(Word32And(hash, Int32Constant(mask))); | 1139 return ChangeUint32ToWord(Word32And(hash, Int32Constant(mask))); |
1138 } | 1140 } |
1139 | 1141 |
1140 void AccessorAssemblerImpl::TryProbeStubCacheTable( | 1142 void AccessorAssembler::TryProbeStubCacheTable(StubCache* stub_cache, |
1141 StubCache* stub_cache, StubCacheTable table_id, Node* entry_offset, | 1143 StubCacheTable table_id, |
1142 Node* name, Node* map, Label* if_handler, Variable* var_handler, | 1144 Node* entry_offset, Node* name, |
1143 Label* if_miss) { | 1145 Node* map, Label* if_handler, |
| 1146 Variable* var_handler, |
| 1147 Label* if_miss) { |
1144 StubCache::Table table = static_cast<StubCache::Table>(table_id); | 1148 StubCache::Table table = static_cast<StubCache::Table>(table_id); |
1145 #ifdef DEBUG | 1149 #ifdef DEBUG |
1146 if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) { | 1150 if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) { |
1147 Goto(if_miss); | 1151 Goto(if_miss); |
1148 return; | 1152 return; |
1149 } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) { | 1153 } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) { |
1150 Goto(if_miss); | 1154 Goto(if_miss); |
1151 return; | 1155 return; |
1152 } | 1156 } |
1153 #endif | 1157 #endif |
(...skipping 19 matching lines...) Expand all Loading... |
1173 DCHECK_EQ(kPointerSize, stub_cache->value_reference(table).address() - | 1177 DCHECK_EQ(kPointerSize, stub_cache->value_reference(table).address() - |
1174 stub_cache->key_reference(table).address()); | 1178 stub_cache->key_reference(table).address()); |
1175 Node* handler = Load(MachineType::TaggedPointer(), key_base, | 1179 Node* handler = Load(MachineType::TaggedPointer(), key_base, |
1176 IntPtrAdd(entry_offset, IntPtrConstant(kPointerSize))); | 1180 IntPtrAdd(entry_offset, IntPtrConstant(kPointerSize))); |
1177 | 1181 |
1178 // We found the handler. | 1182 // We found the handler. |
1179 var_handler->Bind(handler); | 1183 var_handler->Bind(handler); |
1180 Goto(if_handler); | 1184 Goto(if_handler); |
1181 } | 1185 } |
1182 | 1186 |
1183 void AccessorAssemblerImpl::TryProbeStubCache(StubCache* stub_cache, | 1187 void AccessorAssembler::TryProbeStubCache(StubCache* stub_cache, Node* receiver, |
1184 Node* receiver, Node* name, | 1188 Node* name, Label* if_handler, |
1185 Label* if_handler, | 1189 Variable* var_handler, |
1186 Variable* var_handler, | 1190 Label* if_miss) { |
1187 Label* if_miss) { | |
1188 Label try_secondary(this), miss(this); | 1191 Label try_secondary(this), miss(this); |
1189 | 1192 |
1190 Counters* counters = isolate()->counters(); | 1193 Counters* counters = isolate()->counters(); |
1191 IncrementCounter(counters->megamorphic_stub_cache_probes(), 1); | 1194 IncrementCounter(counters->megamorphic_stub_cache_probes(), 1); |
1192 | 1195 |
1193 // Check that the {receiver} isn't a smi. | 1196 // Check that the {receiver} isn't a smi. |
1194 GotoIf(TaggedIsSmi(receiver), &miss); | 1197 GotoIf(TaggedIsSmi(receiver), &miss); |
1195 | 1198 |
1196 Node* receiver_map = LoadMap(receiver); | 1199 Node* receiver_map = LoadMap(receiver); |
1197 | 1200 |
(...skipping 12 matching lines...) Expand all Loading... |
1210 | 1213 |
1211 Bind(&miss); | 1214 Bind(&miss); |
1212 { | 1215 { |
1213 IncrementCounter(counters->megamorphic_stub_cache_misses(), 1); | 1216 IncrementCounter(counters->megamorphic_stub_cache_misses(), 1); |
1214 Goto(if_miss); | 1217 Goto(if_miss); |
1215 } | 1218 } |
1216 } | 1219 } |
1217 | 1220 |
1218 //////////////////// Entry points into private implementation (one per stub). | 1221 //////////////////// Entry points into private implementation (one per stub). |
1219 | 1222 |
1220 void AccessorAssemblerImpl::LoadIC(const LoadICParameters* p) { | 1223 void AccessorAssembler::LoadIC(const LoadICParameters* p) { |
1221 Variable var_handler(this, MachineRepresentation::kTagged); | 1224 Variable var_handler(this, MachineRepresentation::kTagged); |
1222 // TODO(ishell): defer blocks when it works. | 1225 // TODO(ishell): defer blocks when it works. |
1223 Label if_handler(this, &var_handler), try_polymorphic(this), | 1226 Label if_handler(this, &var_handler), try_polymorphic(this), |
1224 try_megamorphic(this /*, Label::kDeferred*/), | 1227 try_megamorphic(this /*, Label::kDeferred*/), |
1225 miss(this /*, Label::kDeferred*/); | 1228 miss(this /*, Label::kDeferred*/); |
1226 | 1229 |
1227 Node* receiver_map = LoadReceiverMap(p->receiver); | 1230 Node* receiver_map = LoadReceiverMap(p->receiver); |
1228 | 1231 |
1229 // Check monomorphic case. | 1232 // Check monomorphic case. |
1230 Node* feedback = | 1233 Node* feedback = |
(...skipping 22 matching lines...) Expand all Loading... |
1253 TryProbeStubCache(isolate()->load_stub_cache(), p->receiver, p->name, | 1256 TryProbeStubCache(isolate()->load_stub_cache(), p->receiver, p->name, |
1254 &if_handler, &var_handler, &miss); | 1257 &if_handler, &var_handler, &miss); |
1255 } | 1258 } |
1256 Bind(&miss); | 1259 Bind(&miss); |
1257 { | 1260 { |
1258 TailCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, p->name, | 1261 TailCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, p->name, |
1259 p->slot, p->vector); | 1262 p->slot, p->vector); |
1260 } | 1263 } |
1261 } | 1264 } |
1262 | 1265 |
1263 void AccessorAssemblerImpl::LoadICProtoArray( | 1266 void AccessorAssembler::LoadICProtoArray( |
1264 const LoadICParameters* p, Node* handler, | 1267 const LoadICParameters* p, Node* handler, |
1265 bool throw_reference_error_if_nonexistent) { | 1268 bool throw_reference_error_if_nonexistent) { |
1266 Label miss(this); | 1269 Label miss(this); |
1267 CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(handler))); | 1270 CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(handler))); |
1268 CSA_ASSERT(this, IsFixedArrayMap(LoadMap(handler))); | 1271 CSA_ASSERT(this, IsFixedArrayMap(LoadMap(handler))); |
1269 | 1272 |
1270 Node* smi_handler = LoadObjectField(handler, LoadHandler::kSmiHandlerOffset); | 1273 Node* smi_handler = LoadObjectField(handler, LoadHandler::kSmiHandlerOffset); |
1271 Node* handler_flags = SmiUntag(smi_handler); | 1274 Node* handler_flags = SmiUntag(smi_handler); |
1272 | 1275 |
1273 Node* handler_length = LoadAndUntagFixedArrayBaseLength(handler); | 1276 Node* handler_length = LoadAndUntagFixedArrayBaseLength(handler); |
1274 | 1277 |
1275 Node* holder = | 1278 Node* holder = |
1276 EmitLoadICProtoArrayCheck(p, handler, handler_length, handler_flags, | 1279 EmitLoadICProtoArrayCheck(p, handler, handler_length, handler_flags, |
1277 &miss, throw_reference_error_if_nonexistent); | 1280 &miss, throw_reference_error_if_nonexistent); |
1278 | 1281 |
1279 HandleLoadICSmiHandlerCase(p, holder, smi_handler, &miss, kOnlyProperties); | 1282 HandleLoadICSmiHandlerCase(p, holder, smi_handler, &miss, kOnlyProperties); |
1280 | 1283 |
1281 Bind(&miss); | 1284 Bind(&miss); |
1282 { | 1285 { |
1283 TailCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, p->name, | 1286 TailCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, p->name, |
1284 p->slot, p->vector); | 1287 p->slot, p->vector); |
1285 } | 1288 } |
1286 } | 1289 } |
1287 | 1290 |
1288 void AccessorAssemblerImpl::LoadGlobalIC(const LoadICParameters* p, | 1291 void AccessorAssembler::LoadGlobalIC(const LoadICParameters* p, |
1289 TypeofMode typeof_mode) { | 1292 TypeofMode typeof_mode) { |
1290 Label try_handler(this), call_handler(this), miss(this); | 1293 Label try_handler(this), call_handler(this), miss(this); |
1291 Node* weak_cell = | 1294 Node* weak_cell = |
1292 LoadFixedArrayElement(p->vector, p->slot, 0, SMI_PARAMETERS); | 1295 LoadFixedArrayElement(p->vector, p->slot, 0, SMI_PARAMETERS); |
1293 CSA_ASSERT(this, HasInstanceType(weak_cell, WEAK_CELL_TYPE)); | 1296 CSA_ASSERT(this, HasInstanceType(weak_cell, WEAK_CELL_TYPE)); |
1294 | 1297 |
1295 // Load value or try handler case if the {weak_cell} is cleared. | 1298 // Load value or try handler case if the {weak_cell} is cleared. |
1296 Node* property_cell = LoadWeakCellValue(weak_cell, &try_handler); | 1299 Node* property_cell = LoadWeakCellValue(weak_cell, &try_handler); |
1297 CSA_ASSERT(this, HasInstanceType(property_cell, PROPERTY_CELL_TYPE)); | 1300 CSA_ASSERT(this, HasInstanceType(property_cell, PROPERTY_CELL_TYPE)); |
1298 | 1301 |
1299 Node* value = LoadObjectField(property_cell, PropertyCell::kValueOffset); | 1302 Node* value = LoadObjectField(property_cell, PropertyCell::kValueOffset); |
(...skipping 25 matching lines...) Expand all Loading... |
1325 TailCallStub(descriptor, handler, p->context, receiver, p->name, p->slot, | 1328 TailCallStub(descriptor, handler, p->context, receiver, p->name, p->slot, |
1326 p->vector); | 1329 p->vector); |
1327 } | 1330 } |
1328 Bind(&miss); | 1331 Bind(&miss); |
1329 { | 1332 { |
1330 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->name, p->slot, | 1333 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->name, p->slot, |
1331 p->vector); | 1334 p->vector); |
1332 } | 1335 } |
1333 } | 1336 } |
1334 | 1337 |
1335 void AccessorAssemblerImpl::KeyedLoadIC(const LoadICParameters* p) { | 1338 void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p) { |
1336 Variable var_handler(this, MachineRepresentation::kTagged); | 1339 Variable var_handler(this, MachineRepresentation::kTagged); |
1337 // TODO(ishell): defer blocks when it works. | 1340 // TODO(ishell): defer blocks when it works. |
1338 Label if_handler(this, &var_handler), try_polymorphic(this), | 1341 Label if_handler(this, &var_handler), try_polymorphic(this), |
1339 try_megamorphic(this /*, Label::kDeferred*/), | 1342 try_megamorphic(this /*, Label::kDeferred*/), |
1340 try_polymorphic_name(this /*, Label::kDeferred*/), | 1343 try_polymorphic_name(this /*, Label::kDeferred*/), |
1341 miss(this /*, Label::kDeferred*/); | 1344 miss(this /*, Label::kDeferred*/); |
1342 | 1345 |
1343 Node* receiver_map = LoadReceiverMap(p->receiver); | 1346 Node* receiver_map = LoadReceiverMap(p->receiver); |
1344 | 1347 |
1345 // Check monomorphic case. | 1348 // Check monomorphic case. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1385 1); | 1388 1); |
1386 } | 1389 } |
1387 Bind(&miss); | 1390 Bind(&miss); |
1388 { | 1391 { |
1389 Comment("KeyedLoadIC_miss"); | 1392 Comment("KeyedLoadIC_miss"); |
1390 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver, | 1393 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver, |
1391 p->name, p->slot, p->vector); | 1394 p->name, p->slot, p->vector); |
1392 } | 1395 } |
1393 } | 1396 } |
1394 | 1397 |
1395 void AccessorAssemblerImpl::KeyedLoadICGeneric(const LoadICParameters* p) { | 1398 void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { |
1396 Variable var_index(this, MachineType::PointerRepresentation()); | 1399 Variable var_index(this, MachineType::PointerRepresentation()); |
1397 Variable var_unique(this, MachineRepresentation::kTagged); | 1400 Variable var_unique(this, MachineRepresentation::kTagged); |
1398 var_unique.Bind(p->name); // Dummy initialization. | 1401 var_unique.Bind(p->name); // Dummy initialization. |
1399 Variable var_details(this, MachineRepresentation::kWord32); | 1402 Variable var_details(this, MachineRepresentation::kWord32); |
1400 Variable var_value(this, MachineRepresentation::kTagged); | 1403 Variable var_value(this, MachineRepresentation::kTagged); |
1401 Label if_index(this), if_unique_name(this), if_element_hole(this), | 1404 Label if_index(this), if_unique_name(this), if_element_hole(this), |
1402 if_oob(this), slow(this), stub_cache_miss(this), | 1405 if_oob(this), slow(this), stub_cache_miss(this), |
1403 if_property_dictionary(this), if_found_on_receiver(this); | 1406 if_property_dictionary(this), if_found_on_receiver(this); |
1404 | 1407 |
1405 Node* receiver = p->receiver; | 1408 Node* receiver = p->receiver; |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1545 Bind(&slow); | 1548 Bind(&slow); |
1546 { | 1549 { |
1547 Comment("KeyedLoadGeneric_slow"); | 1550 Comment("KeyedLoadGeneric_slow"); |
1548 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_slow(), 1); | 1551 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_slow(), 1); |
1549 // TODO(jkummerow): Should we use the GetProperty TF stub instead? | 1552 // TODO(jkummerow): Should we use the GetProperty TF stub instead? |
1550 TailCallRuntime(Runtime::kKeyedGetProperty, p->context, p->receiver, | 1553 TailCallRuntime(Runtime::kKeyedGetProperty, p->context, p->receiver, |
1551 p->name); | 1554 p->name); |
1552 } | 1555 } |
1553 } | 1556 } |
1554 | 1557 |
1555 void AccessorAssemblerImpl::StoreIC(const StoreICParameters* p) { | 1558 void AccessorAssembler::StoreIC(const StoreICParameters* p) { |
1556 Variable var_handler(this, MachineRepresentation::kTagged); | 1559 Variable var_handler(this, MachineRepresentation::kTagged); |
1557 // TODO(ishell): defer blocks when it works. | 1560 // TODO(ishell): defer blocks when it works. |
1558 Label if_handler(this, &var_handler), try_polymorphic(this), | 1561 Label if_handler(this, &var_handler), try_polymorphic(this), |
1559 try_megamorphic(this /*, Label::kDeferred*/), | 1562 try_megamorphic(this /*, Label::kDeferred*/), |
1560 miss(this /*, Label::kDeferred*/); | 1563 miss(this /*, Label::kDeferred*/); |
1561 | 1564 |
1562 Node* receiver_map = LoadReceiverMap(p->receiver); | 1565 Node* receiver_map = LoadReceiverMap(p->receiver); |
1563 | 1566 |
1564 // Check monomorphic case. | 1567 // Check monomorphic case. |
1565 Node* feedback = | 1568 Node* feedback = |
(...skipping 26 matching lines...) Expand all Loading... |
1592 TryProbeStubCache(isolate()->store_stub_cache(), p->receiver, p->name, | 1595 TryProbeStubCache(isolate()->store_stub_cache(), p->receiver, p->name, |
1593 &if_handler, &var_handler, &miss); | 1596 &if_handler, &var_handler, &miss); |
1594 } | 1597 } |
1595 Bind(&miss); | 1598 Bind(&miss); |
1596 { | 1599 { |
1597 TailCallRuntime(Runtime::kStoreIC_Miss, p->context, p->value, p->slot, | 1600 TailCallRuntime(Runtime::kStoreIC_Miss, p->context, p->value, p->slot, |
1598 p->vector, p->receiver, p->name); | 1601 p->vector, p->receiver, p->name); |
1599 } | 1602 } |
1600 } | 1603 } |
1601 | 1604 |
1602 void AccessorAssemblerImpl::KeyedStoreIC(const StoreICParameters* p, | 1605 void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p, |
1603 LanguageMode language_mode) { | 1606 LanguageMode language_mode) { |
1604 // TODO(ishell): defer blocks when it works. | 1607 // TODO(ishell): defer blocks when it works. |
1605 Label miss(this /*, Label::kDeferred*/); | 1608 Label miss(this /*, Label::kDeferred*/); |
1606 { | 1609 { |
1607 Variable var_handler(this, MachineRepresentation::kTagged); | 1610 Variable var_handler(this, MachineRepresentation::kTagged); |
1608 | 1611 |
1609 // TODO(ishell): defer blocks when it works. | 1612 // TODO(ishell): defer blocks when it works. |
1610 Label if_handler(this, &var_handler), try_polymorphic(this), | 1613 Label if_handler(this, &var_handler), try_polymorphic(this), |
1611 try_megamorphic(this /*, Label::kDeferred*/), | 1614 try_megamorphic(this /*, Label::kDeferred*/), |
1612 try_polymorphic_name(this /*, Label::kDeferred*/); | 1615 try_polymorphic_name(this /*, Label::kDeferred*/); |
1613 | 1616 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1703 Bind(&miss); | 1706 Bind(&miss); |
1704 { | 1707 { |
1705 Comment("KeyedStoreIC_miss"); | 1708 Comment("KeyedStoreIC_miss"); |
1706 TailCallRuntime(Runtime::kKeyedStoreIC_Miss, p->context, p->value, p->slot, | 1709 TailCallRuntime(Runtime::kKeyedStoreIC_Miss, p->context, p->value, p->slot, |
1707 p->vector, p->receiver, p->name); | 1710 p->vector, p->receiver, p->name); |
1708 } | 1711 } |
1709 } | 1712 } |
1710 | 1713 |
1711 //////////////////// Public methods. | 1714 //////////////////// Public methods. |
1712 | 1715 |
1713 void AccessorAssemblerImpl::GenerateLoadIC() { | 1716 void AccessorAssembler::GenerateLoadIC() { |
1714 typedef LoadWithVectorDescriptor Descriptor; | 1717 typedef LoadWithVectorDescriptor Descriptor; |
1715 | 1718 |
1716 Node* receiver = Parameter(Descriptor::kReceiver); | 1719 Node* receiver = Parameter(Descriptor::kReceiver); |
1717 Node* name = Parameter(Descriptor::kName); | 1720 Node* name = Parameter(Descriptor::kName); |
1718 Node* slot = Parameter(Descriptor::kSlot); | 1721 Node* slot = Parameter(Descriptor::kSlot); |
1719 Node* vector = Parameter(Descriptor::kVector); | 1722 Node* vector = Parameter(Descriptor::kVector); |
1720 Node* context = Parameter(Descriptor::kContext); | 1723 Node* context = Parameter(Descriptor::kContext); |
1721 | 1724 |
1722 LoadICParameters p(context, receiver, name, slot, vector); | 1725 LoadICParameters p(context, receiver, name, slot, vector); |
1723 LoadIC(&p); | 1726 LoadIC(&p); |
1724 } | 1727 } |
1725 | 1728 |
1726 void AccessorAssemblerImpl::GenerateLoadICTrampoline() { | 1729 void AccessorAssembler::GenerateLoadICTrampoline() { |
1727 typedef LoadDescriptor Descriptor; | 1730 typedef LoadDescriptor Descriptor; |
1728 | 1731 |
1729 Node* receiver = Parameter(Descriptor::kReceiver); | 1732 Node* receiver = Parameter(Descriptor::kReceiver); |
1730 Node* name = Parameter(Descriptor::kName); | 1733 Node* name = Parameter(Descriptor::kName); |
1731 Node* slot = Parameter(Descriptor::kSlot); | 1734 Node* slot = Parameter(Descriptor::kSlot); |
1732 Node* context = Parameter(Descriptor::kContext); | 1735 Node* context = Parameter(Descriptor::kContext); |
1733 Node* vector = LoadTypeFeedbackVectorForStub(); | 1736 Node* vector = LoadTypeFeedbackVectorForStub(); |
1734 | 1737 |
1735 LoadICParameters p(context, receiver, name, slot, vector); | 1738 LoadICParameters p(context, receiver, name, slot, vector); |
1736 LoadIC(&p); | 1739 LoadIC(&p); |
1737 } | 1740 } |
1738 | 1741 |
1739 void AccessorAssemblerImpl::GenerateLoadICProtoArray( | 1742 void AccessorAssembler::GenerateLoadICProtoArray( |
1740 bool throw_reference_error_if_nonexistent) { | 1743 bool throw_reference_error_if_nonexistent) { |
1741 typedef LoadICProtoArrayStub::Descriptor Descriptor; | 1744 typedef LoadICProtoArrayDescriptor Descriptor; |
1742 | 1745 |
1743 Node* receiver = Parameter(Descriptor::kReceiver); | 1746 Node* receiver = Parameter(Descriptor::kReceiver); |
1744 Node* name = Parameter(Descriptor::kName); | 1747 Node* name = Parameter(Descriptor::kName); |
1745 Node* slot = Parameter(Descriptor::kSlot); | 1748 Node* slot = Parameter(Descriptor::kSlot); |
1746 Node* vector = Parameter(Descriptor::kVector); | 1749 Node* vector = Parameter(Descriptor::kVector); |
1747 Node* handler = Parameter(Descriptor::kHandler); | 1750 Node* handler = Parameter(Descriptor::kHandler); |
1748 Node* context = Parameter(Descriptor::kContext); | 1751 Node* context = Parameter(Descriptor::kContext); |
1749 | 1752 |
1750 LoadICParameters p(context, receiver, name, slot, vector); | 1753 LoadICParameters p(context, receiver, name, slot, vector); |
1751 LoadICProtoArray(&p, handler, throw_reference_error_if_nonexistent); | 1754 LoadICProtoArray(&p, handler, throw_reference_error_if_nonexistent); |
1752 } | 1755 } |
1753 | 1756 |
1754 void AccessorAssemblerImpl::GenerateLoadField() { | 1757 void AccessorAssembler::GenerateLoadField() { |
1755 typedef LoadFieldStub::Descriptor Descriptor; | 1758 typedef LoadFieldDescriptor Descriptor; |
1756 | 1759 |
1757 Node* receiver = Parameter(Descriptor::kReceiver); | 1760 Node* receiver = Parameter(Descriptor::kReceiver); |
1758 Node* name = nullptr; | 1761 Node* name = nullptr; |
1759 Node* slot = nullptr; | 1762 Node* slot = nullptr; |
1760 Node* vector = nullptr; | 1763 Node* vector = nullptr; |
1761 Node* context = Parameter(Descriptor::kContext); | 1764 Node* context = Parameter(Descriptor::kContext); |
1762 LoadICParameters p(context, receiver, name, slot, vector); | 1765 LoadICParameters p(context, receiver, name, slot, vector); |
1763 | 1766 |
1764 HandleLoadICSmiHandlerCase(&p, receiver, Parameter(Descriptor::kSmiHandler), | 1767 HandleLoadICSmiHandlerCase(&p, receiver, Parameter(Descriptor::kSmiHandler), |
1765 nullptr, kOnlyProperties); | 1768 nullptr, kOnlyProperties); |
1766 } | 1769 } |
1767 | 1770 |
1768 void AccessorAssemblerImpl::GenerateLoadGlobalIC(TypeofMode typeof_mode) { | 1771 void AccessorAssembler::GenerateLoadGlobalIC(TypeofMode typeof_mode) { |
1769 typedef LoadGlobalWithVectorDescriptor Descriptor; | 1772 typedef LoadGlobalWithVectorDescriptor Descriptor; |
1770 | 1773 |
1771 Node* name = Parameter(Descriptor::kName); | 1774 Node* name = Parameter(Descriptor::kName); |
1772 Node* slot = Parameter(Descriptor::kSlot); | 1775 Node* slot = Parameter(Descriptor::kSlot); |
1773 Node* vector = Parameter(Descriptor::kVector); | 1776 Node* vector = Parameter(Descriptor::kVector); |
1774 Node* context = Parameter(Descriptor::kContext); | 1777 Node* context = Parameter(Descriptor::kContext); |
1775 | 1778 |
1776 LoadICParameters p(context, nullptr, name, slot, vector); | 1779 LoadICParameters p(context, nullptr, name, slot, vector); |
1777 LoadGlobalIC(&p, typeof_mode); | 1780 LoadGlobalIC(&p, typeof_mode); |
1778 } | 1781 } |
1779 | 1782 |
1780 void AccessorAssemblerImpl::GenerateLoadGlobalICTrampoline( | 1783 void AccessorAssembler::GenerateLoadGlobalICTrampoline(TypeofMode typeof_mode) { |
1781 TypeofMode typeof_mode) { | |
1782 typedef LoadGlobalDescriptor Descriptor; | 1784 typedef LoadGlobalDescriptor Descriptor; |
1783 | 1785 |
1784 Node* name = Parameter(Descriptor::kName); | 1786 Node* name = Parameter(Descriptor::kName); |
1785 Node* slot = Parameter(Descriptor::kSlot); | 1787 Node* slot = Parameter(Descriptor::kSlot); |
1786 Node* context = Parameter(Descriptor::kContext); | 1788 Node* context = Parameter(Descriptor::kContext); |
1787 Node* vector = LoadTypeFeedbackVectorForStub(); | 1789 Node* vector = LoadTypeFeedbackVectorForStub(); |
1788 | 1790 |
1789 LoadICParameters p(context, nullptr, name, slot, vector); | 1791 LoadICParameters p(context, nullptr, name, slot, vector); |
1790 LoadGlobalIC(&p, typeof_mode); | 1792 LoadGlobalIC(&p, typeof_mode); |
1791 } | 1793 } |
1792 | 1794 |
1793 void AccessorAssemblerImpl::GenerateKeyedLoadICTF() { | 1795 void AccessorAssembler::GenerateKeyedLoadIC() { |
1794 typedef LoadWithVectorDescriptor Descriptor; | 1796 typedef LoadWithVectorDescriptor Descriptor; |
1795 | 1797 |
1796 Node* receiver = Parameter(Descriptor::kReceiver); | 1798 Node* receiver = Parameter(Descriptor::kReceiver); |
1797 Node* name = Parameter(Descriptor::kName); | 1799 Node* name = Parameter(Descriptor::kName); |
1798 Node* slot = Parameter(Descriptor::kSlot); | 1800 Node* slot = Parameter(Descriptor::kSlot); |
1799 Node* vector = Parameter(Descriptor::kVector); | 1801 Node* vector = Parameter(Descriptor::kVector); |
1800 Node* context = Parameter(Descriptor::kContext); | 1802 Node* context = Parameter(Descriptor::kContext); |
1801 | 1803 |
1802 LoadICParameters p(context, receiver, name, slot, vector); | 1804 LoadICParameters p(context, receiver, name, slot, vector); |
1803 KeyedLoadIC(&p); | 1805 KeyedLoadIC(&p); |
1804 } | 1806 } |
1805 | 1807 |
1806 void AccessorAssemblerImpl::GenerateKeyedLoadICTrampolineTF() { | 1808 void AccessorAssembler::GenerateKeyedLoadICTrampoline() { |
1807 typedef LoadDescriptor Descriptor; | 1809 typedef LoadDescriptor Descriptor; |
1808 | 1810 |
1809 Node* receiver = Parameter(Descriptor::kReceiver); | 1811 Node* receiver = Parameter(Descriptor::kReceiver); |
1810 Node* name = Parameter(Descriptor::kName); | 1812 Node* name = Parameter(Descriptor::kName); |
1811 Node* slot = Parameter(Descriptor::kSlot); | 1813 Node* slot = Parameter(Descriptor::kSlot); |
1812 Node* context = Parameter(Descriptor::kContext); | 1814 Node* context = Parameter(Descriptor::kContext); |
1813 Node* vector = LoadTypeFeedbackVectorForStub(); | 1815 Node* vector = LoadTypeFeedbackVectorForStub(); |
1814 | 1816 |
1815 LoadICParameters p(context, receiver, name, slot, vector); | 1817 LoadICParameters p(context, receiver, name, slot, vector); |
1816 KeyedLoadIC(&p); | 1818 KeyedLoadIC(&p); |
1817 } | 1819 } |
1818 | 1820 |
1819 void AccessorAssemblerImpl::GenerateKeyedLoadICMegamorphic() { | 1821 void AccessorAssembler::GenerateKeyedLoadIC_Megamorphic() { |
1820 typedef LoadWithVectorDescriptor Descriptor; | 1822 typedef LoadWithVectorDescriptor Descriptor; |
1821 | 1823 |
1822 Node* receiver = Parameter(Descriptor::kReceiver); | 1824 Node* receiver = Parameter(Descriptor::kReceiver); |
1823 Node* name = Parameter(Descriptor::kName); | 1825 Node* name = Parameter(Descriptor::kName); |
1824 Node* slot = Parameter(Descriptor::kSlot); | 1826 Node* slot = Parameter(Descriptor::kSlot); |
1825 Node* vector = Parameter(Descriptor::kVector); | 1827 Node* vector = Parameter(Descriptor::kVector); |
1826 Node* context = Parameter(Descriptor::kContext); | 1828 Node* context = Parameter(Descriptor::kContext); |
1827 | 1829 |
1828 LoadICParameters p(context, receiver, name, slot, vector); | 1830 LoadICParameters p(context, receiver, name, slot, vector); |
1829 KeyedLoadICGeneric(&p); | 1831 KeyedLoadICGeneric(&p); |
1830 } | 1832 } |
1831 | 1833 |
1832 void AccessorAssemblerImpl::GenerateStoreIC() { | 1834 void AccessorAssembler::GenerateStoreIC() { |
1833 typedef StoreWithVectorDescriptor Descriptor; | 1835 typedef StoreWithVectorDescriptor Descriptor; |
1834 | 1836 |
1835 Node* receiver = Parameter(Descriptor::kReceiver); | 1837 Node* receiver = Parameter(Descriptor::kReceiver); |
1836 Node* name = Parameter(Descriptor::kName); | 1838 Node* name = Parameter(Descriptor::kName); |
1837 Node* value = Parameter(Descriptor::kValue); | 1839 Node* value = Parameter(Descriptor::kValue); |
1838 Node* slot = Parameter(Descriptor::kSlot); | 1840 Node* slot = Parameter(Descriptor::kSlot); |
1839 Node* vector = Parameter(Descriptor::kVector); | 1841 Node* vector = Parameter(Descriptor::kVector); |
1840 Node* context = Parameter(Descriptor::kContext); | 1842 Node* context = Parameter(Descriptor::kContext); |
1841 | 1843 |
1842 StoreICParameters p(context, receiver, name, value, slot, vector); | 1844 StoreICParameters p(context, receiver, name, value, slot, vector); |
1843 StoreIC(&p); | 1845 StoreIC(&p); |
1844 } | 1846 } |
1845 | 1847 |
1846 void AccessorAssemblerImpl::GenerateStoreICTrampoline() { | 1848 void AccessorAssembler::GenerateStoreICTrampoline() { |
1847 typedef StoreDescriptor Descriptor; | 1849 typedef StoreDescriptor Descriptor; |
1848 | 1850 |
1849 Node* receiver = Parameter(Descriptor::kReceiver); | 1851 Node* receiver = Parameter(Descriptor::kReceiver); |
1850 Node* name = Parameter(Descriptor::kName); | 1852 Node* name = Parameter(Descriptor::kName); |
1851 Node* value = Parameter(Descriptor::kValue); | 1853 Node* value = Parameter(Descriptor::kValue); |
1852 Node* slot = Parameter(Descriptor::kSlot); | 1854 Node* slot = Parameter(Descriptor::kSlot); |
1853 Node* context = Parameter(Descriptor::kContext); | 1855 Node* context = Parameter(Descriptor::kContext); |
1854 Node* vector = LoadTypeFeedbackVectorForStub(); | 1856 Node* vector = LoadTypeFeedbackVectorForStub(); |
1855 | 1857 |
1856 StoreICParameters p(context, receiver, name, value, slot, vector); | 1858 StoreICParameters p(context, receiver, name, value, slot, vector); |
1857 StoreIC(&p); | 1859 StoreIC(&p); |
1858 } | 1860 } |
1859 | 1861 |
1860 void AccessorAssemblerImpl::GenerateKeyedStoreICTF(LanguageMode language_mode) { | 1862 void AccessorAssembler::GenerateKeyedStoreIC(LanguageMode language_mode) { |
1861 typedef StoreWithVectorDescriptor Descriptor; | 1863 typedef StoreWithVectorDescriptor Descriptor; |
1862 | 1864 |
1863 Node* receiver = Parameter(Descriptor::kReceiver); | 1865 Node* receiver = Parameter(Descriptor::kReceiver); |
1864 Node* name = Parameter(Descriptor::kName); | 1866 Node* name = Parameter(Descriptor::kName); |
1865 Node* value = Parameter(Descriptor::kValue); | 1867 Node* value = Parameter(Descriptor::kValue); |
1866 Node* slot = Parameter(Descriptor::kSlot); | 1868 Node* slot = Parameter(Descriptor::kSlot); |
1867 Node* vector = Parameter(Descriptor::kVector); | 1869 Node* vector = Parameter(Descriptor::kVector); |
1868 Node* context = Parameter(Descriptor::kContext); | 1870 Node* context = Parameter(Descriptor::kContext); |
1869 | 1871 |
1870 StoreICParameters p(context, receiver, name, value, slot, vector); | 1872 StoreICParameters p(context, receiver, name, value, slot, vector); |
1871 KeyedStoreIC(&p, language_mode); | 1873 KeyedStoreIC(&p, language_mode); |
1872 } | 1874 } |
1873 | 1875 |
1874 void AccessorAssemblerImpl::GenerateKeyedStoreICTrampolineTF( | 1876 void AccessorAssembler::GenerateKeyedStoreICTrampoline( |
1875 LanguageMode language_mode) { | 1877 LanguageMode language_mode) { |
1876 typedef StoreDescriptor Descriptor; | 1878 typedef StoreDescriptor Descriptor; |
1877 | 1879 |
1878 Node* receiver = Parameter(Descriptor::kReceiver); | 1880 Node* receiver = Parameter(Descriptor::kReceiver); |
1879 Node* name = Parameter(Descriptor::kName); | 1881 Node* name = Parameter(Descriptor::kName); |
1880 Node* value = Parameter(Descriptor::kValue); | 1882 Node* value = Parameter(Descriptor::kValue); |
1881 Node* slot = Parameter(Descriptor::kSlot); | 1883 Node* slot = Parameter(Descriptor::kSlot); |
1882 Node* context = Parameter(Descriptor::kContext); | 1884 Node* context = Parameter(Descriptor::kContext); |
1883 Node* vector = LoadTypeFeedbackVectorForStub(); | 1885 Node* vector = LoadTypeFeedbackVectorForStub(); |
1884 | 1886 |
1885 StoreICParameters p(context, receiver, name, value, slot, vector); | 1887 StoreICParameters p(context, receiver, name, value, slot, vector); |
1886 KeyedStoreIC(&p, language_mode); | 1888 KeyedStoreIC(&p, language_mode); |
1887 } | 1889 } |
1888 | 1890 |
1889 //////////////////// AccessorAssembler implementation. | |
1890 | |
1891 #define DISPATCH_TO_IMPL(Name) \ | |
1892 void AccessorAssembler::Generate##Name(CodeAssemblerState* state) { \ | |
1893 AccessorAssemblerImpl assembler(state); \ | |
1894 assembler.Generate##Name(); \ | |
1895 } | |
1896 | |
1897 ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE(DISPATCH_TO_IMPL) | |
1898 #undef DISPATCH_TO_IMPL | |
1899 | |
1900 void AccessorAssembler::GenerateLoadICProtoArray( | |
1901 CodeAssemblerState* state, bool throw_reference_error_if_nonexistent) { | |
1902 AccessorAssemblerImpl assembler(state); | |
1903 assembler.GenerateLoadICProtoArray(throw_reference_error_if_nonexistent); | |
1904 } | |
1905 | |
1906 void AccessorAssembler::GenerateLoadGlobalIC(CodeAssemblerState* state, | |
1907 TypeofMode typeof_mode) { | |
1908 AccessorAssemblerImpl assembler(state); | |
1909 assembler.GenerateLoadGlobalIC(typeof_mode); | |
1910 } | |
1911 | |
1912 void AccessorAssembler::GenerateLoadGlobalICTrampoline( | |
1913 CodeAssemblerState* state, TypeofMode typeof_mode) { | |
1914 AccessorAssemblerImpl assembler(state); | |
1915 assembler.GenerateLoadGlobalICTrampoline(typeof_mode); | |
1916 } | |
1917 | |
1918 void AccessorAssembler::GenerateKeyedStoreICTF(CodeAssemblerState* state, | |
1919 LanguageMode language_mode) { | |
1920 AccessorAssemblerImpl assembler(state); | |
1921 assembler.GenerateKeyedStoreICTF(language_mode); | |
1922 } | |
1923 | |
1924 void AccessorAssembler::GenerateKeyedStoreICTrampolineTF( | |
1925 CodeAssemblerState* state, LanguageMode language_mode) { | |
1926 AccessorAssemblerImpl assembler(state); | |
1927 assembler.GenerateKeyedStoreICTrampolineTF(language_mode); | |
1928 } | |
1929 | |
1930 #undef ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE | |
1931 | |
1932 } // namespace internal | 1891 } // namespace internal |
1933 } // namespace v8 | 1892 } // namespace v8 |
OLD | NEW |