| Index: src/mips/assembler-mips-inl.h
|
| diff --git a/src/mips/assembler-mips-inl.h b/src/mips/assembler-mips-inl.h
|
| index f9812b994037fd75e4a7a8006e8b63b7b21dd48c..ca6250e64e892eafd67c608534fcf5642a47af80 100644
|
| --- a/src/mips/assembler-mips-inl.h
|
| +++ b/src/mips/assembler-mips-inl.h
|
| @@ -236,14 +236,42 @@ Address RelocInfo::target_external_reference() {
|
|
|
|
|
| Address RelocInfo::target_internal_reference() {
|
| - DCHECK(rmode_ == INTERNAL_REFERENCE);
|
| - return Memory::Address_at(pc_);
|
| + if (rmode_ == INTERNAL_REFERENCE) {
|
| + return Memory::Address_at(pc_);
|
| + } else {
|
| + 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);
|
| + DCHECK(Assembler::IsLui(instr_lui));
|
| + DCHECK(Assembler::IsOri(instr_ori));
|
| + int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift;
|
| + imm |= (instr_ori & static_cast<int32_t>(kImm16Mask));
|
| + return reinterpret_cast<Address>(imm);
|
| + }
|
| }
|
|
|
|
|
| void RelocInfo::set_target_internal_reference(Address target) {
|
| - DCHECK(rmode_ == INTERNAL_REFERENCE);
|
| - Memory::Address_at(pc_) = target;
|
| + if (rmode_ == INTERNAL_REFERENCE) {
|
| + Memory::Address_at(pc_) = target;
|
| + } else {
|
| + // Encoded internal references are lui/ori load of 32-bit abolute 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);
|
| + 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.
|
| + }
|
| }
|
|
|
|
|
|
|