Mercurial > hg > graal-compiler
annotate src/cpu/sparc/vm/c1_Runtime1_sparc.cpp @ 6812:988bf00cc564
7200261: G1: Liveness counting inconsistencies during marking verification
Summary: The clipping code in the routine that sets the bits for a range of cards, in the liveness accounting verification code was incorrect. It set all the bits in the card bitmap from the given starting index which would lead to spurious marking verification failures.
Reviewed-by: brutisso, jwilhelm, jmasa
author | johnc |
---|---|
date | Thu, 27 Sep 2012 15:44:01 -0700 |
parents | da91efe96a93 |
children | db9981fd3124 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1295
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1295
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1295
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "c1/c1_Defs.hpp" | |
27 #include "c1/c1_MacroAssembler.hpp" | |
28 #include "c1/c1_Runtime1.hpp" | |
29 #include "interpreter/interpreter.hpp" | |
30 #include "nativeInst_sparc.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
31 #include "oops/compiledICHolder.hpp" |
1972 | 32 #include "oops/oop.inline.hpp" |
33 #include "prims/jvmtiExport.hpp" | |
34 #include "register_sparc.hpp" | |
35 #include "runtime/sharedRuntime.hpp" | |
36 #include "runtime/signature.hpp" | |
37 #include "runtime/vframeArray.hpp" | |
38 #include "vmreg_sparc.inline.hpp" | |
0 | 39 |
40 // Implementation of StubAssembler | |
41 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
42 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry_point, int number_of_arguments) { |
0 | 43 // for sparc changing the number of arguments doesn't change |
44 // anything about the frame size so we'll always lie and claim that | |
45 // we are only passing 1 argument. | |
46 set_num_rt_args(1); | |
47 | |
48 assert_not_delayed(); | |
49 // bang stack before going to runtime | |
50 set(-os::vm_page_size() + STACK_BIAS, G3_scratch); | |
51 st(G0, SP, G3_scratch); | |
52 | |
53 // debugging support | |
54 assert(number_of_arguments >= 0 , "cannot have negative number of arguments"); | |
55 | |
56 set_last_Java_frame(SP, noreg); | |
57 if (VerifyThread) mov(G2_thread, O0); // about to be smashed; pass early | |
58 save_thread(L7_thread_cache); | |
59 // do the call | |
60 call(entry_point, relocInfo::runtime_call_type); | |
61 if (!VerifyThread) { | |
62 delayed()->mov(G2_thread, O0); // pass thread as first argument | |
63 } else { | |
64 delayed()->nop(); // (thread already passed) | |
65 } | |
66 int call_offset = offset(); // offset of return address | |
67 restore_thread(L7_thread_cache); | |
68 reset_last_Java_frame(); | |
69 | |
70 // check for pending exceptions | |
71 { Label L; | |
727 | 72 Address exception_addr(G2_thread, Thread::pending_exception_offset()); |
0 | 73 ld_ptr(exception_addr, Gtemp); |
3839 | 74 br_null_short(Gtemp, pt, L); |
727 | 75 Address vm_result_addr(G2_thread, JavaThread::vm_result_offset()); |
0 | 76 st_ptr(G0, vm_result_addr); |
727 | 77 Address vm_result_addr_2(G2_thread, JavaThread::vm_result_2_offset()); |
0 | 78 st_ptr(G0, vm_result_addr_2); |
79 | |
80 if (frame_size() == no_frame_size) { | |
81 // we use O7 linkage so that forward_exception_entry has the issuing PC | |
82 call(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type); | |
83 delayed()->restore(); | |
84 } else if (_stub_id == Runtime1::forward_exception_id) { | |
85 should_not_reach_here(); | |
86 } else { | |
727 | 87 AddressLiteral exc(Runtime1::entry_for(Runtime1::forward_exception_id)); |
88 jump_to(exc, G4); | |
0 | 89 delayed()->nop(); |
90 } | |
91 bind(L); | |
92 } | |
93 | |
94 // get oop result if there is one and reset the value in the thread | |
95 if (oop_result1->is_valid()) { // get oop result if there is one and reset it in the thread | |
96 get_vm_result (oop_result1); | |
97 } else { | |
98 // be a little paranoid and clear the result | |
727 | 99 Address vm_result_addr(G2_thread, JavaThread::vm_result_offset()); |
0 | 100 st_ptr(G0, vm_result_addr); |
101 } | |
102 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
103 // get second result if there is one and reset the value in the thread |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
104 if (metadata_result->is_valid()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
105 get_vm_result_2 (metadata_result); |
0 | 106 } else { |
107 // be a little paranoid and clear the result | |
727 | 108 Address vm_result_addr_2(G2_thread, JavaThread::vm_result_2_offset()); |
0 | 109 st_ptr(G0, vm_result_addr_2); |
110 } | |
111 | |
112 return call_offset; | |
113 } | |
114 | |
115 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
116 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1) { |
0 | 117 // O0 is reserved for the thread |
118 mov(arg1, O1); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
119 return call_RT(oop_result1, metadata_result, entry, 1); |
0 | 120 } |
121 | |
122 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
123 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2) { |
0 | 124 // O0 is reserved for the thread |
125 mov(arg1, O1); | |
126 mov(arg2, O2); assert(arg2 != O1, "smashed argument"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
127 return call_RT(oop_result1, metadata_result, entry, 2); |
0 | 128 } |
129 | |
130 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
131 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2, Register arg3) { |
0 | 132 // O0 is reserved for the thread |
133 mov(arg1, O1); | |
134 mov(arg2, O2); assert(arg2 != O1, "smashed argument"); | |
135 mov(arg3, O3); assert(arg3 != O1 && arg3 != O2, "smashed argument"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
136 return call_RT(oop_result1, metadata_result, entry, 3); |
0 | 137 } |
138 | |
139 | |
140 // Implementation of Runtime1 | |
141 | |
142 #define __ sasm-> | |
143 | |
144 static int cpu_reg_save_offsets[FrameMap::nof_cpu_regs]; | |
145 static int fpu_reg_save_offsets[FrameMap::nof_fpu_regs]; | |
146 static int reg_save_size_in_words; | |
147 static int frame_size_in_bytes = -1; | |
148 | |
149 static OopMap* generate_oop_map(StubAssembler* sasm, bool save_fpu_registers) { | |
150 assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words), | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
151 "mismatch in calculation"); |
0 | 152 sasm->set_frame_size(frame_size_in_bytes / BytesPerWord); |
153 int frame_size_in_slots = frame_size_in_bytes / sizeof(jint); | |
154 OopMap* oop_map = new OopMap(frame_size_in_slots, 0); | |
155 | |
156 int i; | |
157 for (i = 0; i < FrameMap::nof_cpu_regs; i++) { | |
158 Register r = as_Register(i); | |
159 if (r == G1 || r == G3 || r == G4 || r == G5) { | |
160 int sp_offset = cpu_reg_save_offsets[i]; | |
161 oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset), | |
162 r->as_VMReg()); | |
163 } | |
164 } | |
165 | |
166 if (save_fpu_registers) { | |
167 for (i = 0; i < FrameMap::nof_fpu_regs; i++) { | |
168 FloatRegister r = as_FloatRegister(i); | |
169 int sp_offset = fpu_reg_save_offsets[i]; | |
170 oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset), | |
171 r->as_VMReg()); | |
172 } | |
173 } | |
174 return oop_map; | |
175 } | |
176 | |
177 static OopMap* save_live_registers(StubAssembler* sasm, bool save_fpu_registers = true) { | |
178 assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words), | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
179 "mismatch in calculation"); |
0 | 180 __ save_frame_c1(frame_size_in_bytes); |
181 | |
182 // Record volatile registers as callee-save values in an OopMap so their save locations will be | |
183 // propagated to the caller frame's RegisterMap during StackFrameStream construction (needed for | |
184 // deoptimization; see compiledVFrame::create_stack_value). The caller's I, L and O registers | |
185 // are saved in register windows - I's and L's in the caller's frame and O's in the stub frame | |
186 // (as the stub's I's) when the runtime routine called by the stub creates its frame. | |
187 // OopMap frame sizes are in c2 stack slot sizes (sizeof(jint)) | |
188 | |
189 int i; | |
190 for (i = 0; i < FrameMap::nof_cpu_regs; i++) { | |
191 Register r = as_Register(i); | |
192 if (r == G1 || r == G3 || r == G4 || r == G5) { | |
193 int sp_offset = cpu_reg_save_offsets[i]; | |
194 __ st_ptr(r, SP, (sp_offset * BytesPerWord) + STACK_BIAS); | |
195 } | |
196 } | |
197 | |
198 if (save_fpu_registers) { | |
199 for (i = 0; i < FrameMap::nof_fpu_regs; i++) { | |
200 FloatRegister r = as_FloatRegister(i); | |
201 int sp_offset = fpu_reg_save_offsets[i]; | |
202 __ stf(FloatRegisterImpl::S, r, SP, (sp_offset * BytesPerWord) + STACK_BIAS); | |
203 } | |
204 } | |
205 | |
206 return generate_oop_map(sasm, save_fpu_registers); | |
207 } | |
208 | |
209 static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true) { | |
210 for (int i = 0; i < FrameMap::nof_cpu_regs; i++) { | |
211 Register r = as_Register(i); | |
212 if (r == G1 || r == G3 || r == G4 || r == G5) { | |
213 __ ld_ptr(SP, (cpu_reg_save_offsets[i] * BytesPerWord) + STACK_BIAS, r); | |
214 } | |
215 } | |
216 | |
217 if (restore_fpu_registers) { | |
218 for (int i = 0; i < FrameMap::nof_fpu_regs; i++) { | |
219 FloatRegister r = as_FloatRegister(i); | |
220 __ ldf(FloatRegisterImpl::S, SP, (fpu_reg_save_offsets[i] * BytesPerWord) + STACK_BIAS, r); | |
221 } | |
222 } | |
223 } | |
224 | |
225 | |
226 void Runtime1::initialize_pd() { | |
227 // compute word offsets from SP at which live (non-windowed) registers are captured by stub routines | |
228 // | |
229 // A stub routine will have a frame that is at least large enough to hold | |
230 // a register window save area (obviously) and the volatile g registers | |
231 // and floating registers. A user of save_live_registers can have a frame | |
232 // that has more scratch area in it (although typically they will use L-regs). | |
233 // in that case the frame will look like this (stack growing down) | |
234 // | |
235 // FP -> | | | |
236 // | scratch mem | | |
237 // | " " | | |
238 // -------------- | |
239 // | float regs | | |
240 // | " " | | |
241 // --------------- | |
242 // | G regs | | |
243 // | " " | | |
244 // --------------- | |
245 // | abi reg. | | |
246 // | window save | | |
247 // | area | | |
248 // SP -> --------------- | |
249 // | |
250 int i; | |
251 int sp_offset = round_to(frame::register_save_words, 2); // start doubleword aligned | |
252 | |
253 // only G int registers are saved explicitly; others are found in register windows | |
254 for (i = 0; i < FrameMap::nof_cpu_regs; i++) { | |
255 Register r = as_Register(i); | |
256 if (r == G1 || r == G3 || r == G4 || r == G5) { | |
257 cpu_reg_save_offsets[i] = sp_offset; | |
258 sp_offset++; | |
259 } | |
260 } | |
261 | |
262 // all float registers are saved explicitly | |
263 assert(FrameMap::nof_fpu_regs == 32, "double registers not handled here"); | |
264 for (i = 0; i < FrameMap::nof_fpu_regs; i++) { | |
265 fpu_reg_save_offsets[i] = sp_offset; | |
266 sp_offset++; | |
267 } | |
268 reg_save_size_in_words = sp_offset - frame::memory_parameter_word_sp_offset; | |
269 // this should match assembler::total_frame_size_in_bytes, which | |
270 // isn't callable from this context. It's checked by an assert when | |
271 // it's used though. | |
272 frame_size_in_bytes = align_size_up(sp_offset * wordSize, 8); | |
273 } | |
274 | |
275 | |
276 OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address target, bool has_argument) { | |
277 // make a frame and preserve the caller's caller-save registers | |
278 OopMap* oop_map = save_live_registers(sasm); | |
279 int call_offset; | |
280 if (!has_argument) { | |
281 call_offset = __ call_RT(noreg, noreg, target); | |
282 } else { | |
283 call_offset = __ call_RT(noreg, noreg, target, G4); | |
284 } | |
285 OopMapSet* oop_maps = new OopMapSet(); | |
286 oop_maps->add_gc_map(call_offset, oop_map); | |
287 | |
288 __ should_not_reach_here(); | |
289 return oop_maps; | |
290 } | |
291 | |
292 | |
293 OopMapSet* Runtime1::generate_stub_call(StubAssembler* sasm, Register result, address target, | |
294 Register arg1, Register arg2, Register arg3) { | |
295 // make a frame and preserve the caller's caller-save registers | |
296 OopMap* oop_map = save_live_registers(sasm); | |
297 | |
298 int call_offset; | |
299 if (arg1 == noreg) { | |
300 call_offset = __ call_RT(result, noreg, target); | |
301 } else if (arg2 == noreg) { | |
302 call_offset = __ call_RT(result, noreg, target, arg1); | |
303 } else if (arg3 == noreg) { | |
304 call_offset = __ call_RT(result, noreg, target, arg1, arg2); | |
305 } else { | |
306 call_offset = __ call_RT(result, noreg, target, arg1, arg2, arg3); | |
307 } | |
308 OopMapSet* oop_maps = NULL; | |
309 | |
310 oop_maps = new OopMapSet(); | |
311 oop_maps->add_gc_map(call_offset, oop_map); | |
312 restore_live_registers(sasm); | |
313 | |
314 __ ret(); | |
315 __ delayed()->restore(); | |
316 | |
317 return oop_maps; | |
318 } | |
319 | |
320 | |
321 OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { | |
322 // make a frame and preserve the caller's caller-save registers | |
323 OopMap* oop_map = save_live_registers(sasm); | |
324 | |
325 // call the runtime patching routine, returns non-zero if nmethod got deopted. | |
326 int call_offset = __ call_RT(noreg, noreg, target); | |
327 OopMapSet* oop_maps = new OopMapSet(); | |
328 oop_maps->add_gc_map(call_offset, oop_map); | |
329 | |
330 // re-execute the patched instruction or, if the nmethod was deoptmized, return to the | |
331 // deoptimization handler entry that will cause re-execution of the current bytecode | |
332 DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob(); | |
333 assert(deopt_blob != NULL, "deoptimization blob must have been created"); | |
334 | |
335 Label no_deopt; | |
3839 | 336 __ br_null_short(O0, Assembler::pt, no_deopt); |
0 | 337 |
338 // return to the deoptimization handler entry for unpacking and rexecute | |
339 // if we simply returned the we'd deopt as if any call we patched had just | |
340 // returned. | |
341 | |
342 restore_live_registers(sasm); | |
2156
85330eaa15ee
7013812: C1: deopt blob too far from patching stub
iveresov
parents:
2127
diff
changeset
|
343 |
85330eaa15ee
7013812: C1: deopt blob too far from patching stub
iveresov
parents:
2127
diff
changeset
|
344 AddressLiteral dest(deopt_blob->unpack_with_reexecution()); |
85330eaa15ee
7013812: C1: deopt blob too far from patching stub
iveresov
parents:
2127
diff
changeset
|
345 __ jump_to(dest, O0); |
85330eaa15ee
7013812: C1: deopt blob too far from patching stub
iveresov
parents:
2127
diff
changeset
|
346 __ delayed()->restore(); |
0 | 347 |
348 __ bind(no_deopt); | |
349 restore_live_registers(sasm); | |
350 __ ret(); | |
351 __ delayed()->restore(); | |
352 | |
353 return oop_maps; | |
354 } | |
355 | |
356 OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { | |
357 | |
358 OopMapSet* oop_maps = NULL; | |
359 // for better readability | |
360 const bool must_gc_arguments = true; | |
361 const bool dont_gc_arguments = false; | |
362 | |
363 // stub code & info for the different stubs | |
364 switch (id) { | |
365 case forward_exception_id: | |
366 { | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
367 oop_maps = generate_handle_exception(id, sasm); |
0 | 368 } |
369 break; | |
370 | |
371 case new_instance_id: | |
372 case fast_new_instance_id: | |
373 case fast_new_instance_init_check_id: | |
374 { | |
375 Register G5_klass = G5; // Incoming | |
376 Register O0_obj = O0; // Outgoing | |
377 | |
378 if (id == new_instance_id) { | |
379 __ set_info("new_instance", dont_gc_arguments); | |
380 } else if (id == fast_new_instance_id) { | |
381 __ set_info("fast new_instance", dont_gc_arguments); | |
382 } else { | |
383 assert(id == fast_new_instance_init_check_id, "bad StubID"); | |
384 __ set_info("fast new_instance init check", dont_gc_arguments); | |
385 } | |
386 | |
387 if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) && | |
388 UseTLAB && FastTLABRefill) { | |
389 Label slow_path; | |
390 Register G1_obj_size = G1; | |
391 Register G3_t1 = G3; | |
392 Register G4_t2 = G4; | |
393 assert_different_registers(G5_klass, G1_obj_size, G3_t1, G4_t2); | |
394 | |
395 // Push a frame since we may do dtrace notification for the | |
396 // allocation which requires calling out and we don't want | |
397 // to stomp the real return address. | |
398 __ save_frame(0); | |
399 | |
400 if (id == fast_new_instance_init_check_id) { | |
401 // make sure the klass is initialized | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
402 __ ldub(G5_klass, in_bytes(InstanceKlass::init_state_offset()), G3_t1); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
403 __ cmp_and_br_short(G3_t1, InstanceKlass::fully_initialized, Assembler::notEqual, Assembler::pn, slow_path); |
0 | 404 } |
405 #ifdef ASSERT | |
406 // assert object can be fast path allocated | |
407 { | |
408 Label ok, not_ok; | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4048
diff
changeset
|
409 __ ld(G5_klass, in_bytes(Klass::layout_helper_offset()), G1_obj_size); |
3839 | 410 // make sure it's an instance (LH > 0) |
411 __ cmp_and_br_short(G1_obj_size, 0, Assembler::lessEqual, Assembler::pn, not_ok); | |
0 | 412 __ btst(Klass::_lh_instance_slow_path_bit, G1_obj_size); |
413 __ br(Assembler::zero, false, Assembler::pn, ok); | |
414 __ delayed()->nop(); | |
415 __ bind(not_ok); | |
416 __ stop("assert(can be fast path allocated)"); | |
417 __ should_not_reach_here(); | |
418 __ bind(ok); | |
419 } | |
420 #endif // ASSERT | |
421 // if we got here then the TLAB allocation failed, so try | |
422 // refilling the TLAB or allocating directly from eden. | |
423 Label retry_tlab, try_eden; | |
424 __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G5_klass | |
425 | |
426 __ bind(retry_tlab); | |
427 | |
428 // get the instance size | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4048
diff
changeset
|
429 __ ld(G5_klass, in_bytes(Klass::layout_helper_offset()), G1_obj_size); |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
430 |
0 | 431 __ tlab_allocate(O0_obj, G1_obj_size, 0, G3_t1, slow_path); |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
432 |
0 | 433 __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2); |
434 __ verify_oop(O0_obj); | |
435 __ mov(O0, I0); | |
436 __ ret(); | |
437 __ delayed()->restore(); | |
438 | |
439 __ bind(try_eden); | |
440 // get the instance size | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4048
diff
changeset
|
441 __ ld(G5_klass, in_bytes(Klass::layout_helper_offset()), G1_obj_size); |
0 | 442 __ eden_allocate(O0_obj, G1_obj_size, 0, G3_t1, G4_t2, slow_path); |
2127
5577848f5923
7011463: Sparc MacroAssembler::incr_allocated_bytes() needs a RegisterOrConstant argument
phh
parents:
2100
diff
changeset
|
443 __ incr_allocated_bytes(G1_obj_size, G3_t1, G4_t2); |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
444 |
0 | 445 __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2); |
446 __ verify_oop(O0_obj); | |
447 __ mov(O0, I0); | |
448 __ ret(); | |
449 __ delayed()->restore(); | |
450 | |
451 __ bind(slow_path); | |
452 | |
453 // pop this frame so generate_stub_call can push it's own | |
454 __ restore(); | |
455 } | |
456 | |
457 oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_instance), G5_klass); | |
458 // I0->O0: new instance | |
459 } | |
460 | |
461 break; | |
462 | |
463 case counter_overflow_id: | |
1783 | 464 // G4 contains bci, G5 contains method |
465 oop_maps = generate_stub_call(sasm, noreg, CAST_FROM_FN_PTR(address, counter_overflow), G4, G5); | |
0 | 466 break; |
467 | |
468 case new_type_array_id: | |
469 case new_object_array_id: | |
470 { | |
471 Register G5_klass = G5; // Incoming | |
472 Register G4_length = G4; // Incoming | |
473 Register O0_obj = O0; // Outgoing | |
474 | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4048
diff
changeset
|
475 Address klass_lh(G5_klass, Klass::layout_helper_offset()); |
0 | 476 assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise"); |
477 assert(Klass::_lh_header_size_mask == 0xFF, "bytewise"); | |
478 // Use this offset to pick out an individual byte of the layout_helper: | |
479 const int klass_lh_header_size_offset = ((BytesPerInt - 1) // 3 - 2 selects byte {0,1,0,0} | |
480 - Klass::_lh_header_size_shift / BitsPerByte); | |
481 | |
482 if (id == new_type_array_id) { | |
483 __ set_info("new_type_array", dont_gc_arguments); | |
484 } else { | |
485 __ set_info("new_object_array", dont_gc_arguments); | |
486 } | |
487 | |
488 #ifdef ASSERT | |
489 // assert object type is really an array of the proper kind | |
490 { | |
491 Label ok; | |
492 Register G3_t1 = G3; | |
493 __ ld(klass_lh, G3_t1); | |
494 __ sra(G3_t1, Klass::_lh_array_tag_shift, G3_t1); | |
495 int tag = ((id == new_type_array_id) | |
496 ? Klass::_lh_array_tag_type_value | |
497 : Klass::_lh_array_tag_obj_value); | |
3839 | 498 __ cmp_and_brx_short(G3_t1, tag, Assembler::equal, Assembler::pt, ok); |
0 | 499 __ stop("assert(is an array klass)"); |
500 __ should_not_reach_here(); | |
501 __ bind(ok); | |
502 } | |
503 #endif // ASSERT | |
504 | |
505 if (UseTLAB && FastTLABRefill) { | |
506 Label slow_path; | |
507 Register G1_arr_size = G1; | |
508 Register G3_t1 = G3; | |
509 Register O1_t2 = O1; | |
510 assert_different_registers(G5_klass, G4_length, G1_arr_size, G3_t1, O1_t2); | |
511 | |
512 // check that array length is small enough for fast path | |
513 __ set(C1_MacroAssembler::max_array_allocation_length, G3_t1); | |
3839 | 514 __ cmp_and_br_short(G4_length, G3_t1, Assembler::greaterUnsigned, Assembler::pn, slow_path); |
0 | 515 |
516 // if we got here then the TLAB allocation failed, so try | |
517 // refilling the TLAB or allocating directly from eden. | |
518 Label retry_tlab, try_eden; | |
519 __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G4_length and G5_klass | |
520 | |
521 __ bind(retry_tlab); | |
522 | |
523 // get the allocation size: (length << (layout_helper & 0x1F)) + header_size | |
524 __ ld(klass_lh, G3_t1); | |
525 __ sll(G4_length, G3_t1, G1_arr_size); | |
526 __ srl(G3_t1, Klass::_lh_header_size_shift, G3_t1); | |
527 __ and3(G3_t1, Klass::_lh_header_size_mask, G3_t1); | |
528 __ add(G1_arr_size, G3_t1, G1_arr_size); | |
529 __ add(G1_arr_size, MinObjAlignmentInBytesMask, G1_arr_size); // align up | |
530 __ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size); | |
531 | |
532 __ tlab_allocate(O0_obj, G1_arr_size, 0, G3_t1, slow_path); // preserves G1_arr_size | |
533 | |
534 __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2); | |
535 __ ldub(klass_lh, G3_t1, klass_lh_header_size_offset); | |
536 __ sub(G1_arr_size, G3_t1, O1_t2); // body length | |
537 __ add(O0_obj, G3_t1, G3_t1); // body start | |
538 __ initialize_body(G3_t1, O1_t2); | |
539 __ verify_oop(O0_obj); | |
540 __ retl(); | |
541 __ delayed()->nop(); | |
542 | |
543 __ bind(try_eden); | |
544 // get the allocation size: (length << (layout_helper & 0x1F)) + header_size | |
545 __ ld(klass_lh, G3_t1); | |
546 __ sll(G4_length, G3_t1, G1_arr_size); | |
547 __ srl(G3_t1, Klass::_lh_header_size_shift, G3_t1); | |
548 __ and3(G3_t1, Klass::_lh_header_size_mask, G3_t1); | |
549 __ add(G1_arr_size, G3_t1, G1_arr_size); | |
550 __ add(G1_arr_size, MinObjAlignmentInBytesMask, G1_arr_size); | |
551 __ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size); | |
552 | |
553 __ eden_allocate(O0_obj, G1_arr_size, 0, G3_t1, O1_t2, slow_path); // preserves G1_arr_size | |
2127
5577848f5923
7011463: Sparc MacroAssembler::incr_allocated_bytes() needs a RegisterOrConstant argument
phh
parents:
2100
diff
changeset
|
554 __ incr_allocated_bytes(G1_arr_size, G3_t1, O1_t2); |
0 | 555 |
556 __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2); | |
557 __ ldub(klass_lh, G3_t1, klass_lh_header_size_offset); | |
558 __ sub(G1_arr_size, G3_t1, O1_t2); // body length | |
559 __ add(O0_obj, G3_t1, G3_t1); // body start | |
560 __ initialize_body(G3_t1, O1_t2); | |
561 __ verify_oop(O0_obj); | |
562 __ retl(); | |
563 __ delayed()->nop(); | |
564 | |
565 __ bind(slow_path); | |
566 } | |
567 | |
568 if (id == new_type_array_id) { | |
569 oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_type_array), G5_klass, G4_length); | |
570 } else { | |
571 oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_object_array), G5_klass, G4_length); | |
572 } | |
573 // I0 -> O0: new array | |
574 } | |
575 break; | |
576 | |
577 case new_multi_array_id: | |
578 { // O0: klass | |
579 // O1: rank | |
580 // O2: address of 1st dimension | |
581 __ set_info("new_multi_array", dont_gc_arguments); | |
582 oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_multi_array), I0, I1, I2); | |
583 // I0 -> O0: new multi array | |
584 } | |
585 break; | |
586 | |
587 case register_finalizer_id: | |
588 { | |
589 __ set_info("register_finalizer", dont_gc_arguments); | |
590 | |
591 // load the klass and check the has finalizer flag | |
592 Label register_finalizer; | |
593 Register t = O1; | |
2002 | 594 __ load_klass(O0, t); |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4048
diff
changeset
|
595 __ ld(t, in_bytes(Klass::access_flags_offset()), t); |
0 | 596 __ set(JVM_ACC_HAS_FINALIZER, G3); |
597 __ andcc(G3, t, G0); | |
598 __ br(Assembler::notZero, false, Assembler::pt, register_finalizer); | |
599 __ delayed()->nop(); | |
600 | |
601 // do a leaf return | |
602 __ retl(); | |
603 __ delayed()->nop(); | |
604 | |
605 __ bind(register_finalizer); | |
606 OopMap* oop_map = save_live_registers(sasm); | |
607 int call_offset = __ call_RT(noreg, noreg, | |
608 CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), I0); | |
609 oop_maps = new OopMapSet(); | |
610 oop_maps->add_gc_map(call_offset, oop_map); | |
611 | |
612 // Now restore all the live registers | |
613 restore_live_registers(sasm); | |
614 | |
615 __ ret(); | |
616 __ delayed()->restore(); | |
617 } | |
618 break; | |
619 | |
620 case throw_range_check_failed_id: | |
621 { __ set_info("range_check_failed", dont_gc_arguments); // arguments will be discarded | |
622 // G4: index | |
623 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_range_check_exception), true); | |
624 } | |
625 break; | |
626 | |
627 case throw_index_exception_id: | |
628 { __ set_info("index_range_check_failed", dont_gc_arguments); // arguments will be discarded | |
629 // G4: index | |
630 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_index_exception), true); | |
631 } | |
632 break; | |
633 | |
634 case throw_div0_exception_id: | |
635 { __ set_info("throw_div0_exception", dont_gc_arguments); | |
636 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_div0_exception), false); | |
637 } | |
638 break; | |
639 | |
640 case throw_null_pointer_exception_id: | |
641 { __ set_info("throw_null_pointer_exception", dont_gc_arguments); | |
642 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false); | |
643 } | |
644 break; | |
645 | |
646 case handle_exception_id: | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
647 { __ set_info("handle_exception", dont_gc_arguments); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
648 oop_maps = generate_handle_exception(id, sasm); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
649 } |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
650 break; |
0 | 651 |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
652 case handle_exception_from_callee_id: |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
653 { __ set_info("handle_exception_from_callee", dont_gc_arguments); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
654 oop_maps = generate_handle_exception(id, sasm); |
0 | 655 } |
656 break; | |
657 | |
658 case unwind_exception_id: | |
659 { | |
660 // O0: exception | |
661 // I7: address of call to this method | |
662 | |
663 __ set_info("unwind_exception", dont_gc_arguments); | |
664 __ mov(Oexception, Oexception->after_save()); | |
665 __ add(I7, frame::pc_return_offset, Oissuing_pc->after_save()); | |
666 | |
667 __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), | |
1295 | 668 G2_thread, Oissuing_pc->after_save()); |
0 | 669 __ verify_not_null_oop(Oexception->after_save()); |
1564 | 670 |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
671 // Restore SP from L7 if the exception PC is a method handle call site. |
1564 | 672 __ mov(O0, G5); // Save the target address. |
673 __ lduw(Address(G2_thread, JavaThread::is_method_handle_return_offset()), L0); | |
674 __ tst(L0); // Condition codes are preserved over the restore. | |
675 __ restore(); | |
676 | |
677 __ jmp(G5, 0); | |
678 __ delayed()->movcc(Assembler::notZero, false, Assembler::icc, L7_mh_SP_save, SP); // Restore SP if required. | |
0 | 679 } |
680 break; | |
681 | |
682 case throw_array_store_exception_id: | |
683 { | |
684 __ set_info("throw_array_store_exception", dont_gc_arguments); | |
2168
e4fee0bdaa85
7008809: should report the class in ArrayStoreExceptions from compiled code
never
parents:
2127
diff
changeset
|
685 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true); |
0 | 686 } |
687 break; | |
688 | |
689 case throw_class_cast_exception_id: | |
690 { | |
691 // G4: object | |
692 __ set_info("throw_class_cast_exception", dont_gc_arguments); | |
693 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true); | |
694 } | |
695 break; | |
696 | |
697 case throw_incompatible_class_change_error_id: | |
698 { | |
699 __ set_info("throw_incompatible_class_cast_exception", dont_gc_arguments); | |
700 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false); | |
701 } | |
702 break; | |
703 | |
704 case slow_subtype_check_id: | |
705 { // Support for uint StubRoutine::partial_subtype_check( Klass sub, Klass super ); | |
706 // Arguments : | |
707 // | |
708 // ret : G3 | |
709 // sub : G3, argument, destroyed | |
710 // super: G1, argument, not changed | |
711 // raddr: O7, blown by call | |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
342
diff
changeset
|
712 Label miss; |
0 | 713 |
714 __ save_frame(0); // Blow no registers! | |
715 | |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
342
diff
changeset
|
716 __ check_klass_subtype_slow_path(G3, G1, L0, L1, L2, L4, NULL, &miss); |
0 | 717 |
718 __ mov(1, G3); | |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
342
diff
changeset
|
719 __ ret(); // Result in G5 is 'true' |
0 | 720 __ delayed()->restore(); // free copy or add can go here |
721 | |
722 __ bind(miss); | |
723 __ mov(0, G3); | |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
342
diff
changeset
|
724 __ ret(); // Result in G5 is 'false' |
0 | 725 __ delayed()->restore(); // free copy or add can go here |
726 } | |
727 | |
728 case monitorenter_nofpu_id: | |
729 case monitorenter_id: | |
730 { // G4: object | |
731 // G5: lock address | |
732 __ set_info("monitorenter", dont_gc_arguments); | |
733 | |
734 int save_fpu_registers = (id == monitorenter_id); | |
735 // make a frame and preserve the caller's caller-save registers | |
736 OopMap* oop_map = save_live_registers(sasm, save_fpu_registers); | |
737 | |
738 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorenter), G4, G5); | |
739 | |
740 oop_maps = new OopMapSet(); | |
741 oop_maps->add_gc_map(call_offset, oop_map); | |
742 restore_live_registers(sasm, save_fpu_registers); | |
743 | |
744 __ ret(); | |
745 __ delayed()->restore(); | |
746 } | |
747 break; | |
748 | |
749 case monitorexit_nofpu_id: | |
750 case monitorexit_id: | |
751 { // G4: lock address | |
752 // note: really a leaf routine but must setup last java sp | |
753 // => use call_RT for now (speed can be improved by | |
754 // doing last java sp setup manually) | |
755 __ set_info("monitorexit", dont_gc_arguments); | |
756 | |
757 int save_fpu_registers = (id == monitorexit_id); | |
758 // make a frame and preserve the caller's caller-save registers | |
759 OopMap* oop_map = save_live_registers(sasm, save_fpu_registers); | |
760 | |
761 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorexit), G4); | |
762 | |
763 oop_maps = new OopMapSet(); | |
764 oop_maps->add_gc_map(call_offset, oop_map); | |
765 restore_live_registers(sasm, save_fpu_registers); | |
766 | |
767 __ ret(); | |
768 __ delayed()->restore(); | |
4048
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3910
diff
changeset
|
769 } |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3910
diff
changeset
|
770 break; |
0 | 771 |
4048
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3910
diff
changeset
|
772 case deoptimize_id: |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3910
diff
changeset
|
773 { |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3910
diff
changeset
|
774 __ set_info("deoptimize", dont_gc_arguments); |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3910
diff
changeset
|
775 OopMap* oop_map = save_live_registers(sasm); |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3910
diff
changeset
|
776 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize)); |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3910
diff
changeset
|
777 oop_maps = new OopMapSet(); |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3910
diff
changeset
|
778 oop_maps->add_gc_map(call_offset, oop_map); |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3910
diff
changeset
|
779 restore_live_registers(sasm); |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3910
diff
changeset
|
780 DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob(); |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3910
diff
changeset
|
781 assert(deopt_blob != NULL, "deoptimization blob must have been created"); |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3910
diff
changeset
|
782 AddressLiteral dest(deopt_blob->unpack_with_reexecution()); |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3910
diff
changeset
|
783 __ jump_to(dest, O0); |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3910
diff
changeset
|
784 __ delayed()->restore(); |
0 | 785 } |
786 break; | |
787 | |
788 case access_field_patching_id: | |
789 { __ set_info("access_field_patching", dont_gc_arguments); | |
790 oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, access_field_patching)); | |
791 } | |
792 break; | |
793 | |
794 case load_klass_patching_id: | |
795 { __ set_info("load_klass_patching", dont_gc_arguments); | |
796 oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_klass_patching)); | |
797 } | |
798 break; | |
799 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
800 case load_mirror_patching_id: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
801 { __ set_info("load_mirror_patching", dont_gc_arguments); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
802 oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_mirror_patching)); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
803 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
804 break; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4771
diff
changeset
|
805 |
0 | 806 case dtrace_object_alloc_id: |
807 { // O0: object | |
808 __ set_info("dtrace_object_alloc", dont_gc_arguments); | |
809 // we can't gc here so skip the oopmap but make sure that all | |
810 // the live registers get saved. | |
811 save_live_registers(sasm); | |
812 | |
813 __ save_thread(L7_thread_cache); | |
814 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc), | |
815 relocInfo::runtime_call_type); | |
816 __ delayed()->mov(I0, O0); | |
817 __ restore_thread(L7_thread_cache); | |
818 | |
819 restore_live_registers(sasm); | |
820 __ ret(); | |
821 __ delayed()->restore(); | |
822 } | |
823 break; | |
824 | |
342 | 825 #ifndef SERIALGC |
826 case g1_pre_barrier_slow_id: | |
827 { // G4: previous value of memory | |
828 BarrierSet* bs = Universe::heap()->barrier_set(); | |
829 if (bs->kind() != BarrierSet::G1SATBCTLogging) { | |
830 __ save_frame(0); | |
831 __ set((int)id, O1); | |
832 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), I0); | |
833 __ should_not_reach_here(); | |
834 break; | |
835 } | |
836 | |
837 __ set_info("g1_pre_barrier_slow_id", dont_gc_arguments); | |
838 | |
839 Register pre_val = G4; | |
840 Register tmp = G1_scratch; | |
841 Register tmp2 = G3_scratch; | |
842 | |
843 Label refill, restart; | |
844 bool with_frame = false; // I don't know if we can do with-frame. | |
845 int satb_q_index_byte_offset = | |
846 in_bytes(JavaThread::satb_mark_queue_offset() + | |
847 PtrQueue::byte_offset_of_index()); | |
848 int satb_q_buf_byte_offset = | |
849 in_bytes(JavaThread::satb_mark_queue_offset() + | |
850 PtrQueue::byte_offset_of_buf()); | |
3888
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
851 |
342 | 852 __ bind(restart); |
3888
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
853 // Load the index into the SATB buffer. PtrQueue::_index is a |
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
854 // size_t so ld_ptr is appropriate |
342 | 855 __ ld_ptr(G2_thread, satb_q_index_byte_offset, tmp); |
856 | |
3888
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
857 // index == 0? |
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
858 __ cmp_and_brx_short(tmp, G0, Assembler::equal, Assembler::pn, refill); |
342 | 859 |
3888
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
860 __ ld_ptr(G2_thread, satb_q_buf_byte_offset, tmp2); |
342 | 861 __ sub(tmp, oopSize, tmp); |
862 | |
863 __ st_ptr(pre_val, tmp2, tmp); // [_buf + index] := <address_of_card> | |
864 // Use return-from-leaf | |
865 __ retl(); | |
866 __ delayed()->st_ptr(tmp, G2_thread, satb_q_index_byte_offset); | |
867 | |
868 __ bind(refill); | |
869 __ save_frame(0); | |
870 | |
871 __ mov(pre_val, L0); | |
872 __ mov(tmp, L1); | |
873 __ mov(tmp2, L2); | |
874 | |
875 __ call_VM_leaf(L7_thread_cache, | |
876 CAST_FROM_FN_PTR(address, | |
877 SATBMarkQueueSet::handle_zero_index_for_thread), | |
878 G2_thread); | |
879 | |
880 __ mov(L0, pre_val); | |
881 __ mov(L1, tmp); | |
882 __ mov(L2, tmp2); | |
883 | |
884 __ br(Assembler::always, /*annul*/false, Assembler::pt, restart); | |
885 __ delayed()->restore(); | |
886 } | |
887 break; | |
888 | |
889 case g1_post_barrier_slow_id: | |
890 { | |
891 BarrierSet* bs = Universe::heap()->barrier_set(); | |
892 if (bs->kind() != BarrierSet::G1SATBCTLogging) { | |
893 __ save_frame(0); | |
894 __ set((int)id, O1); | |
895 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), I0); | |
896 __ should_not_reach_here(); | |
897 break; | |
898 } | |
899 | |
900 __ set_info("g1_post_barrier_slow_id", dont_gc_arguments); | |
901 | |
902 Register addr = G4; | |
903 Register cardtable = G5; | |
904 Register tmp = G1_scratch; | |
905 Register tmp2 = G3_scratch; | |
906 jbyte* byte_map_base = ((CardTableModRefBS*)bs)->byte_map_base; | |
907 | |
908 Label not_already_dirty, restart, refill; | |
909 | |
910 #ifdef _LP64 | |
911 __ srlx(addr, CardTableModRefBS::card_shift, addr); | |
912 #else | |
913 __ srl(addr, CardTableModRefBS::card_shift, addr); | |
914 #endif | |
915 | |
727 | 916 AddressLiteral rs(byte_map_base); |
917 __ set(rs, cardtable); // cardtable := <card table base> | |
342 | 918 __ ldub(addr, cardtable, tmp); // tmp := [addr + cardtable] |
919 | |
3888
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
920 assert(CardTableModRefBS::dirty_card_val() == 0, "otherwise check this code"); |
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
921 __ cmp_and_br_short(tmp, G0, Assembler::notEqual, Assembler::pt, not_already_dirty); |
342 | 922 |
923 // We didn't take the branch, so we're already dirty: return. | |
924 // Use return-from-leaf | |
925 __ retl(); | |
926 __ delayed()->nop(); | |
927 | |
928 // Not dirty. | |
929 __ bind(not_already_dirty); | |
3888
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
930 |
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
931 // Get cardtable + tmp into a reg by itself |
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
932 __ add(addr, cardtable, tmp2); |
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
933 |
342 | 934 // First, dirty it. |
935 __ stb(G0, tmp2, 0); // [cardPtr] := 0 (i.e., dirty). | |
936 | |
937 Register tmp3 = cardtable; | |
938 Register tmp4 = tmp; | |
939 | |
940 // these registers are now dead | |
941 addr = cardtable = tmp = noreg; | |
942 | |
943 int dirty_card_q_index_byte_offset = | |
944 in_bytes(JavaThread::dirty_card_queue_offset() + | |
945 PtrQueue::byte_offset_of_index()); | |
946 int dirty_card_q_buf_byte_offset = | |
947 in_bytes(JavaThread::dirty_card_queue_offset() + | |
948 PtrQueue::byte_offset_of_buf()); | |
3888
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
949 |
342 | 950 __ bind(restart); |
3888
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
951 |
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
952 // Get the index into the update buffer. PtrQueue::_index is |
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
953 // a size_t so ld_ptr is appropriate here. |
342 | 954 __ ld_ptr(G2_thread, dirty_card_q_index_byte_offset, tmp3); |
955 | |
3888
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
956 // index == 0? |
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
957 __ cmp_and_brx_short(tmp3, G0, Assembler::equal, Assembler::pn, refill); |
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
958 |
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
959 __ ld_ptr(G2_thread, dirty_card_q_buf_byte_offset, tmp4); |
342 | 960 __ sub(tmp3, oopSize, tmp3); |
961 | |
962 __ st_ptr(tmp2, tmp4, tmp3); // [_buf + index] := <address_of_card> | |
963 // Use return-from-leaf | |
964 __ retl(); | |
965 __ delayed()->st_ptr(tmp3, G2_thread, dirty_card_q_index_byte_offset); | |
966 | |
967 __ bind(refill); | |
968 __ save_frame(0); | |
969 | |
970 __ mov(tmp2, L0); | |
971 __ mov(tmp3, L1); | |
972 __ mov(tmp4, L2); | |
973 | |
974 __ call_VM_leaf(L7_thread_cache, | |
975 CAST_FROM_FN_PTR(address, | |
976 DirtyCardQueueSet::handle_zero_index_for_thread), | |
977 G2_thread); | |
978 | |
979 __ mov(L0, tmp2); | |
980 __ mov(L1, tmp3); | |
981 __ mov(L2, tmp4); | |
982 | |
983 __ br(Assembler::always, /*annul*/false, Assembler::pt, restart); | |
984 __ delayed()->restore(); | |
985 } | |
986 break; | |
987 #endif // !SERIALGC | |
988 | |
0 | 989 default: |
990 { __ set_info("unimplemented entry", dont_gc_arguments); | |
991 __ save_frame(0); | |
992 __ set((int)id, O1); | |
993 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), O1); | |
994 __ should_not_reach_here(); | |
995 } | |
996 break; | |
997 } | |
998 return oop_maps; | |
999 } | |
1000 | |
1001 | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1002 OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler* sasm) { |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1003 __ block_comment("generate_handle_exception"); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1004 |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1005 // Save registers, if required. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1006 OopMapSet* oop_maps = new OopMapSet(); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1007 OopMap* oop_map = NULL; |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1008 switch (id) { |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1009 case forward_exception_id: |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1010 // We're handling an exception in the context of a compiled frame. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1011 // The registers have been saved in the standard places. Perform |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1012 // an exception lookup in the caller and dispatch to the handler |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1013 // if found. Otherwise unwind and dispatch to the callers |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1014 // exception handler. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1015 oop_map = generate_oop_map(sasm, true); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1016 |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1017 // transfer the pending exception to the exception_oop |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1018 __ ld_ptr(G2_thread, in_bytes(JavaThread::pending_exception_offset()), Oexception); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1019 __ ld_ptr(Oexception, 0, G0); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1020 __ st_ptr(G0, G2_thread, in_bytes(JavaThread::pending_exception_offset())); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1021 __ add(I7, frame::pc_return_offset, Oissuing_pc); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1022 break; |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1023 case handle_exception_id: |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1024 // At this point all registers MAY be live. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1025 oop_map = save_live_registers(sasm); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1026 __ mov(Oexception->after_save(), Oexception); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1027 __ mov(Oissuing_pc->after_save(), Oissuing_pc); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1028 break; |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1029 case handle_exception_from_callee_id: |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1030 // At this point all registers except exception oop (Oexception) |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1031 // and exception pc (Oissuing_pc) are dead. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1032 oop_map = new OopMap(frame_size_in_bytes / sizeof(jint), 0); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1033 sasm->set_frame_size(frame_size_in_bytes / BytesPerWord); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1034 __ save_frame_c1(frame_size_in_bytes); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1035 __ mov(Oexception->after_save(), Oexception); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1036 __ mov(Oissuing_pc->after_save(), Oissuing_pc); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1037 break; |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1038 default: ShouldNotReachHere(); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1039 } |
0 | 1040 |
1041 __ verify_not_null_oop(Oexception); | |
1042 | |
1043 // save the exception and issuing pc in the thread | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1044 __ st_ptr(Oexception, G2_thread, in_bytes(JavaThread::exception_oop_offset())); |
0 | 1045 __ st_ptr(Oissuing_pc, G2_thread, in_bytes(JavaThread::exception_pc_offset())); |
1046 | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1047 // use the throwing pc as the return address to lookup (has bci & oop map) |
0 | 1048 __ mov(Oissuing_pc, I7); |
1049 __ sub(I7, frame::pc_return_offset, I7); | |
1050 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc)); | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1051 oop_maps->add_gc_map(call_offset, oop_map); |
0 | 1052 |
1053 // Note: if nmethod has been deoptimized then regardless of | |
1054 // whether it had a handler or not we will deoptimize | |
1055 // by entering the deopt blob with a pending exception. | |
1056 | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1057 // Restore the registers that were saved at the beginning, remove |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1058 // the frame and jump to the exception handler. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1059 switch (id) { |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1060 case forward_exception_id: |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1061 case handle_exception_id: |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1062 restore_live_registers(sasm); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1063 __ jmp(O0, 0); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1064 __ delayed()->restore(); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1065 break; |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1066 case handle_exception_from_callee_id: |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1067 // Restore SP from L7 if the exception PC is a method handle call site. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1068 __ mov(O0, G5); // Save the target address. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1069 __ lduw(Address(G2_thread, JavaThread::is_method_handle_return_offset()), L0); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1070 __ tst(L0); // Condition codes are preserved over the restore. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1071 __ restore(); |
0 | 1072 |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1073 __ jmp(G5, 0); // jump to the exception handler |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1074 __ delayed()->movcc(Assembler::notZero, false, Assembler::icc, L7_mh_SP_save, SP); // Restore SP if required. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1075 break; |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1076 default: ShouldNotReachHere(); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1077 } |
0 | 1078 |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2170
diff
changeset
|
1079 return oop_maps; |
0 | 1080 } |
1081 | |
1082 | |
1083 #undef __ | |
1084 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1579
diff
changeset
|
1085 const char *Runtime1::pd_name_for_address(address entry) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1579
diff
changeset
|
1086 return "<unknown function>"; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1579
diff
changeset
|
1087 } |