Index: src/ia32/assembler-ia32.cc |
diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc |
index d7ce5a793ac3155a62eaa624f32023774cebdd49..7e59ab9fa8e05b184efaf88153f23684f2dd0f7a 100644 |
--- a/src/ia32/assembler-ia32.cc |
+++ b/src/ia32/assembler-ia32.cc |
@@ -1340,6 +1340,13 @@ void Assembler::ret(int imm16) { |
} |
+void Assembler::ud2() { |
+ EnsureSpace ensure_space(this); |
+ EMIT(0x0F); |
+ EMIT(0x0B); |
+} |
+ |
+ |
// Labels refer to positions in the (to be) generated code. |
// There are bound, linked, and unused labels. |
// |
@@ -1378,7 +1385,10 @@ void Assembler::bind_to(Label* L, int pos) { |
while (L->is_linked()) { |
Displacement disp = disp_at(L); |
int fixup_pos = L->pos(); |
- if (disp.type() == Displacement::CODE_RELATIVE) { |
+ if (disp.type() == Displacement::CODE_ABSOLUTE) { |
+ long_at_put(fixup_pos, reinterpret_cast<int>(buffer_ + pos)); |
+ internal_reference_positions_.push_back(fixup_pos); |
+ } else if (disp.type() == Displacement::CODE_RELATIVE) { |
// Relative to Code* heap object pointer. |
long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag); |
} else { |
@@ -2690,15 +2700,10 @@ void Assembler::GrowBuffer() { |
reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, |
reloc_info_writer.last_pc() + pc_delta); |
- // Relocate runtime entries. |
- for (RelocIterator it(desc); !it.done(); it.next()) { |
- RelocInfo::Mode rmode = it.rinfo()->rmode(); |
- if (rmode == RelocInfo::INTERNAL_REFERENCE) { |
- int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc()); |
- if (*p != 0) { // 0 means uninitialized. |
- *p += pc_delta; |
- } |
- } |
+ // Relocate internal references. |
+ for (auto pos : internal_reference_positions_) { |
+ int32_t* p = reinterpret_cast<int32_t*>(buffer_ + pos); |
+ *p += pc_delta; |
} |
DCHECK(!buffer_overflow()); |
@@ -2748,7 +2753,21 @@ void Assembler::emit_operand(Register reg, const Operand& adr) { |
if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) { |
pc_ -= sizeof(int32_t); // pc_ must be *at* disp32 |
RecordRelocInfo(adr.rmode_); |
- pc_ += sizeof(int32_t); |
+ if (adr.rmode_ == RelocInfo::INTERNAL_REFERENCE) { // Fixup for labels |
+ emit_label(*reinterpret_cast<Label**>(pc_)); |
+ } else { |
+ pc_ += sizeof(int32_t); |
+ } |
+ } |
+} |
+ |
+ |
+void Assembler::emit_label(Label* label) { |
+ if (label->is_bound()) { |
+ internal_reference_positions_.push_back(pc_offset()); |
+ emit(reinterpret_cast<uint32_t>(buffer_ + label->pos())); |
+ } else { |
+ emit_disp(label, Displacement::CODE_ABSOLUTE); |
} |
} |
@@ -2773,6 +2792,13 @@ void Assembler::dd(uint32_t data) { |
} |
+void Assembler::dd(Label* label) { |
+ EnsureSpace ensure_space(this); |
+ RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); |
+ emit_label(label); |
+} |
+ |
+ |
void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { |
DCHECK(!RelocInfo::IsNone(rmode)); |
// Don't record external references unless the heap will be serialized. |