| 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( |   475 void AccessorAssemblerImpl::HandleStoreICHandlerCase(const StoreICParameters* p, | 
|   476     const StoreICParameters* p, Node* handler, Label* miss, |   476                                                      Node* handler, | 
|   477     ElementSupport support_elements) { |   477                                                      Label* miss) { | 
|   478   Label if_smi_handler(this), if_nonsmi_handler(this); |   478   Label if_smi_handler(this); | 
|   479   Label if_proto_handler(this), if_element_handler(this), call_handler(this); |   479   Label try_proto_handler(this), call_handler(this); | 
|   480  |   480  | 
|   481   Branch(TaggedIsSmi(handler), &if_smi_handler, &if_nonsmi_handler); |   481   Branch(TaggedIsSmi(handler), &if_smi_handler, &try_proto_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(&if_nonsmi_handler); |   494   Bind(&try_proto_handler); | 
|   495   { |   495   { | 
|   496     Node* handler_map = LoadMap(handler); |   496     GotoIf(IsCodeMap(LoadMap(handler)), &call_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   { |  | 
|   510     HandleStoreICProtoHandler(p, handler, miss); |   497     HandleStoreICProtoHandler(p, handler, miss); | 
|   511   } |   498   } | 
|   512  |   499  | 
|   513   // |handler| is a heap object. Must be code, call it. |   500   // |handler| is a heap object. Must be code, call it. | 
|   514   Bind(&call_handler); |   501   Bind(&call_handler); | 
|   515   { |   502   { | 
|   516     StoreWithVectorDescriptor descriptor(isolate()); |   503     StoreWithVectorDescriptor descriptor(isolate()); | 
|   517     TailCallStub(descriptor, handler, p->context, p->receiver, p->name, |   504     TailCallStub(descriptor, handler, p->context, p->receiver, p->name, | 
|   518                  p->value, p->slot, p->vector); |   505                  p->value, p->slot, p->vector); | 
|   519   } |   506   } | 
|   520 } |   507 } | 
|   521  |   508  | 
|   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  |  | 
|   539 void AccessorAssemblerImpl::HandleStoreICProtoHandler( |   509 void AccessorAssemblerImpl::HandleStoreICProtoHandler( | 
|   540     const StoreICParameters* p, Node* handler, Label* miss) { |   510     const StoreICParameters* p, Node* handler, Label* miss) { | 
|   541   // IC dispatchers rely on these assumptions to be held. |   511   // IC dispatchers rely on these assumptions to be held. | 
|   542   STATIC_ASSERT(FixedArray::kLengthOffset == |   512   STATIC_ASSERT(FixedArray::kLengthOffset == | 
|   543                 StoreHandler::kTransitionCellOffset); |   513                 StoreHandler::kTransitionCellOffset); | 
|   544   DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kSmiHandlerIndex), |   514   DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kSmiHandlerIndex), | 
|   545             StoreHandler::kSmiHandlerOffset); |   515             StoreHandler::kSmiHandlerOffset); | 
|   546   DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kValidityCellIndex), |   516   DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kValidityCellIndex), | 
|   547             StoreHandler::kValidityCellOffset); |   517             StoreHandler::kValidityCellOffset); | 
|   548  |   518  | 
| (...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1529  |  1499  | 
|  1530   Node* receiver_map = LoadReceiverMap(p->receiver); |  1500   Node* receiver_map = LoadReceiverMap(p->receiver); | 
|  1531  |  1501  | 
|  1532   // Check monomorphic case. |  1502   // Check monomorphic case. | 
|  1533   Node* feedback = |  1503   Node* feedback = | 
|  1534       TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, |  1504       TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, | 
|  1535                          &var_handler, &try_polymorphic); |  1505                          &var_handler, &try_polymorphic); | 
|  1536   Bind(&if_handler); |  1506   Bind(&if_handler); | 
|  1537   { |  1507   { | 
|  1538     Comment("KeyedStoreIC_if_handler"); |  1508     Comment("KeyedStoreIC_if_handler"); | 
|  1539     HandleStoreICHandlerCase(p, var_handler.value(), &miss, kSupportElements); |  1509     HandleStoreICHandlerCase(p, var_handler.value(), &miss); | 
|  1540   } |  1510   } | 
|  1541  |  1511  | 
|  1542   Bind(&try_polymorphic); |  1512   Bind(&try_polymorphic); | 
|  1543   { |  1513   { | 
|  1544     // CheckPolymorphic case. |  1514     // CheckPolymorphic case. | 
|  1545     Comment("KeyedStoreIC_try_polymorphic"); |  1515     Comment("KeyedStoreIC_try_polymorphic"); | 
|  1546     GotoUnless( |  1516     GotoUnless( | 
|  1547         WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)), |  1517         WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)), | 
|  1548         &try_megamorphic); |  1518         &try_megamorphic); | 
|  1549     Label if_transition_handler(this); |  1519     Label if_transition_handler(this); | 
|  1550     Variable var_transition_map_cell(this, MachineRepresentation::kTagged); |  1520     Variable var_transition_map_cell(this, MachineRepresentation::kTagged); | 
|  1551     HandleKeyedStorePolymorphicCase(receiver_map, feedback, &if_handler, |  1521     HandleKeyedStorePolymorphicCase(receiver_map, feedback, &if_handler, | 
|  1552                                     &var_handler, &if_transition_handler, |  1522                                     &var_handler, &if_transition_handler, | 
|  1553                                     &var_transition_map_cell, &miss); |  1523                                     &var_transition_map_cell, &miss); | 
|  1554     Bind(&if_transition_handler); |  1524     Bind(&if_transition_handler); | 
|  1555     Comment("KeyedStoreIC_polymorphic_transition"); |  1525     Comment("KeyedStoreIC_polymorphic_transition"); | 
|  1556     { |  1526     Node* transition_map = | 
|  1557       Node* handler = var_handler.value(); |  1527         LoadWeakCellValue(var_transition_map_cell.value(), &miss); | 
|  1558       CSA_ASSERT(this, IsTuple2Map(LoadMap(handler))); |  1528     StoreTransitionDescriptor descriptor(isolate()); | 
|  1559  |  1529     TailCallStub(descriptor, var_handler.value(), p->context, p->receiver, | 
|  1560       // Check validity cell. |  1530                  p->name, transition_map, p->value, p->slot, p->vector); | 
|  1561       Node* validity_cell = LoadObjectField(handler, Tuple2::kValue1Offset); |  | 
|  1562       Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset); |  | 
|  1563       GotoIf(WordNotEqual(cell_value, |  | 
|  1564                           SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))), |  | 
|  1565              &miss); |  | 
|  1566  |  | 
|  1567       Node* code_handler = LoadObjectField(handler, Tuple2::kValue2Offset); |  | 
|  1568       CSA_ASSERT(this, IsCodeMap(LoadMap(code_handler))); |  | 
|  1569  |  | 
|  1570       Node* transition_map = |  | 
|  1571           LoadWeakCellValue(var_transition_map_cell.value(), &miss); |  | 
|  1572       StoreTransitionDescriptor descriptor(isolate()); |  | 
|  1573       TailCallStub(descriptor, code_handler, p->context, p->receiver, p->name, |  | 
|  1574                    transition_map, p->value, p->slot, p->vector); |  | 
|  1575     } |  | 
|  1576   } |  1531   } | 
|  1577  |  1532  | 
|  1578   Bind(&try_megamorphic); |  1533   Bind(&try_megamorphic); | 
|  1579   { |  1534   { | 
|  1580     // Check megamorphic case. |  1535     // Check megamorphic case. | 
|  1581     Comment("KeyedStoreIC_try_megamorphic"); |  1536     Comment("KeyedStoreIC_try_megamorphic"); | 
|  1582     GotoUnless( |  1537     GotoUnless( | 
|  1583         WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), |  1538         WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), | 
|  1584         &try_polymorphic_name); |  1539         &try_polymorphic_name); | 
|  1585     TailCallStub( |  1540     TailCallStub( | 
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1812 void AccessorAssembler::GenerateKeyedStoreICTrampolineTF( |  1767 void AccessorAssembler::GenerateKeyedStoreICTrampolineTF( | 
|  1813     CodeAssemblerState* state, LanguageMode language_mode) { |  1768     CodeAssemblerState* state, LanguageMode language_mode) { | 
|  1814   AccessorAssemblerImpl assembler(state); |  1769   AccessorAssemblerImpl assembler(state); | 
|  1815   assembler.GenerateKeyedStoreICTrampolineTF(language_mode); |  1770   assembler.GenerateKeyedStoreICTrampolineTF(language_mode); | 
|  1816 } |  1771 } | 
|  1817  |  1772  | 
|  1818 #undef ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE |  1773 #undef ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE | 
|  1819  |  1774  | 
|  1820 }  // namespace internal |  1775 }  // namespace internal | 
|  1821 }  // namespace v8 |  1776 }  // namespace v8 | 
| OLD | NEW |