hotspot/src/cpu/x86/vm/assembler_x86.cpp
// 64bit only pieces of the assembler
// This should only be used by 64bit instructions that can use rip-relative
// it cannot be used by instructions that want an immediate value.
bool Assembler::reachable(AddressLiteral adr) {
{- -------------------------------------------
(1)
---------------------------------------- -}
int64_t disp;
// None will force a 64bit literal to the code stream. Likely a placeholder
// for something that will be patched later and we need to certain it will
// always be reachable.
if (adr.reloc() == relocInfo::none) {
return false;
}
if (adr.reloc() == relocInfo::internal_word_type) {
// This should be rip relative and easily reachable.
return true;
}
if (adr.reloc() == relocInfo::virtual_call_type ||
adr.reloc() == relocInfo::opt_virtual_call_type ||
adr.reloc() == relocInfo::static_call_type ||
adr.reloc() == relocInfo::static_stub_type ) {
// This should be rip relative within the code cache and easily
// reachable until we get huge code caches. (At which point
// ic code is going to have issues).
return true;
}
if (adr.reloc() != relocInfo::external_word_type &&
adr.reloc() != relocInfo::poll_return_type && // these are really external_word but need special
adr.reloc() != relocInfo::poll_type && // relocs to identify them
adr.reloc() != relocInfo::runtime_call_type ) {
return false;
}
// Stress the correction code
if (ForceUnreachable) {
// Must be runtimecall reloc, see if it is in the codecache
// Flipping stuff in the codecache to be unreachable causes issues
// with things like inline caches where the additional instructions
// are not handled.
if (CodeCache::find_blob(adr._target) == NULL) {
return false;
}
}
// For external_word_type/runtime_call_type if it is reachable from where we
// are now (possibly a temp buffer) and where we might end up
// anywhere in the codeCache then we are always reachable.
// This would have to change if we ever save/restore shared code
// to be more pessimistic.
disp = (int64_t)adr._target - ((int64_t)CodeCache::low_bound() + sizeof(int));
if (!is_simm32(disp)) return false;
disp = (int64_t)adr._target - ((int64_t)CodeCache::high_bound() + sizeof(int));
if (!is_simm32(disp)) return false;
disp = (int64_t)adr._target - ((int64_t)_code_pos + sizeof(int));
// Because rip relative is a disp + address_of_next_instruction and we
// don't know the value of address_of_next_instruction we apply a fudge factor
// to make sure we will be ok no matter the size of the instruction we get placed into.
// We don't have to fudge the checks above here because they are already worst case.
// 12 == override/rex byte, opcode byte, rm byte, sib byte, a 4-byte disp , 4-byte literal
// + 4 because better safe than sorry.
const int fudge = 12 + 4;
if (disp < 0) {
disp -= fudge;
} else {
disp += fudge;
}
return is_simm32(disp);
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.