From: paul.lind Date: Tue, 17 Mar 2015 17:00:12 +0000 (-0700) Subject: MIPS: Support INTERNAL_REFERENCE_ENCODED in serializer. X-Git-Tag: upstream/4.7.83~3796 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cd9b6ec224ba23c0b073ccd4a818d9942720db96;p=platform%2Fupstream%2Fv8.git MIPS: Support INTERNAL_REFERENCE_ENCODED in serializer. Add mips support for the changes in https://codereview.chromium.org/1000373003. On mips, these support the long-branch mechanism. TEST=test-serialize/SerializeToplevelLargeCodeObject BUG= Review URL: https://codereview.chromium.org/1014763003 Cr-Commit-Position: refs/heads/master@{#27244} --- diff --git a/src/mips/assembler-mips-inl.h b/src/mips/assembler-mips-inl.h index f9812b994..ca6250e64 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(kImm16Mask)) << kLuiShift; + imm |= (instr_ori & static_cast(kImm16Mask)); + return reinterpret_cast
(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(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. + } } diff --git a/src/mips64/assembler-mips64-inl.h b/src/mips64/assembler-mips64-inl.h index ae427d6bf..e06c1c0f3 100644 --- a/src/mips64/assembler-mips64-inl.h +++ b/src/mips64/assembler-mips64-inl.h @@ -230,14 +230,50 @@ 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); + 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)); + int64_t imm = (instr_lui & static_cast(kImm16Mask)) << 32; + imm |= (instr_ori & static_cast(kImm16Mask)) << 16; + imm |= (instr_ori2 & static_cast(kImm16Mask)); + return reinterpret_cast
(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 48-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); + 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(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. + } }