src/cpu/sparc/vm/relocInfo_sparc.cpp

Wed, 24 Apr 2013 20:55:28 -0400

author
dlong
date
Wed, 24 Apr 2013 20:55:28 -0400
changeset 5000
a6e09d6dd8e5
parent 4323
f0c2369fda5a
child 5314
7875ea94bea5
permissions
-rw-r--r--

8003853: specify offset of IC load in java_to_interp stub
Summary: refactored code to allow platform-specific differences
Reviewed-by: dlong, twisti
Contributed-by: Goetz Lindenmaier <goetz.lindenmaier@sap.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.hpp"
    27 #include "code/relocInfo.hpp"
    28 #include "nativeInst_sparc.hpp"
    29 #include "oops/oop.inline.hpp"
    30 #include "runtime/safepoint.hpp"
    32 void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
    33   NativeInstruction* ip = nativeInstruction_at(addr());
    34   jint inst = ip->long_at(0);
    35   assert(inst != NativeInstruction::illegal_instruction(), "no breakpoint");
    36   switch (Assembler::inv_op(inst)) {
    38   case Assembler::ldst_op:
    39     #ifdef ASSERT
    40       switch (Assembler::inv_op3(inst)) {
    41         case Assembler::lduw_op3:
    42         case Assembler::ldub_op3:
    43         case Assembler::lduh_op3:
    44         case Assembler::ldd_op3:
    45         case Assembler::ldsw_op3:
    46         case Assembler::ldsb_op3:
    47         case Assembler::ldsh_op3:
    48         case Assembler::ldx_op3:
    49         case Assembler::ldf_op3:
    50         case Assembler::lddf_op3:
    51         case Assembler::stw_op3:
    52         case Assembler::stb_op3:
    53         case Assembler::sth_op3:
    54         case Assembler::std_op3:
    55         case Assembler::stx_op3:
    56         case Assembler::stf_op3:
    57         case Assembler::stdf_op3:
    58         case Assembler::casa_op3:
    59         case Assembler::casxa_op3:
    60           break;
    61         default:
    62           ShouldNotReachHere();
    63       }
    64       goto do_non_sethi;
    65     #endif
    67   case Assembler::arith_op:
    68     #ifdef ASSERT
    69       switch (Assembler::inv_op3(inst)) {
    70         case Assembler::or_op3:
    71         case Assembler::add_op3:
    72         case Assembler::jmpl_op3:
    73           break;
    74         default:
    75           ShouldNotReachHere();
    76       }
    77     do_non_sethi:;
    78     #endif
    79     {
    80     guarantee(Assembler::inv_immed(inst), "must have a simm13 field");
    81     int simm13 = Assembler::low10((intptr_t)x) + o;
    82     guarantee(Assembler::is_simm13(simm13), "offset can't overflow simm13");
    83     inst &= ~Assembler::simm(    -1, 13);
    84     inst |=  Assembler::simm(simm13, 13);
    85     if (verify_only) {
    86       assert(ip->long_at(0) == inst, "instructions must match");
    87     } else {
    88       ip->set_long_at(0, inst);
    89     }
    90     }
    91     break;
    93   case Assembler::branch_op:
    94     {
    95 #ifdef _LP64
    96     jint inst2;
    97     guarantee(Assembler::inv_op2(inst)==Assembler::sethi_op2, "must be sethi");
    98     if (format() != 0) {
    99       assert(type() == relocInfo::oop_type || type() == relocInfo::metadata_type, "only narrow oops or klasses case");
   100       jint np = type() == relocInfo::oop_type ? oopDesc::encode_heap_oop((oop)x) : oopDesc::encode_klass((Klass*)x);
   101       inst &= ~Assembler::hi22(-1);
   102       inst |=  Assembler::hi22((intptr_t)np);
   103       if (verify_only) {
   104         assert(ip->long_at(0) == inst, "instructions must match");
   105       } else {
   106         ip->set_long_at(0, inst);
   107       }
   108       inst2 = ip->long_at( NativeInstruction::nop_instruction_size );
   109       guarantee(Assembler::inv_op(inst2)==Assembler::arith_op, "arith op");
   110       if (verify_only) {
   111         assert(ip->long_at(NativeInstruction::nop_instruction_size) == NativeInstruction::set_data32_simm13( inst2, (intptr_t)np),
   112                "instructions must match");
   113       } else {
   114         ip->set_long_at(NativeInstruction::nop_instruction_size, NativeInstruction::set_data32_simm13( inst2, (intptr_t)np));
   115       }
   116       break;
   117     }
   118     if (verify_only) {
   119       ip->verify_data64_sethi( ip->addr_at(0), (intptr_t)x );
   120     } else {
   121       ip->set_data64_sethi( ip->addr_at(0), (intptr_t)x );
   122     }
   123 #else
   124     guarantee(Assembler::inv_op2(inst)==Assembler::sethi_op2, "must be sethi");
   125     inst &= ~Assembler::hi22(     -1);
   126     inst |=  Assembler::hi22((intptr_t)x);
   127     // (ignore offset; it doesn't play into the sethi)
   128     if (verify_only) {
   129       assert(ip->long_at(0) == inst, "instructions must match");
   130     } else {
   131       ip->set_long_at(0, inst);
   132     }
   133 #endif
   134     }
   135     break;
   137   default:
   138     guarantee(false, "instruction must perform arithmetic or memory access");
   139   }
   140 }
   143 address Relocation::pd_call_destination(address orig_addr) {
   144   intptr_t adj = 0;
   145   if (orig_addr != NULL) {
   146     // We just moved this call instruction from orig_addr to addr().
   147     // This means its target will appear to have grown by addr() - orig_addr.
   148     adj = -( addr() - orig_addr );
   149   }
   150   if (NativeCall::is_call_at(addr())) {
   151     NativeCall* call = nativeCall_at(addr());
   152     return call->destination() + adj;
   153   }
   154   if (NativeFarCall::is_call_at(addr())) {
   155     NativeFarCall* call = nativeFarCall_at(addr());
   156     return call->destination() + adj;
   157   }
   158   // Special case:  Patchable branch local to the code cache.
   159   // This will break badly if the code cache grows larger than a few Mb.
   160   NativeGeneralJump* br = nativeGeneralJump_at(addr());
   161   return br->jump_destination() + adj;
   162 }
   165 void Relocation::pd_set_call_destination(address x) {
   166   if (NativeCall::is_call_at(addr())) {
   167     NativeCall* call = nativeCall_at(addr());
   168     call->set_destination(x);
   169     return;
   170   }
   171   if (NativeFarCall::is_call_at(addr())) {
   172     NativeFarCall* call = nativeFarCall_at(addr());
   173     call->set_destination(x);
   174     return;
   175   }
   176   // Special case:  Patchable branch local to the code cache.
   177   // This will break badly if the code cache grows larger than a few Mb.
   178   NativeGeneralJump* br = nativeGeneralJump_at(addr());
   179   br->set_jump_destination(x);
   180 }
   183 address* Relocation::pd_address_in_code() {
   184   // SPARC never embeds addresses in code, at present.
   185   //assert(type() == relocInfo::oop_type, "only oops are inlined at present");
   186   return (address*)addr();
   187 }
   190 address Relocation::pd_get_address_from_code() {
   191   // SPARC never embeds addresses in code, at present.
   192   //assert(type() == relocInfo::oop_type, "only oops are inlined at present");
   193   return *(address*)addr();
   194 }
   197 int Relocation::pd_breakpoint_size() {
   198   // minimum breakpoint size, in short words
   199   return NativeIllegalInstruction::instruction_size / sizeof(short);
   200 }
   202 void Relocation::pd_swap_in_breakpoint(address x, short* instrs, int instrlen) {
   203   Untested("pd_swap_in_breakpoint");
   204   // %%% probably do not need a general instrlen; just use the trap size
   205   if (instrs != NULL) {
   206     assert(instrlen * sizeof(short) == NativeIllegalInstruction::instruction_size, "enough instrlen in reloc. data");
   207     for (int i = 0; i < instrlen; i++) {
   208       instrs[i] = ((short*)x)[i];
   209     }
   210   }
   211   NativeIllegalInstruction::insert(x);
   212 }
   215 void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen) {
   216   Untested("pd_swap_out_breakpoint");
   217   assert(instrlen * sizeof(short) == sizeof(int), "enough buf");
   218   union { int l; short s[1]; } u;
   219   for (int i = 0; i < instrlen; i++) {
   220     u.s[i] = instrs[i];
   221   }
   222   NativeInstruction* ni = nativeInstruction_at(x);
   223   ni->set_long_at(0, u.l);
   224 }
   226 void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
   227 }
   229 void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
   230 }
   232 void metadata_Relocation::pd_fix_value(address x) {
   233 }

mercurial