src/cpu/sparc/vm/frame_sparc.hpp

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 3099
c124e2e7463e
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) 1997, 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 #ifndef CPU_SPARC_VM_FRAME_SPARC_HPP
    26 #define CPU_SPARC_VM_FRAME_SPARC_HPP
    28 #include "runtime/synchronizer.hpp"
    29 #include "utilities/top.hpp"
    31 // A frame represents a physical stack frame (an activation).  Frames can be
    32 // C or Java frames, and the Java frames can be interpreted or compiled.
    33 // In contrast, vframes represent source-level activations, so that one physical frame
    34 // can correspond to multiple source level frames because of inlining.
    35 // A frame is comprised of {pc, sp, younger_sp}
    38 // Layout of asm interpreter frame:
    39 //
    40 //  0xfffffff
    41 //  ......
    42 // [last  extra incoming arg,  (local # Nargs > 6 ? Nargs-1 : undef)]
    43 // .. Note: incoming args are copied to local frame area upon entry
    44 // [first extra incoming arg,  (local # Nargs > 6 ? 6       : undef)]
    45 // [6 words for C-arg storage (unused)] Are this and next one really needed?
    46 // [C-aggregate-word (unused)] Yes, if want extra params to be  in same place as C convention
    47 // [16 words for register saving]                                    <--- FP
    48 // [interpreter_frame_vm_locals ] (see below)
    50 //              Note: Llocals is always double-word aligned
    51 // [first local i.e. local # 0]        <-- Llocals
    52 // ...
    53 // [last local, i.e. local # Nlocals-1]
    55 // [monitors                 ]
    56 // ....
    57 // [monitors                 ]    <-- Lmonitors (same as Llocals + 6*4 if none)
    58 //                                    (must be double-word aligned because
    59 //                                     monitor element size is constrained to
    60 //                                     doubleword)
    61 //
    62 //                                <-- Lesp (points 1 past TOS)
    63 // [bottom word used for stack ]
    64 // ...
    65 // [top word used for stack]    (first word of stack is double-word aligned)
    67 // [space for outgoing args (conservatively allocated as max_stack - 6 + interpreter_frame_extra_outgoing_argument_words)]
    68 // [6 words for C-arg storage]
    69 // [C-aggregate-word (unused)]
    70 // [16 words for register saving]                                    <--- SP
    71 // ...
    72 // 0x0000000
    73 //
    74 // The in registers and local registers are preserved in a block at SP.
    75 //
    76 // The first six in registers (I0..I5) hold the first six locals.
    77 // The locals are used as follows:
    78 //    Lesp         first free element of expression stack
    79 //                 (which grows towards __higher__ addresses)
    80 //    Lbcp         is set to address of bytecode to execute
    81 //                 It is accessed in the frame under the name "bcx".
    82 //                 It may at times (during GC) be an index instead.
    83 //    Lmethod      the method being interpreted
    84 //    Llocals      the base pointer for accessing the locals array
    85 //                 (lower-numbered locals have lower addresses)
    86 //    Lmonitors    the base pointer for accessing active monitors
    87 //    Lcache       a saved pointer to the method's constant pool cache
    88 //
    89 //
    90 // When calling out to another method,
    91 // G5_method is set to method to call, G5_inline_cache_klass may be set,
    92 // parameters are put in O registers, and also extra parameters
    93 // must be cleverly copied from the top of stack to the outgoing param area in the frame,
    94 // ------------------------------ C++ interpreter ----------------------------------------
    95 // Layout of C++ interpreter frame:
    96 //
   100 // All frames:
   102  public:
   104   enum {
   105     // normal return address is 2 words past PC
   106     pc_return_offset                             = 2 * BytesPerInstWord,
   108     // size of each block, in order of increasing address:
   109     register_save_words                          = 16,
   110 #ifdef _LP64
   111     callee_aggregate_return_pointer_words        =  0,
   112 #else
   113     callee_aggregate_return_pointer_words        =  1,
   114 #endif
   115     callee_register_argument_save_area_words     =  6,
   116     // memory_parameter_words                    = <arbitrary>,
   118     // offset of each block, in order of increasing address:
   119     // (note: callee_register_argument_save_area_words == Assembler::n_register_parameters)
   120     register_save_words_sp_offset                = 0,
   121     callee_aggregate_return_pointer_sp_offset    = register_save_words_sp_offset + register_save_words,
   122     callee_register_argument_save_area_sp_offset = callee_aggregate_return_pointer_sp_offset + callee_aggregate_return_pointer_words,
   123     memory_parameter_word_sp_offset              = callee_register_argument_save_area_sp_offset + callee_register_argument_save_area_words,
   124     varargs_offset                               = memory_parameter_word_sp_offset
   125   };
   127  private:
   128   intptr_t*  _younger_sp;                 // optional SP of callee (used to locate O7)
   129   int        _sp_adjustment_by_callee;   // adjustment in words to SP by callee for making locals contiguous
   131   // Note:  On SPARC, unlike Intel, the saved PC for a stack frame
   132   // is stored at a __variable__ distance from that frame's SP.
   133   // (In fact, it may be in the register save area of the callee frame,
   134   // but that fact need not bother us.)  Thus, we must store the
   135   // address of that saved PC explicitly.  On the other hand, SPARC
   136   // stores the FP for a frame at a fixed offset from the frame's SP,
   137   // so there is no need for a separate "frame::_fp" field.
   139  public:
   140   // Accessors
   142   intptr_t* younger_sp() const {
   143     assert(_younger_sp != NULL, "frame must possess a younger_sp");
   144     return _younger_sp;
   145   }
   147   int callee_sp_adjustment() const { return _sp_adjustment_by_callee; }
   148   void set_sp_adjustment_by_callee(int number_of_words) { _sp_adjustment_by_callee = number_of_words; }
   150   // Constructors
   152   // This constructor relies on the fact that the creator of a frame
   153   // has flushed register windows which the frame will refer to, and
   154   // that those register windows will not be reloaded until the frame is
   155   // done reading and writing the stack.  Moreover, if the "younger_sp"
   156   // argument points into the register save area of the next younger
   157   // frame (though it need not), the register window for that next
   158   // younger frame must also stay flushed.  (The caller is responsible
   159   // for ensuring this.)
   161   frame(intptr_t* sp, intptr_t* younger_sp, bool younger_frame_adjusted_stack = false);
   163   // make a deficient frame which doesn't know where its PC is:
   164   enum unpatchable_t { unpatchable };
   165   frame(intptr_t* sp, unpatchable_t, address pc = NULL, CodeBlob* cb = NULL);
   167   // Walk from sp outward looking for old_sp, and return old_sp's predecessor
   168   // (i.e. return the sp from the frame where old_sp is the fp).
   169   // Register windows are assumed to be flushed for the stack in question.
   171   static intptr_t* next_younger_sp_or_null(intptr_t* old_sp, intptr_t* sp);
   173   // Return true if sp is a younger sp in the stack described by valid_sp.
   174   static bool is_valid_stack_pointer(intptr_t* valid_sp, intptr_t* sp);
   176  public:
   177   // accessors for the instance variables
   178   intptr_t*   fp() const { return (intptr_t*) ((intptr_t)(sp()[FP->sp_offset_in_saved_window()]) + STACK_BIAS ); }
   180   // All frames
   182   intptr_t*  fp_addr_at(int index) const   { return &fp()[index];    }
   183   intptr_t*  sp_addr_at(int index) const   { return &sp()[index];    }
   184   intptr_t   fp_at(     int index) const   { return *fp_addr_at(index); }
   185   intptr_t   sp_at(     int index) const   { return *sp_addr_at(index); }
   187  private:
   188   inline address* I7_addr() const;
   189   inline address* O7_addr() const;
   191   inline address* I0_addr() const;
   192   inline address* O0_addr() const;
   193   intptr_t*  younger_sp_addr_at(int index) const   { return &younger_sp()[index];    }
   195  public:
   196   // access to SPARC arguments and argument registers
   198   // Assumes reg is an in/local register
   199   intptr_t*     register_addr(Register reg) const {
   200     return sp_addr_at(reg->sp_offset_in_saved_window());
   201   }
   203   // Assumes reg is an out register
   204   intptr_t*     out_register_addr(Register reg) const {
   205     return younger_sp_addr_at(reg->after_save()->sp_offset_in_saved_window());
   206   }
   207   intptr_t* memory_param_addr(int param_ix, bool is_in) const {
   208     int offset = callee_register_argument_save_area_sp_offset + param_ix;
   209     if (is_in)
   210       return fp_addr_at(offset);
   211     else
   212       return sp_addr_at(offset);
   213   }
   214   intptr_t*        param_addr(int param_ix, bool is_in) const {
   215     if (param_ix >= callee_register_argument_save_area_words)
   216       return memory_param_addr(param_ix, is_in);
   217     else if (is_in)
   218       return register_addr(Argument(param_ix, true).as_register());
   219     else {
   220       // the registers are stored in the next younger frame
   221       // %%% is this really necessary?
   222       ShouldNotReachHere();
   223       return NULL;
   224     }
   225   }
   228   // Interpreter frames
   230  public:
   231   // Asm interpreter
   232 #ifndef CC_INTERP
   233   enum interpreter_frame_vm_locals {
   234        // 2 words, also used to save float regs across  calls to C
   235        interpreter_frame_d_scratch_fp_offset          = -2,
   236        interpreter_frame_l_scratch_fp_offset          = -4,
   237        interpreter_frame_padding_offset               = -5, // for native calls only
   238        interpreter_frame_oop_temp_offset              = -6, // for native calls only
   239        interpreter_frame_vm_locals_fp_offset          = -6, // should be same as above, and should be zero mod 8
   241        interpreter_frame_vm_local_words = -interpreter_frame_vm_locals_fp_offset,
   244        // interpreter frame set-up needs to save 2 extra words in outgoing param area
   245        // for class and jnienv arguments for native stubs (see nativeStubGen_sparc.cpp_
   247        interpreter_frame_extra_outgoing_argument_words = 2
   248   };
   249 #else
   250   enum interpreter_frame_vm_locals {
   251        // 2 words, also used to save float regs across  calls to C
   252        interpreter_state_ptr_offset                   = 0,  // Is in L0 (Lstate) in save area
   253        interpreter_frame_mirror_offset                = 1,  // Is in L1 (Lmirror) in save area (for native calls only)
   255        // interpreter frame set-up needs to save 2 extra words in outgoing param area
   256        // for class and jnienv arguments for native stubs (see nativeStubGen_sparc.cpp_
   258        interpreter_frame_extra_outgoing_argument_words = 2
   259   };
   260 #endif /* CC_INTERP */
   262   // the compiler frame has many of the same fields as the interpreter frame
   263   // %%%%% factor out declarations of the shared fields
   264   enum compiler_frame_fixed_locals {
   265        compiler_frame_d_scratch_fp_offset          = -2,
   266        compiler_frame_vm_locals_fp_offset          = -2, // should be same as above
   268        compiler_frame_vm_local_words = -compiler_frame_vm_locals_fp_offset
   269   };
   271  private:
   272   constantPoolCacheOop* interpreter_frame_cpoolcache_addr() const;
   274 #ifndef CC_INTERP
   276   // where Lmonitors is saved:
   277   BasicObjectLock**  interpreter_frame_monitors_addr() const {
   278     return (BasicObjectLock**) sp_addr_at(Lmonitors->sp_offset_in_saved_window());
   279   }
   280   intptr_t** interpreter_frame_esp_addr() const {
   281     return (intptr_t**)sp_addr_at(Lesp->sp_offset_in_saved_window());
   282   }
   284   inline void interpreter_frame_set_tos_address(intptr_t* x);
   287   // %%%%% Another idea: instead of defining 3 fns per item, just define one returning a ref
   289   // monitors:
   291   // next two fns read and write Lmonitors value,
   292  private:
   293   BasicObjectLock* interpreter_frame_monitors()           const  { return *interpreter_frame_monitors_addr(); }
   294   void interpreter_frame_set_monitors(BasicObjectLock* monitors) {        *interpreter_frame_monitors_addr() = monitors; }
   295 #else
   296  public:
   297   inline interpreterState get_interpreterState() const {
   298     return ((interpreterState)sp_at(interpreter_state_ptr_offset));
   299   }
   302 #endif /* CC_INTERP */
   306  // Compiled frames
   308  public:
   309   // Tells if this register can hold 64 bits on V9 (really, V8+).
   310   static bool holds_a_doubleword(Register reg) {
   311 #ifdef _LP64
   312     //    return true;
   313     return reg->is_out() || reg->is_global();
   314 #else
   315     return reg->is_out() || reg->is_global();
   316 #endif
   317   }
   319 #endif // CPU_SPARC_VM_FRAME_SPARC_HPP

mercurial