| 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.
|
|
|