src/cpu/sparc/vm/interpreterRT_sparc.cpp

Thu, 07 Apr 2011 09:53:20 -0700

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2314
f95d63e2154a
child 4037
da91efe96a93
permissions
-rw-r--r--

7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes

     1 /*
     2  * Copyright (c) 1998, 2010, 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 "interpreter/interpreter.hpp"
    27 #include "interpreter/interpreterRuntime.hpp"
    28 #include "memory/allocation.inline.hpp"
    29 #include "memory/universe.inline.hpp"
    30 #include "oops/methodOop.hpp"
    31 #include "oops/oop.inline.hpp"
    32 #include "runtime/handles.inline.hpp"
    33 #include "runtime/icache.hpp"
    34 #include "runtime/interfaceSupport.hpp"
    35 #include "runtime/signature.hpp"
    38 #define __ _masm->
    41 // Implementation of SignatureHandlerGenerator
    43 void InterpreterRuntime::SignatureHandlerGenerator::pass_word(int size_of_arg, int offset_in_arg) {
    44   Argument  jni_arg(jni_offset() + offset_in_arg, false);
    45   Register     Rtmp = O0;
    46   __ ld(Llocals, Interpreter::local_offset_in_bytes(offset()), Rtmp);
    48   __ store_argument(Rtmp, jni_arg);
    49 }
    51 void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {
    52   Argument  jni_arg(jni_offset(), false);
    53   Register  Rtmp = O0;
    55 #ifdef _LP64
    56   __ ldx(Llocals, Interpreter::local_offset_in_bytes(offset() + 1), Rtmp);
    57   __ store_long_argument(Rtmp, jni_arg);
    58 #else
    59   __ ld(Llocals, Interpreter::local_offset_in_bytes(offset() + 1), Rtmp);
    60   __ store_argument(Rtmp, jni_arg);
    61   __ ld(Llocals, Interpreter::local_offset_in_bytes(offset() + 0), Rtmp);
    62   Argument successor(jni_arg.successor());
    63   __ store_argument(Rtmp, successor);
    64 #endif
    65 }
    68 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
    69   Argument  jni_arg(jni_offset(), false);
    70 #ifdef _LP64
    71   FloatRegister  Rtmp = F0;
    72   __ ldf(FloatRegisterImpl::S, Llocals, Interpreter::local_offset_in_bytes(offset()), Rtmp);
    73   __ store_float_argument(Rtmp, jni_arg);
    74 #else
    75   Register     Rtmp = O0;
    76   __ ld(Llocals, Interpreter::local_offset_in_bytes(offset()), Rtmp);
    77   __ store_argument(Rtmp, jni_arg);
    78 #endif
    79 }
    82 void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
    83   Argument  jni_arg(jni_offset(), false);
    84 #ifdef _LP64
    85   FloatRegister  Rtmp = F0;
    86   __ ldf(FloatRegisterImpl::D, Llocals, Interpreter::local_offset_in_bytes(offset() + 1), Rtmp);
    87   __ store_double_argument(Rtmp, jni_arg);
    88 #else
    89   Register  Rtmp = O0;
    90   __ ld(Llocals, Interpreter::local_offset_in_bytes(offset() + 1), Rtmp);
    91   __ store_argument(Rtmp, jni_arg);
    92   __ ld(Llocals, Interpreter::local_offset_in_bytes(offset()), Rtmp);
    93   Argument successor(jni_arg.successor());
    94   __ store_argument(Rtmp, successor);
    95 #endif
    96 }
    98 void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {
    99   Argument  jni_arg(jni_offset(), false);
   100   Argument java_arg(    offset(), true);
   101   Register    Rtmp1 = O0;
   102   Register    Rtmp2 =  jni_arg.is_register() ?  jni_arg.as_register() : O0;
   103   Register    Rtmp3 =  G3_scratch;
   105   // the handle for a receiver will never be null
   106   bool do_NULL_check = offset() != 0 || is_static();
   108   Address     h_arg = Address(Llocals, Interpreter::local_offset_in_bytes(offset()));
   109   __ ld_ptr(h_arg, Rtmp1);
   110   if (!do_NULL_check) {
   111     __ add(h_arg.base(), h_arg.disp(), Rtmp2);
   112   } else {
   113     if (Rtmp1 == Rtmp2)
   114           __ tst(Rtmp1);
   115     else  __ addcc(G0, Rtmp1, Rtmp2); // optimize mov/test pair
   116     Label L;
   117     __ brx(Assembler::notZero, true, Assembler::pt, L);
   118     __ delayed()->add(h_arg.base(), h_arg.disp(), Rtmp2);
   119     __ bind(L);
   120   }
   121   __ store_ptr_argument(Rtmp2, jni_arg);    // this is often a no-op
   122 }
   125 void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
   127   // generate code to handle arguments
   128   iterate(fingerprint);
   130   // return result handler
   131   AddressLiteral result_handler(Interpreter::result_handler(method()->result_type()));
   132   __ sethi(result_handler, Lscratch);
   133   __ retl();
   134   __ delayed()->add(Lscratch, result_handler.low10(), Lscratch);
   136   __ flush();
   137 }
   140 // Implementation of SignatureHandlerLibrary
   142 void SignatureHandlerLibrary::pd_set_handler(address handler) {}
   145 class SlowSignatureHandler: public NativeSignatureIterator {
   146  private:
   147   address   _from;
   148   intptr_t* _to;
   149   intptr_t* _RegArgSignature;                   // Signature of first Arguments to be passed in Registers
   150   uint      _argcount;
   152   enum {                                        // We need to differenciate float from non floats in reg args
   153     non_float  = 0,
   154     float_sig  = 1,
   155     double_sig = 2,
   156     long_sig   = 3
   157   };
   159   virtual void pass_int() {
   160     *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
   161     _from -= Interpreter::stackElementSize;
   162     add_signature( non_float );
   163   }
   165   virtual void pass_object() {
   166     // pass address of from
   167     intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
   168     *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
   169     _from -= Interpreter::stackElementSize;
   170     add_signature( non_float );
   171    }
   173 #ifdef _LP64
   174   virtual void pass_float()  {
   175     *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
   176     _from -= Interpreter::stackElementSize;
   177     add_signature( float_sig );
   178    }
   180   virtual void pass_double() {
   181     *_to++ = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
   182     _from -= 2*Interpreter::stackElementSize;
   183    add_signature( double_sig );
   184    }
   186   virtual void pass_long() {
   187     _to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
   188     _to += 1;
   189     _from -= 2*Interpreter::stackElementSize;
   190     add_signature( long_sig );
   191   }
   192 #else
   193    // pass_double() is pass_long() and pass_float() only _LP64
   194   virtual void pass_long() {
   195     _to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
   196     _to[1] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
   197     _to += 2;
   198     _from -= 2*Interpreter::stackElementSize;
   199     add_signature( non_float );
   200   }
   202   virtual void pass_float() {
   203     *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
   204     _from -= Interpreter::stackElementSize;
   205     add_signature( non_float );
   206   }
   208 #endif // _LP64
   210   virtual void add_signature( intptr_t sig_type ) {
   211     if ( _argcount < (sizeof (intptr_t))*4 ) {
   212       *_RegArgSignature |= (sig_type << (_argcount*2) );
   213       _argcount++;
   214     }
   215   }
   218  public:
   219   SlowSignatureHandler(methodHandle method, address from, intptr_t* to, intptr_t *RegArgSig) : NativeSignatureIterator(method) {
   220     _from = from;
   221     _to   = to;
   222     _RegArgSignature = RegArgSig;
   223     *_RegArgSignature = 0;
   224     _argcount = method->is_static() ? 2 : 1;
   225   }
   226 };
   229 IRT_ENTRY(address, InterpreterRuntime::slow_signature_handler(
   230                                                     JavaThread* thread,
   231                                                     methodOopDesc* method,
   232                                                     intptr_t* from,
   233                                                     intptr_t* to ))
   234   methodHandle m(thread, method);
   235   assert(m->is_native(), "sanity check");
   236   // handle arguments
   237   // Warning: We use reg arg slot 00 temporarily to return the RegArgSignature
   238   // back to the code that pops the arguments into the CPU registers
   239   SlowSignatureHandler(m, (address)from, m->is_static() ? to+2 : to+1, to).iterate(UCONST64(-1));
   240   // return result handler
   241   return Interpreter::result_handler(m->result_type());
   242 IRT_END

mercurial