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) { |
1658 TraceStoreIntoObject(object, dest, value); | |
1654 if (value.IsSmi()) { | 1659 if (value.IsSmi()) { |
1655 movl(dest, Immediate(reinterpret_cast<int32_t>(value.raw()))); | 1660 movl(dest, Immediate(reinterpret_cast<int32_t>(value.raw()))); |
1656 } else { | 1661 } else { |
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 | |
1689 void Assembler::TraceStoreIntoObject(Register object, | |
1690 const FieldAddress& dest, | |
1691 const Object& value) { | |
1692 if (HeapTrace::is_enabled()) { | |
1693 pushal(); | |
1694 EnterCallRuntimeFrame(3 * kWordSize); | |
1695 movl(Address(ESP, 0 * kWordSize), object); | |
1696 leal(EAX, dest); | |
1697 movl(Address(ESP, 1 * kWordSize), EAX); | |
1698 movl(Address(ESP, 2 * kWordSize), | |
1699 Immediate(reinterpret_cast<int32_t>(value.raw()))); | |
siva
2012/12/05 16:06:40
This is not right, the raw value is directly being
cshapiro
2012/12/08 03:23:08
This method turns out to not be needed so I will b
| |
1700 CallRuntime(kHeapTraceStoreRuntimeEntry); | |
1701 LeaveCallRuntimeFrame(); | |
1702 popal(); | |
1703 } | |
1704 } | |
1705 | |
1706 | |
1667 void Assembler::LoadDoubleConstant(XmmRegister dst, double value) { | 1707 void Assembler::LoadDoubleConstant(XmmRegister dst, double value) { |
1668 // TODO(5410843): Need to have a code constants table. | 1708 // TODO(5410843): Need to have a code constants table. |
1669 int64_t constant = bit_cast<int64_t, double>(value); | 1709 int64_t constant = bit_cast<int64_t, double>(value); |
1670 pushl(Immediate(Utils::High32Bits(constant))); | 1710 pushl(Immediate(Utils::High32Bits(constant))); |
1671 pushl(Immediate(Utils::Low32Bits(constant))); | 1711 pushl(Immediate(Utils::Low32Bits(constant))); |
1672 movsd(dst, Address(ESP, 0)); | 1712 movsd(dst, Address(ESP, 0)); |
1673 addl(ESP, Immediate(2 * kWordSize)); | 1713 addl(ESP, Immediate(2 * kWordSize)); |
1674 } | 1714 } |
1675 | 1715 |
1676 | 1716 |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2035 | 2075 |
2036 const char* Assembler::XmmRegisterName(XmmRegister reg) { | 2076 const char* Assembler::XmmRegisterName(XmmRegister reg) { |
2037 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 2077 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
2038 return xmm_reg_names[reg]; | 2078 return xmm_reg_names[reg]; |
2039 } | 2079 } |
2040 | 2080 |
2041 | 2081 |
2042 } // namespace dart | 2082 } // namespace dart |
2043 | 2083 |
2044 #endif // defined TARGET_ARCH_IA32 | 2084 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |