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

Side by Side Diff: src/ic/accessor-assembler.cc

Issue 2647493002: [ic] Clean up handler boilerplate (Closed)
Patch Set: drop dead runtime function Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698