src/cpu/sparc/vm/runtime_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 2950
cba7b5c2d53f
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 #ifdef COMPILER2
    27 #include "asm/assembler.hpp"
    28 #include "assembler_sparc.inline.hpp"
    29 #include "classfile/systemDictionary.hpp"
    30 #include "code/vmreg.hpp"
    31 #include "interpreter/interpreter.hpp"
    32 #include "nativeInst_sparc.hpp"
    33 #include "opto/runtime.hpp"
    34 #include "runtime/interfaceSupport.hpp"
    35 #include "runtime/sharedRuntime.hpp"
    36 #include "runtime/stubRoutines.hpp"
    37 #include "runtime/vframeArray.hpp"
    38 #include "utilities/globalDefinitions.hpp"
    39 #include "vmreg_sparc.inline.hpp"
    40 #endif
    43 #define __ masm->
    45 ExceptionBlob      *OptoRuntime::_exception_blob;
    47 //------------------------------ generate_exception_blob ---------------------------
    48 // creates exception blob at the end
    49 // Using exception blob, this code is jumped from a compiled method.
    50 // (see emit_exception_handler in sparc.ad file)
    51 //
    52 // Given an exception pc at a call we call into the runtime for the
    53 // handler in this method. This handler might merely restore state
    54 // (i.e. callee save registers) unwind the frame and jump to the
    55 // exception handler for the nmethod if there is no Java level handler
    56 // for the nmethod.
    57 //
    58 // This code is entered with a jmp.
    59 //
    60 // Arguments:
    61 //   O0: exception oop
    62 //   O1: exception pc
    63 //
    64 // Results:
    65 //   O0: exception oop
    66 //   O1: exception pc in caller or ???
    67 //   destination: exception handler of caller
    68 //
    69 // Note: the exception pc MUST be at a call (precise debug information)
    70 //
    71 void OptoRuntime::generate_exception_blob() {
    72   // allocate space for code
    73   ResourceMark rm;
    74   int pad = VerifyThread ? 256 : 0;// Extra slop space for more verify code
    76   // setup code generation tools
    77   // Measured 8/7/03 at 256 in 32bit debug build (no VerifyThread)
    78   // Measured 8/7/03 at 528 in 32bit debug build (VerifyThread)
    79   CodeBuffer buffer("exception_blob", 600+pad, 512);
    80   MacroAssembler* masm     = new MacroAssembler(&buffer);
    82   int framesize_in_bytes = __ total_frame_size_in_bytes(0);
    83   int framesize_in_words = framesize_in_bytes / wordSize;
    84   int framesize_in_slots = framesize_in_bytes / sizeof(jint);
    86   Label L;
    88   int start = __ offset();
    90   __ verify_thread();
    91   __ st_ptr(Oexception,  G2_thread, JavaThread::exception_oop_offset());
    92   __ st_ptr(Oissuing_pc, G2_thread, JavaThread::exception_pc_offset());
    94   // This call does all the hard work. It checks if an exception catch
    95   // exists in the method.
    96   // If so, it returns the handler address.
    97   // If the nmethod has been deoptimized and it had a handler the handler
    98   // address is the deopt blob unpack_with_exception entry.
    99   //
   100   // If no handler exists it prepares for stack-unwinding, restoring the callee-save
   101   // registers of the frame being removed.
   102   //
   103   __ save_frame(0);
   105   __ mov(G2_thread, O0);
   106   __ set_last_Java_frame(SP, noreg);
   107   __ save_thread(L7_thread_cache);
   109   // This call can block at exit and nmethod can be deoptimized at that
   110   // point. If the nmethod had a catch point we would jump to the
   111   // now deoptimized catch point and fall thru the vanilla deopt
   112   // path and lose the exception
   113   // Sure would be simpler if this call didn't block!
   114   __ call(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C), relocInfo::runtime_call_type);
   115   __ delayed()->mov(L7_thread_cache, O0);
   117   // Set an oopmap for the call site.  This oopmap will only be used if we
   118   // are unwinding the stack.  Hence, all locations will be dead.
   119   // Callee-saved registers will be the same as the frame above (i.e.,
   120   // handle_exception_stub), since they were restored when we got the
   121   // exception.
   123   OopMapSet *oop_maps = new OopMapSet();
   124   oop_maps->add_gc_map( __ offset()-start, new OopMap(framesize_in_slots, 0));
   126   __ bind(L);
   127   __ restore_thread(L7_thread_cache);
   128   __ reset_last_Java_frame();
   130   __ mov(O0, G3_scratch);             // Move handler address to temp
   131   __ restore();
   133   // Restore SP from L7 if the exception PC is a MethodHandle call site.
   134   __ lduw(Address(G2_thread, JavaThread::is_method_handle_return_offset()), O7);
   135   __ tst(O7);
   136   __ movcc(Assembler::notZero, false, Assembler::icc, L7_mh_SP_save, SP);
   138   // G3_scratch contains handler address
   139   // Since this may be the deopt blob we must set O7 to look like we returned
   140   // from the original pc that threw the exception
   142   __ ld_ptr(G2_thread, JavaThread::exception_pc_offset(), O7);
   143   __ sub(O7, frame::pc_return_offset, O7);
   146   assert(Assembler::is_simm13(in_bytes(JavaThread::exception_oop_offset())), "exception offset overflows simm13, following ld instruction cannot be in delay slot");
   147   __ ld_ptr(G2_thread, JavaThread::exception_oop_offset(), Oexception); // O0
   148 #ifdef ASSERT
   149   __ st_ptr(G0, G2_thread, JavaThread::exception_handler_pc_offset());
   150   __ st_ptr(G0, G2_thread, JavaThread::exception_pc_offset());
   151 #endif
   152   __ JMP(G3_scratch, 0);
   153   // Clear the exception oop so GC no longer processes it as a root.
   154   __ delayed()->st_ptr(G0, G2_thread, JavaThread::exception_oop_offset());
   156   // -------------
   157   // make sure all code is generated
   158   masm->flush();
   160   _exception_blob = ExceptionBlob::create(&buffer, oop_maps, framesize_in_words);
   161 }

mercurial