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) 1999, 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 #include "c1/c1_FrameMap.hpp"
27 #include "c1/c1_LIR.hpp"
28 #include "runtime/sharedRuntime.hpp"
29 #include "vmreg_sparc.inline.hpp"
32 const int FrameMap::pd_c_runtime_reserved_arg_size = 7;
35 LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool outgoing) {
36 LIR_Opr opr = LIR_OprFact::illegalOpr;
37 VMReg r_1 = reg->first();
38 VMReg r_2 = reg->second();
39 if (r_1->is_stack()) {
40 // Convert stack slot to an SP offset
41 // The calling convention does not count the SharedRuntime::out_preserve_stack_slots() value
42 // so we must add it in here.
43 int st_off = (r_1->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size;
44 opr = LIR_OprFact::address(new LIR_Address(SP_opr, st_off + STACK_BIAS, type));
45 } else if (r_1->is_Register()) {
46 Register reg = r_1->as_Register();
47 if (outgoing) {
48 assert(!reg->is_in(), "should be using I regs");
49 } else {
50 assert(!reg->is_out(), "should be using O regs");
51 }
52 if (r_2->is_Register() && (type == T_LONG || type == T_DOUBLE)) {
53 opr = as_long_opr(reg);
54 } else if (type == T_OBJECT || type == T_ARRAY) {
55 opr = as_oop_opr(reg);
56 } else {
57 opr = as_opr(reg);
58 }
59 } else if (r_1->is_FloatRegister()) {
60 assert(type == T_DOUBLE || type == T_FLOAT, "wrong type");
61 FloatRegister f = r_1->as_FloatRegister();
62 if (type == T_DOUBLE) {
63 opr = as_double_opr(f);
64 } else {
65 opr = as_float_opr(f);
66 }
67 }
68 return opr;
69 }
71 // FrameMap
72 //--------------------------------------------------------
74 FloatRegister FrameMap::_fpu_regs [FrameMap::nof_fpu_regs];
76 // some useful constant RInfo's:
77 LIR_Opr FrameMap::in_long_opr;
78 LIR_Opr FrameMap::out_long_opr;
79 LIR_Opr FrameMap::g1_long_single_opr;
81 LIR_Opr FrameMap::F0_opr;
82 LIR_Opr FrameMap::F0_double_opr;
84 LIR_Opr FrameMap::G0_opr;
85 LIR_Opr FrameMap::G1_opr;
86 LIR_Opr FrameMap::G2_opr;
87 LIR_Opr FrameMap::G3_opr;
88 LIR_Opr FrameMap::G4_opr;
89 LIR_Opr FrameMap::G5_opr;
90 LIR_Opr FrameMap::G6_opr;
91 LIR_Opr FrameMap::G7_opr;
92 LIR_Opr FrameMap::O0_opr;
93 LIR_Opr FrameMap::O1_opr;
94 LIR_Opr FrameMap::O2_opr;
95 LIR_Opr FrameMap::O3_opr;
96 LIR_Opr FrameMap::O4_opr;
97 LIR_Opr FrameMap::O5_opr;
98 LIR_Opr FrameMap::O6_opr;
99 LIR_Opr FrameMap::O7_opr;
100 LIR_Opr FrameMap::L0_opr;
101 LIR_Opr FrameMap::L1_opr;
102 LIR_Opr FrameMap::L2_opr;
103 LIR_Opr FrameMap::L3_opr;
104 LIR_Opr FrameMap::L4_opr;
105 LIR_Opr FrameMap::L5_opr;
106 LIR_Opr FrameMap::L6_opr;
107 LIR_Opr FrameMap::L7_opr;
108 LIR_Opr FrameMap::I0_opr;
109 LIR_Opr FrameMap::I1_opr;
110 LIR_Opr FrameMap::I2_opr;
111 LIR_Opr FrameMap::I3_opr;
112 LIR_Opr FrameMap::I4_opr;
113 LIR_Opr FrameMap::I5_opr;
114 LIR_Opr FrameMap::I6_opr;
115 LIR_Opr FrameMap::I7_opr;
117 LIR_Opr FrameMap::G0_oop_opr;
118 LIR_Opr FrameMap::G1_oop_opr;
119 LIR_Opr FrameMap::G2_oop_opr;
120 LIR_Opr FrameMap::G3_oop_opr;
121 LIR_Opr FrameMap::G4_oop_opr;
122 LIR_Opr FrameMap::G5_oop_opr;
123 LIR_Opr FrameMap::G6_oop_opr;
124 LIR_Opr FrameMap::G7_oop_opr;
125 LIR_Opr FrameMap::O0_oop_opr;
126 LIR_Opr FrameMap::O1_oop_opr;
127 LIR_Opr FrameMap::O2_oop_opr;
128 LIR_Opr FrameMap::O3_oop_opr;
129 LIR_Opr FrameMap::O4_oop_opr;
130 LIR_Opr FrameMap::O5_oop_opr;
131 LIR_Opr FrameMap::O6_oop_opr;
132 LIR_Opr FrameMap::O7_oop_opr;
133 LIR_Opr FrameMap::L0_oop_opr;
134 LIR_Opr FrameMap::L1_oop_opr;
135 LIR_Opr FrameMap::L2_oop_opr;
136 LIR_Opr FrameMap::L3_oop_opr;
137 LIR_Opr FrameMap::L4_oop_opr;
138 LIR_Opr FrameMap::L5_oop_opr;
139 LIR_Opr FrameMap::L6_oop_opr;
140 LIR_Opr FrameMap::L7_oop_opr;
141 LIR_Opr FrameMap::I0_oop_opr;
142 LIR_Opr FrameMap::I1_oop_opr;
143 LIR_Opr FrameMap::I2_oop_opr;
144 LIR_Opr FrameMap::I3_oop_opr;
145 LIR_Opr FrameMap::I4_oop_opr;
146 LIR_Opr FrameMap::I5_oop_opr;
147 LIR_Opr FrameMap::I6_oop_opr;
148 LIR_Opr FrameMap::I7_oop_opr;
150 LIR_Opr FrameMap::SP_opr;
151 LIR_Opr FrameMap::FP_opr;
153 LIR_Opr FrameMap::Oexception_opr;
154 LIR_Opr FrameMap::Oissuing_pc_opr;
156 LIR_Opr FrameMap::_caller_save_cpu_regs[] = { 0, };
157 LIR_Opr FrameMap::_caller_save_fpu_regs[] = { 0, };
160 FloatRegister FrameMap::nr2floatreg (int rnr) {
161 assert(_init_done, "tables not initialized");
162 debug_only(fpu_range_check(rnr);)
163 return _fpu_regs[rnr];
164 }
167 // returns true if reg could be smashed by a callee.
168 bool FrameMap::is_caller_save_register (LIR_Opr reg) {
169 if (reg->is_single_fpu() || reg->is_double_fpu()) { return true; }
170 if (reg->is_double_cpu()) {
171 return is_caller_save_register(reg->as_register_lo()) ||
172 is_caller_save_register(reg->as_register_hi());
173 }
174 return is_caller_save_register(reg->as_register());
175 }
178 NEEDS_CLEANUP // once the new calling convention is enabled, we no
179 // longer need to treat I5, I4 and L0 specially
180 // Because the interpreter destroys caller's I5, I4 and L0,
181 // we must spill them before doing a Java call as we may land in
182 // interpreter.
183 bool FrameMap::is_caller_save_register (Register r) {
184 return (r->is_global() && (r != G0)) || r->is_out();
185 }
188 void FrameMap::initialize() {
189 assert(!_init_done, "once");
191 int i=0;
192 // Register usage:
193 // O6: sp
194 // I6: fp
195 // I7: return address
196 // G0: zero
197 // G2: thread
198 // G7: not available
199 // G6: not available
200 /* 0 */ map_register(i++, L0);
201 /* 1 */ map_register(i++, L1);
202 /* 2 */ map_register(i++, L2);
203 /* 3 */ map_register(i++, L3);
204 /* 4 */ map_register(i++, L4);
205 /* 5 */ map_register(i++, L5);
206 /* 6 */ map_register(i++, L6);
207 /* 7 */ map_register(i++, L7);
209 /* 8 */ map_register(i++, I0);
210 /* 9 */ map_register(i++, I1);
211 /* 10 */ map_register(i++, I2);
212 /* 11 */ map_register(i++, I3);
213 /* 12 */ map_register(i++, I4);
214 /* 13 */ map_register(i++, I5);
215 /* 14 */ map_register(i++, O0);
216 /* 15 */ map_register(i++, O1);
217 /* 16 */ map_register(i++, O2);
218 /* 17 */ map_register(i++, O3);
219 /* 18 */ map_register(i++, O4);
220 /* 19 */ map_register(i++, O5); // <- last register visible in RegAlloc (RegAlloc::nof+cpu_regs)
221 /* 20 */ map_register(i++, G1);
222 /* 21 */ map_register(i++, G3);
223 /* 22 */ map_register(i++, G4);
224 /* 23 */ map_register(i++, G5);
225 /* 24 */ map_register(i++, G0);
227 // the following registers are not normally available
228 /* 25 */ map_register(i++, O7);
229 /* 26 */ map_register(i++, G2);
230 /* 27 */ map_register(i++, O6);
231 /* 28 */ map_register(i++, I6);
232 /* 29 */ map_register(i++, I7);
233 /* 30 */ map_register(i++, G6);
234 /* 31 */ map_register(i++, G7);
235 assert(i == nof_cpu_regs, "number of CPU registers");
237 for (i = 0; i < nof_fpu_regs; i++) {
238 _fpu_regs[i] = as_FloatRegister(i);
239 }
241 _init_done = true;
243 in_long_opr = as_long_opr(I0);
244 out_long_opr = as_long_opr(O0);
245 g1_long_single_opr = as_long_single_opr(G1);
247 G0_opr = as_opr(G0);
248 G1_opr = as_opr(G1);
249 G2_opr = as_opr(G2);
250 G3_opr = as_opr(G3);
251 G4_opr = as_opr(G4);
252 G5_opr = as_opr(G5);
253 G6_opr = as_opr(G6);
254 G7_opr = as_opr(G7);
255 O0_opr = as_opr(O0);
256 O1_opr = as_opr(O1);
257 O2_opr = as_opr(O2);
258 O3_opr = as_opr(O3);
259 O4_opr = as_opr(O4);
260 O5_opr = as_opr(O5);
261 O6_opr = as_opr(O6);
262 O7_opr = as_opr(O7);
263 L0_opr = as_opr(L0);
264 L1_opr = as_opr(L1);
265 L2_opr = as_opr(L2);
266 L3_opr = as_opr(L3);
267 L4_opr = as_opr(L4);
268 L5_opr = as_opr(L5);
269 L6_opr = as_opr(L6);
270 L7_opr = as_opr(L7);
271 I0_opr = as_opr(I0);
272 I1_opr = as_opr(I1);
273 I2_opr = as_opr(I2);
274 I3_opr = as_opr(I3);
275 I4_opr = as_opr(I4);
276 I5_opr = as_opr(I5);
277 I6_opr = as_opr(I6);
278 I7_opr = as_opr(I7);
280 G0_oop_opr = as_oop_opr(G0);
281 G1_oop_opr = as_oop_opr(G1);
282 G2_oop_opr = as_oop_opr(G2);
283 G3_oop_opr = as_oop_opr(G3);
284 G4_oop_opr = as_oop_opr(G4);
285 G5_oop_opr = as_oop_opr(G5);
286 G6_oop_opr = as_oop_opr(G6);
287 G7_oop_opr = as_oop_opr(G7);
288 O0_oop_opr = as_oop_opr(O0);
289 O1_oop_opr = as_oop_opr(O1);
290 O2_oop_opr = as_oop_opr(O2);
291 O3_oop_opr = as_oop_opr(O3);
292 O4_oop_opr = as_oop_opr(O4);
293 O5_oop_opr = as_oop_opr(O5);
294 O6_oop_opr = as_oop_opr(O6);
295 O7_oop_opr = as_oop_opr(O7);
296 L0_oop_opr = as_oop_opr(L0);
297 L1_oop_opr = as_oop_opr(L1);
298 L2_oop_opr = as_oop_opr(L2);
299 L3_oop_opr = as_oop_opr(L3);
300 L4_oop_opr = as_oop_opr(L4);
301 L5_oop_opr = as_oop_opr(L5);
302 L6_oop_opr = as_oop_opr(L6);
303 L7_oop_opr = as_oop_opr(L7);
304 I0_oop_opr = as_oop_opr(I0);
305 I1_oop_opr = as_oop_opr(I1);
306 I2_oop_opr = as_oop_opr(I2);
307 I3_oop_opr = as_oop_opr(I3);
308 I4_oop_opr = as_oop_opr(I4);
309 I5_oop_opr = as_oop_opr(I5);
310 I6_oop_opr = as_oop_opr(I6);
311 I7_oop_opr = as_oop_opr(I7);
313 FP_opr = as_pointer_opr(FP);
314 SP_opr = as_pointer_opr(SP);
316 F0_opr = as_float_opr(F0);
317 F0_double_opr = as_double_opr(F0);
319 Oexception_opr = as_oop_opr(Oexception);
320 Oissuing_pc_opr = as_opr(Oissuing_pc);
322 _caller_save_cpu_regs[0] = FrameMap::O0_opr;
323 _caller_save_cpu_regs[1] = FrameMap::O1_opr;
324 _caller_save_cpu_regs[2] = FrameMap::O2_opr;
325 _caller_save_cpu_regs[3] = FrameMap::O3_opr;
326 _caller_save_cpu_regs[4] = FrameMap::O4_opr;
327 _caller_save_cpu_regs[5] = FrameMap::O5_opr;
328 _caller_save_cpu_regs[6] = FrameMap::G1_opr;
329 _caller_save_cpu_regs[7] = FrameMap::G3_opr;
330 _caller_save_cpu_regs[8] = FrameMap::G4_opr;
331 _caller_save_cpu_regs[9] = FrameMap::G5_opr;
332 for (int i = 0; i < nof_caller_save_fpu_regs; i++) {
333 _caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i);
334 }
335 }
338 Address FrameMap::make_new_address(ByteSize sp_offset) const {
339 return Address(SP, STACK_BIAS + in_bytes(sp_offset));
340 }
343 VMReg FrameMap::fpu_regname (int n) {
344 return as_FloatRegister(n)->as_VMReg();
345 }
348 LIR_Opr FrameMap::stack_pointer() {
349 return SP_opr;
350 }
353 // JSR 292
354 LIR_Opr FrameMap::method_handle_invoke_SP_save_opr() {
355 assert(L7 == L7_mh_SP_save, "must be same register");
356 return L7_opr;
357 }
360 bool FrameMap::validate_frame() {
361 int max_offset = in_bytes(framesize_in_bytes());
362 int java_index = 0;
363 for (int i = 0; i < _incoming_arguments->length(); i++) {
364 LIR_Opr opr = _incoming_arguments->at(i);
365 if (opr->is_stack()) {
366 max_offset = MAX2(_argument_locations->at(java_index), max_offset);
367 }
368 java_index += type2size[opr->type()];
369 }
370 return Assembler::is_simm13(max_offset + STACK_BIAS);
371 }