src/cpu/sparc/vm/interp_masm_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 2438
dd031b2226de
child 3050
fdb992d83a87
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, 2011, 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_INTERP_MASM_SPARC_HPP
    26 #define CPU_SPARC_VM_INTERP_MASM_SPARC_HPP
    28 #include "assembler_sparc.inline.hpp"
    29 #include "interpreter/invocationCounter.hpp"
    31 // This file specializes the assember with interpreter-specific macros
    33 REGISTER_DECLARATION(     Register, Otos_i , O0); // tos for ints, etc
    34 REGISTER_DECLARATION(     Register, Otos_l , O0); // for longs
    35 REGISTER_DECLARATION(     Register, Otos_l1, O0); // for 1st part of longs
    36 REGISTER_DECLARATION(     Register, Otos_l2, O1); // for 2nd part of longs
    37 REGISTER_DECLARATION(FloatRegister, Ftos_f , F0); // for floats
    38 REGISTER_DECLARATION(FloatRegister, Ftos_d , F0); // for doubles
    39 REGISTER_DECLARATION(FloatRegister, Ftos_d1, F0); // for 1st part of double
    40 REGISTER_DECLARATION(FloatRegister, Ftos_d2, F1); // for 2nd part of double
    42 #ifndef DONT_USE_REGISTER_DEFINES
    43 #define Otos_i  O0
    44 #define Otos_l  O0
    45 #define Otos_l1 O0
    46 #define Otos_l2 O1
    47 #define Ftos_f  F0
    48 #define Ftos_d  F0
    49 #define Ftos_d1 F0
    50 #define Ftos_d2 F1
    51 #endif // DONT_USE_REGISTER_DEFINES
    53 class InterpreterMacroAssembler: public MacroAssembler {
    54  protected:
    55 #ifndef CC_INTERP
    56   // Interpreter specific version of call_VM_base
    57     virtual void call_VM_leaf_base(
    58     Register java_thread,
    59     address  entry_point,
    60     int      number_of_arguments
    61   );
    63   virtual void call_VM_base(
    64     Register        oop_result,
    65     Register        java_thread,
    66     Register        last_java_sp,
    67     address         entry_point,
    68     int             number_of_arguments,
    69     bool            check_exception=true
    70   );
    72   virtual void check_and_handle_popframe(Register java_thread);
    73   virtual void check_and_handle_earlyret(Register java_thread);
    75   // base routine for all dispatches
    76   void dispatch_base(TosState state, address* table);
    77 #endif /* CC_INTERP */
    79  public:
    80   InterpreterMacroAssembler(CodeBuffer* c)
    81     : MacroAssembler(c) {}
    83 #ifndef CC_INTERP
    84   virtual void load_earlyret_value(TosState state);
    86   static const Address l_tmp ;
    87   static const Address d_tmp ;
    88 #endif /* CC_INTERP */
    90   // helper routine for frame allocation/deallocation
    91   // compute the delta by which the caller's SP has to
    92   // be adjusted to accomodate for the non-argument
    93   // locals
    94   void compute_extra_locals_size_in_bytes(Register args_size, Register locals_size, Register delta);
    96 #ifndef CC_INTERP
    98   // dispatch routines
    99   void dispatch_prolog(TosState state, int step = 0);
   100   void dispatch_epilog(TosState state, int step = 0);
   101   void dispatch_only(TosState state);
   102   void dispatch_normal(TosState state);
   103   void dispatch_next(TosState state, int step = 0);
   104   void dispatch_next_noverify_oop(TosState state, int step = 0);
   105   void dispatch_via (TosState state, address* table);
   108   // Removes the current activation (incl. unlocking of monitors).
   109   // Additionally this code is used for earlyReturn in which case we
   110   // want to skip throwing an exception and installing an exception.
   111   void remove_activation(TosState state,
   112                          bool throw_monitor_exception = true,
   113                          bool install_monitor_exception = true);
   115  protected:
   116   void dispatch_Lbyte_code(TosState state, address* table, int bcp_incr = 0, bool verify = true);
   117 #endif /* CC_INTERP */
   119  public:
   120   // Super call_VM calls - correspond to MacroAssembler::call_VM(_leaf) calls
   121   void super_call_VM(Register thread_cache,
   122                      Register oop_result,
   123                      Register last_java_sp,
   124                      address entry_point,
   125                      Register arg_1,
   126                      Register arg_2,
   127                      bool check_exception = true);
   129 #ifndef CC_INTERP
   130   void super_call_VM_leaf(Register thread_cache, address entry_point, Register arg_1, Register arg_2);
   132   // Generate a subtype check: branch to ok_is_subtype if sub_klass is
   133   // a subtype of super_klass.  Blows registers tmp1, tmp2 and tmp3.
   134   void gen_subtype_check( Register sub_klass, Register super_klass, Register tmp1, Register tmp2, Register tmp3, Label &ok_is_subtype );
   136   // helpers for tossing exceptions
   137   void throw_if_not_1_icc( Condition ok_condition, Label& ok );
   138   void throw_if_not_1_xcc( Condition ok_condition, Label& ok );
   139   void throw_if_not_1_x  ( Condition ok_condition, Label& ok ); // chooses icc or xcc based on _LP64
   141   void throw_if_not_2( address throw_entry_point, Register Rscratch, Label& ok);
   143   void throw_if_not_icc( Condition ok_condition, address throw_entry_point, Register Rscratch );
   144   void throw_if_not_xcc( Condition ok_condition, address throw_entry_point, Register Rscratch );
   145   void throw_if_not_x  ( Condition ok_condition, address throw_entry_point, Register Rscratch );
   147   // helpers for expression stack
   149   void pop_i(     Register r = Otos_i);
   150   void pop_ptr(   Register r = Otos_i, Register scratch = O4);
   151   void pop_l(     Register r = Otos_l1);
   152   // G4_scratch and Lscratch are used at call sites!!
   153   void pop_f(FloatRegister f = Ftos_f,  Register scratch = G1_scratch);
   154   void pop_d(FloatRegister f = Ftos_d1, Register scratch = G1_scratch);
   156   void push_i(     Register r = Otos_i);
   157   void push_ptr(   Register r = Otos_i);
   158   void push_l(     Register r = Otos_l1);
   159   void push_f(FloatRegister f = Ftos_f);
   160   void push_d(FloatRegister f = Ftos_d1);
   163   void pop (TosState state);           // transition vtos -> state
   164   void push(TosState state);           // transition state -> vtos
   165   void empty_expression_stack();       // resets both Lesp and SP
   167 #ifdef ASSERT
   168   void verify_sp(Register Rsp, Register Rtemp);
   169   void verify_esp(Register Resp);      // verify that Lesp points to a word in the temp stack
   170 #endif // ASSERT
   172  public:
   173   void if_cmp(Condition cc, bool ptr_compare);
   175   // Load values from bytecode stream:
   177   enum signedOrNot { Signed, Unsigned };
   178   enum setCCOrNot  { set_CC,  dont_set_CC };
   180   void get_2_byte_integer_at_bcp( int         bcp_offset,
   181                                   Register    Rtmp,
   182                                   Register    Rdst,
   183                                   signedOrNot is_signed,
   184                                   setCCOrNot  should_set_CC = dont_set_CC );
   186   void get_4_byte_integer_at_bcp( int        bcp_offset,
   187                                   Register   Rtmp,
   188                                   Register   Rdst,
   189                                   setCCOrNot should_set_CC = dont_set_CC );
   191   void get_cache_and_index_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
   192   void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
   193   void get_cache_index_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
   196   // common code
   198   void field_offset_at(int n, Register tmp, Register dest, Register base);
   199   int  field_offset_at(Register object, address bcp, int offset);
   200   void fast_iaaccess(int n, address bcp);
   201   void fast_iagetfield(address bcp);
   202   void fast_iaputfield(address bcp, bool do_store_check );
   204   void index_check(Register array, Register index, int index_shift, Register tmp, Register res);
   205   void index_check_without_pop(Register array, Register index, int index_shift, Register tmp, Register res);
   207   void get_constant_pool(Register Rdst);
   208   void get_constant_pool_cache(Register Rdst);
   209   void get_cpool_and_tags(Register Rcpool, Register Rtags);
   210   void is_a(Label& L);
   212   // Load compiled (i2c) or interpreter entry and call from interpreted
   213   void call_from_interpreter(Register target, Register scratch, Register Rret);
   215   // --------------------------------------------------
   217   void unlock_if_synchronized_method(TosState state, bool throw_monitor_exception = true, bool install_monitor_exception = true);
   219   void add_monitor_to_stack( bool stack_is_empty,
   220                              Register Rtemp,
   221                              Register Rtemp2 );
   223   // Load/store aligned in _LP64 but unaligned otherwise
   224   // These only apply to the Interpreter expression stack and locals!
   225   void  load_unaligned_double(Register r1, int offset,  FloatRegister d);
   226   void store_unaligned_double(FloatRegister d, Register r1, int offset );
   228   // Load/store aligned in _LP64 but unaligned otherwise
   229   void  load_unaligned_long(Register r1, int offset,  Register d);
   230   void store_unaligned_long(Register d, Register r1, int offset );
   232   void access_local_int( Register index, Register dst );
   233   void access_local_ptr( Register index, Register dst );
   234   void access_local_returnAddress( Register index, Register dst );
   235   void access_local_long( Register index, Register dst );
   236   void access_local_float( Register index, FloatRegister dst );
   237   void access_local_double( Register index, FloatRegister dst );
   238 #ifdef ASSERT
   239   void check_for_regarea_stomp( Register Rindex, int offset, Register Rlimit, Register Rscratch, Register Rscratch1);
   240 #endif // ASSERT
   241   void store_local_int( Register index, Register src );
   242   void store_local_ptr( Register index, Register src );
   243   void store_local_ptr( int n, Register src );
   244   void store_local_long( Register index, Register src );
   245   void store_local_float( Register index, FloatRegister src );
   246   void store_local_double( Register index, FloatRegister src );
   248   // Helpers for swap and dup
   249   void load_ptr(int n, Register val);
   250   void store_ptr(int n, Register val);
   252   // Helper for getting receiver in register.
   253   void load_receiver(Register param_count, Register recv);
   255   static int top_most_monitor_byte_offset(); // offset in bytes to top of monitor block
   256   Address top_most_monitor();
   257   void compute_stack_base( Register Rdest );
   259 #endif /* CC_INTERP */
   260   void increment_invocation_counter( Register Rtmp, Register Rtmp2 );
   261   void increment_backedge_counter( Register Rtmp, Register Rtmp2 );
   262 #ifndef CC_INTERP
   263   void test_backedge_count_for_osr( Register backedge_count, Register branch_bcp, Register Rtmp );
   265 #endif /* CC_INTERP */
   266   // Object locking
   267   void lock_object  (Register lock_reg, Register obj_reg);
   268   void unlock_object(Register lock_reg);
   270 #ifndef CC_INTERP
   271   // Interpreter profiling operations
   272   void set_method_data_pointer();
   273   void set_method_data_pointer_for_bcp();
   274   void test_method_data_pointer(Label& zero_continue);
   275   void verify_method_data_pointer();
   276   void test_invocation_counter_for_mdp(Register invocation_count, Register Rtmp, Label &profile_continue);
   278   void set_mdp_data_at(int constant, Register value);
   279   void increment_mdp_data_at(Address counter, Register bumped_count,
   280                              bool decrement = false);
   281   void increment_mdp_data_at(int constant, Register bumped_count,
   282                              bool decrement = false);
   283   void increment_mdp_data_at(Register reg, int constant,
   284                              Register bumped_count, Register scratch2,
   285                              bool decrement = false);
   286   void increment_mask_and_jump(Address counter_addr,
   287                                int increment, int mask,
   288                                Register scratch1, Register scratch2,
   289                                Condition cond, Label *where);
   290   void set_mdp_flag_at(int flag_constant, Register scratch);
   291   void test_mdp_data_at(int offset, Register value, Label& not_equal_continue,
   292                         Register scratch);
   294   void record_klass_in_profile(Register receiver, Register scratch, bool is_virtual_call);
   295   void record_klass_in_profile_helper(Register receiver, Register scratch,
   296                                       int start_row, Label& done, bool is_virtual_call);
   298   void update_mdp_by_offset(int offset_of_disp, Register scratch);
   299   void update_mdp_by_offset(Register reg, int offset_of_disp,
   300                             Register scratch);
   301   void update_mdp_by_constant(int constant);
   302   void update_mdp_for_ret(TosState state, Register return_bci);
   304   void profile_taken_branch(Register scratch, Register bumped_count);
   305   void profile_not_taken_branch(Register scratch);
   306   void profile_call(Register scratch);
   307   void profile_final_call(Register scratch);
   308   void profile_virtual_call(Register receiver, Register scratch, bool receiver_can_be_null = false);
   309   void profile_ret(TosState state, Register return_bci, Register scratch);
   310   void profile_null_seen(Register scratch);
   311   void profile_typecheck(Register klass, Register scratch);
   312   void profile_typecheck_failed(Register scratch);
   313   void profile_switch_default(Register scratch);
   314   void profile_switch_case(Register index,
   315                            Register scratch1,
   316                            Register scratch2,
   317                            Register scratch3);
   319   // Debugging
   320   void interp_verify_oop(Register reg, TosState state, const char * file, int line);    // only if +VerifyOops && state == atos
   321   void verify_oop_or_return_address(Register reg, Register rtmp); // for astore
   322   void verify_FPU(int stack_depth, TosState state = ftos); // only if +VerifyFPU  && (state == ftos || state == dtos)
   324 #endif /* CC_INTERP */
   325   // support for JVMTI/Dtrace
   326   typedef enum { NotifyJVMTI, SkipNotifyJVMTI } NotifyMethodExitMode;
   327   void notify_method_entry();
   328   void notify_method_exit(
   329     bool save_result, TosState state, NotifyMethodExitMode mode);
   331   void save_return_value(TosState state, bool is_native_call);
   332   void restore_return_value(TosState state, bool is_native_call);
   334 };
   336 #endif // CPU_SPARC_VM_INTERP_MASM_SPARC_HPP

mercurial