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

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

Issue 2733563002: [ic] Inline LoadIC into LdaNamedProperty bytecode handler (Closed)
Patch Set: 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
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"
11 #include "src/ic/stub-cache.h" 11 #include "src/ic/stub-cache.h"
12 #include "src/objects-inl.h" 12 #include "src/objects-inl.h"
13 13
14 namespace v8 { 14 namespace v8 {
15 namespace internal { 15 namespace internal {
16 16
17 using compiler::CodeAssemblerState; 17 using compiler::CodeAssemblerState;
18 using compiler::Node; 18 using compiler::Node;
19 19
20 //////////////////// Private helpers. 20 //////////////////// Private helpers.
21 21
22 Node* AccessorAssembler::LoadFeedbackSlot(Node* vector, Node* slot,
jgruber 2017/03/03 13:31:14 This is basically LoadFixedArrayElement but with t
23 int additional_offset) {
24 int32_t header_size =
25 FixedArray::kHeaderSize - kHeapObjectTag + additional_offset;
26
27 // Adding |header_size| with a separate IntPtrAdd rather than passing it
28 // into ElementOffsetFromIndex() allows it to be folded into a single
29 // [base, index, offset] indirect memory access on x64.
30 Node* offset =
31 ElementOffsetFromIndex(slot, FAST_HOLEY_ELEMENTS, SMI_PARAMETERS);
32 return Load(MachineType::AnyTagged(), vector,
33 IntPtrAdd(offset, IntPtrConstant(header_size)));
34 }
35
22 Node* AccessorAssembler::TryMonomorphicCase(Node* slot, Node* vector, 36 Node* AccessorAssembler::TryMonomorphicCase(Node* slot, Node* vector,
23 Node* receiver_map, 37 Node* receiver_map,
24 Label* if_handler, 38 Label* if_handler,
25 Variable* var_handler, 39 Variable* var_handler,
26 Label* if_miss) { 40 Label* if_miss) {
41 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep());
42
43 Node* feedback = nullptr;
44 Node* handler = nullptr;
45 std::tie(feedback, handler) =
46 TryMonomorphicCase(slot, vector, receiver_map, if_miss);
47
48 var_handler->Bind(handler);
49 Goto(if_handler);
50
51 return feedback;
52 }
53
54 std::pair<Node*, Node*> AccessorAssembler::TryMonomorphicCase(
jgruber 2017/03/03 13:31:14 This version avoids needs a variable and a label l
55 Node* slot, Node* vector, Node* receiver_map, Label* if_miss) {
27 Comment("TryMonomorphicCase"); 56 Comment("TryMonomorphicCase");
28 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep());
29 57
30 // TODO(ishell): add helper class that hides offset computations for a series 58 // TODO(ishell): add helper class that hides offset computations for a series
31 // of loads. 59 // of loads.
32 int32_t header_size = FixedArray::kHeaderSize - kHeapObjectTag; 60 int32_t header_size = FixedArray::kHeaderSize - kHeapObjectTag;
33 // Adding |header_size| with a separate IntPtrAdd rather than passing it 61 // Adding |header_size| with a separate IntPtrAdd rather than passing it
34 // into ElementOffsetFromIndex() allows it to be folded into a single 62 // into ElementOffsetFromIndex() allows it to be folded into a single
35 // [base, index, offset] indirect memory access on x64. 63 // [base, index, offset] indirect memory access on x64.
36 Node* offset = 64 Node* offset =
37 ElementOffsetFromIndex(slot, FAST_HOLEY_ELEMENTS, SMI_PARAMETERS); 65 ElementOffsetFromIndex(slot, FAST_HOLEY_ELEMENTS, SMI_PARAMETERS);
38 Node* feedback = Load(MachineType::AnyTagged(), vector, 66 Node* feedback = Load(MachineType::AnyTagged(), vector,
39 IntPtrAdd(offset, IntPtrConstant(header_size))); 67 IntPtrAdd(offset, IntPtrConstant(header_size)));
40 68
41 // Try to quickly handle the monomorphic case without knowing for sure 69 // Try to quickly handle the monomorphic case without knowing for sure
42 // if we have a weak cell in feedback. We do know it's safe to look 70 // if we have a weak cell in feedback. We do know it's safe to look
43 // at WeakCell::kValueOffset. 71 // at WeakCell::kValueOffset.
44 GotoIf(WordNotEqual(receiver_map, LoadWeakCellValueUnchecked(feedback)), 72 GotoIf(WordNotEqual(receiver_map, LoadWeakCellValueUnchecked(feedback)),
45 if_miss); 73 if_miss);
46 74
47 Node* handler = 75 Node* handler =
48 Load(MachineType::AnyTagged(), vector, 76 Load(MachineType::AnyTagged(), vector,
49 IntPtrAdd(offset, IntPtrConstant(header_size + kPointerSize))); 77 IntPtrAdd(offset, IntPtrConstant(header_size + kPointerSize)));
50 78
51 var_handler->Bind(handler); 79 return std::make_pair(feedback, handler);
52 Goto(if_handler);
53 return feedback;
54 } 80 }
55 81
56 void AccessorAssembler::HandlePolymorphicCase(Node* receiver_map, 82 void AccessorAssembler::HandlePolymorphicCase(Node* receiver_map,
57 Node* feedback, Label* if_handler, 83 Node* feedback, Label* if_handler,
58 Variable* var_handler, 84 Variable* var_handler,
59 Label* if_miss, 85 Label* if_miss,
60 int unroll_count) { 86 int unroll_count) {
61 Comment("HandlePolymorphicCase"); 87 Comment("HandlePolymorphicCase");
62 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); 88 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep());
63 89
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 160
135 Bind(&next_entry); 161 Bind(&next_entry);
136 }, 162 },
137 kEntrySize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); 163 kEntrySize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost);
138 // The loop falls through if no handler was found. 164 // The loop falls through if no handler was found.
139 Goto(if_miss); 165 Goto(if_miss);
140 } 166 }
141 167
142 void AccessorAssembler::HandleLoadICHandlerCase( 168 void AccessorAssembler::HandleLoadICHandlerCase(
143 const LoadICParameters* p, Node* handler, Label* miss, 169 const LoadICParameters* p, Node* handler, Label* miss,
144 ElementSupport support_elements) { 170 ExitPoint* exit_point, ElementSupport support_elements) {
145 Comment("have_handler"); 171 Comment("have_handler");
146 ExitPoint direct_exit(this);
147 172
148 Variable var_holder(this, MachineRepresentation::kTagged, p->receiver); 173 Variable var_holder(this, MachineRepresentation::kTagged, p->receiver);
149 Variable var_smi_handler(this, MachineRepresentation::kTagged, handler); 174 Variable var_smi_handler(this, MachineRepresentation::kTagged, handler);
150 175
151 Variable* vars[] = {&var_holder, &var_smi_handler}; 176 Variable* vars[] = {&var_holder, &var_smi_handler};
152 Label if_smi_handler(this, 2, vars); 177 Label if_smi_handler(this, 2, vars);
153 Label try_proto_handler(this, Label::kDeferred), 178 Label try_proto_handler(this, Label::kDeferred),
154 call_handler(this, Label::kDeferred); 179 call_handler(this, Label::kDeferred);
155 180
156 Branch(TaggedIsSmi(handler), &if_smi_handler, &try_proto_handler); 181 Branch(TaggedIsSmi(handler), &if_smi_handler, &try_proto_handler);
157 182
158 // |handler| is a Smi, encoding what to do. See SmiHandler methods 183 // |handler| is a Smi, encoding what to do. See SmiHandler methods
159 // for the encoding format. 184 // for the encoding format.
160 Bind(&if_smi_handler); 185 Bind(&if_smi_handler);
161 { 186 {
162 HandleLoadICSmiHandlerCase(p, var_holder.value(), var_smi_handler.value(), 187 HandleLoadICSmiHandlerCase(p, var_holder.value(), var_smi_handler.value(),
163 miss, &direct_exit, support_elements); 188 miss, exit_point, support_elements);
164 } 189 }
165 190
166 Bind(&try_proto_handler); 191 Bind(&try_proto_handler);
167 { 192 {
168 GotoIf(IsCodeMap(LoadMap(handler)), &call_handler); 193 GotoIf(IsCodeMap(LoadMap(handler)), &call_handler);
169 HandleLoadICProtoHandlerCase(p, handler, &var_holder, &var_smi_handler, 194 HandleLoadICProtoHandlerCase(p, handler, &var_holder, &var_smi_handler,
170 &if_smi_handler, miss, &direct_exit, false); 195 &if_smi_handler, miss, exit_point, false);
171 } 196 }
172 197
173 Bind(&call_handler); 198 Bind(&call_handler);
174 { 199 {
175 typedef LoadWithVectorDescriptor Descriptor; 200 typedef LoadWithVectorDescriptor Descriptor;
176 TailCallStub(Descriptor(isolate()), handler, p->context, p->receiver, 201 exit_point->ReturnCallStub(Descriptor(isolate()), handler, p->context,
177 p->name, p->slot, p->vector); 202 p->receiver, p->name, p->slot, p->vector);
178 } 203 }
179 } 204 }
180 205
181 void AccessorAssembler::HandleLoadField(Node* holder, Node* handler_word, 206 void AccessorAssembler::HandleLoadField(Node* holder, Node* handler_word,
182 Variable* var_double_value, 207 Variable* var_double_value,
183 Label* rebox_double, 208 Label* rebox_double,
184 ExitPoint* exit_point) { 209 ExitPoint* exit_point) {
185 Comment("field_load"); 210 Comment("field_load");
186 Node* offset = DecodeWord<LoadHandler::FieldOffsetBits>(handler_word); 211 Node* offset = DecodeWord<LoadHandler::FieldOffsetBits>(handler_word);
187 212
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset), 291 WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset),
267 SmiConstant(Smi::FromInt(Isolate::kProtectorValid))), 292 SmiConstant(Smi::FromInt(Isolate::kProtectorValid))),
268 miss); 293 miss);
269 exit_point->Return(UndefinedConstant()); 294 exit_point->Return(UndefinedConstant());
270 } 295 }
271 296
272 Bind(&property); 297 Bind(&property);
273 Comment("property_load"); 298 Comment("property_load");
274 } 299 }
275 300
276 Label constant(this, Label::kDeferred), field(this), 301 Label constant(this), field(this), normal(this, Label::kDeferred);
jgruber 2017/03/03 13:31:14 Both constant and field cases can omit frame const
277 normal(this, Label::kDeferred);
278 GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForFields)), 302 GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForFields)),
279 &field); 303 &field);
280 304
281 Branch(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForConstants)), 305 Branch(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForConstants)),
282 &constant, &normal); 306 &constant, &normal);
283 307
284 Bind(&field); 308 Bind(&field);
285 HandleLoadField(holder, handler_word, &var_double_value, &rebox_double, 309 HandleLoadField(holder, handler_word, &var_double_value, &rebox_double,
286 exit_point); 310 exit_point);
287 311
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 var_transition.Bind(transition); 681 var_transition.Bind(transition);
658 Goto(&if_transition); 682 Goto(&if_transition);
659 } 683 }
660 684
661 Bind(&if_transition); 685 Bind(&if_transition);
662 { 686 {
663 Node* holder = p->receiver; 687 Node* holder = p->receiver;
664 Node* transition = var_transition.value(); 688 Node* transition = var_transition.value();
665 Node* handler_word = SmiUntag(smi_handler); 689 Node* handler_word = SmiUntag(smi_handler);
666 690
667 GotoIf(IsSetWord32<Map::Deprecated>(LoadMapBitField3(transition)), miss); 691 GotoIf(IsDeprecatedMap(transition), miss);
668 692
669 Node* handler_kind = DecodeWord<StoreHandler::KindBits>(handler_word); 693 Node* handler_kind = DecodeWord<StoreHandler::KindBits>(handler_word);
670 GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kStoreNormal)), 694 GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kStoreNormal)),
671 &if_store_normal); 695 &if_store_normal);
672 GotoIf(WordEqual(handler_kind, 696 GotoIf(WordEqual(handler_kind,
673 IntPtrConstant(StoreHandler::kTransitionToConstant)), 697 IntPtrConstant(StoreHandler::kTransitionToConstant)),
674 &if_transition_to_constant); 698 &if_transition_to_constant);
675 699
676 // Handle transitioning field stores. 700 // Handle transitioning field stores.
677 HandleStoreICSmiHandlerCase(handler_word, holder, p->value, transition, 701 HandleStoreICSmiHandlerCase(handler_word, holder, p->value, transition,
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after
1315 Bind(&return_undefined); 1339 Bind(&return_undefined);
1316 Return(UndefinedConstant()); 1340 Return(UndefinedConstant());
1317 } 1341 }
1318 } 1342 }
1319 1343
1320 void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, 1344 void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map,
1321 Node* instance_type, Node* key, 1345 Node* instance_type, Node* key,
1322 const LoadICParameters* p, 1346 const LoadICParameters* p,
1323 Label* slow, 1347 Label* slow,
1324 UseStubCache use_stub_cache) { 1348 UseStubCache use_stub_cache) {
1349 ExitPoint direct_exit(this);
1350
1325 Comment("key is unique name"); 1351 Comment("key is unique name");
1326 Label if_found_on_receiver(this), if_property_dictionary(this), 1352 Label if_found_on_receiver(this), if_property_dictionary(this),
1327 lookup_prototype_chain(this); 1353 lookup_prototype_chain(this);
1328 Variable var_details(this, MachineRepresentation::kWord32); 1354 Variable var_details(this, MachineRepresentation::kWord32);
1329 Variable var_value(this, MachineRepresentation::kTagged); 1355 Variable var_value(this, MachineRepresentation::kTagged);
1330 1356
1331 // Receivers requiring non-standard accesses (interceptors, access 1357 // Receivers requiring non-standard accesses (interceptors, access
1332 // checks, strings and string wrappers, proxies) are handled in the runtime. 1358 // checks, strings and string wrappers, proxies) are handled in the runtime.
1333 GotoIf(Int32LessThanOrEqual(instance_type, 1359 GotoIf(Int32LessThanOrEqual(instance_type,
1334 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), 1360 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
(...skipping 26 matching lines...) Expand all
1361 } 1387 }
1362 1388
1363 if (use_stub_cache == kUseStubCache) { 1389 if (use_stub_cache == kUseStubCache) {
1364 Bind(&stub_cache); 1390 Bind(&stub_cache);
1365 Comment("stub cache probe for fast property load"); 1391 Comment("stub cache probe for fast property load");
1366 Variable var_handler(this, MachineRepresentation::kTagged); 1392 Variable var_handler(this, MachineRepresentation::kTagged);
1367 Label found_handler(this, &var_handler), stub_cache_miss(this); 1393 Label found_handler(this, &var_handler), stub_cache_miss(this);
1368 TryProbeStubCache(isolate()->load_stub_cache(), receiver, key, 1394 TryProbeStubCache(isolate()->load_stub_cache(), receiver, key,
1369 &found_handler, &var_handler, &stub_cache_miss); 1395 &found_handler, &var_handler, &stub_cache_miss);
1370 Bind(&found_handler); 1396 Bind(&found_handler);
1371 { HandleLoadICHandlerCase(p, var_handler.value(), slow); } 1397 { HandleLoadICHandlerCase(p, var_handler.value(), slow, &direct_exit); }
1372 1398
1373 Bind(&stub_cache_miss); 1399 Bind(&stub_cache_miss);
1374 { 1400 {
1375 // TODO(jkummerow): Check if the property exists on the prototype 1401 // TODO(jkummerow): Check if the property exists on the prototype
1376 // chain. If it doesn't, then there's no point in missing. 1402 // chain. If it doesn't, then there's no point in missing.
1377 Comment("KeyedLoadGeneric_miss"); 1403 Comment("KeyedLoadGeneric_miss");
1378 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver, 1404 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver,
1379 p->name, p->slot, p->vector); 1405 p->name, p->slot, p->vector);
1380 } 1406 }
1381 } 1407 }
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
1570 Bind(&miss); 1596 Bind(&miss);
1571 { 1597 {
1572 IncrementCounter(counters->megamorphic_stub_cache_misses(), 1); 1598 IncrementCounter(counters->megamorphic_stub_cache_misses(), 1);
1573 Goto(if_miss); 1599 Goto(if_miss);
1574 } 1600 }
1575 } 1601 }
1576 1602
1577 //////////////////// Entry points into private implementation (one per stub). 1603 //////////////////// Entry points into private implementation (one per stub).
1578 1604
1579 void AccessorAssembler::LoadIC(const LoadICParameters* p) { 1605 void AccessorAssembler::LoadIC(const LoadICParameters* p) {
1606 // Must be kept in sync with Interpreter::BuildLoadIC.
1607
1608 ExitPoint direct_exit(this);
1609
1580 Variable var_handler(this, MachineRepresentation::kTagged); 1610 Variable var_handler(this, MachineRepresentation::kTagged);
1581 Label if_handler(this, &var_handler), try_polymorphic(this, Label::kDeferred), 1611 Label if_handler(this, &var_handler), non_monomorphic(this, Label::kDeferred),
1582 try_megamorphic(this, Label::kDeferred), 1612 miss(this, Label::kDeferred);
1583 try_uninitialized(this, Label::kDeferred), miss(this, Label::kDeferred);
1584 1613
1585 Node* receiver_map = LoadReceiverMap(p->receiver); 1614 Node* receiver_map = LoadReceiverMap(p->receiver);
1586 GotoIf(IsSetWord32<Map::Deprecated>(LoadMapBitField3(receiver_map)), &miss); 1615 GotoIf(IsDeprecatedMap(receiver_map), &miss);
1587 1616
1588 // Check monomorphic case. 1617 // Check monomorphic case.
1589 Node* feedback = 1618 Node* feedback =
1590 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, 1619 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
1591 &var_handler, &try_polymorphic); 1620 &var_handler, &non_monomorphic);
1592 Bind(&if_handler); 1621 Bind(&if_handler);
1593 { HandleLoadICHandlerCase(p, var_handler.value(), &miss); } 1622 HandleLoadICHandlerCase(p, var_handler.value(), &miss, &direct_exit);
1594 1623
1595 Bind(&try_polymorphic); 1624 Bind(&non_monomorphic);
1625 LoadIC_Noninlined(p, receiver_map, feedback, &var_handler, &if_handler, &miss,
1626 &direct_exit);
1627
1628 Bind(&miss);
1629 direct_exit.ReturnCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver,
1630 p->name, p->slot, p->vector);
1631 }
1632
1633 void AccessorAssembler::LoadIC_Noninlined(const LoadICParameters* p,
jgruber 2017/03/03 13:31:14 I don't have a better name for this. Right now it'
1634 Node* receiver_map, Node* feedback,
1635 Variable* var_handler,
1636 Label* if_handler, Label* miss,
1637 ExitPoint* exit_point) {
1638 Label try_megamorphic(this, Label::kDeferred),
1639 try_uninitialized(this, Label::kDeferred);
1640
1641 // Neither deprecated map nor monomorphic. These cases are handled in the
1642 // bytecode handler.
1643 CSA_ASSERT(this, Word32BinaryNot(IsDeprecatedMap(receiver_map)));
1644 CSA_ASSERT(this,
1645 WordNotEqual(receiver_map, LoadWeakCellValueUnchecked(feedback)));
1646 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep());
1647
1596 { 1648 {
1597 // Check polymorphic case. 1649 // Check polymorphic case.
1598 Comment("LoadIC_try_polymorphic"); 1650 Comment("LoadIC_try_polymorphic");
1599 GotoIfNot(WordEqual(LoadMap(feedback), FixedArrayMapConstant()), 1651 GotoIfNot(WordEqual(LoadMap(feedback), FixedArrayMapConstant()),
1600 &try_megamorphic); 1652 &try_megamorphic);
1601 HandlePolymorphicCase(receiver_map, feedback, &if_handler, &var_handler, 1653 HandlePolymorphicCase(receiver_map, feedback, if_handler, var_handler, miss,
1602 &miss, 2); 1654 2);
1603 } 1655 }
1604 1656
1605 Bind(&try_megamorphic); 1657 Bind(&try_megamorphic);
1606 { 1658 {
1607 // Check megamorphic case. 1659 // Check megamorphic case.
1608 GotoIfNot(WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), 1660 GotoIfNot(WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)),
1609 &try_uninitialized); 1661 &try_uninitialized);
1610 1662
1611 TryProbeStubCache(isolate()->load_stub_cache(), p->receiver, p->name, 1663 TryProbeStubCache(isolate()->load_stub_cache(), p->receiver, p->name,
1612 &if_handler, &var_handler, &miss); 1664 if_handler, var_handler, miss);
1613 } 1665 }
1666
1614 Bind(&try_uninitialized); 1667 Bind(&try_uninitialized);
1615 { 1668 {
1616 // Check uninitialized case. 1669 // Check uninitialized case.
1617 GotoIfNot( 1670 GotoIfNot(
1618 WordEqual(feedback, LoadRoot(Heap::kuninitialized_symbolRootIndex)), 1671 WordEqual(feedback, LoadRoot(Heap::kuninitialized_symbolRootIndex)),
1619 &miss); 1672 miss);
1620 TailCallStub(CodeFactory::LoadIC_Uninitialized(isolate()), p->context, 1673 exit_point->ReturnCallStub(CodeFactory::LoadIC_Uninitialized(isolate()),
1621 p->receiver, p->name, p->slot, p->vector); 1674 p->context, p->receiver, p->name, p->slot,
1622 } 1675 p->vector);
1623 Bind(&miss);
1624 {
1625 TailCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, p->name,
1626 p->slot, p->vector);
1627 } 1676 }
1628 } 1677 }
1629 1678
1630 void AccessorAssembler::LoadIC_Uninitialized(const LoadICParameters* p) { 1679 void AccessorAssembler::LoadIC_Uninitialized(const LoadICParameters* p) {
1631 Label miss(this); 1680 Label miss(this);
1632 Node* receiver = p->receiver; 1681 Node* receiver = p->receiver;
1633 GotoIf(TaggedIsSmi(receiver), &miss); 1682 GotoIf(TaggedIsSmi(receiver), &miss);
1634 Node* receiver_map = LoadMap(receiver); 1683 Node* receiver_map = LoadMap(receiver);
1635 Node* instance_type = LoadMapInstanceType(receiver_map); 1684 Node* instance_type = LoadMapInstanceType(receiver_map);
1636 1685
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1760 void AccessorAssembler::LoadGlobalIC_MissCase(const LoadICParameters* p, 1809 void AccessorAssembler::LoadGlobalIC_MissCase(const LoadICParameters* p,
1761 ExitPoint* exit_point) { 1810 ExitPoint* exit_point) {
1762 Comment("LoadGlobalIC_MissCase"); 1811 Comment("LoadGlobalIC_MissCase");
1763 1812
1764 exit_point->ReturnCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, 1813 exit_point->ReturnCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context,
1765 p->name, p->slot, p->vector); 1814 p->name, p->slot, p->vector);
1766 } 1815 }
1767 1816
1768 void AccessorAssembler::LoadGlobalIC(const LoadICParameters* p, 1817 void AccessorAssembler::LoadGlobalIC(const LoadICParameters* p,
1769 TypeofMode typeof_mode) { 1818 TypeofMode typeof_mode) {
1819 // Must be kept in sync with Interpreter::BuildLoadGlobal.
1820
1770 ExitPoint direct_exit(this); 1821 ExitPoint direct_exit(this);
1771 1822
1772 Label try_handler(this), miss(this); 1823 Label try_handler(this), miss(this);
1773 LoadGlobalIC_TryPropertyCellCase(p->vector, p->slot, &direct_exit, 1824 LoadGlobalIC_TryPropertyCellCase(p->vector, p->slot, &direct_exit,
1774 &try_handler, &miss); 1825 &try_handler, &miss);
1775 1826
1776 Bind(&try_handler); 1827 Bind(&try_handler);
1777 LoadGlobalIC_TryHandlerCase(p, typeof_mode, &direct_exit, &miss); 1828 LoadGlobalIC_TryHandlerCase(p, typeof_mode, &direct_exit, &miss);
1778 1829
1779 Bind(&miss); 1830 Bind(&miss);
1780 LoadGlobalIC_MissCase(p, &direct_exit); 1831 LoadGlobalIC_MissCase(p, &direct_exit);
1781 } 1832 }
1782 1833
1783 void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p) { 1834 void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p) {
1835 ExitPoint direct_exit(this);
1836
1784 Variable var_handler(this, MachineRepresentation::kTagged); 1837 Variable var_handler(this, MachineRepresentation::kTagged);
1785 Label if_handler(this, &var_handler), try_polymorphic(this, Label::kDeferred), 1838 Label if_handler(this, &var_handler), try_polymorphic(this, Label::kDeferred),
1786 try_megamorphic(this, Label::kDeferred), 1839 try_megamorphic(this, Label::kDeferred),
1787 try_polymorphic_name(this, Label::kDeferred), 1840 try_polymorphic_name(this, Label::kDeferred),
1788 miss(this, Label::kDeferred); 1841 miss(this, Label::kDeferred);
1789 1842
1790 Node* receiver_map = LoadReceiverMap(p->receiver); 1843 Node* receiver_map = LoadReceiverMap(p->receiver);
1791 GotoIf(IsSetWord32<Map::Deprecated>(LoadMapBitField3(receiver_map)), &miss); 1844 GotoIf(IsDeprecatedMap(receiver_map), &miss);
1792 1845
1793 // Check monomorphic case. 1846 // Check monomorphic case.
1794 Node* feedback = 1847 Node* feedback =
1795 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, 1848 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
1796 &var_handler, &try_polymorphic); 1849 &var_handler, &try_polymorphic);
1797 Bind(&if_handler); 1850 Bind(&if_handler);
1798 { HandleLoadICHandlerCase(p, var_handler.value(), &miss, kSupportElements); } 1851 {
1852 HandleLoadICHandlerCase(p, var_handler.value(), &miss, &direct_exit,
1853 kSupportElements);
1854 }
1799 1855
1800 Bind(&try_polymorphic); 1856 Bind(&try_polymorphic);
1801 { 1857 {
1802 // Check polymorphic case. 1858 // Check polymorphic case.
1803 Comment("KeyedLoadIC_try_polymorphic"); 1859 Comment("KeyedLoadIC_try_polymorphic");
1804 GotoIfNot(WordEqual(LoadMap(feedback), FixedArrayMapConstant()), 1860 GotoIfNot(WordEqual(LoadMap(feedback), FixedArrayMapConstant()),
1805 &try_megamorphic); 1861 &try_megamorphic);
1806 HandlePolymorphicCase(receiver_map, feedback, &if_handler, &var_handler, 1862 HandlePolymorphicCase(receiver_map, feedback, &if_handler, &var_handler,
1807 &miss, 2); 1863 &miss, 2);
1808 } 1864 }
1809 1865
1810 Bind(&try_megamorphic); 1866 Bind(&try_megamorphic);
1811 { 1867 {
1812 // Check megamorphic case. 1868 // Check megamorphic case.
1813 Comment("KeyedLoadIC_try_megamorphic"); 1869 Comment("KeyedLoadIC_try_megamorphic");
1814 GotoIfNot(WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), 1870 GotoIfNot(WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)),
1815 &try_polymorphic_name); 1871 &try_polymorphic_name);
1816 // TODO(jkummerow): Inline this? Or some of it? 1872 // TODO(jkummerow): Inline this? Or some of it?
1817 TailCallStub(CodeFactory::KeyedLoadIC_Megamorphic(isolate()), p->context, 1873 TailCallStub(CodeFactory::KeyedLoadIC_Megamorphic(isolate()), p->context,
1818 p->receiver, p->name, p->slot, p->vector); 1874 p->receiver, p->name, p->slot, p->vector);
1819 } 1875 }
1820 Bind(&try_polymorphic_name); 1876 Bind(&try_polymorphic_name);
1821 { 1877 {
1822 // We might have a name in feedback, and a fixed array in the next slot. 1878 // We might have a name in feedback, and a fixed array in the next slot.
1823 Comment("KeyedLoadIC_try_polymorphic_name"); 1879 Comment("KeyedLoadIC_try_polymorphic_name");
1824 GotoIfNot(WordEqual(feedback, p->name), &miss); 1880 GotoIfNot(WordEqual(feedback, p->name), &miss);
1825 // If the name comparison succeeded, we know we have a fixed array with 1881 // If the name comparison succeeded, we know we have a fixed array with
1826 // at least one map/handler pair. 1882 // at least one map/handler pair.
1827 Node* offset = ElementOffsetFromIndex( 1883 Node* array = LoadFeedbackSlot(p->vector, p->slot, kPointerSize);
1828 p->slot, FAST_HOLEY_ELEMENTS, 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, 1884 HandlePolymorphicCase(receiver_map, array, &if_handler, &var_handler, &miss,
1832 1); 1885 1);
1833 } 1886 }
1834 Bind(&miss); 1887 Bind(&miss);
1835 { 1888 {
1836 Comment("KeyedLoadIC_miss"); 1889 Comment("KeyedLoadIC_miss");
1837 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver, 1890 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver,
1838 p->name, p->slot, p->vector); 1891 p->name, p->slot, p->vector);
1839 } 1892 }
1840 } 1893 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1874 p->name); 1927 p->name);
1875 } 1928 }
1876 } 1929 }
1877 1930
1878 void AccessorAssembler::StoreIC(const StoreICParameters* p) { 1931 void AccessorAssembler::StoreIC(const StoreICParameters* p) {
1879 Variable var_handler(this, MachineRepresentation::kTagged); 1932 Variable var_handler(this, MachineRepresentation::kTagged);
1880 Label if_handler(this, &var_handler), try_polymorphic(this, Label::kDeferred), 1933 Label if_handler(this, &var_handler), try_polymorphic(this, Label::kDeferred),
1881 try_megamorphic(this, Label::kDeferred), miss(this, Label::kDeferred); 1934 try_megamorphic(this, Label::kDeferred), miss(this, Label::kDeferred);
1882 1935
1883 Node* receiver_map = LoadReceiverMap(p->receiver); 1936 Node* receiver_map = LoadReceiverMap(p->receiver);
1884 GotoIf(IsSetWord32<Map::Deprecated>(LoadMapBitField3(receiver_map)), &miss); 1937 GotoIf(IsDeprecatedMap(receiver_map), &miss);
1885 1938
1886 // Check monomorphic case. 1939 // Check monomorphic case.
1887 Node* feedback = 1940 Node* feedback =
1888 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, 1941 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
1889 &var_handler, &try_polymorphic); 1942 &var_handler, &try_polymorphic);
1890 Bind(&if_handler); 1943 Bind(&if_handler);
1891 { 1944 {
1892 Comment("StoreIC_if_handler"); 1945 Comment("StoreIC_if_handler");
1893 HandleStoreICHandlerCase(p, var_handler.value(), &miss); 1946 HandleStoreICHandlerCase(p, var_handler.value(), &miss);
1894 } 1947 }
(...skipping 30 matching lines...) Expand all
1925 Label miss(this, Label::kDeferred); 1978 Label miss(this, Label::kDeferred);
1926 { 1979 {
1927 Variable var_handler(this, MachineRepresentation::kTagged); 1980 Variable var_handler(this, MachineRepresentation::kTagged);
1928 1981
1929 Label if_handler(this, &var_handler), 1982 Label if_handler(this, &var_handler),
1930 try_polymorphic(this, Label::kDeferred), 1983 try_polymorphic(this, Label::kDeferred),
1931 try_megamorphic(this, Label::kDeferred), 1984 try_megamorphic(this, Label::kDeferred),
1932 try_polymorphic_name(this, Label::kDeferred); 1985 try_polymorphic_name(this, Label::kDeferred);
1933 1986
1934 Node* receiver_map = LoadReceiverMap(p->receiver); 1987 Node* receiver_map = LoadReceiverMap(p->receiver);
1935 GotoIf(IsSetWord32<Map::Deprecated>(LoadMapBitField3(receiver_map)), &miss); 1988 GotoIf(IsDeprecatedMap(receiver_map), &miss);
1936 1989
1937 // Check monomorphic case. 1990 // Check monomorphic case.
1938 Node* feedback = 1991 Node* feedback =
1939 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, 1992 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
1940 &var_handler, &try_polymorphic); 1993 &var_handler, &try_polymorphic);
1941 Bind(&if_handler); 1994 Bind(&if_handler);
1942 { 1995 {
1943 Comment("KeyedStoreIC_if_handler"); 1996 Comment("KeyedStoreIC_if_handler");
1944 HandleStoreICHandlerCase(p, var_handler.value(), &miss, kSupportElements); 1997 HandleStoreICHandlerCase(p, var_handler.value(), &miss, kSupportElements);
1945 } 1998 }
(...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); 2059 p->context, p->receiver, p->name, p->value, p->slot, p->vector);
2007 } 2060 }
2008 2061
2009 Bind(&try_polymorphic_name); 2062 Bind(&try_polymorphic_name);
2010 { 2063 {
2011 // We might have a name in feedback, and a fixed array in the next slot. 2064 // We might have a name in feedback, and a fixed array in the next slot.
2012 Comment("KeyedStoreIC_try_polymorphic_name"); 2065 Comment("KeyedStoreIC_try_polymorphic_name");
2013 GotoIfNot(WordEqual(feedback, p->name), &miss); 2066 GotoIfNot(WordEqual(feedback, p->name), &miss);
2014 // If the name comparison succeeded, we know we have a FixedArray with 2067 // If the name comparison succeeded, we know we have a FixedArray with
2015 // at least one map/handler pair. 2068 // at least one map/handler pair.
2016 Node* offset = ElementOffsetFromIndex( 2069 Node* array = LoadFeedbackSlot(p->vector, p->slot, kPointerSize);
2017 p->slot, FAST_HOLEY_ELEMENTS, 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, 2070 HandlePolymorphicCase(receiver_map, array, &if_handler, &var_handler,
2021 &miss, 1); 2071 &miss, 1);
2022 } 2072 }
2023 } 2073 }
2024 Bind(&miss); 2074 Bind(&miss);
2025 { 2075 {
2026 Comment("KeyedStoreIC_miss"); 2076 Comment("KeyedStoreIC_miss");
2027 TailCallRuntime(Runtime::kKeyedStoreIC_Miss, p->context, p->value, p->slot, 2077 TailCallRuntime(Runtime::kKeyedStoreIC_Miss, p->context, p->value, p->slot,
2028 p->vector, p->receiver, p->name); 2078 p->vector, p->receiver, p->name);
2029 } 2079 }
2030 } 2080 }
2031 2081
2032 //////////////////// Public methods. 2082 //////////////////// Public methods.
2033 2083
2034 void AccessorAssembler::GenerateLoadIC() { 2084 void AccessorAssembler::GenerateLoadIC() {
2035 typedef LoadWithVectorDescriptor Descriptor; 2085 typedef LoadWithVectorDescriptor Descriptor;
2036 2086
2037 Node* receiver = Parameter(Descriptor::kReceiver); 2087 Node* receiver = Parameter(Descriptor::kReceiver);
2038 Node* name = Parameter(Descriptor::kName); 2088 Node* name = Parameter(Descriptor::kName);
2039 Node* slot = Parameter(Descriptor::kSlot); 2089 Node* slot = Parameter(Descriptor::kSlot);
2040 Node* vector = Parameter(Descriptor::kVector); 2090 Node* vector = Parameter(Descriptor::kVector);
2041 Node* context = Parameter(Descriptor::kContext); 2091 Node* context = Parameter(Descriptor::kContext);
2042 2092
2043 LoadICParameters p(context, receiver, name, slot, vector); 2093 LoadICParameters p(context, receiver, name, slot, vector);
2044 LoadIC(&p); 2094 LoadIC(&p);
2045 } 2095 }
2046 2096
2097 void AccessorAssembler::GenerateLoadIC_Noninlined() {
2098 typedef LoadWithVectorDescriptor Descriptor;
2099
2100 Node* receiver = Parameter(Descriptor::kReceiver);
2101 Node* name = Parameter(Descriptor::kName);
2102 Node* slot = Parameter(Descriptor::kSlot);
2103 Node* vector = Parameter(Descriptor::kVector);
2104 Node* context = Parameter(Descriptor::kContext);
2105
2106 ExitPoint direct_exit(this);
2107 Variable var_handler(this, MachineRepresentation::kTagged);
2108 Label if_handler(this, &var_handler), miss(this, Label::kDeferred);
2109
2110 Node* receiver_map = LoadReceiverMap(receiver);
2111 Node* feedback = LoadFeedbackSlot(vector, slot, 0);
jgruber 2017/03/03 13:31:14 We could avoid these two loads if we pass the map
2112
2113 LoadICParameters p(context, receiver, name, slot, vector);
2114 LoadIC_Noninlined(&p, receiver_map, feedback, &var_handler, &if_handler,
2115 &miss, &direct_exit);
2116
2117 Bind(&if_handler);
2118 HandleLoadICHandlerCase(&p, var_handler.value(), &miss, &direct_exit);
2119
2120 Bind(&miss);
2121 direct_exit.ReturnCallRuntime(Runtime::kLoadIC_Miss, context, receiver, name,
2122 slot, vector);
2123 }
2124
2047 void AccessorAssembler::GenerateLoadIC_Uninitialized() { 2125 void AccessorAssembler::GenerateLoadIC_Uninitialized() {
2048 typedef LoadWithVectorDescriptor Descriptor; 2126 typedef LoadWithVectorDescriptor Descriptor;
2049 2127
2050 Node* receiver = Parameter(Descriptor::kReceiver); 2128 Node* receiver = Parameter(Descriptor::kReceiver);
2051 Node* name = Parameter(Descriptor::kName); 2129 Node* name = Parameter(Descriptor::kName);
2052 Node* slot = Parameter(Descriptor::kSlot); 2130 Node* slot = Parameter(Descriptor::kSlot);
2053 Node* vector = Parameter(Descriptor::kVector); 2131 Node* vector = Parameter(Descriptor::kVector);
2054 Node* context = Parameter(Descriptor::kContext); 2132 Node* context = Parameter(Descriptor::kContext);
2055 2133
2056 LoadICParameters p(context, receiver, name, slot, vector); 2134 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); 2306 Node* context = Parameter(Descriptor::kContext);
2229 Node* vector = LoadFeedbackVectorForStub(); 2307 Node* vector = LoadFeedbackVectorForStub();
2230 2308
2231 Callable callable = 2309 Callable callable =
2232 CodeFactory::KeyedStoreICInOptimizedCode(isolate(), language_mode); 2310 CodeFactory::KeyedStoreICInOptimizedCode(isolate(), language_mode);
2233 TailCallStub(callable, context, receiver, name, value, slot, vector); 2311 TailCallStub(callable, context, receiver, name, value, slot, vector);
2234 } 2312 }
2235 2313
2236 } // namespace internal 2314 } // namespace internal
2237 } // namespace v8 2315 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698