void Assembler::deserialization_set_target_internal_reference_at(
- Address pc, Address target) {
+ Address pc, Address target, RelocInfo::Mode mode) {
Memory::Address_at(pc) = target;
}
// This sets the internal reference at the pc.
inline static void deserialization_set_target_internal_reference_at(
- Address pc, Address target);
+ Address pc, Address target,
+ RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
// Here we are patching the address in the constant pool, not the actual call
// instruction. The address in the constant pool is the same size as a
void Assembler::deserialization_set_target_internal_reference_at(
- Address pc, Address target) {
+ Address pc, Address target, RelocInfo::Mode mode) {
Memory::Address_at(pc) = target;
}
// This sets the internal reference at the pc.
inline static void deserialization_set_target_internal_reference_at(
- Address pc, Address target);
+ Address pc, Address target,
+ RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
// All addresses in the constant pool are the same size as pointers.
static const int kSpecialTargetSize = kPointerSize;
void Assembler::deserialization_set_target_internal_reference_at(
- Address pc, Address target) {
+ Address pc, Address target, RelocInfo::Mode mode) {
Memory::Address_at(pc) = target;
}
// This sets the internal reference at the pc.
inline static void deserialization_set_target_internal_reference_at(
- Address pc, Address target);
+ Address pc, Address target,
+ RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
static const int kSpecialTargetSize = kPointerSize;
}
+void Assembler::set_target_internal_reference_encoded_at(Address pc,
+ Address target) {
+ // Encoded internal references are lui/ori load of 32-bit abolute address.
+ Instr instr_lui = Assembler::instr_at(pc + 0 * Assembler::kInstrSize);
+ Instr instr_ori = Assembler::instr_at(pc + 1 * Assembler::kInstrSize);
+ DCHECK(Assembler::IsLui(instr_lui));
+ DCHECK(Assembler::IsOri(instr_ori));
+ instr_lui &= ~kImm16Mask;
+ instr_ori &= ~kImm16Mask;
+ int32_t imm = reinterpret_cast<int32_t>(target);
+ DCHECK((imm & 3) == 0);
+ Assembler::instr_at_put(pc + 0 * Assembler::kInstrSize,
+ instr_lui | ((imm >> kLuiShift) & kImm16Mask));
+ Assembler::instr_at_put(pc + 1 * Assembler::kInstrSize,
+ instr_ori | (imm & kImm16Mask));
+
+ // Currently used only by deserializer, and all code will be flushed
+ // after complete deserialization, no need to flush on each reference.
+}
+
+
void Assembler::deserialization_set_target_internal_reference_at(
- Address pc, Address target) {
- if (IsLui(instr_at(pc))) {
- // Encoded internal references are lui/ori load of 32-bit abolute address.
- Instr instr_lui = Assembler::instr_at(pc + 0 * Assembler::kInstrSize);
- Instr instr_ori = Assembler::instr_at(pc + 1 * Assembler::kInstrSize);
- DCHECK(Assembler::IsLui(instr_lui));
- DCHECK(Assembler::IsOri(instr_ori));
- instr_lui &= ~kImm16Mask;
- instr_ori &= ~kImm16Mask;
- int32_t imm = reinterpret_cast<int32_t>(target);
- DCHECK((imm & 3) == 0);
- Assembler::instr_at_put(pc + 0 * Assembler::kInstrSize,
- instr_lui | ((imm >> kLuiShift) & kImm16Mask));
- Assembler::instr_at_put(pc + 1 * Assembler::kInstrSize,
- instr_ori | (imm & kImm16Mask));
+ Address pc, Address target, RelocInfo::Mode mode) {
+ if (mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) {
+ DCHECK(IsLui(instr_at(pc)));
+ set_target_internal_reference_encoded_at(pc, target);
} else {
+ DCHECK(mode == RelocInfo::INTERNAL_REFERENCE);
Memory::Address_at(pc) = target;
}
}
if (IsInternalReference(rmode_)) {
Memory::Address_at(pc_) = NULL;
} else if (IsInternalReferenceEncoded(rmode_)) {
- Instr instr_lui = Assembler::instr_at(pc_ + 0 * Assembler::kInstrSize);
- Instr instr_ori = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize);
- DCHECK(Assembler::IsLui(instr_lui));
- DCHECK(Assembler::IsOri(instr_ori));
- instr_lui &= ~kImm16Mask;
- instr_ori &= ~kImm16Mask;
- int32_t imm = 0;
- Assembler::instr_at_put(pc_ + 0 * Assembler::kInstrSize,
- instr_lui | ((imm >> kLuiShift) & kImm16Mask));
- Assembler::instr_at_put(pc_ + 1 * Assembler::kInstrSize,
- instr_ori | (imm & kImm16Mask));
- // Currently used only by deserializer, and all code will be flushed
- // after complete deserialization, no need to flush on each reference.
+ Assembler::set_target_internal_reference_encoded_at(pc_, nullptr);
} else {
Assembler::set_target_address_at(pc_, host_, NULL);
}
// This sets the internal reference at the pc.
inline static void deserialization_set_target_internal_reference_at(
- Address pc, Address target);
+ Address pc, Address target,
+ RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
// Size of an instruction.
static const int kInstrSize = sizeof(Instr);
}
private:
+ inline static void set_target_internal_reference_encoded_at(Address pc,
+ Address target);
+
// Buffer size and constant pool distance are checked together at regular
// intervals of kBufferCheckInterval emitted bytes.
static const int kBufferCheckInterval = 1*KB/2;
}
+void Assembler::set_target_internal_reference_encoded_at(Address pc,
+ Address target) {
+ // Encoded internal references are lui/ori load of 48-bit absolute address.
+ Instr instr_lui = Assembler::instr_at(pc + 0 * Assembler::kInstrSize);
+ Instr instr_ori = Assembler::instr_at(pc + 1 * Assembler::kInstrSize);
+ Instr instr_ori2 = Assembler::instr_at(pc + 3 * Assembler::kInstrSize);
+ DCHECK(Assembler::IsLui(instr_lui));
+ DCHECK(Assembler::IsOri(instr_ori));
+ DCHECK(Assembler::IsOri(instr_ori2));
+ instr_lui &= ~kImm16Mask;
+ instr_ori &= ~kImm16Mask;
+ instr_ori2 &= ~kImm16Mask;
+ int64_t imm = reinterpret_cast<int64_t>(target);
+ DCHECK((imm & 3) == 0);
+ Assembler::instr_at_put(pc + 0 * Assembler::kInstrSize,
+ instr_lui | ((imm >> 32) & kImm16Mask));
+ Assembler::instr_at_put(pc + 1 * Assembler::kInstrSize,
+ instr_ori | ((imm >> 16) & kImm16Mask));
+ Assembler::instr_at_put(pc + 3 * Assembler::kInstrSize,
+ instr_ori | (imm & kImm16Mask));
+ // Currently used only by deserializer, and all code will be flushed
+ // after complete deserialization, no need to flush on each reference.
+}
+
+
void Assembler::deserialization_set_target_internal_reference_at(
- Address pc, Address target) {
- if (IsLui(instr_at(pc))) {
- // Encoded internal references are lui/ori load of 48-bit abolute address.
- Instr instr_lui = Assembler::instr_at(pc + 0 * Assembler::kInstrSize);
- Instr instr_ori = Assembler::instr_at(pc + 1 * Assembler::kInstrSize);
- Instr instr_ori2 = Assembler::instr_at(pc + 3 * Assembler::kInstrSize);
- DCHECK(Assembler::IsLui(instr_lui));
- DCHECK(Assembler::IsOri(instr_ori));
- DCHECK(Assembler::IsOri(instr_ori2));
- instr_lui &= ~kImm16Mask;
- instr_ori &= ~kImm16Mask;
- instr_ori2 &= ~kImm16Mask;
- int64_t imm = reinterpret_cast<int64_t>(target);
- DCHECK((imm & 3) == 0);
- Assembler::instr_at_put(pc + 0 * Assembler::kInstrSize,
- instr_lui | ((imm >> 32) & kImm16Mask));
- Assembler::instr_at_put(pc + 1 * Assembler::kInstrSize,
- instr_ori | ((imm >> 16) & kImm16Mask));
- Assembler::instr_at_put(pc + 3 * Assembler::kInstrSize,
- instr_ori | (imm & kImm16Mask));
- // Currently used only by deserializer, and all code will be flushed
- // after complete deserialization, no need to flush on each reference.
+ Address pc, Address target, RelocInfo::Mode mode) {
+ if (mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) {
+ DCHECK(IsLui(instr_at(pc)));
+ set_target_internal_reference_encoded_at(pc, target);
} else {
+ DCHECK(mode == RelocInfo::INTERNAL_REFERENCE);
Memory::Address_at(pc) = target;
}
}
if (rmode_ == INTERNAL_REFERENCE) {
return Memory::Address_at(pc_);
} else {
- // Encoded internal references are lui/ori load of 48-bit abolute address.
+ // Encoded internal references are lui/ori load of 48-bit absolute address.
DCHECK(rmode_ == INTERNAL_REFERENCE_ENCODED);
Instr instr_lui = Assembler::instr_at(pc_ + 0 * Assembler::kInstrSize);
Instr instr_ori = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize);
if (IsInternalReference(rmode_)) {
Memory::Address_at(pc_) = NULL;
} else if (IsInternalReferenceEncoded(rmode_)) {
- Instr instr_lui = Assembler::instr_at(pc_ + 0 * Assembler::kInstrSize);
- Instr instr_ori = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize);
- Instr instr_ori2 = Assembler::instr_at(pc_ + 3 * Assembler::kInstrSize);
- DCHECK(Assembler::IsLui(instr_lui));
- DCHECK(Assembler::IsOri(instr_ori));
- DCHECK(Assembler::IsOri(instr_ori2));
- instr_lui &= ~kImm16Mask;
- instr_ori &= ~kImm16Mask;
- instr_ori2 &= ~kImm16Mask;
- int64_t imm = 0;
- Assembler::instr_at_put(pc_ + 0 * Assembler::kInstrSize,
- instr_lui | ((imm >> 32) & kImm16Mask));
- Assembler::instr_at_put(pc_ + 1 * Assembler::kInstrSize,
- instr_ori | ((imm >> 16) & kImm16Mask));
- Assembler::instr_at_put(pc_ + 3 * Assembler::kInstrSize,
- instr_ori | (imm & kImm16Mask));
- // Currently used only by deserializer, and all code will be flushed
- // after complete deserialization, no need to flush on each reference.
+ Assembler::set_target_internal_reference_encoded_at(pc_, nullptr);
} else {
Assembler::set_target_address_at(pc_, host_, NULL);
}
// This sets the internal reference at the pc.
inline static void deserialization_set_target_internal_reference_at(
- Address pc, Address target);
+ Address pc, Address target,
+ RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
// Size of an instruction.
static const int kInstrSize = sizeof(Instr);
// the relocation info.
TypeFeedbackId recorded_ast_id_;
+ inline static void set_target_internal_reference_encoded_at(Address pc,
+ Address target);
+
int64_t buffer_space() const { return reloc_info_writer.pos() - pc_; }
// Decode branch instruction at pos and return branch target pos.
break;
}
+ case kInternalReferenceEncoded:
case kInternalReference: {
// Internal reference address is not encoded via skip, but by offset
// from code entry.
DCHECK(0 <= target_offset && target_offset <= code->instruction_size());
Address pc = code->entry() + pc_offset;
Address target = code->entry() + target_offset;
- Assembler::deserialization_set_target_internal_reference_at(pc, target);
+ Assembler::deserialization_set_target_internal_reference_at(
+ pc, target, data == kInternalReference
+ ? RelocInfo::INTERNAL_REFERENCE
+ : RelocInfo::INTERNAL_REFERENCE_ENCODED);
break;
}
pc_offset <= Code::cast(object_)->instruction_size());
DCHECK(0 <= target_offset &&
target_offset <= Code::cast(object_)->instruction_size());
- sink_->Put(kInternalReference, "InternalRef");
+ sink_->Put(rinfo->rmode() == RelocInfo::INTERNAL_REFERENCE
+ ? kInternalReference
+ : kInternalReferenceEncoded,
+ "InternalRef");
sink_->PutInt(static_cast<uintptr_t>(pc_offset), "internal ref address");
sink_->PutInt(static_cast<uintptr_t>(target_offset), "internal ref value");
}
kAttachedReference = 0x1b,
// 0x1c Builtin code referenced by index.
kBuiltin = 0x1c
- // 0x1d..0x1e Misc (including 0x3d..0x3f, 0x5d..0x5f, 0x7d..0x7f)
- // 0x1f Unused (including 0x3f, 0x5f, 0x7f).
+ // 0x1d..0x1f Misc (including 0x3d..0x3f, 0x5d..0x5f, 0x7d..0x7f)
};
static const int kWhereMask = 0x1f;
static const int kSkip = 0x1d;
// Internal reference encoded as offsets of pc and target from code entry.
static const int kInternalReference = 0x1e;
+ static const int kInternalReferenceEncoded = 0x1f;
// Do nothing, used for padding.
static const int kNop = 0x3d;
// Move to next reserved chunk.
void Assembler::deserialization_set_target_internal_reference_at(
- Address pc, Address target) {
+ Address pc, Address target, RelocInfo::Mode mode) {
Memory::Address_at(pc) = target;
}
// This sets the internal reference at the pc.
inline static void deserialization_set_target_internal_reference_at(
- Address instruction, Address target);
+ Address pc, Address target,
+ RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
static inline RelocInfo::Mode RelocInfoNone() {
if (kPointerSize == kInt64Size) {