| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 #ifndef RUNTIME_VM_ASSEMBLER_IA32_H_ | 5 #ifndef RUNTIME_VM_ASSEMBLER_IA32_H_ |
| 6 #define RUNTIME_VM_ASSEMBLER_IA32_H_ | 6 #define RUNTIME_VM_ASSEMBLER_IA32_H_ |
| 7 | 7 |
| 8 #ifndef RUNTIME_VM_ASSEMBLER_H_ | 8 #ifndef RUNTIME_VM_ASSEMBLER_H_ |
| 9 #error Do not include assembler_ia32.h directly; use assembler.h instead. | 9 #error Do not include assembler_ia32.h directly; use assembler.h instead. |
| 10 #endif | 10 #endif |
| 11 | 11 |
| 12 #include "platform/assert.h" | 12 #include "platform/assert.h" |
| 13 #include "platform/utils.h" | 13 #include "platform/utils.h" |
| 14 #include "vm/constants_ia32.h" | 14 #include "vm/constants_ia32.h" |
| 15 | 15 |
| 16 namespace dart { | 16 namespace dart { |
| 17 | 17 |
| 18 // Forward declarations. | 18 // Forward declarations. |
| 19 class RuntimeEntry; | 19 class RuntimeEntry; |
| 20 class StubEntry; | 20 class StubEntry; |
| 21 | 21 |
| 22 class Immediate : public ValueObject { | 22 class Immediate : public ValueObject { |
| 23 public: | 23 public: |
| 24 explicit Immediate(int32_t value) : value_(value) { } | 24 explicit Immediate(int32_t value) : value_(value) {} |
| 25 | 25 |
| 26 Immediate(const Immediate& other) : ValueObject(), value_(other.value_) { } | 26 Immediate(const Immediate& other) : ValueObject(), value_(other.value_) {} |
| 27 | 27 |
| 28 int32_t value() const { return value_; } | 28 int32_t value() const { return value_; } |
| 29 | 29 |
| 30 bool is_int8() const { return Utils::IsInt(8, value_); } | 30 bool is_int8() const { return Utils::IsInt(8, value_); } |
| 31 bool is_uint8() const { return Utils::IsUint(8, value_); } | 31 bool is_uint8() const { return Utils::IsUint(8, value_); } |
| 32 bool is_uint16() const { return Utils::IsUint(16, value_); } | 32 bool is_uint16() const { return Utils::IsUint(16, value_); } |
| 33 | 33 |
| 34 private: | 34 private: |
| 35 const int32_t value_; | 35 const int32_t value_; |
| 36 | 36 |
| 37 // TODO(5411081): Add DISALLOW_COPY_AND_ASSIGN(Immediate) once the mac | 37 // TODO(5411081): Add DISALLOW_COPY_AND_ASSIGN(Immediate) once the mac |
| 38 // build issue is resolved. | 38 // build issue is resolved. |
| 39 // And remove the unnecessary copy constructor. | 39 // And remove the unnecessary copy constructor. |
| 40 }; | 40 }; |
| 41 | 41 |
| 42 | 42 |
| 43 class Operand : public ValueObject { | 43 class Operand : public ValueObject { |
| 44 public: | 44 public: |
| 45 uint8_t mod() const { | 45 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; } |
| 46 return (encoding_at(0) >> 6) & 3; | |
| 47 } | |
| 48 | 46 |
| 49 Register rm() const { | 47 Register rm() const { return static_cast<Register>(encoding_at(0) & 7); } |
| 50 return static_cast<Register>(encoding_at(0) & 7); | |
| 51 } | |
| 52 | 48 |
| 53 ScaleFactor scale() const { | 49 ScaleFactor scale() const { |
| 54 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3); | 50 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3); |
| 55 } | 51 } |
| 56 | 52 |
| 57 Register index() const { | 53 Register index() const { |
| 58 return static_cast<Register>((encoding_at(1) >> 3) & 7); | 54 return static_cast<Register>((encoding_at(1) >> 3) & 7); |
| 59 } | 55 } |
| 60 | 56 |
| 61 Register base() const { | 57 Register base() const { return static_cast<Register>(encoding_at(1) & 7); } |
| 62 return static_cast<Register>(encoding_at(1) & 7); | |
| 63 } | |
| 64 | 58 |
| 65 int8_t disp8() const { | 59 int8_t disp8() const { |
| 66 ASSERT(length_ >= 2); | 60 ASSERT(length_ >= 2); |
| 67 return static_cast<int8_t>(encoding_[length_ - 1]); | 61 return static_cast<int8_t>(encoding_[length_ - 1]); |
| 68 } | 62 } |
| 69 | 63 |
| 70 int32_t disp32() const { | 64 int32_t disp32() const { |
| 71 ASSERT(length_ >= 5); | 65 ASSERT(length_ >= 5); |
| 72 return bit_copy<int32_t>(encoding_[length_ - 4]); | 66 return bit_copy<int32_t>(encoding_[length_ - 4]); |
| 73 } | 67 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 84 | 78 |
| 85 bool Equals(const Operand& other) const { | 79 bool Equals(const Operand& other) const { |
| 86 if (length_ != other.length_) return false; | 80 if (length_ != other.length_) return false; |
| 87 for (uint8_t i = 0; i < length_; i++) { | 81 for (uint8_t i = 0; i < length_; i++) { |
| 88 if (encoding_[i] != other.encoding_[i]) return false; | 82 if (encoding_[i] != other.encoding_[i]) return false; |
| 89 } | 83 } |
| 90 return true; | 84 return true; |
| 91 } | 85 } |
| 92 | 86 |
| 93 protected: | 87 protected: |
| 94 Operand() : length_(0) { } // Needed by subclass Address. | 88 Operand() : length_(0) {} // Needed by subclass Address. |
| 95 | 89 |
| 96 void SetModRM(int mod, Register rm) { | 90 void SetModRM(int mod, Register rm) { |
| 97 ASSERT((mod & ~3) == 0); | 91 ASSERT((mod & ~3) == 0); |
| 98 encoding_[0] = (mod << 6) | rm; | 92 encoding_[0] = (mod << 6) | rm; |
| 99 length_ = 1; | 93 length_ = 1; |
| 100 } | 94 } |
| 101 | 95 |
| 102 void SetSIB(ScaleFactor scale, Register index, Register base) { | 96 void SetSIB(ScaleFactor scale, Register index, Register base) { |
| 103 ASSERT(length_ == 1); | 97 ASSERT(length_ == 1); |
| 104 ASSERT((scale & ~3) == 0); | 98 ASSERT((scale & ~3) == 0); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 128 // Get the operand encoding byte at the given index. | 122 // Get the operand encoding byte at the given index. |
| 129 uint8_t encoding_at(intptr_t index) const { | 123 uint8_t encoding_at(intptr_t index) const { |
| 130 ASSERT(index >= 0 && index < length_); | 124 ASSERT(index >= 0 && index < length_); |
| 131 return encoding_[index]; | 125 return encoding_[index]; |
| 132 } | 126 } |
| 133 | 127 |
| 134 // Returns whether or not this operand is really the given register in | 128 // Returns whether or not this operand is really the given register in |
| 135 // disguise. Used from the assembler to generate better encodings. | 129 // disguise. Used from the assembler to generate better encodings. |
| 136 bool IsRegister(Register reg) const { | 130 bool IsRegister(Register reg) const { |
| 137 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only. | 131 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only. |
| 138 && ((encoding_[0] & 0x07) == reg); // Register codes match. | 132 && ((encoding_[0] & 0x07) == reg); // Register codes match. |
| 139 } | 133 } |
| 140 | 134 |
| 141 friend class Assembler; | 135 friend class Assembler; |
| 142 }; | 136 }; |
| 143 | 137 |
| 144 | 138 |
| 145 class Address : public Operand { | 139 class Address : public Operand { |
| 146 public: | 140 public: |
| 147 Address(Register base, int32_t disp) { | 141 Address(Register base, int32_t disp) { |
| 148 if (disp == 0 && base != EBP) { | 142 if (disp == 0 && base != EBP) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 } else { | 175 } else { |
| 182 SetModRM(2, ESP); | 176 SetModRM(2, ESP); |
| 183 SetSIB(scale, index, base); | 177 SetSIB(scale, index, base); |
| 184 SetDisp32(disp); | 178 SetDisp32(disp); |
| 185 } | 179 } |
| 186 } | 180 } |
| 187 | 181 |
| 188 // This addressing mode does not exist. | 182 // This addressing mode does not exist. |
| 189 Address(Register base, Register index, ScaleFactor scale, Register r); | 183 Address(Register base, Register index, ScaleFactor scale, Register r); |
| 190 | 184 |
| 191 Address(const Address& other) : Operand(other) { } | 185 Address(const Address& other) : Operand(other) {} |
| 192 | 186 |
| 193 Address& operator=(const Address& other) { | 187 Address& operator=(const Address& other) { |
| 194 Operand::operator=(other); | 188 Operand::operator=(other); |
| 195 return *this; | 189 return *this; |
| 196 } | 190 } |
| 197 | 191 |
| 198 static Address Absolute(const uword addr) { | 192 static Address Absolute(const uword addr) { |
| 199 Address result; | 193 Address result; |
| 200 result.SetModRM(0, EBP); | 194 result.SetModRM(0, EBP); |
| 201 result.SetDisp32(addr); | 195 result.SetDisp32(addr); |
| 202 return result; | 196 return result; |
| 203 } | 197 } |
| 204 | 198 |
| 205 private: | 199 private: |
| 206 Address() { } // Needed by Address::Absolute. | 200 Address() {} // Needed by Address::Absolute. |
| 207 }; | 201 }; |
| 208 | 202 |
| 209 | 203 |
| 210 class FieldAddress : public Address { | 204 class FieldAddress : public Address { |
| 211 public: | 205 public: |
| 212 FieldAddress(Register base, int32_t disp) | 206 FieldAddress(Register base, int32_t disp) |
| 213 : Address(base, disp - kHeapObjectTag) { } | 207 : Address(base, disp - kHeapObjectTag) {} |
| 214 | 208 |
| 215 // This addressing mode does not exist. | 209 // This addressing mode does not exist. |
| 216 FieldAddress(Register base, Register r); | 210 FieldAddress(Register base, Register r); |
| 217 | 211 |
| 218 FieldAddress(Register base, Register index, ScaleFactor scale, int32_t disp) | 212 FieldAddress(Register base, Register index, ScaleFactor scale, int32_t disp) |
| 219 : Address(base, index, scale, disp - kHeapObjectTag) { } | 213 : Address(base, index, scale, disp - kHeapObjectTag) {} |
| 220 | 214 |
| 221 // This addressing mode does not exist. | 215 // This addressing mode does not exist. |
| 222 FieldAddress(Register base, Register index, ScaleFactor scale, Register r); | 216 FieldAddress(Register base, Register index, ScaleFactor scale, Register r); |
| 223 | 217 |
| 224 FieldAddress(const FieldAddress& other) : Address(other) { } | 218 FieldAddress(const FieldAddress& other) : Address(other) {} |
| 225 | 219 |
| 226 FieldAddress& operator=(const FieldAddress& other) { | 220 FieldAddress& operator=(const FieldAddress& other) { |
| 227 Address::operator=(other); | 221 Address::operator=(other); |
| 228 return *this; | 222 return *this; |
| 229 } | 223 } |
| 230 }; | 224 }; |
| 231 | 225 |
| 232 | 226 |
| 233 class Label : public ValueObject { | 227 class Label : public ValueObject { |
| 234 public: | 228 public: |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 public: | 297 public: |
| 304 explicit Assembler(bool use_far_branches = false) | 298 explicit Assembler(bool use_far_branches = false) |
| 305 : buffer_(), | 299 : buffer_(), |
| 306 prologue_offset_(-1), | 300 prologue_offset_(-1), |
| 307 jit_cookie_(0), | 301 jit_cookie_(0), |
| 308 comments_(), | 302 comments_(), |
| 309 code_(Code::ZoneHandle()) { | 303 code_(Code::ZoneHandle()) { |
| 310 // This mode is only needed and implemented for MIPS and ARM. | 304 // This mode is only needed and implemented for MIPS and ARM. |
| 311 ASSERT(!use_far_branches); | 305 ASSERT(!use_far_branches); |
| 312 } | 306 } |
| 313 ~Assembler() { } | 307 ~Assembler() {} |
| 314 | 308 |
| 315 static const bool kNearJump = true; | 309 static const bool kNearJump = true; |
| 316 static const bool kFarJump = false; | 310 static const bool kFarJump = false; |
| 317 | 311 |
| 318 /* | 312 /* |
| 319 * Emit Machine Instructions. | 313 * Emit Machine Instructions. |
| 320 */ | 314 */ |
| 321 void call(Register reg); | 315 void call(Register reg); |
| 322 void call(const Address& address); | 316 void call(const Address& address); |
| 323 void call(Label* label); | 317 void call(Label* label); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 void orpd(XmmRegister dst, XmmRegister src); | 485 void orpd(XmmRegister dst, XmmRegister src); |
| 492 | 486 |
| 493 void pextrd(Register dst, XmmRegister src, const Immediate& imm); | 487 void pextrd(Register dst, XmmRegister src, const Immediate& imm); |
| 494 void pmovsxdq(XmmRegister dst, XmmRegister src); | 488 void pmovsxdq(XmmRegister dst, XmmRegister src); |
| 495 void pcmpeqq(XmmRegister dst, XmmRegister src); | 489 void pcmpeqq(XmmRegister dst, XmmRegister src); |
| 496 | 490 |
| 497 void pxor(XmmRegister dst, XmmRegister src); | 491 void pxor(XmmRegister dst, XmmRegister src); |
| 498 | 492 |
| 499 enum RoundingMode { | 493 enum RoundingMode { |
| 500 kRoundToNearest = 0x0, | 494 kRoundToNearest = 0x0, |
| 501 kRoundDown = 0x1, | 495 kRoundDown = 0x1, |
| 502 kRoundUp = 0x2, | 496 kRoundUp = 0x2, |
| 503 kRoundToZero = 0x3 | 497 kRoundToZero = 0x3 |
| 504 }; | 498 }; |
| 505 void roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode); | 499 void roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode); |
| 506 | 500 |
| 507 void flds(const Address& src); | 501 void flds(const Address& src); |
| 508 void fstps(const Address& dst); | 502 void fstps(const Address& dst); |
| 509 | 503 |
| 510 void fldl(const Address& src); | 504 void fldl(const Address& src); |
| 511 void fstpl(const Address& dst); | 505 void fstpl(const Address& dst); |
| 512 | 506 |
| 513 void fnstcw(const Address& dst); | 507 void fnstcw(const Address& dst); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 void leave(); | 619 void leave(); |
| 626 | 620 |
| 627 void ret(); | 621 void ret(); |
| 628 void ret(const Immediate& imm); | 622 void ret(const Immediate& imm); |
| 629 | 623 |
| 630 // 'size' indicates size in bytes and must be in the range 1..8. | 624 // 'size' indicates size in bytes and must be in the range 1..8. |
| 631 void nop(int size = 1); | 625 void nop(int size = 1); |
| 632 void int3(); | 626 void int3(); |
| 633 void hlt(); | 627 void hlt(); |
| 634 | 628 |
| 635 static uword GetBreakInstructionFiller() { | 629 static uword GetBreakInstructionFiller() { return 0xCCCCCCCC; } |
| 636 return 0xCCCCCCCC; | |
| 637 } | |
| 638 | 630 |
| 639 void j(Condition condition, Label* label, bool near = kFarJump); | 631 void j(Condition condition, Label* label, bool near = kFarJump); |
| 640 void j(Condition condition, const ExternalLabel* label); | 632 void j(Condition condition, const ExternalLabel* label); |
| 641 | 633 |
| 642 void jmp(Register reg); | 634 void jmp(Register reg); |
| 643 void jmp(Label* label, bool near = kFarJump); | 635 void jmp(Label* label, bool near = kFarJump); |
| 644 void jmp(const ExternalLabel* label); | 636 void jmp(const ExternalLabel* label); |
| 645 | 637 |
| 646 void lock(); | 638 void lock(); |
| 647 void cmpxchgl(const Address& address, Register reg); | 639 void cmpxchgl(const Address& address, Register reg); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 668 void LoadObject(Register dst, const Object& object); | 660 void LoadObject(Register dst, const Object& object); |
| 669 | 661 |
| 670 // If 'object' is a large Smi, xor it with a per-assembler cookie value to | 662 // If 'object' is a large Smi, xor it with a per-assembler cookie value to |
| 671 // prevent user-controlled immediates from appearing in the code stream. | 663 // prevent user-controlled immediates from appearing in the code stream. |
| 672 void LoadObjectSafely(Register dst, const Object& object); | 664 void LoadObjectSafely(Register dst, const Object& object); |
| 673 | 665 |
| 674 void PushObject(const Object& object); | 666 void PushObject(const Object& object); |
| 675 void CompareObject(Register reg, const Object& object); | 667 void CompareObject(Register reg, const Object& object); |
| 676 void LoadDoubleConstant(XmmRegister dst, double value); | 668 void LoadDoubleConstant(XmmRegister dst, double value); |
| 677 | 669 |
| 678 void StoreIntoObject(Register object, // Object we are storing into. | 670 void StoreIntoObject(Register object, // Object we are storing into. |
| 679 const Address& dest, // Where we are storing into. | 671 const Address& dest, // Where we are storing into. |
| 680 Register value, // Value we are storing. | 672 Register value, // Value we are storing. |
| 681 bool can_value_be_smi = true); | 673 bool can_value_be_smi = true); |
| 682 | 674 |
| 683 void StoreIntoObjectNoBarrier(Register object, | 675 void StoreIntoObjectNoBarrier(Register object, |
| 684 const Address& dest, | 676 const Address& dest, |
| 685 Register value); | 677 Register value); |
| 686 void StoreIntoObjectNoBarrier(Register object, | 678 void StoreIntoObjectNoBarrier(Register object, |
| 687 const Address& dest, | 679 const Address& dest, |
| 688 const Object& value); | 680 const Object& value); |
| 689 | 681 |
| 690 // Stores a Smi value into a heap object field that always contains a Smi. | 682 // Stores a Smi value into a heap object field that always contains a Smi. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 752 Register array, | 744 Register array, |
| 753 Register index); | 745 Register index); |
| 754 | 746 |
| 755 static Address VMTagAddress() { | 747 static Address VMTagAddress() { |
| 756 return Address(THR, Thread::vm_tag_offset()); | 748 return Address(THR, Thread::vm_tag_offset()); |
| 757 } | 749 } |
| 758 | 750 |
| 759 /* | 751 /* |
| 760 * Misc. functionality | 752 * Misc. functionality |
| 761 */ | 753 */ |
| 762 void SmiTag(Register reg) { | 754 void SmiTag(Register reg) { addl(reg, reg); } |
| 763 addl(reg, reg); | |
| 764 } | |
| 765 | 755 |
| 766 void SmiUntag(Register reg) { | 756 void SmiUntag(Register reg) { sarl(reg, Immediate(kSmiTagSize)); } |
| 767 sarl(reg, Immediate(kSmiTagSize)); | |
| 768 } | |
| 769 | 757 |
| 770 void BranchIfNotSmi(Register reg, Label* label) { | 758 void BranchIfNotSmi(Register reg, Label* label) { |
| 771 testl(reg, Immediate(kSmiTagMask)); | 759 testl(reg, Immediate(kSmiTagMask)); |
| 772 j(NOT_ZERO, label); | 760 j(NOT_ZERO, label); |
| 773 } | 761 } |
| 774 | 762 |
| 775 void Align(intptr_t alignment, intptr_t offset); | 763 void Align(intptr_t alignment, intptr_t offset); |
| 776 void Bind(Label* label); | 764 void Bind(Label* label); |
| 777 void Jump(Label* label) { jmp(label); } | 765 void Jump(Label* label) { jmp(label); } |
| 778 | 766 |
| 779 // Address of code at offset. | 767 // Address of code at offset. |
| 780 uword CodeAddress(intptr_t offset) { | 768 uword CodeAddress(intptr_t offset) { return buffer_.Address(offset); } |
| 781 return buffer_.Address(offset); | |
| 782 } | |
| 783 | 769 |
| 784 intptr_t CodeSize() const { return buffer_.Size(); } | 770 intptr_t CodeSize() const { return buffer_.Size(); } |
| 785 intptr_t prologue_offset() const { return prologue_offset_; } | 771 intptr_t prologue_offset() const { return prologue_offset_; } |
| 786 bool has_single_entry_point() const { return true; } | 772 bool has_single_entry_point() const { return true; } |
| 787 | 773 |
| 788 // Count the fixups that produce a pointer offset, without processing | 774 // Count the fixups that produce a pointer offset, without processing |
| 789 // the fixups. | 775 // the fixups. |
| 790 intptr_t CountPointerOffsets() const { | 776 intptr_t CountPointerOffsets() const { return buffer_.CountPointerOffsets(); } |
| 791 return buffer_.CountPointerOffsets(); | |
| 792 } | |
| 793 const ZoneGrowableArray<intptr_t>& GetPointerOffsets() const { | 777 const ZoneGrowableArray<intptr_t>& GetPointerOffsets() const { |
| 794 return buffer_.pointer_offsets(); | 778 return buffer_.pointer_offsets(); |
| 795 } | 779 } |
| 796 | 780 |
| 797 ObjectPoolWrapper& object_pool_wrapper() { return object_pool_wrapper_; } | 781 ObjectPoolWrapper& object_pool_wrapper() { return object_pool_wrapper_; } |
| 798 | 782 |
| 799 RawObjectPool* MakeObjectPool() { | 783 RawObjectPool* MakeObjectPool() { |
| 800 return object_pool_wrapper_.MakeObjectPool(); | 784 return object_pool_wrapper_.MakeObjectPool(); |
| 801 } | 785 } |
| 802 | 786 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 925 if (Utils::IsPowerOfTwo(value) || Utils::IsPowerOfTwo(value + 1)) { | 909 if (Utils::IsPowerOfTwo(value) || Utils::IsPowerOfTwo(value + 1)) { |
| 926 return true; | 910 return true; |
| 927 } | 911 } |
| 928 | 912 |
| 929 return false; | 913 return false; |
| 930 } | 914 } |
| 931 static bool IsSafe(const Object& object) { | 915 static bool IsSafe(const Object& object) { |
| 932 return !object.IsSmi() || IsSafeSmi(object); | 916 return !object.IsSmi() || IsSafeSmi(object); |
| 933 } | 917 } |
| 934 | 918 |
| 935 void set_code_object(const Code& code) { | 919 void set_code_object(const Code& code) { code_ ^= code.raw(); } |
| 936 code_ ^= code.raw(); | |
| 937 } | |
| 938 | 920 |
| 939 void PushCodeObject(); | 921 void PushCodeObject(); |
| 940 | 922 |
| 941 private: | 923 private: |
| 942 class CodeComment : public ZoneAllocated { | 924 class CodeComment : public ZoneAllocated { |
| 943 public: | 925 public: |
| 944 CodeComment(intptr_t pc_offset, const String& comment) | 926 CodeComment(intptr_t pc_offset, const String& comment) |
| 945 : pc_offset_(pc_offset), comment_(comment) { } | 927 : pc_offset_(pc_offset), comment_(comment) {} |
| 946 | 928 |
| 947 intptr_t pc_offset() const { return pc_offset_; } | 929 intptr_t pc_offset() const { return pc_offset_; } |
| 948 const String& comment() const { return comment_; } | 930 const String& comment() const { return comment_; } |
| 949 | 931 |
| 950 private: | 932 private: |
| 951 intptr_t pc_offset_; | 933 intptr_t pc_offset_; |
| 952 const String& comment_; | 934 const String& comment_; |
| 953 | 935 |
| 954 DISALLOW_COPY_AND_ASSIGN(CodeComment); | 936 DISALLOW_COPY_AND_ASSIGN(CodeComment); |
| 955 }; | 937 }; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1020 } | 1002 } |
| 1021 | 1003 |
| 1022 | 1004 |
| 1023 inline void Assembler::EmitOperandSizeOverride() { | 1005 inline void Assembler::EmitOperandSizeOverride() { |
| 1024 EmitUint8(0x66); | 1006 EmitUint8(0x66); |
| 1025 } | 1007 } |
| 1026 | 1008 |
| 1027 } // namespace dart | 1009 } // namespace dart |
| 1028 | 1010 |
| 1029 #endif // RUNTIME_VM_ASSEMBLER_IA32_H_ | 1011 #endif // RUNTIME_VM_ASSEMBLER_IA32_H_ |
| OLD | NEW |