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

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

Issue 2733563002: [ic] Inline LoadIC into LdaNamedProperty bytecode handler (Closed)
Patch Set: Remove LoadFeedbackSlot Created 3 years, 9 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/interpreter/interpreter.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 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/counters.h" 9 #include "src/counters.h"
10 #include "src/ic/handler-configuration.h" 10 #include "src/ic/handler-configuration.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 } 54 }
55 55
56 void AccessorAssembler::HandlePolymorphicCase(Node* receiver_map, 56 void AccessorAssembler::HandlePolymorphicCase(Node* receiver_map,
57 Node* feedback, Label* if_handler, 57 Node* feedback, Label* if_handler,
58 Variable* var_handler, 58 Variable* var_handler,
59 Label* if_miss, 59 Label* if_miss,
60 int unroll_count) { 60 int unroll_count) {
61 Comment("HandlePolymorphicCase"); 61 Comment("HandlePolymorphicCase");
62 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); 62 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep());
63 63
64 // Deferred so the unrolled case can omit frame construction in bytecode
65 // handler.
66 Label loop(this, Label::kDeferred);
67
64 // Iterate {feedback} array. 68 // Iterate {feedback} array.
65 const int kEntrySize = 2; 69 const int kEntrySize = 2;
66 70
67 for (int i = 0; i < unroll_count; i++) { 71 for (int i = 0; i < unroll_count; i++) {
68 Label next_entry(this); 72 Label next_entry(this);
69 Node* cached_map = 73 Node* cached_map =
70 LoadWeakCellValue(LoadFixedArrayElement(feedback, i * kEntrySize)); 74 LoadWeakCellValue(LoadFixedArrayElement(feedback, i * kEntrySize));
71 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); 75 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry);
72 76
73 // Found, now call handler. 77 // Found, now call handler.
74 Node* handler = LoadFixedArrayElement(feedback, i * kEntrySize + 1); 78 Node* handler = LoadFixedArrayElement(feedback, i * kEntrySize + 1);
75 var_handler->Bind(handler); 79 var_handler->Bind(handler);
76 Goto(if_handler); 80 Goto(if_handler);
77 81
78 Bind(&next_entry); 82 Bind(&next_entry);
79 } 83 }
84 Goto(&loop);
80 85
81 // Loop from {unroll_count}*kEntrySize to {length}. 86 // Loop from {unroll_count}*kEntrySize to {length}.
87 Bind(&loop);
82 Node* init = IntPtrConstant(unroll_count * kEntrySize); 88 Node* init = IntPtrConstant(unroll_count * kEntrySize);
83 Node* length = LoadAndUntagFixedArrayBaseLength(feedback); 89 Node* length = LoadAndUntagFixedArrayBaseLength(feedback);
84 BuildFastLoop( 90 BuildFastLoop(
85 init, length, 91 init, length,
86 [this, receiver_map, feedback, if_handler, var_handler](Node* index) { 92 [this, receiver_map, feedback, if_handler, var_handler](Node* index) {
87 Node* cached_map = 93 Node* cached_map =
88 LoadWeakCellValue(LoadFixedArrayElement(feedback, index)); 94 LoadWeakCellValue(LoadFixedArrayElement(feedback, index));
89 95
90 Label next_entry(this); 96 Label next_entry(this);
91 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); 97 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 140
135 Bind(&next_entry); 141 Bind(&next_entry);
136 }, 142 },
137 kEntrySize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); 143 kEntrySize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost);
138 // The loop falls through if no handler was found. 144 // The loop falls through if no handler was found.
139 Goto(if_miss); 145 Goto(if_miss);
140 } 146 }
141 147
142 void AccessorAssembler::HandleLoadICHandlerCase( 148 void AccessorAssembler::HandleLoadICHandlerCase(
143 const LoadICParameters* p, Node* handler, Label* miss, 149 const LoadICParameters* p, Node* handler, Label* miss,
144 ElementSupport support_elements) { 150 ExitPoint* exit_point, ElementSupport support_elements) {
145 Comment("have_handler"); 151 Comment("have_handler");
146 ExitPoint direct_exit(this);
147 152
148 Variable var_holder(this, MachineRepresentation::kTagged, p->receiver); 153 Variable var_holder(this, MachineRepresentation::kTagged, p->receiver);
149 Variable var_smi_handler(this, MachineRepresentation::kTagged, handler); 154 Variable var_smi_handler(this, MachineRepresentation::kTagged, handler);
150 155
151 Variable* vars[] = {&var_holder, &var_smi_handler}; 156 Variable* vars[] = {&var_holder, &var_smi_handler};
152 Label if_smi_handler(this, 2, vars); 157 Label if_smi_handler(this, 2, vars);
153 Label try_proto_handler(this, Label::kDeferred), 158 Label try_proto_handler(this, Label::kDeferred),
154 call_handler(this, Label::kDeferred); 159 call_handler(this, Label::kDeferred);
155 160
156 Branch(TaggedIsSmi(handler), &if_smi_handler, &try_proto_handler); 161 Branch(TaggedIsSmi(handler), &if_smi_handler, &try_proto_handler);
157 162
158 // |handler| is a Smi, encoding what to do. See SmiHandler methods 163 // |handler| is a Smi, encoding what to do. See SmiHandler methods
159 // for the encoding format. 164 // for the encoding format.
160 Bind(&if_smi_handler); 165 Bind(&if_smi_handler);
161 { 166 {
162 HandleLoadICSmiHandlerCase(p, var_holder.value(), var_smi_handler.value(), 167 HandleLoadICSmiHandlerCase(p, var_holder.value(), var_smi_handler.value(),
163 miss, &direct_exit, support_elements); 168 miss, exit_point, support_elements);
164 } 169 }
165 170
166 Bind(&try_proto_handler); 171 Bind(&try_proto_handler);
167 { 172 {
168 GotoIf(IsCodeMap(LoadMap(handler)), &call_handler); 173 GotoIf(IsCodeMap(LoadMap(handler)), &call_handler);
169 HandleLoadICProtoHandlerCase(p, handler, &var_holder, &var_smi_handler, 174 HandleLoadICProtoHandlerCase(p, handler, &var_holder, &var_smi_handler,
170 &if_smi_handler, miss, &direct_exit, false); 175 &if_smi_handler, miss, exit_point, false);
171 } 176 }
172 177
173 Bind(&call_handler); 178 Bind(&call_handler);
174 { 179 {
175 typedef LoadWithVectorDescriptor Descriptor; 180 typedef LoadWithVectorDescriptor Descriptor;
176 TailCallStub(Descriptor(isolate()), handler, p->context, p->receiver, 181 exit_point->ReturnCallStub(Descriptor(isolate()), handler, p->context,
177 p->name, p->slot, p->vector); 182 p->receiver, p->name, p->slot, p->vector);
178 } 183 }
179 } 184 }
180 185
181 void AccessorAssembler::HandleLoadField(Node* holder, Node* handler_word, 186 void AccessorAssembler::HandleLoadField(Node* holder, Node* handler_word,
182 Variable* var_double_value, 187 Variable* var_double_value,
183 Label* rebox_double, 188 Label* rebox_double,
184 ExitPoint* exit_point) { 189 ExitPoint* exit_point) {
185 Comment("field_load"); 190 Comment("field_load");
186 Node* offset = DecodeWord<LoadHandler::FieldOffsetBits>(handler_word); 191 Node* offset = DecodeWord<LoadHandler::FieldOffsetBits>(handler_word);
187 192
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset), 271 WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset),
267 SmiConstant(Smi::FromInt(Isolate::kProtectorValid))), 272 SmiConstant(Smi::FromInt(Isolate::kProtectorValid))),
268 miss); 273 miss);
269 exit_point->Return(UndefinedConstant()); 274 exit_point->Return(UndefinedConstant());
270 } 275 }
271 276
272 Bind(&property); 277 Bind(&property);
273 Comment("property_load"); 278 Comment("property_load");
274 } 279 }
275 280
276 Label constant(this, Label::kDeferred), field(this), 281 Label constant(this), field(this), normal(this, Label::kDeferred);
277 normal(this, Label::kDeferred);
278 GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForFields)), 282 GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForFields)),
279 &field); 283 &field);
280 284
281 Branch(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForConstants)), 285 Branch(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForConstants)),
282 &constant, &normal); 286 &constant, &normal);
283 287
284 Bind(&field); 288 Bind(&field);
285 HandleLoadField(holder, handler_word, &var_double_value, &rebox_double, 289 HandleLoadField(holder, handler_word, &var_double_value, &rebox_double,
286 exit_point); 290 exit_point);
287 291
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 var_transition.Bind(transition); 661 var_transition.Bind(transition);
658 Goto(&if_transition); 662 Goto(&if_transition);
659 } 663 }
660 664
661 Bind(&if_transition); 665 Bind(&if_transition);
662 { 666 {
663 Node* holder = p->receiver; 667 Node* holder = p->receiver;
664 Node* transition = var_transition.value(); 668 Node* transition = var_transition.value();
665 Node* handler_word = SmiUntag(smi_handler); 669 Node* handler_word = SmiUntag(smi_handler);
666 670
667 GotoIf(IsSetWord32<Map::Deprecated>(LoadMapBitField3(transition)), miss); 671 GotoIf(IsDeprecatedMap(transition), miss);
668 672
669 Node* handler_kind = DecodeWord<StoreHandler::KindBits>(handler_word); 673 Node* handler_kind = DecodeWord<StoreHandler::KindBits>(handler_word);
670 GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kStoreNormal)), 674 GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kStoreNormal)),
671 &if_store_normal); 675 &if_store_normal);
672 GotoIf(WordEqual(handler_kind, 676 GotoIf(WordEqual(handler_kind,
673 IntPtrConstant(StoreHandler::kTransitionToConstant)), 677 IntPtrConstant(StoreHandler::kTransitionToConstant)),
674 &if_transition_to_constant); 678 &if_transition_to_constant);
675 679
676 // Handle transitioning field stores. 680 // Handle transitioning field stores.
677 HandleStoreICSmiHandlerCase(handler_word, holder, p->value, transition, 681 HandleStoreICSmiHandlerCase(handler_word, holder, p->value, transition,
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after
1315 Bind(&return_undefined); 1319 Bind(&return_undefined);
1316 Return(UndefinedConstant()); 1320 Return(UndefinedConstant());
1317 } 1321 }
1318 } 1322 }
1319 1323
1320 void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, 1324 void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map,
1321 Node* instance_type, Node* key, 1325 Node* instance_type, Node* key,
1322 const LoadICParameters* p, 1326 const LoadICParameters* p,
1323 Label* slow, 1327 Label* slow,
1324 UseStubCache use_stub_cache) { 1328 UseStubCache use_stub_cache) {
1329 ExitPoint direct_exit(this);
1330
1325 Comment("key is unique name"); 1331 Comment("key is unique name");
1326 Label if_found_on_receiver(this), if_property_dictionary(this), 1332 Label if_found_on_receiver(this), if_property_dictionary(this),
1327 lookup_prototype_chain(this); 1333 lookup_prototype_chain(this);
1328 Variable var_details(this, MachineRepresentation::kWord32); 1334 Variable var_details(this, MachineRepresentation::kWord32);
1329 Variable var_value(this, MachineRepresentation::kTagged); 1335 Variable var_value(this, MachineRepresentation::kTagged);
1330 1336
1331 // Receivers requiring non-standard accesses (interceptors, access 1337 // Receivers requiring non-standard accesses (interceptors, access
1332 // checks, strings and string wrappers, proxies) are handled in the runtime. 1338 // checks, strings and string wrappers, proxies) are handled in the runtime.
1333 GotoIf(Int32LessThanOrEqual(instance_type, 1339 GotoIf(Int32LessThanOrEqual(instance_type,
1334 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), 1340 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
(...skipping 26 matching lines...) Expand all
1361 } 1367 }
1362 1368
1363 if (use_stub_cache == kUseStubCache) { 1369 if (use_stub_cache == kUseStubCache) {
1364 Bind(&stub_cache); 1370 Bind(&stub_cache);
1365 Comment("stub cache probe for fast property load"); 1371 Comment("stub cache probe for fast property load");
1366 Variable var_handler(this, MachineRepresentation::kTagged); 1372 Variable var_handler(this, MachineRepresentation::kTagged);
1367 Label found_handler(this, &var_handler), stub_cache_miss(this); 1373 Label found_handler(this, &var_handler), stub_cache_miss(this);
1368 TryProbeStubCache(isolate()->load_stub_cache(), receiver, key, 1374 TryProbeStubCache(isolate()->load_stub_cache(), receiver, key,
1369 &found_handler, &var_handler, &stub_cache_miss); 1375 &found_handler, &var_handler, &stub_cache_miss);
1370 Bind(&found_handler); 1376 Bind(&found_handler);
1371 { HandleLoadICHandlerCase(p, var_handler.value(), slow); } 1377 { HandleLoadICHandlerCase(p, var_handler.value(), slow, &direct_exit); }
1372 1378
1373 Bind(&stub_cache_miss); 1379 Bind(&stub_cache_miss);
1374 { 1380 {
1375 // TODO(jkummerow): Check if the property exists on the prototype 1381 // TODO(jkummerow): Check if the property exists on the prototype
1376 // chain. If it doesn't, then there's no point in missing. 1382 // chain. If it doesn't, then there's no point in missing.
1377 Comment("KeyedLoadGeneric_miss"); 1383 Comment("KeyedLoadGeneric_miss");
1378 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver, 1384 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver,
1379 p->name, p->slot, p->vector); 1385 p->name, p->slot, p->vector);
1380 } 1386 }
1381 } 1387 }
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1569 1575
1570 Bind(&miss); 1576 Bind(&miss);
1571 { 1577 {
1572 IncrementCounter(counters->megamorphic_stub_cache_misses(), 1); 1578 IncrementCounter(counters->megamorphic_stub_cache_misses(), 1);
1573 Goto(if_miss); 1579 Goto(if_miss);
1574 } 1580 }
1575 } 1581 }
1576 1582
1577 //////////////////// Entry points into private implementation (one per stub). 1583 //////////////////// Entry points into private implementation (one per stub).
1578 1584
1585 void AccessorAssembler::LoadIC_BytecodeHandler(const LoadICParameters* p,
1586 ExitPoint* exit_point) {
1587 // Must be kept in sync with LoadIC.
1588
1589 // This function is hand-tuned to omit frame construction for common cases,
1590 // e.g.: monomorphic field and constant loads through smi handlers.
1591 // Polymorphic ICs with a hit in the first two entries also omit frames.
1592 // TODO(jgruber): Frame omission is fragile and can be affected by minor
1593 // changes in control flow and logic. We currently have no way of ensuring
1594 // that no frame is constructed, so it's easy to break this optimization by
1595 // accident.
1596 Label stub_call(this, Label::kDeferred), miss(this, Label::kDeferred);
1597
1598 // Inlined fast path.
1599 {
1600 Comment("LoadIC_BytecodeHandler_fast");
1601
1602 Node* recv_map = LoadReceiverMap(p->receiver);
1603 GotoIf(IsDeprecatedMap(recv_map), &miss);
1604
1605 Variable var_handler(this, MachineRepresentation::kTagged);
1606 Label try_polymorphic(this), if_handler(this, &var_handler);
1607
1608 Node* feedback =
1609 TryMonomorphicCase(p->slot, p->vector, recv_map, &if_handler,
1610 &var_handler, &try_polymorphic);
1611
1612 Bind(&if_handler);
1613 HandleLoadICHandlerCase(p, var_handler.value(), &miss, exit_point);
1614
1615 Bind(&try_polymorphic);
1616 {
1617 GotoIfNot(WordEqual(LoadMap(feedback), FixedArrayMapConstant()),
1618 &stub_call);
1619 HandlePolymorphicCase(recv_map, feedback, &if_handler, &var_handler,
1620 &miss, 2);
1621 }
1622 }
1623
1624 Bind(&stub_call);
1625 {
1626 Comment("LoadIC_BytecodeHandler_noninlined");
1627
1628 // Call into the stub that implements the non-inlined parts of LoadIC.
1629 Callable ic = CodeFactory::LoadICInOptimizedCode_Noninlined(isolate());
1630 Node* code_target = HeapConstant(ic.code());
1631 exit_point->ReturnCallStub(ic.descriptor(), code_target, p->context,
1632 p->receiver, p->name, p->slot, p->vector);
1633 }
1634
1635 Bind(&miss);
1636 {
1637 Comment("LoadIC_BytecodeHandler_miss");
1638
1639 exit_point->ReturnCallRuntime(Runtime::kLoadIC_Miss, p->context,
1640 p->receiver, p->name, p->slot, p->vector);
1641 }
1642 }
1643
1579 void AccessorAssembler::LoadIC(const LoadICParameters* p) { 1644 void AccessorAssembler::LoadIC(const LoadICParameters* p) {
1645 // Must be kept in sync with LoadIC_BytecodeHandler.
1646
1647 ExitPoint direct_exit(this);
1648
1580 Variable var_handler(this, MachineRepresentation::kTagged); 1649 Variable var_handler(this, MachineRepresentation::kTagged);
1581 Label if_handler(this, &var_handler), try_polymorphic(this, Label::kDeferred), 1650 Label if_handler(this, &var_handler), non_inlined(this, Label::kDeferred),
1582 try_megamorphic(this, Label::kDeferred), 1651 try_polymorphic(this), miss(this, Label::kDeferred);
1583 try_uninitialized(this, Label::kDeferred), miss(this, Label::kDeferred);
1584 1652
1585 Node* receiver_map = LoadReceiverMap(p->receiver); 1653 Node* receiver_map = LoadReceiverMap(p->receiver);
1586 GotoIf(IsSetWord32<Map::Deprecated>(LoadMapBitField3(receiver_map)), &miss); 1654 GotoIf(IsDeprecatedMap(receiver_map), &miss);
1587 1655
1588 // Check monomorphic case. 1656 // Check monomorphic case.
1589 Node* feedback = 1657 Node* feedback =
1590 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, 1658 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
1591 &var_handler, &try_polymorphic); 1659 &var_handler, &try_polymorphic);
1592 Bind(&if_handler); 1660 Bind(&if_handler);
1593 { HandleLoadICHandlerCase(p, var_handler.value(), &miss); } 1661 HandleLoadICHandlerCase(p, var_handler.value(), &miss, &direct_exit);
1594 1662
1595 Bind(&try_polymorphic); 1663 Bind(&try_polymorphic);
1596 { 1664 {
1597 // Check polymorphic case. 1665 // Check polymorphic case.
1598 Comment("LoadIC_try_polymorphic"); 1666 Comment("LoadIC_try_polymorphic");
1599 GotoIfNot(WordEqual(LoadMap(feedback), FixedArrayMapConstant()), 1667 GotoIfNot(WordEqual(LoadMap(feedback), FixedArrayMapConstant()),
1600 &try_megamorphic); 1668 &non_inlined);
1601 HandlePolymorphicCase(receiver_map, feedback, &if_handler, &var_handler, 1669 HandlePolymorphicCase(receiver_map, feedback, &if_handler, &var_handler,
1602 &miss, 2); 1670 &miss, 2);
1603 } 1671 }
1604 1672
1605 Bind(&try_megamorphic); 1673 Bind(&non_inlined);
1674 LoadIC_Noninlined(p, receiver_map, feedback, &var_handler, &if_handler, &miss,
1675 &direct_exit);
1676
1677 Bind(&miss);
1678 direct_exit.ReturnCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver,
1679 p->name, p->slot, p->vector);
1680 }
1681
1682 void AccessorAssembler::LoadIC_Noninlined(const LoadICParameters* p,
1683 Node* receiver_map, Node* feedback,
1684 Variable* var_handler,
1685 Label* if_handler, Label* miss,
1686 ExitPoint* exit_point) {
1687 Label try_uninitialized(this, Label::kDeferred);
1688
1689 // Neither deprecated map nor monomorphic. These cases are handled in the
1690 // bytecode handler.
1691 CSA_ASSERT(this, Word32BinaryNot(IsDeprecatedMap(receiver_map)));
1692 CSA_ASSERT(this,
1693 WordNotEqual(receiver_map, LoadWeakCellValueUnchecked(feedback)));
1694 CSA_ASSERT(this, WordNotEqual(LoadMap(feedback), FixedArrayMapConstant()));
1695 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep());
1696
1606 { 1697 {
1607 // Check megamorphic case. 1698 // Check megamorphic case.
1608 GotoIfNot(WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), 1699 GotoIfNot(WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)),
1609 &try_uninitialized); 1700 &try_uninitialized);
1610 1701
1611 TryProbeStubCache(isolate()->load_stub_cache(), p->receiver, p->name, 1702 TryProbeStubCache(isolate()->load_stub_cache(), p->receiver, p->name,
1612 &if_handler, &var_handler, &miss); 1703 if_handler, var_handler, miss);
1613 } 1704 }
1705
1614 Bind(&try_uninitialized); 1706 Bind(&try_uninitialized);
1615 { 1707 {
1616 // Check uninitialized case. 1708 // Check uninitialized case.
1617 GotoIfNot( 1709 GotoIfNot(
1618 WordEqual(feedback, LoadRoot(Heap::kuninitialized_symbolRootIndex)), 1710 WordEqual(feedback, LoadRoot(Heap::kuninitialized_symbolRootIndex)),
1619 &miss); 1711 miss);
1620 TailCallStub(CodeFactory::LoadIC_Uninitialized(isolate()), p->context, 1712 exit_point->ReturnCallStub(CodeFactory::LoadIC_Uninitialized(isolate()),
1621 p->receiver, p->name, p->slot, p->vector); 1713 p->context, p->receiver, p->name, p->slot,
1622 } 1714 p->vector);
1623 Bind(&miss);
1624 {
1625 TailCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, p->name,
1626 p->slot, p->vector);
1627 } 1715 }
1628 } 1716 }
1629 1717
1630 void AccessorAssembler::LoadIC_Uninitialized(const LoadICParameters* p) { 1718 void AccessorAssembler::LoadIC_Uninitialized(const LoadICParameters* p) {
1631 Label miss(this); 1719 Label miss(this);
1632 Node* receiver = p->receiver; 1720 Node* receiver = p->receiver;
1633 GotoIf(TaggedIsSmi(receiver), &miss); 1721 GotoIf(TaggedIsSmi(receiver), &miss);
1634 Node* receiver_map = LoadMap(receiver); 1722 Node* receiver_map = LoadMap(receiver);
1635 Node* instance_type = LoadMapInstanceType(receiver_map); 1723 Node* instance_type = LoadMapInstanceType(receiver_map);
1636 1724
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1760 void AccessorAssembler::LoadGlobalIC_MissCase(const LoadICParameters* p, 1848 void AccessorAssembler::LoadGlobalIC_MissCase(const LoadICParameters* p,
1761 ExitPoint* exit_point) { 1849 ExitPoint* exit_point) {
1762 Comment("LoadGlobalIC_MissCase"); 1850 Comment("LoadGlobalIC_MissCase");
1763 1851
1764 exit_point->ReturnCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, 1852 exit_point->ReturnCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context,
1765 p->name, p->slot, p->vector); 1853 p->name, p->slot, p->vector);
1766 } 1854 }
1767 1855
1768 void AccessorAssembler::LoadGlobalIC(const LoadICParameters* p, 1856 void AccessorAssembler::LoadGlobalIC(const LoadICParameters* p,
1769 TypeofMode typeof_mode) { 1857 TypeofMode typeof_mode) {
1858 // Must be kept in sync with Interpreter::BuildLoadGlobal.
1859
1770 ExitPoint direct_exit(this); 1860 ExitPoint direct_exit(this);
1771 1861
1772 Label try_handler(this), miss(this); 1862 Label try_handler(this), miss(this);
1773 LoadGlobalIC_TryPropertyCellCase(p->vector, p->slot, &direct_exit, 1863 LoadGlobalIC_TryPropertyCellCase(p->vector, p->slot, &direct_exit,
1774 &try_handler, &miss); 1864 &try_handler, &miss);
1775 1865
1776 Bind(&try_handler); 1866 Bind(&try_handler);
1777 LoadGlobalIC_TryHandlerCase(p, typeof_mode, &direct_exit, &miss); 1867 LoadGlobalIC_TryHandlerCase(p, typeof_mode, &direct_exit, &miss);
1778 1868
1779 Bind(&miss); 1869 Bind(&miss);
1780 LoadGlobalIC_MissCase(p, &direct_exit); 1870 LoadGlobalIC_MissCase(p, &direct_exit);
1781 } 1871 }
1782 1872
1783 void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p) { 1873 void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p) {
1874 ExitPoint direct_exit(this);
1875
1784 Variable var_handler(this, MachineRepresentation::kTagged); 1876 Variable var_handler(this, MachineRepresentation::kTagged);
1785 Label if_handler(this, &var_handler), try_polymorphic(this, Label::kDeferred), 1877 Label if_handler(this, &var_handler), try_polymorphic(this, Label::kDeferred),
1786 try_megamorphic(this, Label::kDeferred), 1878 try_megamorphic(this, Label::kDeferred),
1787 try_polymorphic_name(this, Label::kDeferred), 1879 try_polymorphic_name(this, Label::kDeferred),
1788 miss(this, Label::kDeferred); 1880 miss(this, Label::kDeferred);
1789 1881
1790 Node* receiver_map = LoadReceiverMap(p->receiver); 1882 Node* receiver_map = LoadReceiverMap(p->receiver);
1791 GotoIf(IsSetWord32<Map::Deprecated>(LoadMapBitField3(receiver_map)), &miss); 1883 GotoIf(IsDeprecatedMap(receiver_map), &miss);
1792 1884
1793 // Check monomorphic case. 1885 // Check monomorphic case.
1794 Node* feedback = 1886 Node* feedback =
1795 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, 1887 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
1796 &var_handler, &try_polymorphic); 1888 &var_handler, &try_polymorphic);
1797 Bind(&if_handler); 1889 Bind(&if_handler);
1798 { HandleLoadICHandlerCase(p, var_handler.value(), &miss, kSupportElements); } 1890 {
1891 HandleLoadICHandlerCase(p, var_handler.value(), &miss, &direct_exit,
1892 kSupportElements);
1893 }
1799 1894
1800 Bind(&try_polymorphic); 1895 Bind(&try_polymorphic);
1801 { 1896 {
1802 // Check polymorphic case. 1897 // Check polymorphic case.
1803 Comment("KeyedLoadIC_try_polymorphic"); 1898 Comment("KeyedLoadIC_try_polymorphic");
1804 GotoIfNot(WordEqual(LoadMap(feedback), FixedArrayMapConstant()), 1899 GotoIfNot(WordEqual(LoadMap(feedback), FixedArrayMapConstant()),
1805 &try_megamorphic); 1900 &try_megamorphic);
1806 HandlePolymorphicCase(receiver_map, feedback, &if_handler, &var_handler, 1901 HandlePolymorphicCase(receiver_map, feedback, &if_handler, &var_handler,
1807 &miss, 2); 1902 &miss, 2);
1808 } 1903 }
1809 1904
1810 Bind(&try_megamorphic); 1905 Bind(&try_megamorphic);
1811 { 1906 {
1812 // Check megamorphic case. 1907 // Check megamorphic case.
1813 Comment("KeyedLoadIC_try_megamorphic"); 1908 Comment("KeyedLoadIC_try_megamorphic");
1814 GotoIfNot(WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), 1909 GotoIfNot(WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)),
1815 &try_polymorphic_name); 1910 &try_polymorphic_name);
1816 // TODO(jkummerow): Inline this? Or some of it? 1911 // TODO(jkummerow): Inline this? Or some of it?
1817 TailCallStub(CodeFactory::KeyedLoadIC_Megamorphic(isolate()), p->context, 1912 TailCallStub(CodeFactory::KeyedLoadIC_Megamorphic(isolate()), p->context,
1818 p->receiver, p->name, p->slot, p->vector); 1913 p->receiver, p->name, p->slot, p->vector);
1819 } 1914 }
1820 Bind(&try_polymorphic_name); 1915 Bind(&try_polymorphic_name);
1821 { 1916 {
1822 // We might have a name in feedback, and a fixed array in the next slot. 1917 // We might have a name in feedback, and a fixed array in the next slot.
1823 Comment("KeyedLoadIC_try_polymorphic_name"); 1918 Comment("KeyedLoadIC_try_polymorphic_name");
1824 GotoIfNot(WordEqual(feedback, p->name), &miss); 1919 GotoIfNot(WordEqual(feedback, p->name), &miss);
1825 // If the name comparison succeeded, we know we have a fixed array with 1920 // If the name comparison succeeded, we know we have a fixed array with
1826 // at least one map/handler pair. 1921 // at least one map/handler pair.
1827 Node* offset = ElementOffsetFromIndex( 1922 Node* array =
1828 p->slot, FAST_HOLEY_ELEMENTS, SMI_PARAMETERS, 1923 LoadFixedArrayElement(p->vector, p->slot, kPointerSize, SMI_PARAMETERS);
1829 FixedArray::kHeaderSize + kPointerSize - kHeapObjectTag);
1830 Node* array = Load(MachineType::AnyTagged(), p->vector, offset);
1831 HandlePolymorphicCase(receiver_map, array, &if_handler, &var_handler, &miss, 1924 HandlePolymorphicCase(receiver_map, array, &if_handler, &var_handler, &miss,
1832 1); 1925 1);
1833 } 1926 }
1834 Bind(&miss); 1927 Bind(&miss);
1835 { 1928 {
1836 Comment("KeyedLoadIC_miss"); 1929 Comment("KeyedLoadIC_miss");
1837 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver, 1930 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver,
1838 p->name, p->slot, p->vector); 1931 p->name, p->slot, p->vector);
1839 } 1932 }
1840 } 1933 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1874 p->name); 1967 p->name);
1875 } 1968 }
1876 } 1969 }
1877 1970
1878 void AccessorAssembler::StoreIC(const StoreICParameters* p) { 1971 void AccessorAssembler::StoreIC(const StoreICParameters* p) {
1879 Variable var_handler(this, MachineRepresentation::kTagged); 1972 Variable var_handler(this, MachineRepresentation::kTagged);
1880 Label if_handler(this, &var_handler), try_polymorphic(this, Label::kDeferred), 1973 Label if_handler(this, &var_handler), try_polymorphic(this, Label::kDeferred),
1881 try_megamorphic(this, Label::kDeferred), miss(this, Label::kDeferred); 1974 try_megamorphic(this, Label::kDeferred), miss(this, Label::kDeferred);
1882 1975
1883 Node* receiver_map = LoadReceiverMap(p->receiver); 1976 Node* receiver_map = LoadReceiverMap(p->receiver);
1884 GotoIf(IsSetWord32<Map::Deprecated>(LoadMapBitField3(receiver_map)), &miss); 1977 GotoIf(IsDeprecatedMap(receiver_map), &miss);
1885 1978
1886 // Check monomorphic case. 1979 // Check monomorphic case.
1887 Node* feedback = 1980 Node* feedback =
1888 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, 1981 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
1889 &var_handler, &try_polymorphic); 1982 &var_handler, &try_polymorphic);
1890 Bind(&if_handler); 1983 Bind(&if_handler);
1891 { 1984 {
1892 Comment("StoreIC_if_handler"); 1985 Comment("StoreIC_if_handler");
1893 HandleStoreICHandlerCase(p, var_handler.value(), &miss); 1986 HandleStoreICHandlerCase(p, var_handler.value(), &miss);
1894 } 1987 }
(...skipping 30 matching lines...) Expand all
1925 Label miss(this, Label::kDeferred); 2018 Label miss(this, Label::kDeferred);
1926 { 2019 {
1927 Variable var_handler(this, MachineRepresentation::kTagged); 2020 Variable var_handler(this, MachineRepresentation::kTagged);
1928 2021
1929 Label if_handler(this, &var_handler), 2022 Label if_handler(this, &var_handler),
1930 try_polymorphic(this, Label::kDeferred), 2023 try_polymorphic(this, Label::kDeferred),
1931 try_megamorphic(this, Label::kDeferred), 2024 try_megamorphic(this, Label::kDeferred),
1932 try_polymorphic_name(this, Label::kDeferred); 2025 try_polymorphic_name(this, Label::kDeferred);
1933 2026
1934 Node* receiver_map = LoadReceiverMap(p->receiver); 2027 Node* receiver_map = LoadReceiverMap(p->receiver);
1935 GotoIf(IsSetWord32<Map::Deprecated>(LoadMapBitField3(receiver_map)), &miss); 2028 GotoIf(IsDeprecatedMap(receiver_map), &miss);
1936 2029
1937 // Check monomorphic case. 2030 // Check monomorphic case.
1938 Node* feedback = 2031 Node* feedback =
1939 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, 2032 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
1940 &var_handler, &try_polymorphic); 2033 &var_handler, &try_polymorphic);
1941 Bind(&if_handler); 2034 Bind(&if_handler);
1942 { 2035 {
1943 Comment("KeyedStoreIC_if_handler"); 2036 Comment("KeyedStoreIC_if_handler");
1944 HandleStoreICHandlerCase(p, var_handler.value(), &miss, kSupportElements); 2037 HandleStoreICHandlerCase(p, var_handler.value(), &miss, kSupportElements);
1945 } 2038 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2006 p->context, p->receiver, p->name, p->value, p->slot, p->vector); 2099 p->context, p->receiver, p->name, p->value, p->slot, p->vector);
2007 } 2100 }
2008 2101
2009 Bind(&try_polymorphic_name); 2102 Bind(&try_polymorphic_name);
2010 { 2103 {
2011 // We might have a name in feedback, and a fixed array in the next slot. 2104 // We might have a name in feedback, and a fixed array in the next slot.
2012 Comment("KeyedStoreIC_try_polymorphic_name"); 2105 Comment("KeyedStoreIC_try_polymorphic_name");
2013 GotoIfNot(WordEqual(feedback, p->name), &miss); 2106 GotoIfNot(WordEqual(feedback, p->name), &miss);
2014 // If the name comparison succeeded, we know we have a FixedArray with 2107 // If the name comparison succeeded, we know we have a FixedArray with
2015 // at least one map/handler pair. 2108 // at least one map/handler pair.
2016 Node* offset = ElementOffsetFromIndex( 2109 Node* array = LoadFixedArrayElement(p->vector, p->slot, kPointerSize,
2017 p->slot, FAST_HOLEY_ELEMENTS, SMI_PARAMETERS, 2110 SMI_PARAMETERS);
2018 FixedArray::kHeaderSize + kPointerSize - kHeapObjectTag);
2019 Node* array = Load(MachineType::AnyTagged(), p->vector, offset);
2020 HandlePolymorphicCase(receiver_map, array, &if_handler, &var_handler, 2111 HandlePolymorphicCase(receiver_map, array, &if_handler, &var_handler,
2021 &miss, 1); 2112 &miss, 1);
2022 } 2113 }
2023 } 2114 }
2024 Bind(&miss); 2115 Bind(&miss);
2025 { 2116 {
2026 Comment("KeyedStoreIC_miss"); 2117 Comment("KeyedStoreIC_miss");
2027 TailCallRuntime(Runtime::kKeyedStoreIC_Miss, p->context, p->value, p->slot, 2118 TailCallRuntime(Runtime::kKeyedStoreIC_Miss, p->context, p->value, p->slot,
2028 p->vector, p->receiver, p->name); 2119 p->vector, p->receiver, p->name);
2029 } 2120 }
2030 } 2121 }
2031 2122
2032 //////////////////// Public methods. 2123 //////////////////// Public methods.
2033 2124
2034 void AccessorAssembler::GenerateLoadIC() { 2125 void AccessorAssembler::GenerateLoadIC() {
2035 typedef LoadWithVectorDescriptor Descriptor; 2126 typedef LoadWithVectorDescriptor Descriptor;
2036 2127
2037 Node* receiver = Parameter(Descriptor::kReceiver); 2128 Node* receiver = Parameter(Descriptor::kReceiver);
2038 Node* name = Parameter(Descriptor::kName); 2129 Node* name = Parameter(Descriptor::kName);
2039 Node* slot = Parameter(Descriptor::kSlot); 2130 Node* slot = Parameter(Descriptor::kSlot);
2040 Node* vector = Parameter(Descriptor::kVector); 2131 Node* vector = Parameter(Descriptor::kVector);
2041 Node* context = Parameter(Descriptor::kContext); 2132 Node* context = Parameter(Descriptor::kContext);
2042 2133
2043 LoadICParameters p(context, receiver, name, slot, vector); 2134 LoadICParameters p(context, receiver, name, slot, vector);
2044 LoadIC(&p); 2135 LoadIC(&p);
2045 } 2136 }
2046 2137
2138 void AccessorAssembler::GenerateLoadIC_Noninlined() {
2139 typedef LoadWithVectorDescriptor Descriptor;
2140
2141 Node* receiver = Parameter(Descriptor::kReceiver);
2142 Node* name = Parameter(Descriptor::kName);
2143 Node* slot = Parameter(Descriptor::kSlot);
2144 Node* vector = Parameter(Descriptor::kVector);
2145 Node* context = Parameter(Descriptor::kContext);
2146
2147 ExitPoint direct_exit(this);
2148 Variable var_handler(this, MachineRepresentation::kTagged);
2149 Label if_handler(this, &var_handler), miss(this, Label::kDeferred);
2150
2151 Node* receiver_map = LoadReceiverMap(receiver);
2152 Node* feedback = LoadFixedArrayElement(vector, slot, 0, SMI_PARAMETERS);
2153
2154 LoadICParameters p(context, receiver, name, slot, vector);
2155 LoadIC_Noninlined(&p, receiver_map, feedback, &var_handler, &if_handler,
2156 &miss, &direct_exit);
2157
2158 Bind(&if_handler);
2159 HandleLoadICHandlerCase(&p, var_handler.value(), &miss, &direct_exit);
2160
2161 Bind(&miss);
2162 direct_exit.ReturnCallRuntime(Runtime::kLoadIC_Miss, context, receiver, name,
2163 slot, vector);
2164 }
2165
2047 void AccessorAssembler::GenerateLoadIC_Uninitialized() { 2166 void AccessorAssembler::GenerateLoadIC_Uninitialized() {
2048 typedef LoadWithVectorDescriptor Descriptor; 2167 typedef LoadWithVectorDescriptor Descriptor;
2049 2168
2050 Node* receiver = Parameter(Descriptor::kReceiver); 2169 Node* receiver = Parameter(Descriptor::kReceiver);
2051 Node* name = Parameter(Descriptor::kName); 2170 Node* name = Parameter(Descriptor::kName);
2052 Node* slot = Parameter(Descriptor::kSlot); 2171 Node* slot = Parameter(Descriptor::kSlot);
2053 Node* vector = Parameter(Descriptor::kVector); 2172 Node* vector = Parameter(Descriptor::kVector);
2054 Node* context = Parameter(Descriptor::kContext); 2173 Node* context = Parameter(Descriptor::kContext);
2055 2174
2056 LoadICParameters p(context, receiver, name, slot, vector); 2175 LoadICParameters p(context, receiver, name, slot, vector);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
2228 Node* context = Parameter(Descriptor::kContext); 2347 Node* context = Parameter(Descriptor::kContext);
2229 Node* vector = LoadFeedbackVectorForStub(); 2348 Node* vector = LoadFeedbackVectorForStub();
2230 2349
2231 Callable callable = 2350 Callable callable =
2232 CodeFactory::KeyedStoreICInOptimizedCode(isolate(), language_mode); 2351 CodeFactory::KeyedStoreICInOptimizedCode(isolate(), language_mode);
2233 TailCallStub(callable, context, receiver, name, value, slot, vector); 2352 TailCallStub(callable, context, receiver, name, value, slot, vector);
2234 } 2353 }
2235 2354
2236 } // namespace internal 2355 } // namespace internal
2237 } // namespace v8 2356 } // namespace v8
OLDNEW
« no previous file with comments | « src/ic/accessor-assembler.h ('k') | src/interpreter/interpreter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698