OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_ARM | 5 #if V8_TARGET_ARCH_ARM |
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 1232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1243 __ CallStub(&stub); | 1243 __ CallStub(&stub); |
1244 } else { | 1244 } else { |
1245 __ Push(info); | 1245 __ Push(info); |
1246 __ CallRuntime( | 1246 __ CallRuntime( |
1247 pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1); | 1247 pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1); |
1248 } | 1248 } |
1249 context()->Plug(r0); | 1249 context()->Plug(r0); |
1250 } | 1250 } |
1251 | 1251 |
1252 | 1252 |
1253 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1253 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, |
1254 int offset, | 1254 FeedbackVectorICSlot slot) { |
1255 FeedbackVectorICSlot slot) { | 1255 DCHECK(NeedsHomeObject(initializer)); |
1256 if (NeedsHomeObject(initializer)) { | 1256 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); |
1257 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); | 1257 __ mov(StoreDescriptor::NameRegister(), |
1258 __ mov(StoreDescriptor::NameRegister(), | 1258 Operand(isolate()->factory()->home_object_symbol())); |
1259 Operand(isolate()->factory()->home_object_symbol())); | 1259 __ ldr(StoreDescriptor::ValueRegister(), |
1260 __ ldr(StoreDescriptor::ValueRegister(), | 1260 MemOperand(sp, offset * kPointerSize)); |
1261 MemOperand(sp, offset * kPointerSize)); | 1261 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
1262 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 1262 CallStoreIC(); |
1263 CallStoreIC(); | |
1264 } | |
1265 } | 1263 } |
1266 | 1264 |
1267 | 1265 |
| 1266 void FullCodeGenerator::EmitSetHomeObjectAccumulator( |
| 1267 Expression* initializer, int offset, FeedbackVectorICSlot slot) { |
| 1268 DCHECK(NeedsHomeObject(initializer)); |
| 1269 __ Move(StoreDescriptor::ReceiverRegister(), r0); |
| 1270 __ mov(StoreDescriptor::NameRegister(), |
| 1271 Operand(isolate()->factory()->home_object_symbol())); |
| 1272 __ ldr(StoreDescriptor::ValueRegister(), |
| 1273 MemOperand(sp, offset * kPointerSize)); |
| 1274 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1275 CallStoreIC(); |
| 1276 } |
| 1277 |
| 1278 |
1268 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1279 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
1269 TypeofMode typeof_mode, | 1280 TypeofMode typeof_mode, |
1270 Label* slow) { | 1281 Label* slow) { |
1271 Register current = cp; | 1282 Register current = cp; |
1272 Register next = r1; | 1283 Register next = r1; |
1273 Register temp = r2; | 1284 Register temp = r2; |
1274 | 1285 |
1275 Scope* s = scope(); | 1286 Scope* s = scope(); |
1276 while (s != NULL) { | 1287 while (s != NULL) { |
1277 if (s->num_heap_slots() > 0) { | 1288 if (s->num_heap_slots() > 0) { |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1524 __ bind(&allocated); | 1535 __ bind(&allocated); |
1525 // After this, registers are used as follows: | 1536 // After this, registers are used as follows: |
1526 // r0: Newly allocated regexp. | 1537 // r0: Newly allocated regexp. |
1527 // r5: Materialized regexp. | 1538 // r5: Materialized regexp. |
1528 // r2: temp. | 1539 // r2: temp. |
1529 __ CopyFields(r0, r5, d0, size / kPointerSize); | 1540 __ CopyFields(r0, r5, d0, size / kPointerSize); |
1530 context()->Plug(r0); | 1541 context()->Plug(r0); |
1531 } | 1542 } |
1532 | 1543 |
1533 | 1544 |
1534 void FullCodeGenerator::EmitAccessor(Expression* expression) { | 1545 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { |
| 1546 Expression* expression = (property == NULL) ? NULL : property->value(); |
1535 if (expression == NULL) { | 1547 if (expression == NULL) { |
1536 __ LoadRoot(r1, Heap::kNullValueRootIndex); | 1548 __ LoadRoot(r1, Heap::kNullValueRootIndex); |
1537 __ push(r1); | 1549 __ push(r1); |
1538 } else { | 1550 } else { |
1539 VisitForStackValue(expression); | 1551 VisitForStackValue(expression); |
| 1552 if (NeedsHomeObject(expression)) { |
| 1553 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || |
| 1554 property->kind() == ObjectLiteral::Property::SETTER); |
| 1555 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; |
| 1556 EmitSetHomeObject(expression, offset, property->GetSlot()); |
| 1557 } |
1540 } | 1558 } |
1541 } | 1559 } |
1542 | 1560 |
1543 | 1561 |
1544 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { | 1562 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
1545 Comment cmnt(masm_, "[ ObjectLiteral"); | 1563 Comment cmnt(masm_, "[ ObjectLiteral"); |
1546 | 1564 |
1547 Handle<FixedArray> constant_properties = expr->constant_properties(); | 1565 Handle<FixedArray> constant_properties = expr->constant_properties(); |
1548 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1566 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
1549 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); | 1567 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); |
1550 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); | 1568 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); |
1551 __ mov(r1, Operand(constant_properties)); | 1569 __ mov(r1, Operand(constant_properties)); |
1552 int flags = expr->ComputeFlags(); | 1570 int flags = expr->ComputeFlags(); |
1553 __ mov(r0, Operand(Smi::FromInt(flags))); | 1571 __ mov(r0, Operand(Smi::FromInt(flags))); |
1554 if (MustCreateObjectLiteralWithRuntime(expr)) { | 1572 if (MustCreateObjectLiteralWithRuntime(expr)) { |
1555 __ Push(r3, r2, r1, r0); | 1573 __ Push(r3, r2, r1, r0); |
1556 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); | 1574 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); |
1557 } else { | 1575 } else { |
1558 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); | 1576 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); |
1559 __ CallStub(&stub); | 1577 __ CallStub(&stub); |
1560 } | 1578 } |
1561 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1579 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
1562 | 1580 |
1563 // If result_saved is true the result is on top of the stack. If | 1581 // If result_saved is true the result is on top of the stack. If |
1564 // result_saved is false the result is in r0. | 1582 // result_saved is false the result is in r0. |
1565 bool result_saved = false; | 1583 bool result_saved = false; |
1566 | 1584 |
1567 AccessorTable accessor_table(zone()); | 1585 AccessorTable accessor_table(zone()); |
1568 int property_index = 0; | 1586 int property_index = 0; |
1569 // store_slot_index points to the vector IC slot for the next store IC used. | |
1570 // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots | |
1571 // and must be updated if the number of store ICs emitted here changes. | |
1572 int store_slot_index = 0; | |
1573 for (; property_index < expr->properties()->length(); property_index++) { | 1587 for (; property_index < expr->properties()->length(); property_index++) { |
1574 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1588 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
1575 if (property->is_computed_name()) break; | 1589 if (property->is_computed_name()) break; |
1576 if (property->IsCompileTimeValue()) continue; | 1590 if (property->IsCompileTimeValue()) continue; |
1577 | 1591 |
1578 Literal* key = property->key()->AsLiteral(); | 1592 Literal* key = property->key()->AsLiteral(); |
1579 Expression* value = property->value(); | 1593 Expression* value = property->value(); |
1580 if (!result_saved) { | 1594 if (!result_saved) { |
1581 __ push(r0); // Save result on stack | 1595 __ push(r0); // Save result on stack |
1582 result_saved = true; | 1596 result_saved = true; |
1583 } | 1597 } |
1584 switch (property->kind()) { | 1598 switch (property->kind()) { |
1585 case ObjectLiteral::Property::CONSTANT: | 1599 case ObjectLiteral::Property::CONSTANT: |
1586 UNREACHABLE(); | 1600 UNREACHABLE(); |
1587 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1601 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1588 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1602 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
1589 // Fall through. | 1603 // Fall through. |
1590 case ObjectLiteral::Property::COMPUTED: | 1604 case ObjectLiteral::Property::COMPUTED: |
1591 // It is safe to use [[Put]] here because the boilerplate already | 1605 // It is safe to use [[Put]] here because the boilerplate already |
1592 // contains computed properties with an uninitialized value. | 1606 // contains computed properties with an uninitialized value. |
1593 if (key->value()->IsInternalizedString()) { | 1607 if (key->value()->IsInternalizedString()) { |
1594 if (property->emit_store()) { | 1608 if (property->emit_store()) { |
1595 VisitForAccumulatorValue(value); | 1609 VisitForAccumulatorValue(value); |
1596 DCHECK(StoreDescriptor::ValueRegister().is(r0)); | 1610 DCHECK(StoreDescriptor::ValueRegister().is(r0)); |
1597 __ mov(StoreDescriptor::NameRegister(), Operand(key->value())); | 1611 __ mov(StoreDescriptor::NameRegister(), Operand(key->value())); |
1598 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); | 1612 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); |
1599 if (FLAG_vector_stores) { | 1613 if (FLAG_vector_stores) { |
1600 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); | 1614 EmitLoadStoreICSlot(property->GetSlot(0)); |
1601 CallStoreIC(); | 1615 CallStoreIC(); |
1602 } else { | 1616 } else { |
1603 CallStoreIC(key->LiteralFeedbackId()); | 1617 CallStoreIC(key->LiteralFeedbackId()); |
1604 } | 1618 } |
1605 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1619 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1606 | 1620 |
1607 if (NeedsHomeObject(value)) { | 1621 if (NeedsHomeObject(value)) { |
1608 __ Move(StoreDescriptor::ReceiverRegister(), r0); | 1622 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); |
1609 __ mov(StoreDescriptor::NameRegister(), | |
1610 Operand(isolate()->factory()->home_object_symbol())); | |
1611 __ ldr(StoreDescriptor::ValueRegister(), MemOperand(sp)); | |
1612 if (FLAG_vector_stores) { | |
1613 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); | |
1614 } | |
1615 CallStoreIC(); | |
1616 } | 1623 } |
1617 } else { | 1624 } else { |
1618 VisitForEffect(value); | 1625 VisitForEffect(value); |
1619 } | 1626 } |
1620 break; | 1627 break; |
1621 } | 1628 } |
1622 // Duplicate receiver on stack. | 1629 // Duplicate receiver on stack. |
1623 __ ldr(r0, MemOperand(sp)); | 1630 __ ldr(r0, MemOperand(sp)); |
1624 __ push(r0); | 1631 __ push(r0); |
1625 VisitForStackValue(key); | 1632 VisitForStackValue(key); |
1626 VisitForStackValue(value); | 1633 VisitForStackValue(value); |
1627 if (property->emit_store()) { | 1634 if (property->emit_store()) { |
1628 EmitSetHomeObjectIfNeeded( | 1635 if (NeedsHomeObject(value)) { |
1629 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); | 1636 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 1637 } |
1630 __ mov(r0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes | 1638 __ mov(r0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes |
1631 __ push(r0); | 1639 __ push(r0); |
1632 __ CallRuntime(Runtime::kSetProperty, 4); | 1640 __ CallRuntime(Runtime::kSetProperty, 4); |
1633 } else { | 1641 } else { |
1634 __ Drop(3); | 1642 __ Drop(3); |
1635 } | 1643 } |
1636 break; | 1644 break; |
1637 case ObjectLiteral::Property::PROTOTYPE: | 1645 case ObjectLiteral::Property::PROTOTYPE: |
1638 // Duplicate receiver on stack. | 1646 // Duplicate receiver on stack. |
1639 __ ldr(r0, MemOperand(sp)); | 1647 __ ldr(r0, MemOperand(sp)); |
1640 __ push(r0); | 1648 __ push(r0); |
1641 VisitForStackValue(value); | 1649 VisitForStackValue(value); |
1642 DCHECK(property->emit_store()); | 1650 DCHECK(property->emit_store()); |
1643 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1651 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
1644 break; | 1652 break; |
1645 | 1653 |
1646 case ObjectLiteral::Property::GETTER: | 1654 case ObjectLiteral::Property::GETTER: |
1647 if (property->emit_store()) { | 1655 if (property->emit_store()) { |
1648 accessor_table.lookup(key)->second->getter = value; | 1656 accessor_table.lookup(key)->second->getter = property; |
1649 } | 1657 } |
1650 break; | 1658 break; |
1651 case ObjectLiteral::Property::SETTER: | 1659 case ObjectLiteral::Property::SETTER: |
1652 if (property->emit_store()) { | 1660 if (property->emit_store()) { |
1653 accessor_table.lookup(key)->second->setter = value; | 1661 accessor_table.lookup(key)->second->setter = property; |
1654 } | 1662 } |
1655 break; | 1663 break; |
1656 } | 1664 } |
1657 } | 1665 } |
1658 | 1666 |
1659 // Emit code to define accessors, using only a single call to the runtime for | 1667 // Emit code to define accessors, using only a single call to the runtime for |
1660 // each pair of corresponding getters and setters. | 1668 // each pair of corresponding getters and setters. |
1661 for (AccessorTable::Iterator it = accessor_table.begin(); | 1669 for (AccessorTable::Iterator it = accessor_table.begin(); |
1662 it != accessor_table.end(); | 1670 it != accessor_table.end(); |
1663 ++it) { | 1671 ++it) { |
1664 __ ldr(r0, MemOperand(sp)); // Duplicate receiver. | 1672 __ ldr(r0, MemOperand(sp)); // Duplicate receiver. |
1665 __ push(r0); | 1673 __ push(r0); |
1666 VisitForStackValue(it->first); | 1674 VisitForStackValue(it->first); |
1667 EmitAccessor(it->second->getter); | 1675 EmitAccessor(it->second->getter); |
1668 EmitSetHomeObjectIfNeeded( | |
1669 it->second->getter, 2, | |
1670 expr->SlotForHomeObject(it->second->getter, &store_slot_index)); | |
1671 EmitAccessor(it->second->setter); | 1676 EmitAccessor(it->second->setter); |
1672 EmitSetHomeObjectIfNeeded( | |
1673 it->second->setter, 3, | |
1674 expr->SlotForHomeObject(it->second->setter, &store_slot_index)); | |
1675 __ mov(r0, Operand(Smi::FromInt(NONE))); | 1677 __ mov(r0, Operand(Smi::FromInt(NONE))); |
1676 __ push(r0); | 1678 __ push(r0); |
1677 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 1679 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); |
1678 } | 1680 } |
1679 | 1681 |
1680 // Object literals have two parts. The "static" part on the left contains no | 1682 // Object literals have two parts. The "static" part on the left contains no |
1681 // computed property names, and so we can compute its map ahead of time; see | 1683 // computed property names, and so we can compute its map ahead of time; see |
1682 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1684 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
1683 // starts with the first computed property name, and continues with all | 1685 // starts with the first computed property name, and continues with all |
1684 // properties to its right. All the code from above initializes the static | 1686 // properties to its right. All the code from above initializes the static |
(...skipping 14 matching lines...) Expand all Loading... |
1699 __ push(r0); | 1701 __ push(r0); |
1700 | 1702 |
1701 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1703 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
1702 DCHECK(!property->is_computed_name()); | 1704 DCHECK(!property->is_computed_name()); |
1703 VisitForStackValue(value); | 1705 VisitForStackValue(value); |
1704 DCHECK(property->emit_store()); | 1706 DCHECK(property->emit_store()); |
1705 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1707 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
1706 } else { | 1708 } else { |
1707 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); | 1709 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); |
1708 VisitForStackValue(value); | 1710 VisitForStackValue(value); |
1709 EmitSetHomeObjectIfNeeded( | 1711 if (NeedsHomeObject(value)) { |
1710 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); | 1712 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 1713 } |
1711 | 1714 |
1712 switch (property->kind()) { | 1715 switch (property->kind()) { |
1713 case ObjectLiteral::Property::CONSTANT: | 1716 case ObjectLiteral::Property::CONSTANT: |
1714 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1717 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1715 case ObjectLiteral::Property::COMPUTED: | 1718 case ObjectLiteral::Property::COMPUTED: |
1716 if (property->emit_store()) { | 1719 if (property->emit_store()) { |
1717 __ mov(r0, Operand(Smi::FromInt(NONE))); | 1720 __ mov(r0, Operand(Smi::FromInt(NONE))); |
1718 __ push(r0); | 1721 __ push(r0); |
1719 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); | 1722 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); |
1720 } else { | 1723 } else { |
(...skipping 25 matching lines...) Expand all Loading... |
1746 __ ldr(r0, MemOperand(sp)); | 1749 __ ldr(r0, MemOperand(sp)); |
1747 __ push(r0); | 1750 __ push(r0); |
1748 __ CallRuntime(Runtime::kToFastProperties, 1); | 1751 __ CallRuntime(Runtime::kToFastProperties, 1); |
1749 } | 1752 } |
1750 | 1753 |
1751 if (result_saved) { | 1754 if (result_saved) { |
1752 context()->PlugTOS(); | 1755 context()->PlugTOS(); |
1753 } else { | 1756 } else { |
1754 context()->Plug(r0); | 1757 context()->Plug(r0); |
1755 } | 1758 } |
1756 | |
1757 // Verify that compilation exactly consumed the number of store ic slots that | |
1758 // the ObjectLiteral node had to offer. | |
1759 DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count()); | |
1760 } | 1759 } |
1761 | 1760 |
1762 | 1761 |
1763 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1762 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
1764 Comment cmnt(masm_, "[ ArrayLiteral"); | 1763 Comment cmnt(masm_, "[ ArrayLiteral"); |
1765 | 1764 |
1766 expr->BuildConstantElements(isolate()); | 1765 expr->BuildConstantElements(isolate()); |
1767 | 1766 |
1768 Handle<FixedArray> constant_elements = expr->constant_elements(); | 1767 Handle<FixedArray> constant_elements = expr->constant_elements(); |
1769 bool has_fast_elements = | 1768 bool has_fast_elements = |
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2427 break; | 2426 break; |
2428 default: | 2427 default: |
2429 UNREACHABLE(); | 2428 UNREACHABLE(); |
2430 } | 2429 } |
2431 | 2430 |
2432 __ bind(&done); | 2431 __ bind(&done); |
2433 context()->Plug(r0); | 2432 context()->Plug(r0); |
2434 } | 2433 } |
2435 | 2434 |
2436 | 2435 |
2437 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit, | 2436 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { |
2438 int* used_store_slots) { | |
2439 // Constructor is in r0. | 2437 // Constructor is in r0. |
2440 DCHECK(lit != NULL); | 2438 DCHECK(lit != NULL); |
2441 __ push(r0); | 2439 __ push(r0); |
2442 | 2440 |
2443 // No access check is needed here since the constructor is created by the | 2441 // No access check is needed here since the constructor is created by the |
2444 // class literal. | 2442 // class literal. |
2445 Register scratch = r1; | 2443 Register scratch = r1; |
2446 __ ldr(scratch, | 2444 __ ldr(scratch, |
2447 FieldMemOperand(r0, JSFunction::kPrototypeOrInitialMapOffset)); | 2445 FieldMemOperand(r0, JSFunction::kPrototypeOrInitialMapOffset)); |
2448 __ push(scratch); | 2446 __ push(scratch); |
(...skipping 13 matching lines...) Expand all Loading... |
2462 // The static prototype property is read only. We handle the non computed | 2460 // The static prototype property is read only. We handle the non computed |
2463 // property name case in the parser. Since this is the only case where we | 2461 // property name case in the parser. Since this is the only case where we |
2464 // need to check for an own read only property we special case this so we do | 2462 // need to check for an own read only property we special case this so we do |
2465 // not need to do this for every property. | 2463 // not need to do this for every property. |
2466 if (property->is_static() && property->is_computed_name()) { | 2464 if (property->is_static() && property->is_computed_name()) { |
2467 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); | 2465 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); |
2468 __ push(r0); | 2466 __ push(r0); |
2469 } | 2467 } |
2470 | 2468 |
2471 VisitForStackValue(value); | 2469 VisitForStackValue(value); |
2472 EmitSetHomeObjectIfNeeded(value, 2, | 2470 if (NeedsHomeObject(value)) { |
2473 lit->SlotForHomeObject(value, used_store_slots)); | 2471 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 2472 } |
2474 | 2473 |
2475 switch (property->kind()) { | 2474 switch (property->kind()) { |
2476 case ObjectLiteral::Property::CONSTANT: | 2475 case ObjectLiteral::Property::CONSTANT: |
2477 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 2476 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
2478 case ObjectLiteral::Property::PROTOTYPE: | 2477 case ObjectLiteral::Property::PROTOTYPE: |
2479 UNREACHABLE(); | 2478 UNREACHABLE(); |
2480 case ObjectLiteral::Property::COMPUTED: | 2479 case ObjectLiteral::Property::COMPUTED: |
2481 __ CallRuntime(Runtime::kDefineClassMethod, 3); | 2480 __ CallRuntime(Runtime::kDefineClassMethod, 3); |
2482 break; | 2481 break; |
2483 | 2482 |
(...skipping 2878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5362 DCHECK(interrupt_address == | 5361 DCHECK(interrupt_address == |
5363 isolate->builtins()->OsrAfterStackCheck()->entry()); | 5362 isolate->builtins()->OsrAfterStackCheck()->entry()); |
5364 return OSR_AFTER_STACK_CHECK; | 5363 return OSR_AFTER_STACK_CHECK; |
5365 } | 5364 } |
5366 | 5365 |
5367 | 5366 |
5368 } // namespace internal | 5367 } // namespace internal |
5369 } // namespace v8 | 5368 } // namespace v8 |
5370 | 5369 |
5371 #endif // V8_TARGET_ARCH_ARM | 5370 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |