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

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

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

Powered by Google App Engine
This is Rietveld 408576698