Thu, 07 Apr 2011 09:53:20 -0700
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