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