OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/code_generator.h" |
9 #include "vm/heap.h" | 10 #include "vm/heap.h" |
| 11 #include "vm/heap_trace.h" |
10 #include "vm/memory_region.h" | 12 #include "vm/memory_region.h" |
11 #include "vm/runtime_entry.h" | 13 #include "vm/runtime_entry.h" |
12 #include "vm/stub_code.h" | 14 #include "vm/stub_code.h" |
13 | 15 |
14 namespace dart { | 16 namespace dart { |
15 | 17 |
16 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); | 18 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
17 DEFINE_FLAG(bool, code_comments, false, | 19 DEFINE_FLAG(bool, code_comments, false, |
18 "Include comments into code and disassembly"); | 20 "Include comments into code and disassembly"); |
19 DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available"); | 21 DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available"); |
(...skipping 1593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1613 (kNewObjectAlignmentOffset >> 1) + kHeapObjectTag + | 1615 (kNewObjectAlignmentOffset >> 1) + kHeapObjectTag + |
1614 kOldObjectAlignmentOffset + kHeapObjectTag)); | 1616 kOldObjectAlignmentOffset + kHeapObjectTag)); |
1615 j(NOT_ZERO, no_update, Assembler::kNearJump); | 1617 j(NOT_ZERO, no_update, Assembler::kNearJump); |
1616 } | 1618 } |
1617 | 1619 |
1618 | 1620 |
1619 void Assembler::StoreIntoObject(Register object, | 1621 void Assembler::StoreIntoObject(Register object, |
1620 const FieldAddress& dest, | 1622 const FieldAddress& dest, |
1621 Register value) { | 1623 Register value) { |
1622 ASSERT(object != value); | 1624 ASSERT(object != value); |
| 1625 TraceStoreIntoObject(object, dest, value); |
1623 movl(dest, value); | 1626 movl(dest, value); |
1624 Label done; | 1627 Label done; |
1625 StoreIntoObjectFilter(object, value, &done); | 1628 StoreIntoObjectFilter(object, value, &done); |
1626 // A store buffer update is required. | 1629 // A store buffer update is required. |
1627 if (value != EAX) pushl(EAX); // Preserve EAX. | 1630 if (value != EAX) pushl(EAX); // Preserve EAX. |
1628 leal(EAX, dest); | 1631 leal(EAX, dest); |
1629 call(&StubCode::UpdateStoreBufferLabel()); | 1632 call(&StubCode::UpdateStoreBufferLabel()); |
1630 if (value != EAX) popl(EAX); // Restore EAX. | 1633 if (value != EAX) popl(EAX); // Restore EAX. |
1631 Bind(&done); | 1634 Bind(&done); |
1632 } | 1635 } |
1633 | 1636 |
1634 | 1637 |
1635 void Assembler::StoreIntoObjectNoBarrier(Register object, | 1638 void Assembler::StoreIntoObjectNoBarrier(Register object, |
1636 const FieldAddress& dest, | 1639 const FieldAddress& dest, |
1637 Register value) { | 1640 Register value) { |
| 1641 TraceStoreIntoObject(object, dest, value); |
1638 movl(dest, value); | 1642 movl(dest, value); |
1639 #if defined(DEBUG) | 1643 #if defined(DEBUG) |
1640 Label done; | 1644 Label done; |
1641 pushl(value); | 1645 pushl(value); |
1642 StoreIntoObjectFilter(object, value, &done); | 1646 StoreIntoObjectFilter(object, value, &done); |
1643 Stop("Store buffer update is required"); | 1647 Stop("Store buffer update is required"); |
1644 Bind(&done); | 1648 Bind(&done); |
1645 popl(value); | 1649 popl(value); |
1646 #endif // defined(DEBUG) | 1650 #endif // defined(DEBUG) |
1647 // No store buffer update. | 1651 // No store buffer update. |
1648 } | 1652 } |
1649 | 1653 |
1650 | 1654 |
1651 void Assembler::StoreIntoObjectNoBarrier(Register object, | 1655 void Assembler::StoreIntoObjectNoBarrier(Register object, |
1652 const FieldAddress& dest, | 1656 const FieldAddress& dest, |
1653 const Object& value) { | 1657 const Object& value) { |
1654 if (value.IsSmi()) { | 1658 if (value.IsSmi()) { |
1655 movl(dest, Immediate(reinterpret_cast<int32_t>(value.raw()))); | 1659 movl(dest, Immediate(reinterpret_cast<int32_t>(value.raw()))); |
1656 } else { | 1660 } else { |
| 1661 // No heap trace for an old object store. |
1657 ASSERT(value.IsOld()); | 1662 ASSERT(value.IsOld()); |
1658 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1663 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1659 EmitUint8(0xC7); | 1664 EmitUint8(0xC7); |
1660 EmitOperand(0, dest); | 1665 EmitOperand(0, dest); |
1661 buffer_.EmitObject(value); | 1666 buffer_.EmitObject(value); |
1662 } | 1667 } |
1663 // No store buffer update. | 1668 // No store buffer update. |
1664 } | 1669 } |
1665 | 1670 |
1666 | 1671 |
| 1672 void Assembler::TraceStoreIntoObject(Register object, |
| 1673 const FieldAddress& dest, |
| 1674 Register value) { |
| 1675 if (HeapTrace::is_enabled()) { |
| 1676 pushal(); |
| 1677 EnterCallRuntimeFrame(3 * kWordSize); |
| 1678 movl(Address(ESP, 0 * kWordSize), object); |
| 1679 leal(EAX, dest); |
| 1680 movl(Address(ESP, 1 * kWordSize), EAX); |
| 1681 movl(Address(ESP, 2 * kWordSize), value); |
| 1682 CallRuntime(kHeapTraceStoreRuntimeEntry); |
| 1683 LeaveCallRuntimeFrame(); |
| 1684 popal(); |
| 1685 } |
| 1686 } |
| 1687 |
| 1688 |
1667 void Assembler::LoadDoubleConstant(XmmRegister dst, double value) { | 1689 void Assembler::LoadDoubleConstant(XmmRegister dst, double value) { |
1668 // TODO(5410843): Need to have a code constants table. | 1690 // TODO(5410843): Need to have a code constants table. |
1669 int64_t constant = bit_cast<int64_t, double>(value); | 1691 int64_t constant = bit_cast<int64_t, double>(value); |
1670 pushl(Immediate(Utils::High32Bits(constant))); | 1692 pushl(Immediate(Utils::High32Bits(constant))); |
1671 pushl(Immediate(Utils::Low32Bits(constant))); | 1693 pushl(Immediate(Utils::Low32Bits(constant))); |
1672 movsd(dst, Address(ESP, 0)); | 1694 movsd(dst, Address(ESP, 0)); |
1673 addl(ESP, Immediate(2 * kWordSize)); | 1695 addl(ESP, Immediate(2 * kWordSize)); |
1674 } | 1696 } |
1675 | 1697 |
1676 | 1698 |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2035 | 2057 |
2036 const char* Assembler::XmmRegisterName(XmmRegister reg) { | 2058 const char* Assembler::XmmRegisterName(XmmRegister reg) { |
2037 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 2059 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
2038 return xmm_reg_names[reg]; | 2060 return xmm_reg_names[reg]; |
2039 } | 2061 } |
2040 | 2062 |
2041 | 2063 |
2042 } // namespace dart | 2064 } // namespace dart |
2043 | 2065 |
2044 #endif // defined TARGET_ARCH_IA32 | 2066 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |