| 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_X64 | 5 #if V8_TARGET_ARCH_X64 |
| 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 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1201 __ CallStub(&stub); | 1201 __ CallStub(&stub); |
| 1202 } else { | 1202 } else { |
| 1203 __ Push(info); | 1203 __ Push(info); |
| 1204 __ CallRuntime( | 1204 __ CallRuntime( |
| 1205 pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1); | 1205 pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1); |
| 1206 } | 1206 } |
| 1207 context()->Plug(rax); | 1207 context()->Plug(rax); |
| 1208 } | 1208 } |
| 1209 | 1209 |
| 1210 | 1210 |
| 1211 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1211 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, |
| 1212 int offset, | 1212 FeedbackVectorICSlot slot) { |
| 1213 FeedbackVectorICSlot slot) { | 1213 DCHECK(NeedsHomeObject(initializer)); |
| 1214 if (NeedsHomeObject(initializer)) { | 1214 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| 1215 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); | 1215 __ Move(StoreDescriptor::NameRegister(), |
| 1216 __ Move(StoreDescriptor::NameRegister(), | 1216 isolate()->factory()->home_object_symbol()); |
| 1217 isolate()->factory()->home_object_symbol()); | 1217 __ movp(StoreDescriptor::ValueRegister(), |
| 1218 __ movp(StoreDescriptor::ValueRegister(), | 1218 Operand(rsp, offset * kPointerSize)); |
| 1219 Operand(rsp, offset * kPointerSize)); | 1219 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1220 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 1220 CallStoreIC(); |
| 1221 CallStoreIC(); | |
| 1222 } | |
| 1223 } | 1221 } |
| 1224 | 1222 |
| 1225 | 1223 |
| 1224 void FullCodeGenerator::EmitSetHomeObjectAccumulator( |
| 1225 Expression* initializer, int offset, FeedbackVectorICSlot slot) { |
| 1226 DCHECK(NeedsHomeObject(initializer)); |
| 1227 __ movp(StoreDescriptor::ReceiverRegister(), rax); |
| 1228 __ Move(StoreDescriptor::NameRegister(), |
| 1229 isolate()->factory()->home_object_symbol()); |
| 1230 __ movp(StoreDescriptor::ValueRegister(), |
| 1231 Operand(rsp, offset * kPointerSize)); |
| 1232 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1233 CallStoreIC(); |
| 1234 } |
| 1235 |
| 1236 |
| 1226 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1237 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
| 1227 TypeofMode typeof_mode, | 1238 TypeofMode typeof_mode, |
| 1228 Label* slow) { | 1239 Label* slow) { |
| 1229 Register context = rsi; | 1240 Register context = rsi; |
| 1230 Register temp = rdx; | 1241 Register temp = rdx; |
| 1231 | 1242 |
| 1232 Scope* s = scope(); | 1243 Scope* s = scope(); |
| 1233 while (s != NULL) { | 1244 while (s != NULL) { |
| 1234 if (s->num_heap_slots() > 0) { | 1245 if (s->num_heap_slots() > 0) { |
| 1235 if (s->calls_sloppy_eval()) { | 1246 if (s->calls_sloppy_eval()) { |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1485 __ movp(FieldOperand(rax, i + kPointerSize), rcx); | 1496 __ movp(FieldOperand(rax, i + kPointerSize), rcx); |
| 1486 } | 1497 } |
| 1487 if ((size % (2 * kPointerSize)) != 0) { | 1498 if ((size % (2 * kPointerSize)) != 0) { |
| 1488 __ movp(rdx, FieldOperand(rbx, size - kPointerSize)); | 1499 __ movp(rdx, FieldOperand(rbx, size - kPointerSize)); |
| 1489 __ movp(FieldOperand(rax, size - kPointerSize), rdx); | 1500 __ movp(FieldOperand(rax, size - kPointerSize), rdx); |
| 1490 } | 1501 } |
| 1491 context()->Plug(rax); | 1502 context()->Plug(rax); |
| 1492 } | 1503 } |
| 1493 | 1504 |
| 1494 | 1505 |
| 1495 void FullCodeGenerator::EmitAccessor(Expression* expression) { | 1506 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { |
| 1507 Expression* expression = (property == NULL) ? NULL : property->value(); |
| 1496 if (expression == NULL) { | 1508 if (expression == NULL) { |
| 1497 __ PushRoot(Heap::kNullValueRootIndex); | 1509 __ PushRoot(Heap::kNullValueRootIndex); |
| 1498 } else { | 1510 } else { |
| 1499 VisitForStackValue(expression); | 1511 VisitForStackValue(expression); |
| 1512 if (NeedsHomeObject(expression)) { |
| 1513 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || |
| 1514 property->kind() == ObjectLiteral::Property::SETTER); |
| 1515 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; |
| 1516 EmitSetHomeObject(expression, offset, property->GetSlot()); |
| 1517 } |
| 1500 } | 1518 } |
| 1501 } | 1519 } |
| 1502 | 1520 |
| 1503 | 1521 |
| 1504 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { | 1522 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
| 1505 Comment cmnt(masm_, "[ ObjectLiteral"); | 1523 Comment cmnt(masm_, "[ ObjectLiteral"); |
| 1506 | 1524 |
| 1507 Handle<FixedArray> constant_properties = expr->constant_properties(); | 1525 Handle<FixedArray> constant_properties = expr->constant_properties(); |
| 1508 int flags = expr->ComputeFlags(); | 1526 int flags = expr->ComputeFlags(); |
| 1509 if (MustCreateObjectLiteralWithRuntime(expr)) { | 1527 if (MustCreateObjectLiteralWithRuntime(expr)) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1523 __ CallStub(&stub); | 1541 __ CallStub(&stub); |
| 1524 } | 1542 } |
| 1525 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1543 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
| 1526 | 1544 |
| 1527 // If result_saved is true the result is on top of the stack. If | 1545 // If result_saved is true the result is on top of the stack. If |
| 1528 // result_saved is false the result is in rax. | 1546 // result_saved is false the result is in rax. |
| 1529 bool result_saved = false; | 1547 bool result_saved = false; |
| 1530 | 1548 |
| 1531 AccessorTable accessor_table(zone()); | 1549 AccessorTable accessor_table(zone()); |
| 1532 int property_index = 0; | 1550 int property_index = 0; |
| 1533 // store_slot_index points to the vector IC slot for the next store IC used. | |
| 1534 // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots | |
| 1535 // and must be updated if the number of store ICs emitted here changes. | |
| 1536 int store_slot_index = 0; | |
| 1537 for (; property_index < expr->properties()->length(); property_index++) { | 1551 for (; property_index < expr->properties()->length(); property_index++) { |
| 1538 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1552 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1539 if (property->is_computed_name()) break; | 1553 if (property->is_computed_name()) break; |
| 1540 if (property->IsCompileTimeValue()) continue; | 1554 if (property->IsCompileTimeValue()) continue; |
| 1541 | 1555 |
| 1542 Literal* key = property->key()->AsLiteral(); | 1556 Literal* key = property->key()->AsLiteral(); |
| 1543 Expression* value = property->value(); | 1557 Expression* value = property->value(); |
| 1544 if (!result_saved) { | 1558 if (!result_saved) { |
| 1545 __ Push(rax); // Save result on the stack | 1559 __ Push(rax); // Save result on the stack |
| 1546 result_saved = true; | 1560 result_saved = true; |
| 1547 } | 1561 } |
| 1548 switch (property->kind()) { | 1562 switch (property->kind()) { |
| 1549 case ObjectLiteral::Property::CONSTANT: | 1563 case ObjectLiteral::Property::CONSTANT: |
| 1550 UNREACHABLE(); | 1564 UNREACHABLE(); |
| 1551 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1565 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1552 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); | 1566 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); |
| 1553 // Fall through. | 1567 // Fall through. |
| 1554 case ObjectLiteral::Property::COMPUTED: | 1568 case ObjectLiteral::Property::COMPUTED: |
| 1555 // It is safe to use [[Put]] here because the boilerplate already | 1569 // It is safe to use [[Put]] here because the boilerplate already |
| 1556 // contains computed properties with an uninitialized value. | 1570 // contains computed properties with an uninitialized value. |
| 1557 if (key->value()->IsInternalizedString()) { | 1571 if (key->value()->IsInternalizedString()) { |
| 1558 if (property->emit_store()) { | 1572 if (property->emit_store()) { |
| 1559 VisitForAccumulatorValue(value); | 1573 VisitForAccumulatorValue(value); |
| 1560 DCHECK(StoreDescriptor::ValueRegister().is(rax)); | 1574 DCHECK(StoreDescriptor::ValueRegister().is(rax)); |
| 1561 __ Move(StoreDescriptor::NameRegister(), key->value()); | 1575 __ Move(StoreDescriptor::NameRegister(), key->value()); |
| 1562 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); | 1576 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| 1563 if (FLAG_vector_stores) { | 1577 if (FLAG_vector_stores) { |
| 1564 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); | 1578 EmitLoadStoreICSlot(property->GetSlot(0)); |
| 1565 CallStoreIC(); | 1579 CallStoreIC(); |
| 1566 } else { | 1580 } else { |
| 1567 CallStoreIC(key->LiteralFeedbackId()); | 1581 CallStoreIC(key->LiteralFeedbackId()); |
| 1568 } | 1582 } |
| 1569 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1583 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1570 | 1584 |
| 1571 if (NeedsHomeObject(value)) { | 1585 if (NeedsHomeObject(value)) { |
| 1572 __ movp(StoreDescriptor::ReceiverRegister(), rax); | 1586 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); |
| 1573 __ Move(StoreDescriptor::NameRegister(), | |
| 1574 isolate()->factory()->home_object_symbol()); | |
| 1575 __ movp(StoreDescriptor::ValueRegister(), Operand(rsp, 0)); | |
| 1576 if (FLAG_vector_stores) { | |
| 1577 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); | |
| 1578 } | |
| 1579 CallStoreIC(); | |
| 1580 } | 1587 } |
| 1581 } else { | 1588 } else { |
| 1582 VisitForEffect(value); | 1589 VisitForEffect(value); |
| 1583 } | 1590 } |
| 1584 break; | 1591 break; |
| 1585 } | 1592 } |
| 1586 __ Push(Operand(rsp, 0)); // Duplicate receiver. | 1593 __ Push(Operand(rsp, 0)); // Duplicate receiver. |
| 1587 VisitForStackValue(key); | 1594 VisitForStackValue(key); |
| 1588 VisitForStackValue(value); | 1595 VisitForStackValue(value); |
| 1589 if (property->emit_store()) { | 1596 if (property->emit_store()) { |
| 1590 EmitSetHomeObjectIfNeeded( | 1597 if (NeedsHomeObject(value)) { |
| 1591 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); | 1598 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 1599 } |
| 1592 __ Push(Smi::FromInt(SLOPPY)); // Language mode | 1600 __ Push(Smi::FromInt(SLOPPY)); // Language mode |
| 1593 __ CallRuntime(Runtime::kSetProperty, 4); | 1601 __ CallRuntime(Runtime::kSetProperty, 4); |
| 1594 } else { | 1602 } else { |
| 1595 __ Drop(3); | 1603 __ Drop(3); |
| 1596 } | 1604 } |
| 1597 break; | 1605 break; |
| 1598 case ObjectLiteral::Property::PROTOTYPE: | 1606 case ObjectLiteral::Property::PROTOTYPE: |
| 1599 __ Push(Operand(rsp, 0)); // Duplicate receiver. | 1607 __ Push(Operand(rsp, 0)); // Duplicate receiver. |
| 1600 VisitForStackValue(value); | 1608 VisitForStackValue(value); |
| 1601 DCHECK(property->emit_store()); | 1609 DCHECK(property->emit_store()); |
| 1602 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1610 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
| 1603 break; | 1611 break; |
| 1604 case ObjectLiteral::Property::GETTER: | 1612 case ObjectLiteral::Property::GETTER: |
| 1605 if (property->emit_store()) { | 1613 if (property->emit_store()) { |
| 1606 accessor_table.lookup(key)->second->getter = value; | 1614 accessor_table.lookup(key)->second->getter = property; |
| 1607 } | 1615 } |
| 1608 break; | 1616 break; |
| 1609 case ObjectLiteral::Property::SETTER: | 1617 case ObjectLiteral::Property::SETTER: |
| 1610 if (property->emit_store()) { | 1618 if (property->emit_store()) { |
| 1611 accessor_table.lookup(key)->second->setter = value; | 1619 accessor_table.lookup(key)->second->setter = property; |
| 1612 } | 1620 } |
| 1613 break; | 1621 break; |
| 1614 } | 1622 } |
| 1615 } | 1623 } |
| 1616 | 1624 |
| 1617 // Emit code to define accessors, using only a single call to the runtime for | 1625 // Emit code to define accessors, using only a single call to the runtime for |
| 1618 // each pair of corresponding getters and setters. | 1626 // each pair of corresponding getters and setters. |
| 1619 for (AccessorTable::Iterator it = accessor_table.begin(); | 1627 for (AccessorTable::Iterator it = accessor_table.begin(); |
| 1620 it != accessor_table.end(); | 1628 it != accessor_table.end(); |
| 1621 ++it) { | 1629 ++it) { |
| 1622 __ Push(Operand(rsp, 0)); // Duplicate receiver. | 1630 __ Push(Operand(rsp, 0)); // Duplicate receiver. |
| 1623 VisitForStackValue(it->first); | 1631 VisitForStackValue(it->first); |
| 1624 EmitAccessor(it->second->getter); | 1632 EmitAccessor(it->second->getter); |
| 1625 EmitSetHomeObjectIfNeeded( | |
| 1626 it->second->getter, 2, | |
| 1627 expr->SlotForHomeObject(it->second->getter, &store_slot_index)); | |
| 1628 EmitAccessor(it->second->setter); | 1633 EmitAccessor(it->second->setter); |
| 1629 EmitSetHomeObjectIfNeeded( | |
| 1630 it->second->setter, 3, | |
| 1631 expr->SlotForHomeObject(it->second->setter, &store_slot_index)); | |
| 1632 __ Push(Smi::FromInt(NONE)); | 1634 __ Push(Smi::FromInt(NONE)); |
| 1633 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 1635 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); |
| 1634 } | 1636 } |
| 1635 | 1637 |
| 1636 // Object literals have two parts. The "static" part on the left contains no | 1638 // Object literals have two parts. The "static" part on the left contains no |
| 1637 // computed property names, and so we can compute its map ahead of time; see | 1639 // computed property names, and so we can compute its map ahead of time; see |
| 1638 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1640 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
| 1639 // starts with the first computed property name, and continues with all | 1641 // starts with the first computed property name, and continues with all |
| 1640 // properties to its right. All the code from above initializes the static | 1642 // properties to its right. All the code from above initializes the static |
| 1641 // component of the object literal, and arranges for the map of the result to | 1643 // component of the object literal, and arranges for the map of the result to |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1654 __ Push(Operand(rsp, 0)); // Duplicate receiver. | 1656 __ Push(Operand(rsp, 0)); // Duplicate receiver. |
| 1655 | 1657 |
| 1656 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1658 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
| 1657 DCHECK(!property->is_computed_name()); | 1659 DCHECK(!property->is_computed_name()); |
| 1658 VisitForStackValue(value); | 1660 VisitForStackValue(value); |
| 1659 DCHECK(property->emit_store()); | 1661 DCHECK(property->emit_store()); |
| 1660 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1662 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
| 1661 } else { | 1663 } else { |
| 1662 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); | 1664 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); |
| 1663 VisitForStackValue(value); | 1665 VisitForStackValue(value); |
| 1664 EmitSetHomeObjectIfNeeded( | 1666 if (NeedsHomeObject(value)) { |
| 1665 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); | 1667 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 1668 } |
| 1666 | 1669 |
| 1667 switch (property->kind()) { | 1670 switch (property->kind()) { |
| 1668 case ObjectLiteral::Property::CONSTANT: | 1671 case ObjectLiteral::Property::CONSTANT: |
| 1669 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1672 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1670 case ObjectLiteral::Property::COMPUTED: | 1673 case ObjectLiteral::Property::COMPUTED: |
| 1671 if (property->emit_store()) { | 1674 if (property->emit_store()) { |
| 1672 __ Push(Smi::FromInt(NONE)); | 1675 __ Push(Smi::FromInt(NONE)); |
| 1673 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); | 1676 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); |
| 1674 } else { | 1677 } else { |
| 1675 __ Drop(3); | 1678 __ Drop(3); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1697 DCHECK(result_saved); | 1700 DCHECK(result_saved); |
| 1698 __ Push(Operand(rsp, 0)); | 1701 __ Push(Operand(rsp, 0)); |
| 1699 __ CallRuntime(Runtime::kToFastProperties, 1); | 1702 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1700 } | 1703 } |
| 1701 | 1704 |
| 1702 if (result_saved) { | 1705 if (result_saved) { |
| 1703 context()->PlugTOS(); | 1706 context()->PlugTOS(); |
| 1704 } else { | 1707 } else { |
| 1705 context()->Plug(rax); | 1708 context()->Plug(rax); |
| 1706 } | 1709 } |
| 1707 | |
| 1708 // Verify that compilation exactly consumed the number of store ic slots that | |
| 1709 // the ObjectLiteral node had to offer. | |
| 1710 DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count()); | |
| 1711 } | 1710 } |
| 1712 | 1711 |
| 1713 | 1712 |
| 1714 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1713 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
| 1715 Comment cmnt(masm_, "[ ArrayLiteral"); | 1714 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 1716 | 1715 |
| 1717 expr->BuildConstantElements(isolate()); | 1716 expr->BuildConstantElements(isolate()); |
| 1718 Handle<FixedArray> constant_elements = expr->constant_elements(); | 1717 Handle<FixedArray> constant_elements = expr->constant_elements(); |
| 1719 bool has_constant_fast_elements = | 1718 bool has_constant_fast_elements = |
| 1720 IsFastObjectElementsKind(expr->constant_elements_kind()); | 1719 IsFastObjectElementsKind(expr->constant_elements_kind()); |
| (...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2370 default: | 2369 default: |
| 2371 UNREACHABLE(); | 2370 UNREACHABLE(); |
| 2372 break; | 2371 break; |
| 2373 } | 2372 } |
| 2374 | 2373 |
| 2375 __ bind(&done); | 2374 __ bind(&done); |
| 2376 context()->Plug(rax); | 2375 context()->Plug(rax); |
| 2377 } | 2376 } |
| 2378 | 2377 |
| 2379 | 2378 |
| 2380 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit, | 2379 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { |
| 2381 int* used_store_slots) { | |
| 2382 // Constructor is in rax. | 2380 // Constructor is in rax. |
| 2383 DCHECK(lit != NULL); | 2381 DCHECK(lit != NULL); |
| 2384 __ Push(rax); | 2382 __ Push(rax); |
| 2385 | 2383 |
| 2386 // No access check is needed here since the constructor is created by the | 2384 // No access check is needed here since the constructor is created by the |
| 2387 // class literal. | 2385 // class literal. |
| 2388 Register scratch = rbx; | 2386 Register scratch = rbx; |
| 2389 __ movp(scratch, FieldOperand(rax, JSFunction::kPrototypeOrInitialMapOffset)); | 2387 __ movp(scratch, FieldOperand(rax, JSFunction::kPrototypeOrInitialMapOffset)); |
| 2390 __ Push(scratch); | 2388 __ Push(scratch); |
| 2391 | 2389 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2403 // The static prototype property is read only. We handle the non computed | 2401 // The static prototype property is read only. We handle the non computed |
| 2404 // property name case in the parser. Since this is the only case where we | 2402 // property name case in the parser. Since this is the only case where we |
| 2405 // need to check for an own read only property we special case this so we do | 2403 // need to check for an own read only property we special case this so we do |
| 2406 // not need to do this for every property. | 2404 // not need to do this for every property. |
| 2407 if (property->is_static() && property->is_computed_name()) { | 2405 if (property->is_static() && property->is_computed_name()) { |
| 2408 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); | 2406 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); |
| 2409 __ Push(rax); | 2407 __ Push(rax); |
| 2410 } | 2408 } |
| 2411 | 2409 |
| 2412 VisitForStackValue(value); | 2410 VisitForStackValue(value); |
| 2413 EmitSetHomeObjectIfNeeded(value, 2, | 2411 if (NeedsHomeObject(value)) { |
| 2414 lit->SlotForHomeObject(value, used_store_slots)); | 2412 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 2413 } |
| 2415 | 2414 |
| 2416 switch (property->kind()) { | 2415 switch (property->kind()) { |
| 2417 case ObjectLiteral::Property::CONSTANT: | 2416 case ObjectLiteral::Property::CONSTANT: |
| 2418 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 2417 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 2419 case ObjectLiteral::Property::PROTOTYPE: | 2418 case ObjectLiteral::Property::PROTOTYPE: |
| 2420 UNREACHABLE(); | 2419 UNREACHABLE(); |
| 2421 case ObjectLiteral::Property::COMPUTED: | 2420 case ObjectLiteral::Property::COMPUTED: |
| 2422 __ CallRuntime(Runtime::kDefineClassMethod, 3); | 2421 __ CallRuntime(Runtime::kDefineClassMethod, 3); |
| 2423 break; | 2422 break; |
| 2424 | 2423 |
| (...skipping 2859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5284 Assembler::target_address_at(call_target_address, | 5283 Assembler::target_address_at(call_target_address, |
| 5285 unoptimized_code)); | 5284 unoptimized_code)); |
| 5286 return OSR_AFTER_STACK_CHECK; | 5285 return OSR_AFTER_STACK_CHECK; |
| 5287 } | 5286 } |
| 5288 | 5287 |
| 5289 | 5288 |
| 5290 } // namespace internal | 5289 } // namespace internal |
| 5291 } // namespace v8 | 5290 } // namespace v8 |
| 5292 | 5291 |
| 5293 #endif // V8_TARGET_ARCH_X64 | 5292 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |