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

duke@435 1 /*
iveresov@2438 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
stefank@2314 25 #ifndef CPU_SPARC_VM_INTERP_MASM_SPARC_HPP
stefank@2314 26 #define CPU_SPARC_VM_INTERP_MASM_SPARC_HPP
stefank@2314 27
stefank@2314 28 #include "assembler_sparc.inline.hpp"
stefank@2314 29 #include "interpreter/invocationCounter.hpp"
stefank@2314 30
duke@435 31 // This file specializes the assember with interpreter-specific macros
duke@435 32
duke@435 33 REGISTER_DECLARATION( Register, Otos_i , O0); // tos for ints, etc
duke@435 34 REGISTER_DECLARATION( Register, Otos_l , O0); // for longs
duke@435 35 REGISTER_DECLARATION( Register, Otos_l1, O0); // for 1st part of longs
duke@435 36 REGISTER_DECLARATION( Register, Otos_l2, O1); // for 2nd part of longs
duke@435 37 REGISTER_DECLARATION(FloatRegister, Ftos_f , F0); // for floats
duke@435 38 REGISTER_DECLARATION(FloatRegister, Ftos_d , F0); // for doubles
duke@435 39 REGISTER_DECLARATION(FloatRegister, Ftos_d1, F0); // for 1st part of double
duke@435 40 REGISTER_DECLARATION(FloatRegister, Ftos_d2, F1); // for 2nd part of double
duke@435 41
duke@435 42 #ifndef DONT_USE_REGISTER_DEFINES
duke@435 43 #define Otos_i O0
duke@435 44 #define Otos_l O0
duke@435 45 #define Otos_l1 O0
duke@435 46 #define Otos_l2 O1
duke@435 47 #define Ftos_f F0
duke@435 48 #define Ftos_d F0
duke@435 49 #define Ftos_d1 F0
duke@435 50 #define Ftos_d2 F1
duke@435 51 #endif // DONT_USE_REGISTER_DEFINES
duke@435 52
duke@435 53 class InterpreterMacroAssembler: public MacroAssembler {
duke@435 54 protected:
duke@435 55 #ifndef CC_INTERP
duke@435 56 // Interpreter specific version of call_VM_base
duke@435 57 virtual void call_VM_leaf_base(
duke@435 58 Register java_thread,
duke@435 59 address entry_point,
duke@435 60 int number_of_arguments
duke@435 61 );
duke@435 62
duke@435 63 virtual void call_VM_base(
duke@435 64 Register oop_result,
duke@435 65 Register java_thread,
duke@435 66 Register last_java_sp,
duke@435 67 address entry_point,
duke@435 68 int number_of_arguments,
duke@435 69 bool check_exception=true
duke@435 70 );
duke@435 71
duke@435 72 virtual void check_and_handle_popframe(Register java_thread);
duke@435 73 virtual void check_and_handle_earlyret(Register java_thread);
duke@435 74
duke@435 75 // base routine for all dispatches
duke@435 76 void dispatch_base(TosState state, address* table);
duke@435 77 #endif /* CC_INTERP */
duke@435 78
duke@435 79 public:
duke@435 80 InterpreterMacroAssembler(CodeBuffer* c)
duke@435 81 : MacroAssembler(c) {}
duke@435 82
duke@435 83 #ifndef CC_INTERP
duke@435 84 virtual void load_earlyret_value(TosState state);
duke@435 85
duke@435 86 static const Address l_tmp ;
duke@435 87 static const Address d_tmp ;
duke@435 88 #endif /* CC_INTERP */
duke@435 89
duke@435 90 // helper routine for frame allocation/deallocation
duke@435 91 // compute the delta by which the caller's SP has to
duke@435 92 // be adjusted to accomodate for the non-argument
duke@435 93 // locals
duke@435 94 void compute_extra_locals_size_in_bytes(Register args_size, Register locals_size, Register delta);
duke@435 95
duke@435 96 #ifndef CC_INTERP
duke@435 97
duke@435 98 // dispatch routines
duke@435 99 void dispatch_prolog(TosState state, int step = 0);
duke@435 100 void dispatch_epilog(TosState state, int step = 0);
duke@435 101 void dispatch_only(TosState state);
duke@435 102 void dispatch_normal(TosState state);
duke@435 103 void dispatch_next(TosState state, int step = 0);
duke@435 104 void dispatch_next_noverify_oop(TosState state, int step = 0);
duke@435 105 void dispatch_via (TosState state, address* table);
duke@435 106
duke@435 107
duke@435 108 // Removes the current activation (incl. unlocking of monitors).
duke@435 109 // Additionally this code is used for earlyReturn in which case we
duke@435 110 // want to skip throwing an exception and installing an exception.
duke@435 111 void remove_activation(TosState state,
duke@435 112 bool throw_monitor_exception = true,
duke@435 113 bool install_monitor_exception = true);
duke@435 114
duke@435 115 protected:
duke@435 116 void dispatch_Lbyte_code(TosState state, address* table, int bcp_incr = 0, bool verify = true);
duke@435 117 #endif /* CC_INTERP */
duke@435 118
duke@435 119 public:
duke@435 120 // Super call_VM calls - correspond to MacroAssembler::call_VM(_leaf) calls
duke@435 121 void super_call_VM(Register thread_cache,
duke@435 122 Register oop_result,
duke@435 123 Register last_java_sp,
duke@435 124 address entry_point,
duke@435 125 Register arg_1,
duke@435 126 Register arg_2,
duke@435 127 bool check_exception = true);
duke@435 128
duke@435 129 #ifndef CC_INTERP
twisti@1730 130 void super_call_VM_leaf(Register thread_cache, address entry_point, Register arg_1, Register arg_2);
duke@435 131
duke@435 132 // Generate a subtype check: branch to ok_is_subtype if sub_klass is
duke@435 133 // a subtype of super_klass. Blows registers tmp1, tmp2 and tmp3.
duke@435 134 void gen_subtype_check( Register sub_klass, Register super_klass, Register tmp1, Register tmp2, Register tmp3, Label &ok_is_subtype );
duke@435 135
duke@435 136 // helpers for tossing exceptions
duke@435 137 void throw_if_not_1_icc( Condition ok_condition, Label& ok );
duke@435 138 void throw_if_not_1_xcc( Condition ok_condition, Label& ok );
duke@435 139 void throw_if_not_1_x ( Condition ok_condition, Label& ok ); // chooses icc or xcc based on _LP64
duke@435 140
duke@435 141 void throw_if_not_2( address throw_entry_point, Register Rscratch, Label& ok);
duke@435 142
duke@435 143 void throw_if_not_icc( Condition ok_condition, address throw_entry_point, Register Rscratch );
duke@435 144 void throw_if_not_xcc( Condition ok_condition, address throw_entry_point, Register Rscratch );
duke@435 145 void throw_if_not_x ( Condition ok_condition, address throw_entry_point, Register Rscratch );
duke@435 146
duke@435 147 // helpers for expression stack
duke@435 148
duke@435 149 void pop_i( Register r = Otos_i);
duke@435 150 void pop_ptr( Register r = Otos_i, Register scratch = O4);
duke@435 151 void pop_l( Register r = Otos_l1);
duke@435 152 // G4_scratch and Lscratch are used at call sites!!
duke@435 153 void pop_f(FloatRegister f = Ftos_f, Register scratch = G1_scratch);
duke@435 154 void pop_d(FloatRegister f = Ftos_d1, Register scratch = G1_scratch);
duke@435 155
duke@435 156 void push_i( Register r = Otos_i);
duke@435 157 void push_ptr( Register r = Otos_i);
duke@435 158 void push_l( Register r = Otos_l1);
duke@435 159 void push_f(FloatRegister f = Ftos_f);
duke@435 160 void push_d(FloatRegister f = Ftos_d1);
duke@435 161
duke@435 162
duke@435 163 void pop (TosState state); // transition vtos -> state
duke@435 164 void push(TosState state); // transition state -> vtos
duke@435 165 void empty_expression_stack(); // resets both Lesp and SP
duke@435 166
duke@435 167 #ifdef ASSERT
duke@435 168 void verify_sp(Register Rsp, Register Rtemp);
duke@435 169 void verify_esp(Register Resp); // verify that Lesp points to a word in the temp stack
duke@435 170 #endif // ASSERT
duke@435 171
duke@435 172 public:
duke@435 173 void if_cmp(Condition cc, bool ptr_compare);
duke@435 174
duke@435 175 // Load values from bytecode stream:
duke@435 176
duke@435 177 enum signedOrNot { Signed, Unsigned };
duke@435 178 enum setCCOrNot { set_CC, dont_set_CC };
duke@435 179
duke@435 180 void get_2_byte_integer_at_bcp( int bcp_offset,
duke@435 181 Register Rtmp,
duke@435 182 Register Rdst,
duke@435 183 signedOrNot is_signed,
duke@435 184 setCCOrNot should_set_CC = dont_set_CC );
duke@435 185
duke@435 186 void get_4_byte_integer_at_bcp( int bcp_offset,
duke@435 187 Register Rtmp,
duke@435 188 Register Rdst,
duke@435 189 setCCOrNot should_set_CC = dont_set_CC );
duke@435 190
jrose@1920 191 void get_cache_and_index_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
jrose@1920 192 void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
jrose@1920 193 void get_cache_index_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
duke@435 194
duke@435 195
duke@435 196 // common code
duke@435 197
duke@435 198 void field_offset_at(int n, Register tmp, Register dest, Register base);
duke@435 199 int field_offset_at(Register object, address bcp, int offset);
duke@435 200 void fast_iaaccess(int n, address bcp);
duke@435 201 void fast_iagetfield(address bcp);
duke@435 202 void fast_iaputfield(address bcp, bool do_store_check );
duke@435 203
duke@435 204 void index_check(Register array, Register index, int index_shift, Register tmp, Register res);
duke@435 205 void index_check_without_pop(Register array, Register index, int index_shift, Register tmp, Register res);
duke@435 206
duke@435 207 void get_constant_pool(Register Rdst);
duke@435 208 void get_constant_pool_cache(Register Rdst);
duke@435 209 void get_cpool_and_tags(Register Rcpool, Register Rtags);
duke@435 210 void is_a(Label& L);
duke@435 211
duke@435 212 // Load compiled (i2c) or interpreter entry and call from interpreted
duke@435 213 void call_from_interpreter(Register target, Register scratch, Register Rret);
duke@435 214
duke@435 215 // --------------------------------------------------
duke@435 216
duke@435 217 void unlock_if_synchronized_method(TosState state, bool throw_monitor_exception = true, bool install_monitor_exception = true);
duke@435 218
duke@435 219 void add_monitor_to_stack( bool stack_is_empty,
duke@435 220 Register Rtemp,
duke@435 221 Register Rtemp2 );
duke@435 222
duke@435 223 // Load/store aligned in _LP64 but unaligned otherwise
duke@435 224 // These only apply to the Interpreter expression stack and locals!
duke@435 225 void load_unaligned_double(Register r1, int offset, FloatRegister d);
duke@435 226 void store_unaligned_double(FloatRegister d, Register r1, int offset );
duke@435 227
duke@435 228 // Load/store aligned in _LP64 but unaligned otherwise
duke@435 229 void load_unaligned_long(Register r1, int offset, Register d);
duke@435 230 void store_unaligned_long(Register d, Register r1, int offset );
duke@435 231
duke@435 232 void access_local_int( Register index, Register dst );
duke@435 233 void access_local_ptr( Register index, Register dst );
duke@435 234 void access_local_returnAddress( Register index, Register dst );
duke@435 235 void access_local_long( Register index, Register dst );
duke@435 236 void access_local_float( Register index, FloatRegister dst );
duke@435 237 void access_local_double( Register index, FloatRegister dst );
duke@435 238 #ifdef ASSERT
duke@435 239 void check_for_regarea_stomp( Register Rindex, int offset, Register Rlimit, Register Rscratch, Register Rscratch1);
duke@435 240 #endif // ASSERT
duke@435 241 void store_local_int( Register index, Register src );
twisti@1861 242 void store_local_ptr( Register index, Register src );
twisti@1861 243 void store_local_ptr( int n, Register src );
duke@435 244 void store_local_long( Register index, Register src );
duke@435 245 void store_local_float( Register index, FloatRegister src );
duke@435 246 void store_local_double( Register index, FloatRegister src );
duke@435 247
twisti@1861 248 // Helpers for swap and dup
twisti@1861 249 void load_ptr(int n, Register val);
twisti@1861 250 void store_ptr(int n, Register val);
duke@435 251
twisti@1861 252 // Helper for getting receiver in register.
duke@435 253 void load_receiver(Register param_count, Register recv);
duke@435 254
duke@435 255 static int top_most_monitor_byte_offset(); // offset in bytes to top of monitor block
duke@435 256 Address top_most_monitor();
duke@435 257 void compute_stack_base( Register Rdest );
duke@435 258
duke@435 259 #endif /* CC_INTERP */
duke@435 260 void increment_invocation_counter( Register Rtmp, Register Rtmp2 );
duke@435 261 void increment_backedge_counter( Register Rtmp, Register Rtmp2 );
duke@435 262 #ifndef CC_INTERP
duke@435 263 void test_backedge_count_for_osr( Register backedge_count, Register branch_bcp, Register Rtmp );
duke@435 264
duke@435 265 #endif /* CC_INTERP */
duke@435 266 // Object locking
duke@435 267 void lock_object (Register lock_reg, Register obj_reg);
duke@435 268 void unlock_object(Register lock_reg);
duke@435 269
duke@435 270 #ifndef CC_INTERP
duke@435 271 // Interpreter profiling operations
iveresov@2438 272 void set_method_data_pointer();
duke@435 273 void set_method_data_pointer_for_bcp();
duke@435 274 void test_method_data_pointer(Label& zero_continue);
duke@435 275 void verify_method_data_pointer();
iveresov@2438 276 void test_invocation_counter_for_mdp(Register invocation_count, Register Rtmp, Label &profile_continue);
duke@435 277
duke@435 278 void set_mdp_data_at(int constant, Register value);
duke@435 279 void increment_mdp_data_at(Address counter, Register bumped_count,
duke@435 280 bool decrement = false);
duke@435 281 void increment_mdp_data_at(int constant, Register bumped_count,
duke@435 282 bool decrement = false);
duke@435 283 void increment_mdp_data_at(Register reg, int constant,
duke@435 284 Register bumped_count, Register scratch2,
duke@435 285 bool decrement = false);
iveresov@2138 286 void increment_mask_and_jump(Address counter_addr,
iveresov@2138 287 int increment, int mask,
iveresov@2138 288 Register scratch1, Register scratch2,
iveresov@2138 289 Condition cond, Label *where);
duke@435 290 void set_mdp_flag_at(int flag_constant, Register scratch);
duke@435 291 void test_mdp_data_at(int offset, Register value, Label& not_equal_continue,
duke@435 292 Register scratch);
duke@435 293
kvn@1641 294 void record_klass_in_profile(Register receiver, Register scratch, bool is_virtual_call);
duke@435 295 void record_klass_in_profile_helper(Register receiver, Register scratch,
kvn@1641 296 int start_row, Label& done, bool is_virtual_call);
duke@435 297
duke@435 298 void update_mdp_by_offset(int offset_of_disp, Register scratch);
duke@435 299 void update_mdp_by_offset(Register reg, int offset_of_disp,
duke@435 300 Register scratch);
duke@435 301 void update_mdp_by_constant(int constant);
duke@435 302 void update_mdp_for_ret(TosState state, Register return_bci);
duke@435 303
duke@435 304 void profile_taken_branch(Register scratch, Register bumped_count);
duke@435 305 void profile_not_taken_branch(Register scratch);
duke@435 306 void profile_call(Register scratch);
duke@435 307 void profile_final_call(Register scratch);
twisti@1858 308 void profile_virtual_call(Register receiver, Register scratch, bool receiver_can_be_null = false);
duke@435 309 void profile_ret(TosState state, Register return_bci, Register scratch);
duke@435 310 void profile_null_seen(Register scratch);
duke@435 311 void profile_typecheck(Register klass, Register scratch);
duke@435 312 void profile_typecheck_failed(Register scratch);
duke@435 313 void profile_switch_default(Register scratch);
duke@435 314 void profile_switch_case(Register index,
duke@435 315 Register scratch1,
duke@435 316 Register scratch2,
duke@435 317 Register scratch3);
duke@435 318
duke@435 319 // Debugging
duke@435 320 void interp_verify_oop(Register reg, TosState state, const char * file, int line); // only if +VerifyOops && state == atos
duke@435 321 void verify_oop_or_return_address(Register reg, Register rtmp); // for astore
duke@435 322 void verify_FPU(int stack_depth, TosState state = ftos); // only if +VerifyFPU && (state == ftos || state == dtos)
duke@435 323
duke@435 324 #endif /* CC_INTERP */
duke@435 325 // support for JVMTI/Dtrace
duke@435 326 typedef enum { NotifyJVMTI, SkipNotifyJVMTI } NotifyMethodExitMode;
duke@435 327 void notify_method_entry();
duke@435 328 void notify_method_exit(
duke@435 329 bool save_result, TosState state, NotifyMethodExitMode mode);
duke@435 330
duke@435 331 void save_return_value(TosState state, bool is_native_call);
duke@435 332 void restore_return_value(TosState state, bool is_native_call);
iveresov@2138 333
duke@435 334 };
stefank@2314 335
stefank@2314 336 #endif // CPU_SPARC_VM_INTERP_MASM_SPARC_HPP

mercurial