src/cpu/x86/vm/relocInfo_x86.cpp

Sat, 01 Sep 2012 13:25:18 -0400

author
coleenp
date
Sat, 01 Sep 2012 13:25:18 -0400
changeset 4037
da91efe96a93
parent 2686
b40d4fa697bf
child 4318
cd3d6a6b95d9
permissions
-rw-r--r--

6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>

     1 /*
     2  * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #include "precompiled.hpp"
    26 #include "asm/assembler.inline.hpp"
    27 #include "assembler_x86.inline.hpp"
    28 #include "code/relocInfo.hpp"
    29 #include "nativeInst_x86.hpp"
    30 #include "oops/oop.inline.hpp"
    31 #include "runtime/safepoint.hpp"
    34 void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
    35 #ifdef AMD64
    36   x += o;
    37   typedef Assembler::WhichOperand WhichOperand;
    38   WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm, call32, narrow oop
    39   assert(which == Assembler::disp32_operand ||
    40          which == Assembler::narrow_oop_operand ||
    41          which == Assembler::imm_operand, "format unpacks ok");
    42   if (which == Assembler::imm_operand) {
    43     if (verify_only) {
    44       assert(*pd_address_in_code() == x, "instructions must match");
    45     } else {
    46       *pd_address_in_code() = x;
    47     }
    48   } else if (which == Assembler::narrow_oop_operand) {
    49     address disp = Assembler::locate_operand(addr(), which);
    50     // both compressed oops and compressed classes look the same
    51     if (Universe::heap()->is_in_reserved((oop)x)) {
    52     if (verify_only) {
    53       assert(*(uint32_t*) disp == oopDesc::encode_heap_oop((oop)x), "instructions must match");
    54     } else {
    55       *(int32_t*) disp = oopDesc::encode_heap_oop((oop)x);
    56     }
    57   } else {
    58       if (verify_only) {
    59         assert(*(uint32_t*) disp == oopDesc::encode_klass((Klass*)x), "instructions must match");
    60       } else {
    61         *(int32_t*) disp = oopDesc::encode_klass((Klass*)x);
    62       }
    63     }
    64   } else {
    65     // Note:  Use runtime_call_type relocations for call32_operand.
    66     address ip = addr();
    67     address disp = Assembler::locate_operand(ip, which);
    68     address next_ip = Assembler::locate_next_instruction(ip);
    69     if (verify_only) {
    70       assert(*(int32_t*) disp == (x - next_ip), "instructions must match");
    71     } else {
    72       *(int32_t*) disp = x - next_ip;
    73     }
    74   }
    75 #else
    76   if (verify_only) {
    77     assert(*pd_address_in_code() == (x + o), "instructions must match");
    78   } else {
    79     *pd_address_in_code() = x + o;
    80   }
    81 #endif // AMD64
    82 }
    85 address Relocation::pd_call_destination(address orig_addr) {
    86   intptr_t adj = 0;
    87   if (orig_addr != NULL) {
    88     // We just moved this call instruction from orig_addr to addr().
    89     // This means its target will appear to have grown by addr() - orig_addr.
    90     adj = -( addr() - orig_addr );
    91   }
    92   NativeInstruction* ni = nativeInstruction_at(addr());
    93   if (ni->is_call()) {
    94     return nativeCall_at(addr())->destination() + adj;
    95   } else if (ni->is_jump()) {
    96     return nativeJump_at(addr())->jump_destination() + adj;
    97   } else if (ni->is_cond_jump()) {
    98     return nativeGeneralJump_at(addr())->jump_destination() + adj;
    99   } else if (ni->is_mov_literal64()) {
   100     return (address) ((NativeMovConstReg*)ni)->data();
   101   } else {
   102     ShouldNotReachHere();
   103     return NULL;
   104   }
   105 }
   108 void Relocation::pd_set_call_destination(address x) {
   109   NativeInstruction* ni = nativeInstruction_at(addr());
   110   if (ni->is_call()) {
   111     nativeCall_at(addr())->set_destination(x);
   112   } else if (ni->is_jump()) {
   113     NativeJump* nj = nativeJump_at(addr());
   115     // Unresolved jumps are recognized by a destination of -1
   116     // However 64bit can't actually produce such an address
   117     // and encodes a jump to self but jump_destination will
   118     // return a -1 as the signal. We must not relocate this
   119     // jmp or the ic code will not see it as unresolved.
   121     if (nj->jump_destination() == (address) -1) {
   122       x = addr(); // jump to self
   123     }
   124     nj->set_jump_destination(x);
   125   } else if (ni->is_cond_jump()) {
   126     // %%%% kludge this, for now, until we get a jump_destination method
   127     address old_dest = nativeGeneralJump_at(addr())->jump_destination();
   128     address disp = Assembler::locate_operand(addr(), Assembler::call32_operand);
   129     *(jint*)disp += (x - old_dest);
   130   } else if (ni->is_mov_literal64()) {
   131     ((NativeMovConstReg*)ni)->set_data((intptr_t)x);
   132   } else {
   133     ShouldNotReachHere();
   134   }
   135 }
   138 address* Relocation::pd_address_in_code() {
   139   // All embedded Intel addresses are stored in 32-bit words.
   140   // Since the addr points at the start of the instruction,
   141   // we must parse the instruction a bit to find the embedded word.
   142   assert(is_data(), "must be a DataRelocation");
   143   typedef Assembler::WhichOperand WhichOperand;
   144   WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32
   145 #ifdef AMD64
   146   assert(which == Assembler::disp32_operand ||
   147          which == Assembler::call32_operand ||
   148          which == Assembler::imm_operand, "format unpacks ok");
   149   if (which != Assembler::imm_operand) {
   150     // The "address" in the code is a displacement can't return it as
   151     // and address* since it is really a jint*
   152     ShouldNotReachHere();
   153     return NULL;
   154   }
   155 #else
   156   assert(which == Assembler::disp32_operand || which == Assembler::imm_operand, "format unpacks ok");
   157 #endif // AMD64
   158   return (address*) Assembler::locate_operand(addr(), which);
   159 }
   162 address Relocation::pd_get_address_from_code() {
   163 #ifdef AMD64
   164   // All embedded Intel addresses are stored in 32-bit words.
   165   // Since the addr points at the start of the instruction,
   166   // we must parse the instruction a bit to find the embedded word.
   167   assert(is_data(), "must be a DataRelocation");
   168   typedef Assembler::WhichOperand WhichOperand;
   169   WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32
   170   assert(which == Assembler::disp32_operand ||
   171          which == Assembler::call32_operand ||
   172          which == Assembler::imm_operand, "format unpacks ok");
   173   if (which != Assembler::imm_operand) {
   174     address ip = addr();
   175     address disp = Assembler::locate_operand(ip, which);
   176     address next_ip = Assembler::locate_next_instruction(ip);
   177     address a = next_ip + *(int32_t*) disp;
   178     return a;
   179   }
   180 #endif // AMD64
   181   return *pd_address_in_code();
   182 }
   184 int Relocation::pd_breakpoint_size() {
   185   // minimum breakpoint size, in short words
   186   return NativeIllegalInstruction::instruction_size / sizeof(short);
   187 }
   189 void Relocation::pd_swap_in_breakpoint(address x, short* instrs, int instrlen) {
   190   Untested("pd_swap_in_breakpoint");
   191   if (instrs != NULL) {
   192     assert(instrlen * sizeof(short) == NativeIllegalInstruction::instruction_size, "enough instrlen in reloc. data");
   193     for (int i = 0; i < instrlen; i++) {
   194       instrs[i] = ((short*)x)[i];
   195     }
   196   }
   197   NativeIllegalInstruction::insert(x);
   198 }
   201 void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen) {
   202   Untested("pd_swap_out_breakpoint");
   203   assert(NativeIllegalInstruction::instruction_size == sizeof(short), "right address unit for update");
   204   NativeInstruction* ni = nativeInstruction_at(x);
   205   *(short*)ni->addr_at(0) = instrs[0];
   206 }
   208 void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
   209 #ifdef _LP64
   210   if (!Assembler::is_polling_page_far()) {
   211     typedef Assembler::WhichOperand WhichOperand;
   212     WhichOperand which = (WhichOperand) format();
   213     // This format is imm but it is really disp32
   214     which = Assembler::disp32_operand;
   215     address orig_addr = old_addr_for(addr(), src, dest);
   216     NativeInstruction* oni = nativeInstruction_at(orig_addr);
   217     int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
   218     // This poll_addr is incorrect by the size of the instruction it is irrelevant
   219     intptr_t poll_addr = (intptr_t)oni + *orig_disp;
   221     NativeInstruction* ni = nativeInstruction_at(addr());
   222     intptr_t new_disp = poll_addr - (intptr_t) ni;
   224     int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
   225     * disp = (int32_t)new_disp;
   226   }
   227 #endif // _LP64
   228 }
   230 void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
   231 #ifdef _LP64
   232   if (!Assembler::is_polling_page_far()) {
   233     typedef Assembler::WhichOperand WhichOperand;
   234     WhichOperand which = (WhichOperand) format();
   235     // This format is imm but it is really disp32
   236     which = Assembler::disp32_operand;
   237     address orig_addr = old_addr_for(addr(), src, dest);
   238     NativeInstruction* oni = nativeInstruction_at(orig_addr);
   239     int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
   240     // This poll_addr is incorrect by the size of the instruction it is irrelevant
   241     intptr_t poll_addr = (intptr_t)oni + *orig_disp;
   243     NativeInstruction* ni = nativeInstruction_at(addr());
   244     intptr_t new_disp = poll_addr - (intptr_t) ni;
   246     int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
   247     * disp = (int32_t)new_disp;
   248   }
   249 #endif // _LP64
   250 }
   252 void metadata_Relocation::pd_fix_value(address x) {
   253 }

mercurial