void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) { #ifdef AMD64 x += o; typedef Assembler::WhichOperand WhichOperand; WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm, call32, narrow oop assert(which == Assembler::disp32_operand || which == Assembler::narrow_oop_operand || which == Assembler::imm_operand, "format unpacks ok"); if (which == Assembler::imm_operand) { if (verify_only) { assert(*pd_address_in_code() == x, "instructions must match"); } else { *pd_address_in_code() = x; } } else if (which == Assembler::narrow_oop_operand) { address disp = Assembler::locate_operand(addr(), which); // both compressed oops and compressed classes look the same if (Universe::heap()->is_in_reserved((oop)x)) { if (verify_only) { assert(*(uint32_t*) disp == oopDesc::encode_heap_oop((oop)x), "instructions must match"); } else { *(int32_t*) disp = oopDesc::encode_heap_oop((oop)x); } } else { if (verify_only) { assert(*(uint32_t*) disp == Klass::encode_klass((Klass*)x), "instructions must match"); } else { *(int32_t*) disp = Klass::encode_klass((Klass*)x); } } } else { // Note: Use runtime_call_type relocations for call32_operand. address ip = addr(); address disp = Assembler::locate_operand(ip, which); address next_ip = Assembler::locate_next_instruction(ip); if (verify_only) { assert(*(int32_t*) disp == (x - next_ip), "instructions must match"); } else { *(int32_t*) disp = x - next_ip; } } #else if (verify_only) { assert(*pd_address_in_code() == (x + o), "instructions must match"); } else { *pd_address_in_code() = x + o; } #endif // AMD64 }
oop* oop_Relocation::oop_addr() { #ifndef CORE int n = _oop_index; if (n == 0) return (oop*) &pd_address_in_code(); else { assert(code()->is_nmethod(), "must refere to an nmethod"); return ((nmethod *)code())->oop_addr_at(n); } #else return NULL; #endif // !CORE }
void Relocation::pd_set_data_value(address x, intptr_t o) { #ifdef AMD64 x += o; typedef Assembler::WhichOperand WhichOperand; WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm, call32, narrow oop assert(which == Assembler::disp32_operand || which == Assembler::narrow_oop_operand || which == Assembler::imm_operand, "format unpacks ok"); if (which == Assembler::imm_operand) { *pd_address_in_code() = x; } else if (which == Assembler::narrow_oop_operand) { address disp = Assembler::locate_operand(addr(), which); *(int32_t*) disp = oopDesc::encode_heap_oop((oop)x); } else { // Note: Use runtime_call_type relocations for call32_operand. address ip = addr(); address disp = Assembler::locate_operand(ip, which); address next_ip = Assembler::locate_next_instruction(ip); *(int32_t*) disp = x - next_ip; } #else *pd_address_in_code() = x + o; #endif // AMD64 }
address Relocation::pd_get_address_from_code() { #ifdef AMD64 // All embedded Intel addresses are stored in 32-bit words. // Since the addr points at the start of the instruction, // we must parse the instruction a bit to find the embedded word. assert(is_data(), "must be a DataRelocation"); typedef Assembler::WhichOperand WhichOperand; WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32 assert(which == Assembler::disp32_operand || which == Assembler::call32_operand || which == Assembler::imm_operand, "format unpacks ok"); if (which != Assembler::imm_operand) { address ip = addr(); address disp = Assembler::locate_operand(ip, which); address next_ip = Assembler::locate_next_instruction(ip); address a = next_ip + *(int32_t*) disp; return a; } #endif // AMD64 return *pd_address_in_code(); }