| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
| 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/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/compiler.h" | 10 #include "src/compiler.h" |
| (...skipping 1228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1239 __ CallStub(&stub); | 1239 __ CallStub(&stub); |
| 1240 } else { | 1240 } else { |
| 1241 __ Push(info); | 1241 __ Push(info); |
| 1242 __ CallRuntime( | 1242 __ CallRuntime( |
| 1243 pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1); | 1243 pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1); |
| 1244 } | 1244 } |
| 1245 context()->Plug(x0); | 1245 context()->Plug(x0); |
| 1246 } | 1246 } |
| 1247 | 1247 |
| 1248 | 1248 |
| 1249 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1249 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, |
| 1250 int offset, | 1250 FeedbackVectorICSlot slot) { |
| 1251 FeedbackVectorICSlot slot) { | 1251 DCHECK(NeedsHomeObject(initializer)); |
| 1252 if (NeedsHomeObject(initializer)) { | 1252 __ Peek(StoreDescriptor::ReceiverRegister(), 0); |
| 1253 __ Peek(StoreDescriptor::ReceiverRegister(), 0); | 1253 __ Mov(StoreDescriptor::NameRegister(), |
| 1254 __ Mov(StoreDescriptor::NameRegister(), | 1254 Operand(isolate()->factory()->home_object_symbol())); |
| 1255 Operand(isolate()->factory()->home_object_symbol())); | 1255 __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize); |
| 1256 __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize); | 1256 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1257 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 1257 CallStoreIC(); |
| 1258 CallStoreIC(); | |
| 1259 } | |
| 1260 } | 1258 } |
| 1261 | 1259 |
| 1262 | 1260 |
| 1261 void FullCodeGenerator::EmitSetHomeObjectAccumulator( |
| 1262 Expression* initializer, int offset, FeedbackVectorICSlot slot) { |
| 1263 DCHECK(NeedsHomeObject(initializer)); |
| 1264 __ Move(StoreDescriptor::ReceiverRegister(), x0); |
| 1265 __ Mov(StoreDescriptor::NameRegister(), |
| 1266 Operand(isolate()->factory()->home_object_symbol())); |
| 1267 __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize); |
| 1268 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1269 CallStoreIC(); |
| 1270 } |
| 1271 |
| 1272 |
| 1263 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1273 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
| 1264 TypeofMode typeof_mode, | 1274 TypeofMode typeof_mode, |
| 1265 Label* slow) { | 1275 Label* slow) { |
| 1266 Register current = cp; | 1276 Register current = cp; |
| 1267 Register next = x10; | 1277 Register next = x10; |
| 1268 Register temp = x11; | 1278 Register temp = x11; |
| 1269 | 1279 |
| 1270 Scope* s = scope(); | 1280 Scope* s = scope(); |
| 1271 while (s != NULL) { | 1281 while (s != NULL) { |
| 1272 if (s->num_heap_slots() > 0) { | 1282 if (s->num_heap_slots() > 0) { |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1511 __ Bind(&allocated); | 1521 __ Bind(&allocated); |
| 1512 // After this, registers are used as follows: | 1522 // After this, registers are used as follows: |
| 1513 // x0: Newly allocated regexp. | 1523 // x0: Newly allocated regexp. |
| 1514 // x5: Materialized regexp. | 1524 // x5: Materialized regexp. |
| 1515 // x10, x11, x12: temps. | 1525 // x10, x11, x12: temps. |
| 1516 __ CopyFields(x0, x5, CPURegList(x10, x11, x12), size / kPointerSize); | 1526 __ CopyFields(x0, x5, CPURegList(x10, x11, x12), size / kPointerSize); |
| 1517 context()->Plug(x0); | 1527 context()->Plug(x0); |
| 1518 } | 1528 } |
| 1519 | 1529 |
| 1520 | 1530 |
| 1521 void FullCodeGenerator::EmitAccessor(Expression* expression) { | 1531 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { |
| 1532 Expression* expression = (property == NULL) ? NULL : property->value(); |
| 1522 if (expression == NULL) { | 1533 if (expression == NULL) { |
| 1523 __ LoadRoot(x10, Heap::kNullValueRootIndex); | 1534 __ LoadRoot(x10, Heap::kNullValueRootIndex); |
| 1524 __ Push(x10); | 1535 __ Push(x10); |
| 1525 } else { | 1536 } else { |
| 1526 VisitForStackValue(expression); | 1537 VisitForStackValue(expression); |
| 1538 if (NeedsHomeObject(expression)) { |
| 1539 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || |
| 1540 property->kind() == ObjectLiteral::Property::SETTER); |
| 1541 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; |
| 1542 EmitSetHomeObject(expression, offset, property->GetSlot()); |
| 1543 } |
| 1527 } | 1544 } |
| 1528 } | 1545 } |
| 1529 | 1546 |
| 1530 | 1547 |
| 1531 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { | 1548 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
| 1532 Comment cmnt(masm_, "[ ObjectLiteral"); | 1549 Comment cmnt(masm_, "[ ObjectLiteral"); |
| 1533 | 1550 |
| 1534 Handle<FixedArray> constant_properties = expr->constant_properties(); | 1551 Handle<FixedArray> constant_properties = expr->constant_properties(); |
| 1535 __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1552 __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1536 __ Ldr(x3, FieldMemOperand(x3, JSFunction::kLiteralsOffset)); | 1553 __ Ldr(x3, FieldMemOperand(x3, JSFunction::kLiteralsOffset)); |
| 1537 __ Mov(x2, Smi::FromInt(expr->literal_index())); | 1554 __ Mov(x2, Smi::FromInt(expr->literal_index())); |
| 1538 __ Mov(x1, Operand(constant_properties)); | 1555 __ Mov(x1, Operand(constant_properties)); |
| 1539 int flags = expr->ComputeFlags(); | 1556 int flags = expr->ComputeFlags(); |
| 1540 __ Mov(x0, Smi::FromInt(flags)); | 1557 __ Mov(x0, Smi::FromInt(flags)); |
| 1541 if (MustCreateObjectLiteralWithRuntime(expr)) { | 1558 if (MustCreateObjectLiteralWithRuntime(expr)) { |
| 1542 __ Push(x3, x2, x1, x0); | 1559 __ Push(x3, x2, x1, x0); |
| 1543 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); | 1560 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); |
| 1544 } else { | 1561 } else { |
| 1545 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); | 1562 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); |
| 1546 __ CallStub(&stub); | 1563 __ CallStub(&stub); |
| 1547 } | 1564 } |
| 1548 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1565 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
| 1549 | 1566 |
| 1550 // If result_saved is true the result is on top of the stack. If | 1567 // If result_saved is true the result is on top of the stack. If |
| 1551 // result_saved is false the result is in x0. | 1568 // result_saved is false the result is in x0. |
| 1552 bool result_saved = false; | 1569 bool result_saved = false; |
| 1553 | 1570 |
| 1554 AccessorTable accessor_table(zone()); | 1571 AccessorTable accessor_table(zone()); |
| 1555 int property_index = 0; | 1572 int property_index = 0; |
| 1556 // store_slot_index points to the vector IC slot for the next store IC used. | |
| 1557 // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots | |
| 1558 // and must be updated if the number of store ICs emitted here changes. | |
| 1559 int store_slot_index = 0; | |
| 1560 for (; property_index < expr->properties()->length(); property_index++) { | 1573 for (; property_index < expr->properties()->length(); property_index++) { |
| 1561 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1574 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1562 if (property->is_computed_name()) break; | 1575 if (property->is_computed_name()) break; |
| 1563 if (property->IsCompileTimeValue()) continue; | 1576 if (property->IsCompileTimeValue()) continue; |
| 1564 | 1577 |
| 1565 Literal* key = property->key()->AsLiteral(); | 1578 Literal* key = property->key()->AsLiteral(); |
| 1566 Expression* value = property->value(); | 1579 Expression* value = property->value(); |
| 1567 if (!result_saved) { | 1580 if (!result_saved) { |
| 1568 __ Push(x0); // Save result on stack | 1581 __ Push(x0); // Save result on stack |
| 1569 result_saved = true; | 1582 result_saved = true; |
| 1570 } | 1583 } |
| 1571 switch (property->kind()) { | 1584 switch (property->kind()) { |
| 1572 case ObjectLiteral::Property::CONSTANT: | 1585 case ObjectLiteral::Property::CONSTANT: |
| 1573 UNREACHABLE(); | 1586 UNREACHABLE(); |
| 1574 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1587 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1575 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1588 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1576 // Fall through. | 1589 // Fall through. |
| 1577 case ObjectLiteral::Property::COMPUTED: | 1590 case ObjectLiteral::Property::COMPUTED: |
| 1578 // It is safe to use [[Put]] here because the boilerplate already | 1591 // It is safe to use [[Put]] here because the boilerplate already |
| 1579 // contains computed properties with an uninitialized value. | 1592 // contains computed properties with an uninitialized value. |
| 1580 if (key->value()->IsInternalizedString()) { | 1593 if (key->value()->IsInternalizedString()) { |
| 1581 if (property->emit_store()) { | 1594 if (property->emit_store()) { |
| 1582 VisitForAccumulatorValue(value); | 1595 VisitForAccumulatorValue(value); |
| 1583 DCHECK(StoreDescriptor::ValueRegister().is(x0)); | 1596 DCHECK(StoreDescriptor::ValueRegister().is(x0)); |
| 1584 __ Mov(StoreDescriptor::NameRegister(), Operand(key->value())); | 1597 __ Mov(StoreDescriptor::NameRegister(), Operand(key->value())); |
| 1585 __ Peek(StoreDescriptor::ReceiverRegister(), 0); | 1598 __ Peek(StoreDescriptor::ReceiverRegister(), 0); |
| 1586 if (FLAG_vector_stores) { | 1599 if (FLAG_vector_stores) { |
| 1587 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); | 1600 EmitLoadStoreICSlot(property->GetSlot(0)); |
| 1588 CallStoreIC(); | 1601 CallStoreIC(); |
| 1589 } else { | 1602 } else { |
| 1590 CallStoreIC(key->LiteralFeedbackId()); | 1603 CallStoreIC(key->LiteralFeedbackId()); |
| 1591 } | 1604 } |
| 1592 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1605 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1593 | 1606 |
| 1594 if (NeedsHomeObject(value)) { | 1607 if (NeedsHomeObject(value)) { |
| 1595 __ Mov(StoreDescriptor::ReceiverRegister(), x0); | 1608 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); |
| 1596 __ Mov(StoreDescriptor::NameRegister(), | |
| 1597 Operand(isolate()->factory()->home_object_symbol())); | |
| 1598 __ Peek(StoreDescriptor::ValueRegister(), 0); | |
| 1599 if (FLAG_vector_stores) { | |
| 1600 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); | |
| 1601 } | |
| 1602 CallStoreIC(); | |
| 1603 } | 1609 } |
| 1604 } else { | 1610 } else { |
| 1605 VisitForEffect(value); | 1611 VisitForEffect(value); |
| 1606 } | 1612 } |
| 1607 break; | 1613 break; |
| 1608 } | 1614 } |
| 1609 __ Peek(x0, 0); | 1615 __ Peek(x0, 0); |
| 1610 __ Push(x0); | 1616 __ Push(x0); |
| 1611 VisitForStackValue(key); | 1617 VisitForStackValue(key); |
| 1612 VisitForStackValue(value); | 1618 VisitForStackValue(value); |
| 1613 if (property->emit_store()) { | 1619 if (property->emit_store()) { |
| 1614 EmitSetHomeObjectIfNeeded( | 1620 if (NeedsHomeObject(value)) { |
| 1615 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); | 1621 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 1622 } |
| 1616 __ Mov(x0, Smi::FromInt(SLOPPY)); // Language mode | 1623 __ Mov(x0, Smi::FromInt(SLOPPY)); // Language mode |
| 1617 __ Push(x0); | 1624 __ Push(x0); |
| 1618 __ CallRuntime(Runtime::kSetProperty, 4); | 1625 __ CallRuntime(Runtime::kSetProperty, 4); |
| 1619 } else { | 1626 } else { |
| 1620 __ Drop(3); | 1627 __ Drop(3); |
| 1621 } | 1628 } |
| 1622 break; | 1629 break; |
| 1623 case ObjectLiteral::Property::PROTOTYPE: | 1630 case ObjectLiteral::Property::PROTOTYPE: |
| 1624 DCHECK(property->emit_store()); | 1631 DCHECK(property->emit_store()); |
| 1625 // Duplicate receiver on stack. | 1632 // Duplicate receiver on stack. |
| 1626 __ Peek(x0, 0); | 1633 __ Peek(x0, 0); |
| 1627 __ Push(x0); | 1634 __ Push(x0); |
| 1628 VisitForStackValue(value); | 1635 VisitForStackValue(value); |
| 1629 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1636 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
| 1630 break; | 1637 break; |
| 1631 case ObjectLiteral::Property::GETTER: | 1638 case ObjectLiteral::Property::GETTER: |
| 1632 if (property->emit_store()) { | 1639 if (property->emit_store()) { |
| 1633 accessor_table.lookup(key)->second->getter = value; | 1640 accessor_table.lookup(key)->second->getter = property; |
| 1634 } | 1641 } |
| 1635 break; | 1642 break; |
| 1636 case ObjectLiteral::Property::SETTER: | 1643 case ObjectLiteral::Property::SETTER: |
| 1637 if (property->emit_store()) { | 1644 if (property->emit_store()) { |
| 1638 accessor_table.lookup(key)->second->setter = value; | 1645 accessor_table.lookup(key)->second->setter = property; |
| 1639 } | 1646 } |
| 1640 break; | 1647 break; |
| 1641 } | 1648 } |
| 1642 } | 1649 } |
| 1643 | 1650 |
| 1644 // Emit code to define accessors, using only a single call to the runtime for | 1651 // Emit code to define accessors, using only a single call to the runtime for |
| 1645 // each pair of corresponding getters and setters. | 1652 // each pair of corresponding getters and setters. |
| 1646 for (AccessorTable::Iterator it = accessor_table.begin(); | 1653 for (AccessorTable::Iterator it = accessor_table.begin(); |
| 1647 it != accessor_table.end(); | 1654 it != accessor_table.end(); |
| 1648 ++it) { | 1655 ++it) { |
| 1649 __ Peek(x10, 0); // Duplicate receiver. | 1656 __ Peek(x10, 0); // Duplicate receiver. |
| 1650 __ Push(x10); | 1657 __ Push(x10); |
| 1651 VisitForStackValue(it->first); | 1658 VisitForStackValue(it->first); |
| 1652 EmitAccessor(it->second->getter); | 1659 EmitAccessor(it->second->getter); |
| 1653 EmitSetHomeObjectIfNeeded( | |
| 1654 it->second->getter, 2, | |
| 1655 expr->SlotForHomeObject(it->second->getter, &store_slot_index)); | |
| 1656 EmitAccessor(it->second->setter); | 1660 EmitAccessor(it->second->setter); |
| 1657 EmitSetHomeObjectIfNeeded( | |
| 1658 it->second->setter, 3, | |
| 1659 expr->SlotForHomeObject(it->second->setter, &store_slot_index)); | |
| 1660 __ Mov(x10, Smi::FromInt(NONE)); | 1661 __ Mov(x10, Smi::FromInt(NONE)); |
| 1661 __ Push(x10); | 1662 __ Push(x10); |
| 1662 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 1663 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); |
| 1663 } | 1664 } |
| 1664 | 1665 |
| 1665 // Object literals have two parts. The "static" part on the left contains no | 1666 // Object literals have two parts. The "static" part on the left contains no |
| 1666 // computed property names, and so we can compute its map ahead of time; see | 1667 // computed property names, and so we can compute its map ahead of time; see |
| 1667 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1668 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
| 1668 // starts with the first computed property name, and continues with all | 1669 // starts with the first computed property name, and continues with all |
| 1669 // properties to its right. All the code from above initializes the static | 1670 // properties to its right. All the code from above initializes the static |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1684 __ Push(x10); | 1685 __ Push(x10); |
| 1685 | 1686 |
| 1686 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1687 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
| 1687 DCHECK(!property->is_computed_name()); | 1688 DCHECK(!property->is_computed_name()); |
| 1688 VisitForStackValue(value); | 1689 VisitForStackValue(value); |
| 1689 DCHECK(property->emit_store()); | 1690 DCHECK(property->emit_store()); |
| 1690 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1691 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
| 1691 } else { | 1692 } else { |
| 1692 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); | 1693 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); |
| 1693 VisitForStackValue(value); | 1694 VisitForStackValue(value); |
| 1694 EmitSetHomeObjectIfNeeded( | 1695 if (NeedsHomeObject(value)) { |
| 1695 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); | 1696 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 1697 } |
| 1696 | 1698 |
| 1697 switch (property->kind()) { | 1699 switch (property->kind()) { |
| 1698 case ObjectLiteral::Property::CONSTANT: | 1700 case ObjectLiteral::Property::CONSTANT: |
| 1699 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1701 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1700 case ObjectLiteral::Property::COMPUTED: | 1702 case ObjectLiteral::Property::COMPUTED: |
| 1701 if (property->emit_store()) { | 1703 if (property->emit_store()) { |
| 1702 __ Mov(x0, Smi::FromInt(NONE)); | 1704 __ Mov(x0, Smi::FromInt(NONE)); |
| 1703 __ Push(x0); | 1705 __ Push(x0); |
| 1704 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); | 1706 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); |
| 1705 } else { | 1707 } else { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1731 __ Peek(x0, 0); | 1733 __ Peek(x0, 0); |
| 1732 __ Push(x0); | 1734 __ Push(x0); |
| 1733 __ CallRuntime(Runtime::kToFastProperties, 1); | 1735 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1734 } | 1736 } |
| 1735 | 1737 |
| 1736 if (result_saved) { | 1738 if (result_saved) { |
| 1737 context()->PlugTOS(); | 1739 context()->PlugTOS(); |
| 1738 } else { | 1740 } else { |
| 1739 context()->Plug(x0); | 1741 context()->Plug(x0); |
| 1740 } | 1742 } |
| 1741 | |
| 1742 // Verify that compilation exactly consumed the number of store ic slots that | |
| 1743 // the ObjectLiteral node had to offer. | |
| 1744 DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count()); | |
| 1745 } | 1743 } |
| 1746 | 1744 |
| 1747 | 1745 |
| 1748 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1746 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
| 1749 Comment cmnt(masm_, "[ ArrayLiteral"); | 1747 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 1750 | 1748 |
| 1751 expr->BuildConstantElements(isolate()); | 1749 expr->BuildConstantElements(isolate()); |
| 1752 Handle<FixedArray> constant_elements = expr->constant_elements(); | 1750 Handle<FixedArray> constant_elements = expr->constant_elements(); |
| 1753 bool has_fast_elements = | 1751 bool has_fast_elements = |
| 1754 IsFastObjectElementsKind(expr->constant_elements_kind()); | 1752 IsFastObjectElementsKind(expr->constant_elements_kind()); |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2138 JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code. | 2136 JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code. |
| 2139 { | 2137 { |
| 2140 Assembler::BlockPoolsScope scope(masm_); | 2138 Assembler::BlockPoolsScope scope(masm_); |
| 2141 CallIC(code, expr->BinaryOperationFeedbackId()); | 2139 CallIC(code, expr->BinaryOperationFeedbackId()); |
| 2142 patch_site.EmitPatchInfo(); | 2140 patch_site.EmitPatchInfo(); |
| 2143 } | 2141 } |
| 2144 context()->Plug(x0); | 2142 context()->Plug(x0); |
| 2145 } | 2143 } |
| 2146 | 2144 |
| 2147 | 2145 |
| 2148 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit, | 2146 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { |
| 2149 int* used_store_slots) { | |
| 2150 // Constructor is in x0. | 2147 // Constructor is in x0. |
| 2151 DCHECK(lit != NULL); | 2148 DCHECK(lit != NULL); |
| 2152 __ push(x0); | 2149 __ push(x0); |
| 2153 | 2150 |
| 2154 // No access check is needed here since the constructor is created by the | 2151 // No access check is needed here since the constructor is created by the |
| 2155 // class literal. | 2152 // class literal. |
| 2156 Register scratch = x1; | 2153 Register scratch = x1; |
| 2157 __ Ldr(scratch, | 2154 __ Ldr(scratch, |
| 2158 FieldMemOperand(x0, JSFunction::kPrototypeOrInitialMapOffset)); | 2155 FieldMemOperand(x0, JSFunction::kPrototypeOrInitialMapOffset)); |
| 2159 __ Push(scratch); | 2156 __ Push(scratch); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2173 // The static prototype property is read only. We handle the non computed | 2170 // The static prototype property is read only. We handle the non computed |
| 2174 // property name case in the parser. Since this is the only case where we | 2171 // property name case in the parser. Since this is the only case where we |
| 2175 // need to check for an own read only property we special case this so we do | 2172 // need to check for an own read only property we special case this so we do |
| 2176 // not need to do this for every property. | 2173 // not need to do this for every property. |
| 2177 if (property->is_static() && property->is_computed_name()) { | 2174 if (property->is_static() && property->is_computed_name()) { |
| 2178 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); | 2175 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); |
| 2179 __ Push(x0); | 2176 __ Push(x0); |
| 2180 } | 2177 } |
| 2181 | 2178 |
| 2182 VisitForStackValue(value); | 2179 VisitForStackValue(value); |
| 2183 EmitSetHomeObjectIfNeeded(value, 2, | 2180 if (NeedsHomeObject(value)) { |
| 2184 lit->SlotForHomeObject(value, used_store_slots)); | 2181 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 2182 } |
| 2185 | 2183 |
| 2186 switch (property->kind()) { | 2184 switch (property->kind()) { |
| 2187 case ObjectLiteral::Property::CONSTANT: | 2185 case ObjectLiteral::Property::CONSTANT: |
| 2188 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 2186 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 2189 case ObjectLiteral::Property::PROTOTYPE: | 2187 case ObjectLiteral::Property::PROTOTYPE: |
| 2190 UNREACHABLE(); | 2188 UNREACHABLE(); |
| 2191 case ObjectLiteral::Property::COMPUTED: | 2189 case ObjectLiteral::Property::COMPUTED: |
| 2192 __ CallRuntime(Runtime::kDefineClassMethod, 3); | 2190 __ CallRuntime(Runtime::kDefineClassMethod, 3); |
| 2193 break; | 2191 break; |
| 2194 | 2192 |
| (...skipping 3168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5363 } | 5361 } |
| 5364 | 5362 |
| 5365 return INTERRUPT; | 5363 return INTERRUPT; |
| 5366 } | 5364 } |
| 5367 | 5365 |
| 5368 | 5366 |
| 5369 } // namespace internal | 5367 } // namespace internal |
| 5370 } // namespace v8 | 5368 } // namespace v8 |
| 5371 | 5369 |
| 5372 #endif // V8_TARGET_ARCH_ARM64 | 5370 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |