OLD | NEW |
---|---|
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/ic/accessor-assembler.h" | 5 #include "src/ic/accessor-assembler.h" |
6 #include "src/ic/accessor-assembler-impl.h" | 6 #include "src/ic/accessor-assembler-impl.h" |
7 | 7 |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/ic/handler-configuration.h" | 10 #include "src/ic/handler-configuration.h" |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
465 Variable var_smi_handler(this, MachineRepresentation::kTagged); | 465 Variable var_smi_handler(this, MachineRepresentation::kTagged); |
466 Label if_smi_handler(this); | 466 Label if_smi_handler(this); |
467 HandleLoadICProtoHandlerCase(&p, handler, &var_holder, &var_smi_handler, | 467 HandleLoadICProtoHandlerCase(&p, handler, &var_holder, &var_smi_handler, |
468 &if_smi_handler, miss, | 468 &if_smi_handler, miss, |
469 throw_reference_error_if_nonexistent); | 469 throw_reference_error_if_nonexistent); |
470 Bind(&if_smi_handler); | 470 Bind(&if_smi_handler); |
471 HandleLoadICSmiHandlerCase(&p, var_holder.value(), var_smi_handler.value(), | 471 HandleLoadICSmiHandlerCase(&p, var_holder.value(), var_smi_handler.value(), |
472 miss, kOnlyProperties); | 472 miss, kOnlyProperties); |
473 } | 473 } |
474 | 474 |
475 void AccessorAssemblerImpl::HandleStoreICHandlerCase(const StoreICParameters* p, | 475 void AccessorAssemblerImpl::HandleStoreICHandlerCase( |
476 Node* handler, | 476 const StoreICParameters* p, Node* handler, Label* miss, |
477 Label* miss) { | 477 ElementSupport support_elements) { |
478 Label if_smi_handler(this); | 478 Label if_smi_handler(this), if_nonsmi_handler(this); |
479 Label try_proto_handler(this), call_handler(this); | 479 Label if_proto_handler(this), if_element_handler(this), call_handler(this); |
480 | 480 |
481 Branch(TaggedIsSmi(handler), &if_smi_handler, &try_proto_handler); | 481 Branch(TaggedIsSmi(handler), &if_smi_handler, &if_nonsmi_handler); |
482 | 482 |
483 // |handler| is a Smi, encoding what to do. See SmiHandler methods | 483 // |handler| is a Smi, encoding what to do. See SmiHandler methods |
484 // for the encoding format. | 484 // for the encoding format. |
485 Bind(&if_smi_handler); | 485 Bind(&if_smi_handler); |
486 { | 486 { |
487 Node* holder = p->receiver; | 487 Node* holder = p->receiver; |
488 Node* handler_word = SmiUntag(handler); | 488 Node* handler_word = SmiUntag(handler); |
489 | 489 |
490 // Handle non-transitioning field stores. | 490 // Handle non-transitioning field stores. |
491 HandleStoreICSmiHandlerCase(handler_word, holder, p->value, nullptr, miss); | 491 HandleStoreICSmiHandlerCase(handler_word, holder, p->value, nullptr, miss); |
492 } | 492 } |
493 | 493 |
494 Bind(&try_proto_handler); | 494 Bind(&if_nonsmi_handler); |
495 { | 495 { |
496 GotoIf(IsCodeMap(LoadMap(handler)), &call_handler); | 496 Node* handler_map = LoadMap(handler); |
497 if (support_elements == kSupportElements) { | |
498 GotoIf(IsTuple2Map(handler_map), &if_element_handler); | |
499 } | |
500 Branch(IsCodeMap(handler_map), &call_handler, &if_proto_handler); | |
501 } | |
502 | |
503 if (support_elements == kSupportElements) { | |
504 Bind(&if_element_handler); | |
505 { HandleStoreICElementHandlerCase(p, handler, miss); } | |
506 } | |
507 | |
508 Bind(&if_proto_handler); | |
509 { | |
497 HandleStoreICProtoHandler(p, handler, miss); | 510 HandleStoreICProtoHandler(p, handler, miss); |
498 } | 511 } |
499 | 512 |
500 // |handler| is a heap object. Must be code, call it. | 513 // |handler| is a heap object. Must be code, call it. |
501 Bind(&call_handler); | 514 Bind(&call_handler); |
502 { | 515 { |
503 StoreWithVectorDescriptor descriptor(isolate()); | 516 StoreWithVectorDescriptor descriptor(isolate()); |
504 TailCallStub(descriptor, handler, p->context, p->receiver, p->name, | 517 TailCallStub(descriptor, handler, p->context, p->receiver, p->name, |
505 p->value, p->slot, p->vector); | 518 p->value, p->slot, p->vector); |
506 } | 519 } |
507 } | 520 } |
508 | 521 |
522 void AccessorAssemblerImpl::HandleStoreICElementHandlerCase( | |
523 const StoreICParameters* p, Node* handler, Label* miss) { | |
524 Comment("HandleStoreICElementHandlerCase"); | |
525 Node* validity_cell = LoadObjectField(handler, Tuple2::kValue1Offset); | |
526 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset); | |
527 GotoIf(WordNotEqual(cell_value, | |
528 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))), | |
529 miss); | |
530 | |
531 Node* code_handler = LoadObjectField(handler, Tuple2::kValue2Offset); | |
532 CSA_ASSERT(this, IsCodeMap(LoadMap(code_handler))); | |
533 | |
534 StoreWithVectorDescriptor descriptor(isolate()); | |
535 TailCallStub(descriptor, code_handler, p->context, p->receiver, p->name, | |
536 p->value, p->slot, p->vector); | |
537 } | |
538 | |
509 void AccessorAssemblerImpl::HandleStoreICProtoHandler( | 539 void AccessorAssemblerImpl::HandleStoreICProtoHandler( |
510 const StoreICParameters* p, Node* handler, Label* miss) { | 540 const StoreICParameters* p, Node* handler, Label* miss) { |
511 // IC dispatchers rely on these assumptions to be held. | 541 // IC dispatchers rely on these assumptions to be held. |
512 STATIC_ASSERT(FixedArray::kLengthOffset == | 542 STATIC_ASSERT(FixedArray::kLengthOffset == |
513 StoreHandler::kTransitionCellOffset); | 543 StoreHandler::kTransitionCellOffset); |
514 DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kSmiHandlerIndex), | 544 DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kSmiHandlerIndex), |
515 StoreHandler::kSmiHandlerOffset); | 545 StoreHandler::kSmiHandlerOffset); |
516 DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kValidityCellIndex), | 546 DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kValidityCellIndex), |
517 StoreHandler::kValidityCellOffset); | 547 StoreHandler::kValidityCellOffset); |
518 | 548 |
(...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1499 | 1529 |
1500 Node* receiver_map = LoadReceiverMap(p->receiver); | 1530 Node* receiver_map = LoadReceiverMap(p->receiver); |
1501 | 1531 |
1502 // Check monomorphic case. | 1532 // Check monomorphic case. |
1503 Node* feedback = | 1533 Node* feedback = |
1504 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, | 1534 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, |
1505 &var_handler, &try_polymorphic); | 1535 &var_handler, &try_polymorphic); |
1506 Bind(&if_handler); | 1536 Bind(&if_handler); |
1507 { | 1537 { |
1508 Comment("KeyedStoreIC_if_handler"); | 1538 Comment("KeyedStoreIC_if_handler"); |
1509 HandleStoreICHandlerCase(p, var_handler.value(), &miss); | 1539 HandleStoreICHandlerCase(p, var_handler.value(), &miss, kSupportElements); |
1510 } | 1540 } |
1511 | 1541 |
1512 Bind(&try_polymorphic); | 1542 Bind(&try_polymorphic); |
1513 { | 1543 { |
1514 // CheckPolymorphic case. | 1544 // CheckPolymorphic case. |
1515 Comment("KeyedStoreIC_try_polymorphic"); | 1545 Comment("KeyedStoreIC_try_polymorphic"); |
1516 GotoUnless( | 1546 GotoUnless( |
1517 WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)), | 1547 WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)), |
1518 &try_megamorphic); | 1548 &try_megamorphic); |
1519 Label if_transition_handler(this); | 1549 Label if_transition_handler(this); |
1520 Variable var_transition_map_cell(this, MachineRepresentation::kTagged); | 1550 Variable var_transition_map_cell(this, MachineRepresentation::kTagged); |
1521 HandleKeyedStorePolymorphicCase(receiver_map, feedback, &if_handler, | 1551 HandleKeyedStorePolymorphicCase(receiver_map, feedback, &if_handler, |
1522 &var_handler, &if_transition_handler, | 1552 &var_handler, &if_transition_handler, |
1523 &var_transition_map_cell, &miss); | 1553 &var_transition_map_cell, &miss); |
1524 Bind(&if_transition_handler); | 1554 Bind(&if_transition_handler); |
1525 Comment("KeyedStoreIC_polymorphic_transition"); | 1555 Comment("KeyedStoreIC_polymorphic_transition"); |
1526 Node* transition_map = | 1556 { |
1527 LoadWeakCellValue(var_transition_map_cell.value(), &miss); | 1557 Node* handler = var_handler.value(); |
1528 StoreTransitionDescriptor descriptor(isolate()); | 1558 CSA_ASSERT(this, IsTuple2Map(LoadMap(handler))); |
1529 TailCallStub(descriptor, var_handler.value(), p->context, p->receiver, | 1559 |
1530 p->name, transition_map, p->value, p->slot, p->vector); | 1560 // Check validity cell. |
1561 // HandleStoreICElementHandlerCase(p, handler, miss); | |
Jakob Kummerow
2016/11/28 18:48:05
leftover?
Igor Sheludko
2016/11/28 22:25:54
Done.
| |
1562 | |
1563 Node* validity_cell = LoadObjectField(handler, Tuple2::kValue1Offset); | |
1564 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset); | |
1565 GotoIf(WordNotEqual(cell_value, | |
1566 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))), | |
1567 &miss); | |
1568 | |
1569 Node* code_handler = LoadObjectField(handler, Tuple2::kValue2Offset); | |
1570 CSA_ASSERT(this, IsCodeMap(LoadMap(code_handler))); | |
1571 | |
1572 Node* transition_map = | |
1573 LoadWeakCellValue(var_transition_map_cell.value(), &miss); | |
1574 StoreTransitionDescriptor descriptor(isolate()); | |
1575 TailCallStub(descriptor, code_handler, p->context, p->receiver, p->name, | |
1576 transition_map, p->value, p->slot, p->vector); | |
1577 } | |
1531 } | 1578 } |
1532 | 1579 |
1533 Bind(&try_megamorphic); | 1580 Bind(&try_megamorphic); |
1534 { | 1581 { |
1535 // Check megamorphic case. | 1582 // Check megamorphic case. |
1536 Comment("KeyedStoreIC_try_megamorphic"); | 1583 Comment("KeyedStoreIC_try_megamorphic"); |
1537 GotoUnless( | 1584 GotoUnless( |
1538 WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), | 1585 WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), |
1539 &try_polymorphic_name); | 1586 &try_polymorphic_name); |
1540 TailCallStub( | 1587 TailCallStub( |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1767 void AccessorAssembler::GenerateKeyedStoreICTrampolineTF( | 1814 void AccessorAssembler::GenerateKeyedStoreICTrampolineTF( |
1768 CodeAssemblerState* state, LanguageMode language_mode) { | 1815 CodeAssemblerState* state, LanguageMode language_mode) { |
1769 AccessorAssemblerImpl assembler(state); | 1816 AccessorAssemblerImpl assembler(state); |
1770 assembler.GenerateKeyedStoreICTrampolineTF(language_mode); | 1817 assembler.GenerateKeyedStoreICTrampolineTF(language_mode); |
1771 } | 1818 } |
1772 | 1819 |
1773 #undef ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE | 1820 #undef ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE |
1774 | 1821 |
1775 } // namespace internal | 1822 } // namespace internal |
1776 } // namespace v8 | 1823 } // namespace v8 |
OLD | NEW |