--- old/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp 2009-08-01 04:08:08.537430716 +0100 +++ new/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp 2009-08-01 04:08:08.460542525 +0100 @@ -1,8 +1,5 @@ -#ifdef USE_PRAGMA_IDENT_SRC -#pragma ident "@(#)relocInfo_x86.cpp 1.19 07/09/17 09:28:01 JVM" -#endif /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +19,7 @@ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. - * + * */ # include "incls/_precompiled.incl" @@ -33,11 +30,15 @@ #ifdef AMD64 x += o; typedef Assembler::WhichOperand WhichOperand; - WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm64, call32 + WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm, call32, narrow oop assert(which == Assembler::disp32_operand || - which == Assembler::imm64_operand, "format unpacks ok"); - if (which == Assembler::imm64_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(); @@ -80,11 +81,16 @@ nativeCall_at(addr())->set_destination(x); } else if (ni->is_jump()) { NativeJump* nj = nativeJump_at(addr()); -#ifdef AMD64 + + // Unresolved jumps are recognized by a destination of -1 + // However 64bit can't actually produce such an address + // and encodes a jump to self but jump_destination will + // return a -1 as the signal. We must not relocate this + // jmp or the ic code will not see it as unresolved. + if (nj->jump_destination() == (address) -1) { - x = (address) -1; // retain jump to self + x = addr(); // jump to self } -#endif // AMD64 nj->set_jump_destination(x); } else if (ni->is_cond_jump()) { // %%%% kludge this, for now, until we get a jump_destination method @@ -105,19 +111,19 @@ // 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 imm64/imm32 + WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32 #ifdef AMD64 assert(which == Assembler::disp32_operand || which == Assembler::call32_operand || - which == Assembler::imm64_operand, "format unpacks ok"); - if (which != Assembler::imm64_operand) { + which == Assembler::imm_operand, "format unpacks ok"); + if (which != Assembler::imm_operand) { // The "address" in the code is a displacement can't return it as // and address* since it is really a jint* ShouldNotReachHere(); return NULL; } #else - assert(which == Assembler::disp32_operand || which == Assembler::imm32_operand, "format unpacks ok"); + assert(which == Assembler::disp32_operand || which == Assembler::imm_operand, "format unpacks ok"); #endif // AMD64 return (address*) Assembler::locate_operand(addr(), which); } @@ -130,11 +136,11 @@ // 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 imm64/imm32 + WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32 assert(which == Assembler::disp32_operand || which == Assembler::call32_operand || - which == Assembler::imm64_operand, "format unpacks ok"); - if (which != Assembler::imm64_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); @@ -168,3 +174,44 @@ NativeInstruction* ni = nativeInstruction_at(x); *(short*)ni->addr_at(0) = instrs[0]; } + +void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { +#ifdef _LP64 + typedef Assembler::WhichOperand WhichOperand; + WhichOperand which = (WhichOperand) format(); + // This format is imm but it is really disp32 + which = Assembler::disp32_operand; + address orig_addr = old_addr_for(addr(), src, dest); + NativeInstruction* oni = nativeInstruction_at(orig_addr); + int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which); + // This poll_addr is incorrect by the size of the instruction it is irrelevant + intptr_t poll_addr = (intptr_t)oni + *orig_disp; + + NativeInstruction* ni = nativeInstruction_at(addr()); + intptr_t new_disp = poll_addr - (intptr_t) ni; + + int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which); + * disp = (int32_t)new_disp; + +#endif // _LP64 +} + +void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { +#ifdef _LP64 + typedef Assembler::WhichOperand WhichOperand; + WhichOperand which = (WhichOperand) format(); + // This format is imm but it is really disp32 + which = Assembler::disp32_operand; + address orig_addr = old_addr_for(addr(), src, dest); + NativeInstruction* oni = nativeInstruction_at(orig_addr); + int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which); + // This poll_addr is incorrect by the size of the instruction it is irrelevant + intptr_t poll_addr = (intptr_t)oni + *orig_disp; + + NativeInstruction* ni = nativeInstruction_at(addr()); + intptr_t new_disp = poll_addr - (intptr_t) ni; + + int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which); + * disp = (int32_t)new_disp; +#endif // _LP64 +}