Mercurial > hg > graal-compiler
annotate src/cpu/sparc/vm/templateInterpreter_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 | b2dbd323c668 f0c2369fda5a |
rev | line source |
---|---|
0 | 1 /* |
6123
2fe087c3e814
7172967: Eliminate constMethod's _method backpointer to methodOop.
jiangli
parents:
5923
diff
changeset
|
2 * Copyright (c) 1997, 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:
1506
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1506
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:
1506
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "asm/assembler.hpp" | |
27 #include "interpreter/bytecodeHistogram.hpp" | |
28 #include "interpreter/interpreter.hpp" | |
29 #include "interpreter/interpreterGenerator.hpp" | |
30 #include "interpreter/interpreterRuntime.hpp" | |
31 #include "interpreter/templateTable.hpp" | |
32 #include "oops/arrayOop.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
33 #include "oops/methodData.hpp" |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
34 #include "oops/method.hpp" |
1972 | 35 #include "oops/oop.inline.hpp" |
36 #include "prims/jvmtiExport.hpp" | |
37 #include "prims/jvmtiThreadState.hpp" | |
38 #include "runtime/arguments.hpp" | |
39 #include "runtime/deoptimization.hpp" | |
40 #include "runtime/frame.inline.hpp" | |
41 #include "runtime/sharedRuntime.hpp" | |
42 #include "runtime/stubRoutines.hpp" | |
43 #include "runtime/synchronizer.hpp" | |
44 #include "runtime/timer.hpp" | |
45 #include "runtime/vframeArray.hpp" | |
46 #include "utilities/debug.hpp" | |
0 | 47 |
48 #ifndef CC_INTERP | |
49 #ifndef FAST_DISPATCH | |
50 #define FAST_DISPATCH 1 | |
51 #endif | |
52 #undef FAST_DISPATCH | |
53 | |
54 | |
55 // Generation of Interpreter | |
56 // | |
57 // The InterpreterGenerator generates the interpreter into Interpreter::_code. | |
58 | |
59 | |
60 #define __ _masm-> | |
61 | |
62 | |
63 //---------------------------------------------------------------------------------------------------- | |
64 | |
65 | |
66 void InterpreterGenerator::save_native_result(void) { | |
67 // result potentially in O0/O1: save it across calls | |
68 const Address& l_tmp = InterpreterMacroAssembler::l_tmp; | |
69 | |
70 // result potentially in F0/F1: save it across calls | |
71 const Address& d_tmp = InterpreterMacroAssembler::d_tmp; | |
72 | |
73 // save and restore any potential method result value around the unlocking operation | |
74 __ stf(FloatRegisterImpl::D, F0, d_tmp); | |
75 #ifdef _LP64 | |
76 __ stx(O0, l_tmp); | |
77 #else | |
78 __ std(O0, l_tmp); | |
79 #endif | |
80 } | |
81 | |
82 void InterpreterGenerator::restore_native_result(void) { | |
83 const Address& l_tmp = InterpreterMacroAssembler::l_tmp; | |
84 const Address& d_tmp = InterpreterMacroAssembler::d_tmp; | |
85 | |
86 // Restore any method result value | |
87 __ ldf(FloatRegisterImpl::D, d_tmp, F0); | |
88 #ifdef _LP64 | |
89 __ ldx(l_tmp, O0); | |
90 #else | |
91 __ ldd(l_tmp, O0); | |
92 #endif | |
93 } | |
94 | |
95 address TemplateInterpreterGenerator::generate_exception_handler_common(const char* name, const char* message, bool pass_oop) { | |
96 assert(!pass_oop || message == NULL, "either oop or message but not both"); | |
97 address entry = __ pc(); | |
98 // expression stack must be empty before entering the VM if an exception happened | |
99 __ empty_expression_stack(); | |
100 // load exception object | |
101 __ set((intptr_t)name, G3_scratch); | |
102 if (pass_oop) { | |
103 __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::create_klass_exception), G3_scratch, Otos_i); | |
104 } else { | |
105 __ set((intptr_t)message, G4_scratch); | |
106 __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception), G3_scratch, G4_scratch); | |
107 } | |
108 // throw exception | |
109 assert(Interpreter::throw_exception_entry() != NULL, "generate it first"); | |
727 | 110 AddressLiteral thrower(Interpreter::throw_exception_entry()); |
111 __ jump_to(thrower, G3_scratch); | |
0 | 112 __ delayed()->nop(); |
113 return entry; | |
114 } | |
115 | |
116 address TemplateInterpreterGenerator::generate_ClassCastException_handler() { | |
117 address entry = __ pc(); | |
118 // expression stack must be empty before entering the VM if an exception | |
119 // happened | |
120 __ empty_expression_stack(); | |
121 // load exception object | |
122 __ call_VM(Oexception, | |
123 CAST_FROM_FN_PTR(address, | |
124 InterpreterRuntime::throw_ClassCastException), | |
125 Otos_i); | |
126 __ should_not_reach_here(); | |
127 return entry; | |
128 } | |
129 | |
130 | |
131 address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(const char* name) { | |
132 address entry = __ pc(); | |
133 // expression stack must be empty before entering the VM if an exception happened | |
134 __ empty_expression_stack(); | |
135 // convention: expect aberrant index in register G3_scratch, then shuffle the | |
136 // index to G4_scratch for the VM call | |
137 __ mov(G3_scratch, G4_scratch); | |
138 __ set((intptr_t)name, G3_scratch); | |
139 __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException), G3_scratch, G4_scratch); | |
140 __ should_not_reach_here(); | |
141 return entry; | |
142 } | |
143 | |
144 | |
145 address TemplateInterpreterGenerator::generate_StackOverflowError_handler() { | |
146 address entry = __ pc(); | |
147 // expression stack must be empty before entering the VM if an exception happened | |
148 __ empty_expression_stack(); | |
149 __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_StackOverflowError)); | |
150 __ should_not_reach_here(); | |
151 return entry; | |
152 } | |
153 | |
154 | |
1059
389049f3f393
6858164: invokedynamic code needs some cleanup (post-6655638)
jrose
parents:
728
diff
changeset
|
155 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) { |
1503 | 156 TosState incoming_state = state; |
157 | |
158 Label cont; | |
0 | 159 address compiled_entry = __ pc(); |
160 | |
161 address entry = __ pc(); | |
162 #if !defined(_LP64) && defined(COMPILER2) | |
163 // All return values are where we want them, except for Longs. C2 returns | |
164 // longs in G1 in the 32-bit build whereas the interpreter wants them in O0/O1. | |
165 // Since the interpreter will return longs in G1 and O0/O1 in the 32bit | |
166 // build even if we are returning from interpreted we just do a little | |
167 // stupid shuffing. | |
168 // Note: I tried to make c2 return longs in O0/O1 and G1 so we wouldn't have to | |
169 // do this here. Unfortunately if we did a rethrow we'd see an machepilog node | |
170 // first which would move g1 -> O0/O1 and destroy the exception we were throwing. | |
171 | |
1503 | 172 if (incoming_state == ltos) { |
173 __ srl (G1, 0, O1); | |
174 __ srlx(G1, 32, O0); | |
0 | 175 } |
1503 | 176 #endif // !_LP64 && COMPILER2 |
0 | 177 |
178 __ bind(cont); | |
179 | |
180 // The callee returns with the stack possibly adjusted by adapter transition | |
181 // We remove that possible adjustment here. | |
182 // All interpreter local registers are untouched. Any result is passed back | |
183 // in the O0/O1 or float registers. Before continuing, the arguments must be | |
184 // popped from the java expression stack; i.e., Lesp must be adjusted. | |
185 | |
186 __ mov(Llast_SP, SP); // Remove any adapter added stack space. | |
187 | |
1503 | 188 Label L_got_cache, L_giant_index; |
0 | 189 const Register cache = G3_scratch; |
190 const Register size = G1_scratch; | |
1503 | 191 if (EnableInvokeDynamic) { |
192 __ ldub(Address(Lbcp, 0), G1_scratch); // Load current bytecode. | |
3839 | 193 __ cmp_and_br_short(G1_scratch, Bytecodes::_invokedynamic, Assembler::equal, Assembler::pn, L_giant_index); |
1503 | 194 } |
0 | 195 __ get_cache_and_index_at_bcp(cache, G1_scratch, 1); |
1503 | 196 __ bind(L_got_cache); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
197 __ ld_ptr(cache, ConstantPoolCache::base_offset() + |
727 | 198 ConstantPoolCacheEntry::flags_offset(), size); |
0 | 199 __ and3(size, 0xFF, size); // argument size in words |
1506 | 200 __ sll(size, Interpreter::logStackElementSize, size); // each argument size in bytes |
0 | 201 __ add(Lesp, size, Lesp); // pop arguments |
202 __ dispatch_next(state, step); | |
203 | |
1503 | 204 // out of the main line of code... |
205 if (EnableInvokeDynamic) { | |
206 __ bind(L_giant_index); | |
1565 | 207 __ get_cache_and_index_at_bcp(cache, G1_scratch, 1, sizeof(u4)); |
3839 | 208 __ ba_short(L_got_cache); |
1503 | 209 } |
210 | |
0 | 211 return entry; |
212 } | |
213 | |
214 | |
215 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) { | |
216 address entry = __ pc(); | |
217 __ get_constant_pool_cache(LcpoolCache); // load LcpoolCache | |
218 { Label L; | |
727 | 219 Address exception_addr(G2_thread, Thread::pending_exception_offset()); |
220 __ ld_ptr(exception_addr, Gtemp); // Load pending exception. | |
3839 | 221 __ br_null_short(Gtemp, Assembler::pt, L); |
0 | 222 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception)); |
223 __ should_not_reach_here(); | |
224 __ bind(L); | |
225 } | |
226 __ dispatch_next(state, step); | |
227 return entry; | |
228 } | |
229 | |
230 // A result handler converts/unboxes a native call result into | |
231 // a java interpreter/compiler result. The current frame is an | |
232 // interpreter frame. The activation frame unwind code must be | |
233 // consistent with that of TemplateTable::_return(...). In the | |
234 // case of native methods, the caller's SP was not modified. | |
235 address TemplateInterpreterGenerator::generate_result_handler_for(BasicType type) { | |
236 address entry = __ pc(); | |
237 Register Itos_i = Otos_i ->after_save(); | |
238 Register Itos_l = Otos_l ->after_save(); | |
239 Register Itos_l1 = Otos_l1->after_save(); | |
240 Register Itos_l2 = Otos_l2->after_save(); | |
241 switch (type) { | |
242 case T_BOOLEAN: __ subcc(G0, O0, G0); __ addc(G0, 0, Itos_i); break; // !0 => true; 0 => false | |
243 case T_CHAR : __ sll(O0, 16, O0); __ srl(O0, 16, Itos_i); break; // cannot use and3, 0xFFFF too big as immediate value! | |
244 case T_BYTE : __ sll(O0, 24, O0); __ sra(O0, 24, Itos_i); break; | |
245 case T_SHORT : __ sll(O0, 16, O0); __ sra(O0, 16, Itos_i); break; | |
246 case T_LONG : | |
247 #ifndef _LP64 | |
248 __ mov(O1, Itos_l2); // move other half of long | |
249 #endif // ifdef or no ifdef, fall through to the T_INT case | |
250 case T_INT : __ mov(O0, Itos_i); break; | |
251 case T_VOID : /* nothing to do */ break; | |
252 case T_FLOAT : assert(F0 == Ftos_f, "fix this code" ); break; | |
253 case T_DOUBLE : assert(F0 == Ftos_d, "fix this code" ); break; | |
254 case T_OBJECT : | |
255 __ ld_ptr(FP, (frame::interpreter_frame_oop_temp_offset*wordSize) + STACK_BIAS, Itos_i); | |
256 __ verify_oop(Itos_i); | |
257 break; | |
258 default : ShouldNotReachHere(); | |
259 } | |
260 __ ret(); // return from interpreter activation | |
261 __ delayed()->restore(I5_savedSP, G0, SP); // remove interpreter frame | |
262 NOT_PRODUCT(__ emit_long(0);) // marker for disassembly | |
263 return entry; | |
264 } | |
265 | |
266 address TemplateInterpreterGenerator::generate_safept_entry_for(TosState state, address runtime_entry) { | |
267 address entry = __ pc(); | |
268 __ push(state); | |
269 __ call_VM(noreg, runtime_entry); | |
270 __ dispatch_via(vtos, Interpreter::normal_table(vtos)); | |
271 return entry; | |
272 } | |
273 | |
274 | |
275 address TemplateInterpreterGenerator::generate_continuation_for(TosState state) { | |
276 address entry = __ pc(); | |
277 __ dispatch_next(state); | |
278 return entry; | |
279 } | |
280 | |
281 // | |
282 // Helpers for commoning out cases in the various type of method entries. | |
283 // | |
284 | |
285 // increment invocation count & check for overflow | |
286 // | |
287 // Note: checking for negative value instead of overflow | |
288 // so we have a 'sticky' overflow test | |
289 // | |
290 // Lmethod: method | |
291 // ??: invocation counter | |
292 // | |
293 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
294 // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not. |
1783 | 295 if (TieredCompilation) { |
296 const int increment = InvocationCounter::count_increment; | |
297 const int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift; | |
298 Label no_mdo, done; | |
299 if (ProfileInterpreter) { | |
300 // If no method data exists, go to profile_continue. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
301 __ ld_ptr(Lmethod, Method::method_data_offset(), G4_scratch); |
3839 | 302 __ br_null_short(G4_scratch, Assembler::pn, no_mdo); |
1783 | 303 // Increment counter |
304 Address mdo_invocation_counter(G4_scratch, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
305 in_bytes(MethodData::invocation_counter_offset()) + |
1783 | 306 in_bytes(InvocationCounter::counter_offset())); |
307 __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, | |
308 G3_scratch, Lscratch, | |
309 Assembler::zero, overflow); | |
3839 | 310 __ ba_short(done); |
1783 | 311 } |
0 | 312 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
313 // Increment counter in Method* |
1783 | 314 __ bind(no_mdo); |
315 Address invocation_counter(Lmethod, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
316 in_bytes(Method::invocation_counter_offset()) + |
1783 | 317 in_bytes(InvocationCounter::counter_offset())); |
318 __ increment_mask_and_jump(invocation_counter, increment, mask, | |
319 G3_scratch, Lscratch, | |
320 Assembler::zero, overflow); | |
321 __ bind(done); | |
322 } else { | |
323 // Update standard invocation counters | |
324 __ increment_invocation_counter(O0, G3_scratch); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
325 if (ProfileInterpreter) { // %%% Merge this into MethodData* |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
326 Address interpreter_invocation_counter(Lmethod,in_bytes(Method::interpreter_invocation_counter_offset())); |
1783 | 327 __ ld(interpreter_invocation_counter, G3_scratch); |
328 __ inc(G3_scratch); | |
329 __ st(G3_scratch, interpreter_invocation_counter); | |
330 } | |
0 | 331 |
1783 | 332 if (ProfileInterpreter && profile_method != NULL) { |
333 // Test to see if we should create a method data oop | |
334 AddressLiteral profile_limit((address)&InvocationCounter::InterpreterProfileLimit); | |
335 __ load_contents(profile_limit, G3_scratch); | |
3839 | 336 __ cmp_and_br_short(O0, G3_scratch, Assembler::lessUnsigned, Assembler::pn, *profile_method_continue); |
0 | 337 |
1783 | 338 // if no method data exists, go to profile_method |
339 __ test_method_data_pointer(*profile_method); | |
340 } | |
341 | |
342 AddressLiteral invocation_limit((address)&InvocationCounter::InterpreterInvocationLimit); | |
343 __ load_contents(invocation_limit, G3_scratch); | |
344 __ cmp(O0, G3_scratch); | |
3839 | 345 __ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow); // Far distance |
1783 | 346 __ delayed()->nop(); |
347 } | |
0 | 348 |
349 } | |
350 | |
351 // Allocate monitor and lock method (asm interpreter) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
352 // ebx - Method* |
0 | 353 // |
354 void InterpreterGenerator::lock_method(void) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
355 __ ld(Lmethod, in_bytes(Method::access_flags_offset()), O0); // Load access flags. |
0 | 356 |
357 #ifdef ASSERT | |
358 { Label ok; | |
359 __ btst(JVM_ACC_SYNCHRONIZED, O0); | |
360 __ br( Assembler::notZero, false, Assembler::pt, ok); | |
361 __ delayed()->nop(); | |
362 __ stop("method doesn't need synchronization"); | |
363 __ bind(ok); | |
364 } | |
365 #endif // ASSERT | |
366 | |
367 // get synchronization object to O0 | |
368 { Label done; | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
3839
diff
changeset
|
369 const int mirror_offset = in_bytes(Klass::java_mirror_offset()); |
0 | 370 __ btst(JVM_ACC_STATIC, O0); |
371 __ br( Assembler::zero, true, Assembler::pt, done); | |
372 __ delayed()->ld_ptr(Llocals, Interpreter::local_offset_in_bytes(0), O0); // get receiver for not-static case | |
373 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
374 __ ld_ptr( Lmethod, in_bytes(Method::const_offset()), O0); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
375 __ ld_ptr( O0, in_bytes(ConstMethod::constants_offset()), O0); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
376 __ ld_ptr( O0, ConstantPool::pool_holder_offset_in_bytes(), O0); |
0 | 377 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
378 // lock the mirror, not the Klass* |
0 | 379 __ ld_ptr( O0, mirror_offset, O0); |
380 | |
381 #ifdef ASSERT | |
382 __ tst(O0); | |
5923 | 383 __ breakpoint_trap(Assembler::zero, Assembler::ptr_cc); |
0 | 384 #endif // ASSERT |
385 | |
386 __ bind(done); | |
387 } | |
388 | |
389 __ add_monitor_to_stack(true, noreg, noreg); // allocate monitor elem | |
390 __ st_ptr( O0, Lmonitors, BasicObjectLock::obj_offset_in_bytes()); // store object | |
391 // __ untested("lock_object from method entry"); | |
392 __ lock_object(Lmonitors, O0); | |
393 } | |
394 | |
395 | |
396 void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rframe_size, | |
397 Register Rscratch, | |
398 Register Rscratch2) { | |
399 const int page_size = os::vm_page_size(); | |
400 Label after_frame_check; | |
401 | |
402 assert_different_registers(Rframe_size, Rscratch, Rscratch2); | |
403 | |
3839 | 404 __ set(page_size, Rscratch); |
405 __ cmp_and_br_short(Rframe_size, Rscratch, Assembler::lessEqual, Assembler::pt, after_frame_check); | |
0 | 406 |
407 // get the stack base, and in debug, verify it is non-zero | |
727 | 408 __ ld_ptr( G2_thread, Thread::stack_base_offset(), Rscratch ); |
0 | 409 #ifdef ASSERT |
410 Label base_not_zero; | |
3839 | 411 __ br_notnull_short(Rscratch, Assembler::pn, base_not_zero); |
0 | 412 __ stop("stack base is zero in generate_stack_overflow_check"); |
413 __ bind(base_not_zero); | |
414 #endif | |
415 | |
416 // get the stack size, and in debug, verify it is non-zero | |
417 assert( sizeof(size_t) == sizeof(intptr_t), "wrong load size" ); | |
727 | 418 __ ld_ptr( G2_thread, Thread::stack_size_offset(), Rscratch2 ); |
0 | 419 #ifdef ASSERT |
420 Label size_not_zero; | |
3839 | 421 __ br_notnull_short(Rscratch2, Assembler::pn, size_not_zero); |
0 | 422 __ stop("stack size is zero in generate_stack_overflow_check"); |
423 __ bind(size_not_zero); | |
424 #endif | |
425 | |
426 // compute the beginning of the protected zone minus the requested frame size | |
427 __ sub( Rscratch, Rscratch2, Rscratch ); | |
428 __ set( (StackRedPages+StackYellowPages) * page_size, Rscratch2 ); | |
429 __ add( Rscratch, Rscratch2, Rscratch ); | |
430 | |
431 // Add in the size of the frame (which is the same as subtracting it from the | |
432 // SP, which would take another register | |
433 __ add( Rscratch, Rframe_size, Rscratch ); | |
434 | |
435 // the frame is greater than one page in size, so check against | |
436 // the bottom of the stack | |
3839 | 437 __ cmp_and_brx_short(SP, Rscratch, Assembler::greater, Assembler::pt, after_frame_check); |
0 | 438 |
4743 | 439 // the stack will overflow, throw an exception |
440 | |
441 // Note that SP is restored to sender's sp (in the delay slot). This | |
442 // is necessary if the sender's frame is an extended compiled frame | |
443 // (see gen_c2i_adapter()) and safer anyway in case of JSR292 | |
444 // adaptations. | |
0 | 445 |
4743 | 446 // Note also that the restored frame is not necessarily interpreted. |
447 // Use the shared runtime version of the StackOverflowError. | |
448 assert(StubRoutines::throw_StackOverflowError_entry() != NULL, "stub not yet generated"); | |
449 AddressLiteral stub(StubRoutines::throw_StackOverflowError_entry()); | |
450 __ jump_to(stub, Rscratch); | |
451 __ delayed()->mov(O5_savedSP, SP); | |
0 | 452 |
453 // if you get to here, then there is enough stack space | |
454 __ bind( after_frame_check ); | |
455 } | |
456 | |
457 | |
458 // | |
459 // Generate a fixed interpreter frame. This is identical setup for interpreted | |
460 // methods and for native methods hence the shared code. | |
461 | |
462 void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { | |
463 // | |
464 // | |
465 // The entry code sets up a new interpreter frame in 4 steps: | |
466 // | |
467 // 1) Increase caller's SP by for the extra local space needed: | |
468 // (check for overflow) | |
469 // Efficient implementation of xload/xstore bytecodes requires | |
470 // that arguments and non-argument locals are in a contigously | |
471 // addressable memory block => non-argument locals must be | |
472 // allocated in the caller's frame. | |
473 // | |
474 // 2) Create a new stack frame and register window: | |
475 // The new stack frame must provide space for the standard | |
476 // register save area, the maximum java expression stack size, | |
477 // the monitor slots (0 slots initially), and some frame local | |
478 // scratch locations. | |
479 // | |
480 // 3) The following interpreter activation registers must be setup: | |
481 // Lesp : expression stack pointer | |
482 // Lbcp : bytecode pointer | |
483 // Lmethod : method | |
484 // Llocals : locals pointer | |
485 // Lmonitors : monitor pointer | |
486 // LcpoolCache: constant pool cache | |
487 // | |
488 // 4) Initialize the non-argument locals if necessary: | |
489 // Non-argument locals may need to be initialized to NULL | |
490 // for GC to work. If the oop-map information is accurate | |
491 // (in the absence of the JSR problem), no initialization | |
492 // is necessary. | |
493 // | |
494 // (gri - 2/25/2000) | |
495 | |
496 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
497 const Address size_of_parameters(G5_method, Method::size_of_parameters_offset()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
498 const Address size_of_locals (G5_method, Method::size_of_locals_offset()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
499 const Address max_stack (G5_method, Method::max_stack_offset()); |
0 | 500 int rounded_vm_local_words = round_to( frame::interpreter_frame_vm_local_words, WordsPerLong ); |
501 | |
502 const int extra_space = | |
503 rounded_vm_local_words + // frame local scratch space | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
504 //6815692//Method::extra_stack_words() + // extra push slots for MH adapters |
0 | 505 frame::memory_parameter_word_sp_offset + // register save area |
506 (native_call ? frame::interpreter_frame_extra_outgoing_argument_words : 0); | |
507 | |
508 const Register Glocals_size = G3; | |
509 const Register Otmp1 = O3; | |
510 const Register Otmp2 = O4; | |
511 // Lscratch can't be used as a temporary because the call_stub uses | |
512 // it to assert that the stack frame was setup correctly. | |
513 | |
514 __ lduh( size_of_parameters, Glocals_size); | |
515 | |
516 // Gargs points to first local + BytesPerWord | |
517 // Set the saved SP after the register window save | |
518 // | |
519 assert_different_registers(Gargs, Glocals_size, Gframe_size, O5_savedSP); | |
1506 | 520 __ sll(Glocals_size, Interpreter::logStackElementSize, Otmp1); |
0 | 521 __ add(Gargs, Otmp1, Gargs); |
522 | |
523 if (native_call) { | |
524 __ calc_mem_param_words( Glocals_size, Gframe_size ); | |
525 __ add( Gframe_size, extra_space, Gframe_size); | |
526 __ round_to( Gframe_size, WordsPerLong ); | |
527 __ sll( Gframe_size, LogBytesPerWord, Gframe_size ); | |
528 } else { | |
529 | |
530 // | |
531 // Compute number of locals in method apart from incoming parameters | |
532 // | |
533 __ lduh( size_of_locals, Otmp1 ); | |
534 __ sub( Otmp1, Glocals_size, Glocals_size ); | |
535 __ round_to( Glocals_size, WordsPerLong ); | |
1506 | 536 __ sll( Glocals_size, Interpreter::logStackElementSize, Glocals_size ); |
0 | 537 |
538 // see if the frame is greater than one page in size. If so, | |
539 // then we need to verify there is enough stack space remaining | |
540 // Frame_size = (max_stack + extra_space) * BytesPerWord; | |
541 __ lduh( max_stack, Gframe_size ); | |
542 __ add( Gframe_size, extra_space, Gframe_size ); | |
543 __ round_to( Gframe_size, WordsPerLong ); | |
1506 | 544 __ sll( Gframe_size, Interpreter::logStackElementSize, Gframe_size); |
0 | 545 |
546 // Add in java locals size for stack overflow check only | |
547 __ add( Gframe_size, Glocals_size, Gframe_size ); | |
548 | |
549 const Register Otmp2 = O4; | |
550 assert_different_registers(Otmp1, Otmp2, O5_savedSP); | |
551 generate_stack_overflow_check(Gframe_size, Otmp1, Otmp2); | |
552 | |
553 __ sub( Gframe_size, Glocals_size, Gframe_size); | |
554 | |
555 // | |
556 // bump SP to accomodate the extra locals | |
557 // | |
558 __ sub( SP, Glocals_size, SP ); | |
559 } | |
560 | |
561 // | |
562 // now set up a stack frame with the size computed above | |
563 // | |
564 __ neg( Gframe_size ); | |
565 __ save( SP, Gframe_size, SP ); | |
566 | |
567 // | |
568 // now set up all the local cache registers | |
569 // | |
570 // NOTE: At this point, Lbyte_code/Lscratch has been modified. Note | |
571 // that all present references to Lbyte_code initialize the register | |
572 // immediately before use | |
573 if (native_call) { | |
574 __ mov(G0, Lbcp); | |
575 } else { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
576 __ ld_ptr(G5_method, Method::const_offset(), Lbcp); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
577 __ add(Lbcp, in_bytes(ConstMethod::codes_offset()), Lbcp); |
0 | 578 } |
579 __ mov( G5_method, Lmethod); // set Lmethod | |
580 __ get_constant_pool_cache( LcpoolCache ); // set LcpoolCache | |
581 __ sub(FP, rounded_vm_local_words * BytesPerWord, Lmonitors ); // set Lmonitors | |
582 #ifdef _LP64 | |
583 __ add( Lmonitors, STACK_BIAS, Lmonitors ); // Account for 64 bit stack bias | |
584 #endif | |
585 __ sub(Lmonitors, BytesPerWord, Lesp); // set Lesp | |
586 | |
587 // setup interpreter activation registers | |
588 __ sub(Gargs, BytesPerWord, Llocals); // set Llocals | |
589 | |
590 if (ProfileInterpreter) { | |
591 #ifdef FAST_DISPATCH | |
592 // FAST_DISPATCH and ProfileInterpreter are mutually exclusive since | |
593 // they both use I2. | |
594 assert(0, "FAST_DISPATCH and +ProfileInterpreter are mutually exclusive"); | |
595 #endif // FAST_DISPATCH | |
596 __ set_method_data_pointer(); | |
597 } | |
598 | |
599 } | |
600 | |
601 // Empty method, generate a very fast return. | |
602 | |
603 address InterpreterGenerator::generate_empty_entry(void) { | |
604 | |
605 // A method that does nother but return... | |
606 | |
607 address entry = __ pc(); | |
608 Label slow_path; | |
609 | |
610 // do nothing for empty methods (do not even increment invocation counter) | |
611 if ( UseFastEmptyMethods) { | |
612 // If we need a safepoint check, generate full interpreter entry. | |
727 | 613 AddressLiteral sync_state(SafepointSynchronize::address_of_state()); |
614 __ set(sync_state, G3_scratch); | |
3839 | 615 __ cmp_and_br_short(G3_scratch, SafepointSynchronize::_not_synchronized, Assembler::notEqual, Assembler::pn, slow_path); |
0 | 616 |
617 // Code: _return | |
618 __ retl(); | |
619 __ delayed()->mov(O5_savedSP, SP); | |
620 | |
621 __ bind(slow_path); | |
622 (void) generate_normal_entry(false); | |
623 | |
624 return entry; | |
625 } | |
626 return NULL; | |
627 } | |
628 | |
629 // Call an accessor method (assuming it is resolved, otherwise drop into | |
630 // vanilla (slow path) entry | |
631 | |
632 // Generates code to elide accessor methods | |
633 // Uses G3_scratch and G1_scratch as scratch | |
634 address InterpreterGenerator::generate_accessor_entry(void) { | |
635 | |
636 // Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites thereof; | |
637 // parameter size = 1 | |
638 // Note: We can only use this code if the getfield has been resolved | |
639 // and if we don't have a null-pointer exception => check for | |
640 // these conditions first and use slow path if necessary. | |
641 address entry = __ pc(); | |
642 Label slow_path; | |
643 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
644 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
645 // XXX: for compressed oops pointer loading and decoding doesn't fit in |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
646 // delay slot and damages G1 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
647 if ( UseFastAccessorMethods && !UseCompressedOops ) { |
0 | 648 // Check if we need to reach a safepoint and generate full interpreter |
649 // frame if so. | |
727 | 650 AddressLiteral sync_state(SafepointSynchronize::address_of_state()); |
0 | 651 __ load_contents(sync_state, G3_scratch); |
652 __ cmp(G3_scratch, SafepointSynchronize::_not_synchronized); | |
3839 | 653 __ cmp_and_br_short(G3_scratch, SafepointSynchronize::_not_synchronized, Assembler::notEqual, Assembler::pn, slow_path); |
0 | 654 |
655 // Check if local 0 != NULL | |
656 __ ld_ptr(Gargs, G0, Otos_i ); // get local 0 | |
3839 | 657 // check if local 0 == NULL and go the slow path |
658 __ br_null_short(Otos_i, Assembler::pn, slow_path); | |
0 | 659 |
660 | |
661 // read first instruction word and extract bytecode @ 1 and index @ 2 | |
662 // get first 4 bytes of the bytecodes (big endian!) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
663 __ ld_ptr(G5_method, Method::const_offset(), G1_scratch); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
664 __ ld(G1_scratch, ConstMethod::codes_offset(), G1_scratch); |
0 | 665 |
666 // move index @ 2 far left then to the right most two bytes. | |
667 __ sll(G1_scratch, 2*BitsPerByte, G1_scratch); | |
668 __ srl(G1_scratch, 2*BitsPerByte - exact_log2(in_words( | |
669 ConstantPoolCacheEntry::size()) * BytesPerWord), G1_scratch); | |
670 | |
671 // get constant pool cache | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
672 __ ld_ptr(G5_method, Method::const_offset(), G3_scratch); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
673 __ ld_ptr(G3_scratch, ConstMethod::constants_offset(), G3_scratch); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
674 __ ld_ptr(G3_scratch, ConstantPool::cache_offset_in_bytes(), G3_scratch); |
0 | 675 |
676 // get specific constant pool cache entry | |
677 __ add(G3_scratch, G1_scratch, G3_scratch); | |
678 | |
679 // Check the constant Pool cache entry to see if it has been resolved. | |
680 // If not, need the slow path. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
681 ByteSize cp_base_offset = ConstantPoolCache::base_offset(); |
727 | 682 __ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::indices_offset(), G1_scratch); |
0 | 683 __ srl(G1_scratch, 2*BitsPerByte, G1_scratch); |
684 __ and3(G1_scratch, 0xFF, G1_scratch); | |
3839 | 685 __ cmp_and_br_short(G1_scratch, Bytecodes::_getfield, Assembler::notEqual, Assembler::pn, slow_path); |
0 | 686 |
687 // Get the type and return field offset from the constant pool cache | |
727 | 688 __ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::flags_offset(), G1_scratch); |
689 __ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::f2_offset(), G3_scratch); | |
0 | 690 |
691 Label xreturn_path; | |
692 // Need to differentiate between igetfield, agetfield, bgetfield etc. | |
693 // because they are different sizes. | |
694 // Get the type from the constant pool cache | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6123
diff
changeset
|
695 __ srl(G1_scratch, ConstantPoolCacheEntry::tos_state_shift, G1_scratch); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6123
diff
changeset
|
696 // Make sure we don't need to mask G1_scratch after the above shift |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6123
diff
changeset
|
697 ConstantPoolCacheEntry::verify_tos_state_shift(); |
0 | 698 __ cmp(G1_scratch, atos ); |
699 __ br(Assembler::equal, true, Assembler::pt, xreturn_path); | |
700 __ delayed()->ld_ptr(Otos_i, G3_scratch, Otos_i); | |
701 __ cmp(G1_scratch, itos); | |
702 __ br(Assembler::equal, true, Assembler::pt, xreturn_path); | |
703 __ delayed()->ld(Otos_i, G3_scratch, Otos_i); | |
704 __ cmp(G1_scratch, stos); | |
705 __ br(Assembler::equal, true, Assembler::pt, xreturn_path); | |
706 __ delayed()->ldsh(Otos_i, G3_scratch, Otos_i); | |
707 __ cmp(G1_scratch, ctos); | |
708 __ br(Assembler::equal, true, Assembler::pt, xreturn_path); | |
709 __ delayed()->lduh(Otos_i, G3_scratch, Otos_i); | |
710 #ifdef ASSERT | |
711 __ cmp(G1_scratch, btos); | |
712 __ br(Assembler::equal, true, Assembler::pt, xreturn_path); | |
713 __ delayed()->ldsb(Otos_i, G3_scratch, Otos_i); | |
714 __ should_not_reach_here(); | |
715 #endif | |
716 __ ldsb(Otos_i, G3_scratch, Otos_i); | |
717 __ bind(xreturn_path); | |
718 | |
719 // _ireturn/_areturn | |
720 __ retl(); // return from leaf routine | |
721 __ delayed()->mov(O5_savedSP, SP); | |
722 | |
723 // Generate regular method entry | |
724 __ bind(slow_path); | |
725 (void) generate_normal_entry(false); | |
726 return entry; | |
727 } | |
728 return NULL; | |
729 } | |
730 | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
731 // Method entry for java.lang.ref.Reference.get. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
732 address InterpreterGenerator::generate_Reference_get_entry(void) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
733 #ifndef SERIALGC |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
734 // Code: _aload_0, _getfield, _areturn |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
735 // parameter size = 1 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
736 // |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
737 // The code that gets generated by this routine is split into 2 parts: |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
738 // 1. The "intrinsified" code for G1 (or any SATB based GC), |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
739 // 2. The slow path - which is an expansion of the regular method entry. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
740 // |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
741 // Notes:- |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
742 // * In the G1 code we do not check whether we need to block for |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
743 // a safepoint. If G1 is enabled then we must execute the specialized |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
744 // code for Reference.get (except when the Reference object is null) |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
745 // so that we can log the value in the referent field with an SATB |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
746 // update buffer. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
747 // If the code for the getfield template is modified so that the |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
748 // G1 pre-barrier code is executed when the current method is |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
749 // Reference.get() then going through the normal method entry |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
750 // will be fine. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
751 // * The G1 code can, however, check the receiver object (the instance |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
752 // of java.lang.Reference) and jump to the slow path if null. If the |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
753 // Reference object is null then we obviously cannot fetch the referent |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
754 // and so we don't need to call the G1 pre-barrier. Thus we can use the |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
755 // regular method entry code to generate the NPE. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
756 // |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
757 // This code is based on generate_accessor_enty. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
758 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
759 address entry = __ pc(); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
760 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
761 const int referent_offset = java_lang_ref_Reference::referent_offset; |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
762 guarantee(referent_offset > 0, "referent offset not initialized"); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
763 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
764 if (UseG1GC) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
765 Label slow_path; |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
766 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
767 // In the G1 code we don't check if we need to reach a safepoint. We |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
768 // continue and the thread will safepoint at the next bytecode dispatch. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
769 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
770 // Check if local 0 != NULL |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
771 // If the receiver is null then it is OK to jump to the slow path. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
772 __ ld_ptr(Gargs, G0, Otos_i ); // get local 0 |
3839 | 773 // check if local 0 == NULL and go the slow path |
774 __ cmp_and_brx_short(Otos_i, 0, Assembler::equal, Assembler::pn, slow_path); | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
775 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
776 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
777 // Load the value of the referent field. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
778 if (Assembler::is_simm13(referent_offset)) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
779 __ load_heap_oop(Otos_i, referent_offset, Otos_i); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
780 } else { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
781 __ set(referent_offset, G3_scratch); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
782 __ load_heap_oop(Otos_i, G3_scratch, Otos_i); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
783 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
784 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
785 // Generate the G1 pre-barrier code to log the value of |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
786 // the referent field in an SATB buffer. Note with |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
787 // these parameters the pre-barrier does not generate |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
788 // the load of the previous value |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
789 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
790 __ g1_write_barrier_pre(noreg /* obj */, noreg /* index */, 0 /* offset */, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
791 Otos_i /* pre_val */, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
792 G3_scratch /* tmp */, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
793 true /* preserve_o_regs */); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
794 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
795 // _areturn |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
796 __ retl(); // return from leaf routine |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
797 __ delayed()->mov(O5_savedSP, SP); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
798 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
799 // Generate regular method entry |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
800 __ bind(slow_path); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
801 (void) generate_normal_entry(false); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
802 return entry; |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
803 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
804 #endif // SERIALGC |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
805 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
806 // If G1 is not enabled then attempt to go through the accessor entry point |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
807 // Reference.get is an accessor |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
808 return generate_accessor_entry(); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
809 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2118
diff
changeset
|
810 |
0 | 811 // |
812 // Interpreter stub for calling a native method. (asm interpreter) | |
813 // This sets up a somewhat different looking stack for calling the native method | |
814 // than the typical interpreter frame setup. | |
815 // | |
816 | |
817 address InterpreterGenerator::generate_native_entry(bool synchronized) { | |
818 address entry = __ pc(); | |
819 | |
820 // the following temporary registers are used during frame creation | |
821 const Register Gtmp1 = G3_scratch ; | |
822 const Register Gtmp2 = G1_scratch; | |
823 bool inc_counter = UseCompiler || CountCompiledCalls; | |
824 | |
825 // make sure registers are different! | |
826 assert_different_registers(G2_thread, G5_method, Gargs, Gtmp1, Gtmp2); | |
827 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
828 const Address Laccess_flags(Lmethod, Method::access_flags_offset()); |
0 | 829 |
830 const Register Glocals_size = G3; | |
831 assert_different_registers(Glocals_size, G4_scratch, Gframe_size); | |
832 | |
833 // make sure method is native & not abstract | |
834 // rethink these assertions - they can be simplified and shared (gri 2/25/2000) | |
835 #ifdef ASSERT | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
836 __ ld(G5_method, Method::access_flags_offset(), Gtmp1); |
0 | 837 { |
838 Label L; | |
839 __ btst(JVM_ACC_NATIVE, Gtmp1); | |
840 __ br(Assembler::notZero, false, Assembler::pt, L); | |
841 __ delayed()->nop(); | |
842 __ stop("tried to execute non-native method as native"); | |
843 __ bind(L); | |
844 } | |
845 { Label L; | |
846 __ btst(JVM_ACC_ABSTRACT, Gtmp1); | |
847 __ br(Assembler::zero, false, Assembler::pt, L); | |
848 __ delayed()->nop(); | |
849 __ stop("tried to execute abstract method as non-abstract"); | |
850 __ bind(L); | |
851 } | |
852 #endif // ASSERT | |
853 | |
854 // generate the code to allocate the interpreter stack frame | |
855 generate_fixed_frame(true); | |
856 | |
857 // | |
858 // No locals to initialize for native method | |
859 // | |
860 | |
861 // this slot will be set later, we initialize it to null here just in | |
862 // case we get a GC before the actual value is stored later | |
727 | 863 __ st_ptr(G0, FP, (frame::interpreter_frame_oop_temp_offset * wordSize) + STACK_BIAS); |
0 | 864 |
727 | 865 const Address do_not_unlock_if_synchronized(G2_thread, |
866 JavaThread::do_not_unlock_if_synchronized_offset()); | |
0 | 867 // Since at this point in the method invocation the exception handler |
868 // would try to exit the monitor of synchronized methods which hasn't | |
869 // been entered yet, we set the thread local variable | |
870 // _do_not_unlock_if_synchronized to true. If any exception was thrown by | |
871 // runtime, exception handling i.e. unlock_if_synchronized_method will | |
872 // check this thread local flag. | |
873 // This flag has two effects, one is to force an unwind in the topmost | |
874 // interpreter frame and not perform an unlock while doing so. | |
875 | |
876 __ movbool(true, G3_scratch); | |
877 __ stbool(G3_scratch, do_not_unlock_if_synchronized); | |
878 | |
879 // increment invocation counter and check for overflow | |
880 // | |
881 // Note: checking for negative value instead of overflow | |
882 // so we have a 'sticky' overflow test (may be of | |
883 // importance as soon as we have true MT/MP) | |
884 Label invocation_counter_overflow; | |
885 Label Lcontinue; | |
886 if (inc_counter) { | |
887 generate_counter_incr(&invocation_counter_overflow, NULL, NULL); | |
888 | |
889 } | |
890 __ bind(Lcontinue); | |
891 | |
892 bang_stack_shadow_pages(true); | |
893 | |
894 // reset the _do_not_unlock_if_synchronized flag | |
895 __ stbool(G0, do_not_unlock_if_synchronized); | |
896 | |
897 // check for synchronized methods | |
898 // Must happen AFTER invocation_counter check and stack overflow check, | |
899 // so method is not locked if overflows. | |
900 | |
901 if (synchronized) { | |
902 lock_method(); | |
903 } else { | |
904 #ifdef ASSERT | |
905 { Label ok; | |
906 __ ld(Laccess_flags, O0); | |
907 __ btst(JVM_ACC_SYNCHRONIZED, O0); | |
908 __ br( Assembler::zero, false, Assembler::pt, ok); | |
909 __ delayed()->nop(); | |
910 __ stop("method needs synchronization"); | |
911 __ bind(ok); | |
912 } | |
913 #endif // ASSERT | |
914 } | |
915 | |
916 | |
917 // start execution | |
918 __ verify_thread(); | |
919 | |
920 // JVMTI support | |
921 __ notify_method_entry(); | |
922 | |
923 // native call | |
924 | |
925 // (note that O0 is never an oop--at most it is a handle) | |
926 // It is important not to smash any handles created by this call, | |
927 // until any oop handle in O0 is dereferenced. | |
928 | |
929 // (note that the space for outgoing params is preallocated) | |
930 | |
931 // get signature handler | |
932 { Label L; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
933 Address signature_handler(Lmethod, Method::signature_handler_offset()); |
727 | 934 __ ld_ptr(signature_handler, G3_scratch); |
3839 | 935 __ br_notnull_short(G3_scratch, Assembler::pt, L); |
0 | 936 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), Lmethod); |
727 | 937 __ ld_ptr(signature_handler, G3_scratch); |
0 | 938 __ bind(L); |
939 } | |
940 | |
941 // Push a new frame so that the args will really be stored in | |
942 // Copy a few locals across so the new frame has the variables | |
943 // we need but these values will be dead at the jni call and | |
944 // therefore not gc volatile like the values in the current | |
945 // frame (Lmethod in particular) | |
946 | |
947 // Flush the method pointer to the register save area | |
948 __ st_ptr(Lmethod, SP, (Lmethod->sp_offset_in_saved_window() * wordSize) + STACK_BIAS); | |
949 __ mov(Llocals, O1); | |
727 | 950 |
0 | 951 // calculate where the mirror handle body is allocated in the interpreter frame: |
727 | 952 __ add(FP, (frame::interpreter_frame_oop_temp_offset * wordSize) + STACK_BIAS, O2); |
0 | 953 |
954 // Calculate current frame size | |
955 __ sub(SP, FP, O3); // Calculate negative of current frame size | |
956 __ save(SP, O3, SP); // Allocate an identical sized frame | |
957 | |
958 // Note I7 has leftover trash. Slow signature handler will fill it in | |
959 // should we get there. Normal jni call will set reasonable last_Java_pc | |
960 // below (and fix I7 so the stack trace doesn't have a meaningless frame | |
961 // in it). | |
962 | |
963 // Load interpreter frame's Lmethod into same register here | |
964 | |
965 __ ld_ptr(FP, (Lmethod->sp_offset_in_saved_window() * wordSize) + STACK_BIAS, Lmethod); | |
966 | |
967 __ mov(I1, Llocals); | |
968 __ mov(I2, Lscratch2); // save the address of the mirror | |
969 | |
970 | |
971 // ONLY Lmethod and Llocals are valid here! | |
972 | |
973 // call signature handler, It will move the arg properly since Llocals in current frame | |
974 // matches that in outer frame | |
975 | |
976 __ callr(G3_scratch, 0); | |
977 __ delayed()->nop(); | |
978 | |
979 // Result handler is in Lscratch | |
980 | |
981 // Reload interpreter frame's Lmethod since slow signature handler may block | |
982 __ ld_ptr(FP, (Lmethod->sp_offset_in_saved_window() * wordSize) + STACK_BIAS, Lmethod); | |
983 | |
984 { Label not_static; | |
985 | |
986 __ ld(Laccess_flags, O0); | |
987 __ btst(JVM_ACC_STATIC, O0); | |
988 __ br( Assembler::zero, false, Assembler::pt, not_static); | |
727 | 989 // get native function entry point(O0 is a good temp until the very end) |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
990 __ delayed()->ld_ptr(Lmethod, in_bytes(Method::native_function_offset()), O0); |
0 | 991 // for static methods insert the mirror argument |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
3839
diff
changeset
|
992 const int mirror_offset = in_bytes(Klass::java_mirror_offset()); |
0 | 993 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
994 __ ld_ptr(Lmethod, Method:: const_offset(), O1); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
995 __ ld_ptr(O1, ConstMethod::constants_offset(), O1); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
996 __ ld_ptr(O1, ConstantPool::pool_holder_offset_in_bytes(), O1); |
0 | 997 __ ld_ptr(O1, mirror_offset, O1); |
998 #ifdef ASSERT | |
999 if (!PrintSignatureHandlers) // do not dirty the output with this | |
1000 { Label L; | |
3839 | 1001 __ br_notnull_short(O1, Assembler::pt, L); |
0 | 1002 __ stop("mirror is missing"); |
1003 __ bind(L); | |
1004 } | |
1005 #endif // ASSERT | |
1006 __ st_ptr(O1, Lscratch2, 0); | |
1007 __ mov(Lscratch2, O1); | |
1008 __ bind(not_static); | |
1009 } | |
1010 | |
1011 // At this point, arguments have been copied off of stack into | |
1012 // their JNI positions, which are O1..O5 and SP[68..]. | |
1013 // Oops are boxed in-place on the stack, with handles copied to arguments. | |
1014 // The result handler is in Lscratch. O0 will shortly hold the JNIEnv*. | |
1015 | |
1016 #ifdef ASSERT | |
1017 { Label L; | |
3839 | 1018 __ br_notnull_short(O0, Assembler::pt, L); |
0 | 1019 __ stop("native entry point is missing"); |
1020 __ bind(L); | |
1021 } | |
1022 #endif // ASSERT | |
1023 | |
1024 // | |
1025 // setup the frame anchor | |
1026 // | |
1027 // The scavenge function only needs to know that the PC of this frame is | |
1028 // in the interpreter method entry code, it doesn't need to know the exact | |
1029 // PC and hence we can use O7 which points to the return address from the | |
1030 // previous call in the code stream (signature handler function) | |
1031 // | |
1032 // The other trick is we set last_Java_sp to FP instead of the usual SP because | |
1033 // we have pushed the extra frame in order to protect the volatile register(s) | |
1034 // in that frame when we return from the jni call | |
1035 // | |
1036 | |
1037 __ set_last_Java_frame(FP, O7); | |
1038 __ mov(O7, I7); // make dummy interpreter frame look like one above, | |
1039 // not meaningless information that'll confuse me. | |
1040 | |
1041 // flush the windows now. We don't care about the current (protection) frame | |
1042 // only the outer frames | |
1043 | |
1044 __ flush_windows(); | |
1045 | |
1046 // mark windows as flushed | |
727 | 1047 Address flags(G2_thread, JavaThread::frame_anchor_offset() + JavaFrameAnchor::flags_offset()); |
0 | 1048 __ set(JavaFrameAnchor::flushed, G3_scratch); |
1049 __ st(G3_scratch, flags); | |
1050 | |
1051 // Transition from _thread_in_Java to _thread_in_native. We are already safepoint ready. | |
1052 | |
727 | 1053 Address thread_state(G2_thread, JavaThread::thread_state_offset()); |
0 | 1054 #ifdef ASSERT |
1055 { Label L; | |
1056 __ ld(thread_state, G3_scratch); | |
3839 | 1057 __ cmp_and_br_short(G3_scratch, _thread_in_Java, Assembler::equal, Assembler::pt, L); |
0 | 1058 __ stop("Wrong thread state in native stub"); |
1059 __ bind(L); | |
1060 } | |
1061 #endif // ASSERT | |
1062 __ set(_thread_in_native, G3_scratch); | |
1063 __ st(G3_scratch, thread_state); | |
1064 | |
1065 // Call the jni method, using the delay slot to set the JNIEnv* argument. | |
1066 __ save_thread(L7_thread_cache); // save Gthread | |
1067 __ callr(O0, 0); | |
1068 __ delayed()-> | |
1069 add(L7_thread_cache, in_bytes(JavaThread::jni_environment_offset()), O0); | |
1070 | |
1071 // Back from jni method Lmethod in this frame is DEAD, DEAD, DEAD | |
1072 | |
1073 __ restore_thread(L7_thread_cache); // restore G2_thread | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1074 __ reinit_heapbase(); |
0 | 1075 |
1076 // must we block? | |
1077 | |
1078 // Block, if necessary, before resuming in _thread_in_Java state. | |
1079 // In order for GC to work, don't clear the last_Java_sp until after blocking. | |
1080 { Label no_block; | |
727 | 1081 AddressLiteral sync_state(SafepointSynchronize::address_of_state()); |
0 | 1082 |
1083 // Switch thread to "native transition" state before reading the synchronization state. | |
1084 // This additional state is necessary because reading and testing the synchronization | |
1085 // state is not atomic w.r.t. GC, as this scenario demonstrates: | |
1086 // Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted. | |
1087 // VM thread changes sync state to synchronizing and suspends threads for GC. | |
1088 // Thread A is resumed to finish this native method, but doesn't block here since it | |
1089 // didn't see any synchronization is progress, and escapes. | |
1090 __ set(_thread_in_native_trans, G3_scratch); | |
1091 __ st(G3_scratch, thread_state); | |
1092 if(os::is_MP()) { | |
1093 if (UseMembar) { | |
1094 // Force this write out before the read below | |
1095 __ membar(Assembler::StoreLoad); | |
1096 } else { | |
1097 // Write serialization page so VM thread can do a pseudo remote membar. | |
1098 // We use the current thread pointer to calculate a thread specific | |
1099 // offset to write to within the page. This minimizes bus traffic | |
1100 // due to cache line collision. | |
1101 __ serialize_memory(G2_thread, G1_scratch, G3_scratch); | |
1102 } | |
1103 } | |
1104 __ load_contents(sync_state, G3_scratch); | |
1105 __ cmp(G3_scratch, SafepointSynchronize::_not_synchronized); | |
1106 | |
1107 Label L; | |
1108 __ br(Assembler::notEqual, false, Assembler::pn, L); | |
727 | 1109 __ delayed()->ld(G2_thread, JavaThread::suspend_flags_offset(), G3_scratch); |
3839 | 1110 __ cmp_and_br_short(G3_scratch, 0, Assembler::equal, Assembler::pt, no_block); |
0 | 1111 __ bind(L); |
1112 | |
1113 // Block. Save any potential method result value before the operation and | |
1114 // use a leaf call to leave the last_Java_frame setup undisturbed. | |
1115 save_native_result(); | |
1116 __ call_VM_leaf(L7_thread_cache, | |
1117 CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans), | |
1118 G2_thread); | |
1119 | |
1120 // Restore any method result value | |
1121 restore_native_result(); | |
1122 __ bind(no_block); | |
1123 } | |
1124 | |
1125 // Clear the frame anchor now | |
1126 | |
1127 __ reset_last_Java_frame(); | |
1128 | |
1129 // Move the result handler address | |
1130 __ mov(Lscratch, G3_scratch); | |
1131 // return possible result to the outer frame | |
1132 #ifndef __LP64 | |
1133 __ mov(O0, I0); | |
1134 __ restore(O1, G0, O1); | |
1135 #else | |
1136 __ restore(O0, G0, O0); | |
1137 #endif /* __LP64 */ | |
1138 | |
1139 // Move result handler to expected register | |
1140 __ mov(G3_scratch, Lscratch); | |
1141 | |
1142 // Back in normal (native) interpreter frame. State is thread_in_native_trans | |
1143 // switch to thread_in_Java. | |
1144 | |
1145 __ set(_thread_in_Java, G3_scratch); | |
1146 __ st(G3_scratch, thread_state); | |
1147 | |
1148 // reset handle block | |
727 | 1149 __ ld_ptr(G2_thread, JavaThread::active_handles_offset(), G3_scratch); |
0 | 1150 __ st_ptr(G0, G3_scratch, JNIHandleBlock::top_offset_in_bytes()); |
1151 | |
1152 // If we have an oop result store it where it will be safe for any further gc | |
1153 // until we return now that we've released the handle it might be protected by | |
1154 | |
1155 { | |
1156 Label no_oop, store_result; | |
1157 | |
1158 __ set((intptr_t)AbstractInterpreter::result_handler(T_OBJECT), G3_scratch); | |
3839 | 1159 __ cmp_and_brx_short(G3_scratch, Lscratch, Assembler::notEqual, Assembler::pt, no_oop); |
0 | 1160 __ addcc(G0, O0, O0); |
1161 __ brx(Assembler::notZero, true, Assembler::pt, store_result); // if result is not NULL: | |
1162 __ delayed()->ld_ptr(O0, 0, O0); // unbox it | |
1163 __ mov(G0, O0); | |
1164 | |
1165 __ bind(store_result); | |
1166 // Store it where gc will look for it and result handler expects it. | |
1167 __ st_ptr(O0, FP, (frame::interpreter_frame_oop_temp_offset*wordSize) + STACK_BIAS); | |
1168 | |
1169 __ bind(no_oop); | |
1170 | |
1171 } | |
1172 | |
1173 | |
1174 // handle exceptions (exception handling will handle unlocking!) | |
1175 { Label L; | |
727 | 1176 Address exception_addr(G2_thread, Thread::pending_exception_offset()); |
0 | 1177 __ ld_ptr(exception_addr, Gtemp); |
3839 | 1178 __ br_null_short(Gtemp, Assembler::pt, L); |
0 | 1179 // Note: This could be handled more efficiently since we know that the native |
1180 // method doesn't have an exception handler. We could directly return | |
1181 // to the exception handler for the caller. | |
1182 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception)); | |
1183 __ should_not_reach_here(); | |
1184 __ bind(L); | |
1185 } | |
1186 | |
1187 // JVMTI support (preserves thread register) | |
1188 __ notify_method_exit(true, ilgl, InterpreterMacroAssembler::NotifyJVMTI); | |
1189 | |
1190 if (synchronized) { | |
1191 // save and restore any potential method result value around the unlocking operation | |
1192 save_native_result(); | |
1193 | |
1194 __ add( __ top_most_monitor(), O1); | |
1195 __ unlock_object(O1); | |
1196 | |
1197 restore_native_result(); | |
1198 } | |
1199 | |
1200 #if defined(COMPILER2) && !defined(_LP64) | |
1201 | |
1202 // C2 expects long results in G1 we can't tell if we're returning to interpreted | |
1203 // or compiled so just be safe. | |
1204 | |
1205 __ sllx(O0, 32, G1); // Shift bits into high G1 | |
1206 __ srl (O1, 0, O1); // Zero extend O1 | |
1207 __ or3 (O1, G1, G1); // OR 64 bits into G1 | |
1208 | |
1209 #endif /* COMPILER2 && !_LP64 */ | |
1210 | |
1211 // dispose of return address and remove activation | |
1212 #ifdef ASSERT | |
1213 { | |
1214 Label ok; | |
3839 | 1215 __ cmp_and_brx_short(I5_savedSP, FP, Assembler::greaterEqualUnsigned, Assembler::pt, ok); |
0 | 1216 __ stop("bad I5_savedSP value"); |
1217 __ should_not_reach_here(); | |
1218 __ bind(ok); | |
1219 } | |
1220 #endif | |
1221 if (TraceJumps) { | |
1222 // Move target to register that is recordable | |
1223 __ mov(Lscratch, G3_scratch); | |
1224 __ JMP(G3_scratch, 0); | |
1225 } else { | |
1226 __ jmp(Lscratch, 0); | |
1227 } | |
1228 __ delayed()->nop(); | |
1229 | |
1230 | |
1231 if (inc_counter) { | |
1232 // handle invocation counter overflow | |
1233 __ bind(invocation_counter_overflow); | |
1234 generate_counter_overflow(Lcontinue); | |
1235 } | |
1236 | |
1237 | |
1238 | |
1239 return entry; | |
1240 } | |
1241 | |
1242 | |
1243 // Generic method entry to (asm) interpreter | |
1244 //------------------------------------------------------------------------------------------------------------------------ | |
1245 // | |
1246 address InterpreterGenerator::generate_normal_entry(bool synchronized) { | |
1247 address entry = __ pc(); | |
1248 | |
1249 bool inc_counter = UseCompiler || CountCompiledCalls; | |
1250 | |
1251 // the following temporary registers are used during frame creation | |
1252 const Register Gtmp1 = G3_scratch ; | |
1253 const Register Gtmp2 = G1_scratch; | |
1254 | |
1255 // make sure registers are different! | |
1256 assert_different_registers(G2_thread, G5_method, Gargs, Gtmp1, Gtmp2); | |
1257 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1258 const Address size_of_parameters(G5_method, Method::size_of_parameters_offset()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1259 const Address size_of_locals (G5_method, Method::size_of_locals_offset()); |
0 | 1260 // Seems like G5_method is live at the point this is used. So we could make this look consistent |
1261 // and use in the asserts. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1262 const Address access_flags (Lmethod, Method::access_flags_offset()); |
0 | 1263 |
1264 const Register Glocals_size = G3; | |
1265 assert_different_registers(Glocals_size, G4_scratch, Gframe_size); | |
1266 | |
1267 // make sure method is not native & not abstract | |
1268 // rethink these assertions - they can be simplified and shared (gri 2/25/2000) | |
1269 #ifdef ASSERT | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1270 __ ld(G5_method, Method::access_flags_offset(), Gtmp1); |
0 | 1271 { |
1272 Label L; | |
1273 __ btst(JVM_ACC_NATIVE, Gtmp1); | |
1274 __ br(Assembler::zero, false, Assembler::pt, L); | |
1275 __ delayed()->nop(); | |
1276 __ stop("tried to execute native method as non-native"); | |
1277 __ bind(L); | |
1278 } | |
1279 { Label L; | |
1280 __ btst(JVM_ACC_ABSTRACT, Gtmp1); | |
1281 __ br(Assembler::zero, false, Assembler::pt, L); | |
1282 __ delayed()->nop(); | |
1283 __ stop("tried to execute abstract method as non-abstract"); | |
1284 __ bind(L); | |
1285 } | |
1286 #endif // ASSERT | |
1287 | |
1288 // generate the code to allocate the interpreter stack frame | |
1289 | |
1290 generate_fixed_frame(false); | |
1291 | |
1292 #ifdef FAST_DISPATCH | |
1293 __ set((intptr_t)Interpreter::dispatch_table(), IdispatchTables); | |
1294 // set bytecode dispatch table base | |
1295 #endif | |
1296 | |
1297 // | |
1298 // Code to initialize the extra (i.e. non-parm) locals | |
1299 // | |
1300 Register init_value = noreg; // will be G0 if we must clear locals | |
1301 // The way the code was setup before zerolocals was always true for vanilla java entries. | |
1302 // It could only be false for the specialized entries like accessor or empty which have | |
1303 // no extra locals so the testing was a waste of time and the extra locals were always | |
1304 // initialized. We removed this extra complication to already over complicated code. | |
1305 | |
1306 init_value = G0; | |
1307 Label clear_loop; | |
1308 | |
1309 // NOTE: If you change the frame layout, this code will need to | |
1310 // be updated! | |
1311 __ lduh( size_of_locals, O2 ); | |
1312 __ lduh( size_of_parameters, O1 ); | |
1506 | 1313 __ sll( O2, Interpreter::logStackElementSize, O2); |
1314 __ sll( O1, Interpreter::logStackElementSize, O1 ); | |
0 | 1315 __ sub( Llocals, O2, O2 ); |
1316 __ sub( Llocals, O1, O1 ); | |
1317 | |
1318 __ bind( clear_loop ); | |
1319 __ inc( O2, wordSize ); | |
1320 | |
1321 __ cmp( O2, O1 ); | |
1322 __ brx( Assembler::lessEqualUnsigned, true, Assembler::pt, clear_loop ); | |
1323 __ delayed()->st_ptr( init_value, O2, 0 ); | |
1324 | |
727 | 1325 const Address do_not_unlock_if_synchronized(G2_thread, |
1326 JavaThread::do_not_unlock_if_synchronized_offset()); | |
0 | 1327 // Since at this point in the method invocation the exception handler |
1328 // would try to exit the monitor of synchronized methods which hasn't | |
1329 // been entered yet, we set the thread local variable | |
1330 // _do_not_unlock_if_synchronized to true. If any exception was thrown by | |
1331 // runtime, exception handling i.e. unlock_if_synchronized_method will | |
1332 // check this thread local flag. | |
1333 __ movbool(true, G3_scratch); | |
1334 __ stbool(G3_scratch, do_not_unlock_if_synchronized); | |
1335 | |
1336 // increment invocation counter and check for overflow | |
1337 // | |
1338 // Note: checking for negative value instead of overflow | |
1339 // so we have a 'sticky' overflow test (may be of | |
1340 // importance as soon as we have true MT/MP) | |
1341 Label invocation_counter_overflow; | |
1342 Label profile_method; | |
1343 Label profile_method_continue; | |
1344 Label Lcontinue; | |
1345 if (inc_counter) { | |
1346 generate_counter_incr(&invocation_counter_overflow, &profile_method, &profile_method_continue); | |
1347 if (ProfileInterpreter) { | |
1348 __ bind(profile_method_continue); | |
1349 } | |
1350 } | |
1351 __ bind(Lcontinue); | |
1352 | |
1353 bang_stack_shadow_pages(false); | |
1354 | |
1355 // reset the _do_not_unlock_if_synchronized flag | |
1356 __ stbool(G0, do_not_unlock_if_synchronized); | |
1357 | |
1358 // check for synchronized methods | |
1359 // Must happen AFTER invocation_counter check and stack overflow check, | |
1360 // so method is not locked if overflows. | |
1361 | |
1362 if (synchronized) { | |
1363 lock_method(); | |
1364 } else { | |
1365 #ifdef ASSERT | |
1366 { Label ok; | |
1367 __ ld(access_flags, O0); | |
1368 __ btst(JVM_ACC_SYNCHRONIZED, O0); | |
1369 __ br( Assembler::zero, false, Assembler::pt, ok); | |
1370 __ delayed()->nop(); | |
1371 __ stop("method needs synchronization"); | |
1372 __ bind(ok); | |
1373 } | |
1374 #endif // ASSERT | |
1375 } | |
1376 | |
1377 // start execution | |
1378 | |
1379 __ verify_thread(); | |
1380 | |
1381 // jvmti support | |
1382 __ notify_method_entry(); | |
1383 | |
1384 // start executing instructions | |
1385 __ dispatch_next(vtos); | |
1386 | |
1387 | |
1388 if (inc_counter) { | |
1389 if (ProfileInterpreter) { | |
1390 // We have decided to profile this method in the interpreter | |
1391 __ bind(profile_method); | |
1392 | |
2118
dd031b2226de
4930919: race condition in MDO creation at back branch locations
iveresov
parents:
1972
diff
changeset
|
1393 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method)); |
dd031b2226de
4930919: race condition in MDO creation at back branch locations
iveresov
parents:
1972
diff
changeset
|
1394 __ set_method_data_pointer_for_bcp(); |
3839 | 1395 __ ba_short(profile_method_continue); |
0 | 1396 } |
1397 | |
1398 // handle invocation counter overflow | |
1399 __ bind(invocation_counter_overflow); | |
1400 generate_counter_overflow(Lcontinue); | |
1401 } | |
1402 | |
1403 | |
1404 return entry; | |
1405 } | |
1406 | |
1407 | |
1408 //---------------------------------------------------------------------------------------------------- | |
1409 // Entry points & stack frame layout | |
1410 // | |
1411 // Here we generate the various kind of entries into the interpreter. | |
1412 // The two main entry type are generic bytecode methods and native call method. | |
1413 // These both come in synchronized and non-synchronized versions but the | |
1414 // frame layout they create is very similar. The other method entry | |
1415 // types are really just special purpose entries that are really entry | |
1416 // and interpretation all in one. These are for trivial methods like | |
1417 // accessor, empty, or special math methods. | |
1418 // | |
1419 // When control flow reaches any of the entry types for the interpreter | |
1420 // the following holds -> | |
1421 // | |
1422 // C2 Calling Conventions: | |
1423 // | |
1424 // The entry code below assumes that the following registers are set | |
1425 // when coming in: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1426 // G5_method: holds the Method* of the method to call |
0 | 1427 // Lesp: points to the TOS of the callers expression stack |
1428 // after having pushed all the parameters | |
1429 // | |
1430 // The entry code does the following to setup an interpreter frame | |
1431 // pop parameters from the callers stack by adjusting Lesp | |
1432 // set O0 to Lesp | |
1433 // compute X = (max_locals - num_parameters) | |
1434 // bump SP up by X to accomadate the extra locals | |
1435 // compute X = max_expression_stack | |
1436 // + vm_local_words | |
1437 // + 16 words of register save area | |
1438 // save frame doing a save sp, -X, sp growing towards lower addresses | |
1439 // set Lbcp, Lmethod, LcpoolCache | |
1440 // set Llocals to i0 | |
1441 // set Lmonitors to FP - rounded_vm_local_words | |
1442 // set Lesp to Lmonitors - 4 | |
1443 // | |
1444 // The frame has now been setup to do the rest of the entry code | |
1445 | |
1446 // Try this optimization: Most method entries could live in a | |
1447 // "one size fits all" stack frame without all the dynamic size | |
1448 // calculations. It might be profitable to do all this calculation | |
1449 // statically and approximately for "small enough" methods. | |
1450 | |
1451 //----------------------------------------------------------------------------------------------- | |
1452 | |
1453 // C1 Calling conventions | |
1454 // | |
1455 // Upon method entry, the following registers are setup: | |
1456 // | |
1457 // g2 G2_thread: current thread | |
1458 // g5 G5_method: method to activate | |
1459 // g4 Gargs : pointer to last argument | |
1460 // | |
1461 // | |
1462 // Stack: | |
1463 // | |
1464 // +---------------+ <--- sp | |
1465 // | | | |
1466 // : reg save area : | |
1467 // | | | |
1468 // +---------------+ <--- sp + 0x40 | |
1469 // | | | |
1470 // : extra 7 slots : note: these slots are not really needed for the interpreter (fix later) | |
1471 // | | | |
1472 // +---------------+ <--- sp + 0x5c | |
1473 // | | | |
1474 // : free : | |
1475 // | | | |
1476 // +---------------+ <--- Gargs | |
1477 // | | | |
1478 // : arguments : | |
1479 // | | | |
1480 // +---------------+ | |
1481 // | | | |
1482 // | |
1483 // | |
1484 // | |
1485 // AFTER FRAME HAS BEEN SETUP for method interpretation the stack looks like: | |
1486 // | |
1487 // +---------------+ <--- sp | |
1488 // | | | |
1489 // : reg save area : | |
1490 // | | | |
1491 // +---------------+ <--- sp + 0x40 | |
1492 // | | | |
1493 // : extra 7 slots : note: these slots are not really needed for the interpreter (fix later) | |
1494 // | | | |
1495 // +---------------+ <--- sp + 0x5c | |
1496 // | | | |
1497 // : : | |
1498 // | | <--- Lesp | |
1499 // +---------------+ <--- Lmonitors (fp - 0x18) | |
1500 // | VM locals | | |
1501 // +---------------+ <--- fp | |
1502 // | | | |
1503 // : reg save area : | |
1504 // | | | |
1505 // +---------------+ <--- fp + 0x40 | |
1506 // | | | |
1507 // : extra 7 slots : note: these slots are not really needed for the interpreter (fix later) | |
1508 // | | | |
1509 // +---------------+ <--- fp + 0x5c | |
1510 // | | | |
1511 // : free : | |
1512 // | | | |
1513 // +---------------+ | |
1514 // | | | |
1515 // : nonarg locals : | |
1516 // | | | |
1517 // +---------------+ | |
1518 // | | | |
1519 // : arguments : | |
1520 // | | <--- Llocals | |
1521 // +---------------+ <--- Gargs | |
1522 // | | | |
1523 | |
1524 static int size_activation_helper(int callee_extra_locals, int max_stack, int monitor_size) { | |
1525 | |
1526 // Figure out the size of an interpreter frame (in words) given that we have a fully allocated | |
1527 // expression stack, the callee will have callee_extra_locals (so we can account for | |
1528 // frame extension) and monitor_size for monitors. Basically we need to calculate | |
1529 // this exactly like generate_fixed_frame/generate_compute_interpreter_state. | |
1530 // | |
1531 // | |
1532 // The big complicating thing here is that we must ensure that the stack stays properly | |
1533 // aligned. This would be even uglier if monitor size wasn't modulo what the stack | |
1534 // needs to be aligned for). We are given that the sp (fp) is already aligned by | |
1535 // the caller so we must ensure that it is properly aligned for our callee. | |
1536 // | |
1537 const int rounded_vm_local_words = | |
1538 round_to(frame::interpreter_frame_vm_local_words,WordsPerLong); | |
1539 // callee_locals and max_stack are counts, not the size in frame. | |
1540 const int locals_size = | |
1506 | 1541 round_to(callee_extra_locals * Interpreter::stackElementWords, WordsPerLong); |
1542 const int max_stack_words = max_stack * Interpreter::stackElementWords; | |
0 | 1543 return (round_to((max_stack_words |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1544 //6815692//+ Method::extra_stack_words() |
0 | 1545 + rounded_vm_local_words |
1546 + frame::memory_parameter_word_sp_offset), WordsPerLong) | |
1547 // already rounded | |
1548 + locals_size + monitor_size); | |
1549 } | |
1550 | |
1551 // How much stack a method top interpreter activation needs in words. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1552 int AbstractInterpreter::size_top_interpreter_activation(Method* method) { |
0 | 1553 |
1554 // See call_stub code | |
1555 int call_stub_size = round_to(7 + frame::memory_parameter_word_sp_offset, | |
1556 WordsPerLong); // 7 + register save area | |
1557 | |
1558 // Save space for one monitor to get into the interpreted method in case | |
1559 // the method is synchronized | |
1560 int monitor_size = method->is_synchronized() ? | |
1561 1*frame::interpreter_frame_monitor_size() : 0; | |
1562 return size_activation_helper(method->max_locals(), method->max_stack(), | |
1563 monitor_size) + call_stub_size; | |
1564 } | |
1565 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1566 int AbstractInterpreter::layout_activation(Method* method, |
0 | 1567 int tempcount, |
1568 int popframe_extra_args, | |
1569 int moncount, | |
3369
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1570 int caller_actual_parameters, |
0 | 1571 int callee_param_count, |
1572 int callee_local_count, | |
1573 frame* caller, | |
1574 frame* interpreter_frame, | |
1575 bool is_top_frame) { | |
1576 // Note: This calculation must exactly parallel the frame setup | |
1577 // in InterpreterGenerator::generate_fixed_frame. | |
1578 // If f!=NULL, set up the following variables: | |
1579 // - Lmethod | |
1580 // - Llocals | |
1581 // - Lmonitors (to the indicated number of monitors) | |
1582 // - Lesp (to the indicated number of temps) | |
1583 // The frame f (if not NULL) on entry is a description of the caller of the frame | |
1584 // we are about to layout. We are guaranteed that we will be able to fill in a | |
1585 // new interpreter frame as its callee (i.e. the stack space is allocated and | |
1586 // the amount was determined by an earlier call to this method with f == NULL). | |
1587 // On return f (if not NULL) while describe the interpreter frame we just layed out. | |
1588 | |
1589 int monitor_size = moncount * frame::interpreter_frame_monitor_size(); | |
1590 int rounded_vm_local_words = round_to(frame::interpreter_frame_vm_local_words,WordsPerLong); | |
1591 | |
1592 assert(monitor_size == round_to(monitor_size, WordsPerLong), "must align"); | |
1593 // | |
1594 // Note: if you look closely this appears to be doing something much different | |
1595 // than generate_fixed_frame. What is happening is this. On sparc we have to do | |
1596 // this dance with interpreter_sp_adjustment because the window save area would | |
1597 // appear just below the bottom (tos) of the caller's java expression stack. Because | |
1598 // the interpreter want to have the locals completely contiguous generate_fixed_frame | |
1599 // will adjust the caller's sp for the "extra locals" (max_locals - parameter_size). | |
1600 // Now in generate_fixed_frame the extension of the caller's sp happens in the callee. | |
1601 // In this code the opposite occurs the caller adjusts it's own stack base on the callee. | |
1602 // This is mostly ok but it does cause a problem when we get to the initial frame (the oldest) | |
1603 // because the oldest frame would have adjust its callers frame and yet that frame | |
1604 // already exists and isn't part of this array of frames we are unpacking. So at first | |
1605 // glance this would seem to mess up that frame. However Deoptimization::fetch_unroll_info_helper() | |
1606 // will after it calculates all of the frame's on_stack_size()'s will then figure out the | |
1607 // amount to adjust the caller of the initial (oldest) frame and the calculation will all | |
1608 // add up. It does seem like it simpler to account for the adjustment here (and remove the | |
1609 // callee... parameters here). However this would mean that this routine would have to take | |
1610 // the caller frame as input so we could adjust its sp (and set it's interpreter_sp_adjustment) | |
1611 // and run the calling loop in the reverse order. This would also would appear to mean making | |
1612 // this code aware of what the interactions are when that initial caller fram was an osr or | |
1613 // other adapter frame. deoptimization is complicated enough and hard enough to debug that | |
1614 // there is no sense in messing working code. | |
1615 // | |
1616 | |
1617 int rounded_cls = round_to((callee_local_count - callee_param_count), WordsPerLong); | |
1618 assert(rounded_cls == round_to(rounded_cls, WordsPerLong), "must align"); | |
1619 | |
1620 int raw_frame_size = size_activation_helper(rounded_cls, method->max_stack(), | |
1621 monitor_size); | |
1622 | |
1623 if (interpreter_frame != NULL) { | |
1624 // The skeleton frame must already look like an interpreter frame | |
1625 // even if not fully filled out. | |
1626 assert(interpreter_frame->is_interpreted_frame(), "Must be interpreted frame"); | |
1627 | |
1628 intptr_t* fp = interpreter_frame->fp(); | |
1629 | |
1630 JavaThread* thread = JavaThread::current(); | |
1631 RegisterMap map(thread, false); | |
1632 // More verification that skeleton frame is properly walkable | |
1633 assert(fp == caller->sp(), "fp must match"); | |
1634 | |
1635 intptr_t* montop = fp - rounded_vm_local_words; | |
1636 | |
1637 // preallocate monitors (cf. __ add_monitor_to_stack) | |
1638 intptr_t* monitors = montop - monitor_size; | |
1639 | |
1640 // preallocate stack space | |
1641 intptr_t* esp = monitors - 1 - | |
1506 | 1642 (tempcount * Interpreter::stackElementWords) - |
0 | 1643 popframe_extra_args; |
1644 | |
1506 | 1645 int local_words = method->max_locals() * Interpreter::stackElementWords; |
3369
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1646 NEEDS_CLEANUP; |
0 | 1647 intptr_t* locals; |
3369
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1648 if (caller->is_interpreted_frame()) { |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1649 // Can force the locals area to end up properly overlapping the top of the expression stack. |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1650 intptr_t* Lesp_ptr = caller->interpreter_frame_tos_address() - 1; |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1651 // Note that this computation means we replace size_of_parameters() values from the caller |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1652 // interpreter frame's expression stack with our argument locals |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1653 int parm_words = caller_actual_parameters * Interpreter::stackElementWords; |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1654 locals = Lesp_ptr + parm_words; |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1655 int delta = local_words - parm_words; |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1656 int computed_sp_adjustment = (delta > 0) ? round_to(delta, WordsPerLong) : 0; |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1657 *interpreter_frame->register_addr(I5_savedSP) = (intptr_t) (fp + computed_sp_adjustment) - STACK_BIAS; |
0 | 1658 } else { |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6123
diff
changeset
|
1659 assert(caller->is_compiled_frame() || caller->is_entry_frame(), "only possible cases"); |
3369
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1660 // Don't have Lesp available; lay out locals block in the caller |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1661 // adjacent to the register window save area. |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1662 // |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1663 // Compiled frames do not allocate a varargs area which is why this if |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1664 // statement is needed. |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1665 // |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1666 if (caller->is_compiled_frame()) { |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1667 locals = fp + frame::register_save_words + local_words - 1; |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1668 } else { |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1669 locals = fp + frame::memory_parameter_word_sp_offset + local_words - 1; |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1670 } |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1671 if (!caller->is_entry_frame()) { |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1672 // Caller wants his own SP back |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1673 int caller_frame_size = caller->cb()->frame_size(); |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1674 *interpreter_frame->register_addr(I5_savedSP) = (intptr_t)(caller->fp() - caller_frame_size) - STACK_BIAS; |
0 | 1675 } |
1676 } | |
1677 if (TraceDeoptimization) { | |
1678 if (caller->is_entry_frame()) { | |
1679 // make sure I5_savedSP and the entry frames notion of saved SP | |
1680 // agree. This assertion duplicate a check in entry frame code | |
1681 // but catches the failure earlier. | |
1682 assert(*caller->register_addr(Lscratch) == *interpreter_frame->register_addr(I5_savedSP), | |
1683 "would change callers SP"); | |
1684 } | |
1685 if (caller->is_entry_frame()) { | |
1686 tty->print("entry "); | |
1687 } | |
1688 if (caller->is_compiled_frame()) { | |
1689 tty->print("compiled "); | |
1690 if (caller->is_deoptimized_frame()) { | |
1691 tty->print("(deopt) "); | |
1692 } | |
1693 } | |
1694 if (caller->is_interpreted_frame()) { | |
1695 tty->print("interpreted "); | |
1696 } | |
1697 tty->print_cr("caller fp=0x%x sp=0x%x", caller->fp(), caller->sp()); | |
1698 tty->print_cr("save area = 0x%x, 0x%x", caller->sp(), caller->sp() + 16); | |
1699 tty->print_cr("save area = 0x%x, 0x%x", caller->fp(), caller->fp() + 16); | |
1700 tty->print_cr("interpreter fp=0x%x sp=0x%x", interpreter_frame->fp(), interpreter_frame->sp()); | |
1701 tty->print_cr("save area = 0x%x, 0x%x", interpreter_frame->sp(), interpreter_frame->sp() + 16); | |
1702 tty->print_cr("save area = 0x%x, 0x%x", interpreter_frame->fp(), interpreter_frame->fp() + 16); | |
1703 tty->print_cr("Llocals = 0x%x", locals); | |
1704 tty->print_cr("Lesp = 0x%x", esp); | |
1705 tty->print_cr("Lmonitors = 0x%x", monitors); | |
1706 } | |
1707 | |
1708 if (method->max_locals() > 0) { | |
1709 assert(locals < caller->sp() || locals >= (caller->sp() + 16), "locals in save area"); | |
1710 assert(locals < caller->fp() || locals > (caller->fp() + 16), "locals in save area"); | |
1711 assert(locals < interpreter_frame->sp() || locals > (interpreter_frame->sp() + 16), "locals in save area"); | |
1712 assert(locals < interpreter_frame->fp() || locals >= (interpreter_frame->fp() + 16), "locals in save area"); | |
1713 } | |
1714 #ifdef _LP64 | |
1715 assert(*interpreter_frame->register_addr(I5_savedSP) & 1, "must be odd"); | |
1716 #endif | |
1717 | |
1718 *interpreter_frame->register_addr(Lmethod) = (intptr_t) method; | |
1719 *interpreter_frame->register_addr(Llocals) = (intptr_t) locals; | |
1720 *interpreter_frame->register_addr(Lmonitors) = (intptr_t) monitors; | |
1721 *interpreter_frame->register_addr(Lesp) = (intptr_t) esp; | |
1722 // Llast_SP will be same as SP as there is no adapter space | |
1723 *interpreter_frame->register_addr(Llast_SP) = (intptr_t) interpreter_frame->sp() - STACK_BIAS; | |
1724 *interpreter_frame->register_addr(LcpoolCache) = (intptr_t) method->constants()->cache(); | |
1725 #ifdef FAST_DISPATCH | |
1726 *interpreter_frame->register_addr(IdispatchTables) = (intptr_t) Interpreter::dispatch_table(); | |
1727 #endif | |
1728 | |
1729 | |
1730 #ifdef ASSERT | |
1731 BasicObjectLock* mp = (BasicObjectLock*)monitors; | |
1732 | |
1733 assert(interpreter_frame->interpreter_frame_method() == method, "method matches"); | |
1506 | 1734 assert(interpreter_frame->interpreter_frame_local_at(9) == (intptr_t *)((intptr_t)locals - (9 * Interpreter::stackElementSize)), "locals match"); |
0 | 1735 assert(interpreter_frame->interpreter_frame_monitor_end() == mp, "monitor_end matches"); |
1736 assert(((intptr_t *)interpreter_frame->interpreter_frame_monitor_begin()) == ((intptr_t *)mp)+monitor_size, "monitor_begin matches"); | |
1737 assert(interpreter_frame->interpreter_frame_tos_address()-1 == esp, "esp matches"); | |
1738 | |
1739 // check bounds | |
1740 intptr_t* lo = interpreter_frame->sp() + (frame::memory_parameter_word_sp_offset - 1); | |
1741 intptr_t* hi = interpreter_frame->fp() - rounded_vm_local_words; | |
1742 assert(lo < monitors && montop <= hi, "monitors in bounds"); | |
1743 assert(lo <= esp && esp < monitors, "esp in bounds"); | |
1744 #endif // ASSERT | |
1745 } | |
1746 | |
1747 return raw_frame_size; | |
1748 } | |
1749 | |
1750 //---------------------------------------------------------------------------------------------------- | |
1751 // Exceptions | |
1752 void TemplateInterpreterGenerator::generate_throw_exception() { | |
1753 | |
1754 // Entry point in previous activation (i.e., if the caller was interpreted) | |
1755 Interpreter::_rethrow_exception_entry = __ pc(); | |
1756 // O0: exception | |
1757 | |
1758 // entry point for exceptions thrown within interpreter code | |
1759 Interpreter::_throw_exception_entry = __ pc(); | |
1760 __ verify_thread(); | |
1761 // expression stack is undefined here | |
1762 // O0: exception, i.e. Oexception | |
1763 // Lbcp: exception bcx | |
1764 __ verify_oop(Oexception); | |
1765 | |
1766 | |
1767 // expression stack must be empty before entering the VM in case of an exception | |
1768 __ empty_expression_stack(); | |
1769 // find exception handler address and preserve exception oop | |
1770 // call C routine to find handler and jump to it | |
1771 __ call_VM(O1, CAST_FROM_FN_PTR(address, InterpreterRuntime::exception_handler_for_exception), Oexception); | |
1772 __ push_ptr(O1); // push exception for exception handler bytecodes | |
1773 | |
1774 __ JMP(O0, 0); // jump to exception handler (may be remove activation entry!) | |
1775 __ delayed()->nop(); | |
1776 | |
1777 | |
1778 // if the exception is not handled in the current frame | |
1779 // the frame is removed and the exception is rethrown | |
1780 // (i.e. exception continuation is _rethrow_exception) | |
1781 // | |
1782 // Note: At this point the bci is still the bxi for the instruction which caused | |
1783 // the exception and the expression stack is empty. Thus, for any VM calls | |
1784 // at this point, GC will find a legal oop map (with empty expression stack). | |
1785 | |
1786 // in current activation | |
1787 // tos: exception | |
1788 // Lbcp: exception bcp | |
1789 | |
1790 // | |
1791 // JVMTI PopFrame support | |
1792 // | |
1793 | |
1794 Interpreter::_remove_activation_preserving_args_entry = __ pc(); | |
727 | 1795 Address popframe_condition_addr(G2_thread, JavaThread::popframe_condition_offset()); |
0 | 1796 // Set the popframe_processing bit in popframe_condition indicating that we are |
1797 // currently handling popframe, so that call_VMs that may happen later do not trigger new | |
1798 // popframe handling cycles. | |
1799 | |
1800 __ ld(popframe_condition_addr, G3_scratch); | |
1801 __ or3(G3_scratch, JavaThread::popframe_processing_bit, G3_scratch); | |
1802 __ stw(G3_scratch, popframe_condition_addr); | |
1803 | |
1804 // Empty the expression stack, as in normal exception handling | |
1805 __ empty_expression_stack(); | |
1806 __ unlock_if_synchronized_method(vtos, /* throw_monitor_exception */ false, /* install_monitor_exception */ false); | |
1807 | |
1808 { | |
1809 // Check to see whether we are returning to a deoptimized frame. | |
1810 // (The PopFrame call ensures that the caller of the popped frame is | |
1811 // either interpreted or compiled and deoptimizes it if compiled.) | |
1812 // In this case, we can't call dispatch_next() after the frame is | |
1813 // popped, but instead must save the incoming arguments and restore | |
1814 // them after deoptimization has occurred. | |
1815 // | |
1816 // Note that we don't compare the return PC against the | |
1817 // deoptimization blob's unpack entry because of the presence of | |
1818 // adapter frames in C2. | |
1819 Label caller_not_deoptimized; | |
1820 __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, InterpreterRuntime::interpreter_contains), I7); | |
3839 | 1821 __ br_notnull_short(O0, Assembler::pt, caller_not_deoptimized); |
0 | 1822 |
1823 const Register Gtmp1 = G3_scratch; | |
1824 const Register Gtmp2 = G1_scratch; | |
1825 | |
1826 // Compute size of arguments for saving when returning to deoptimized caller | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1827 __ lduh(Lmethod, in_bytes(Method::size_of_parameters_offset()), Gtmp1); |
1506 | 1828 __ sll(Gtmp1, Interpreter::logStackElementSize, Gtmp1); |
0 | 1829 __ sub(Llocals, Gtmp1, Gtmp2); |
1830 __ add(Gtmp2, wordSize, Gtmp2); | |
1831 // Save these arguments | |
1832 __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, Deoptimization::popframe_preserve_args), G2_thread, Gtmp1, Gtmp2); | |
1833 // Inform deoptimization that it is responsible for restoring these arguments | |
1834 __ set(JavaThread::popframe_force_deopt_reexecution_bit, Gtmp1); | |
727 | 1835 Address popframe_condition_addr(G2_thread, JavaThread::popframe_condition_offset()); |
0 | 1836 __ st(Gtmp1, popframe_condition_addr); |
1837 | |
1838 // Return from the current method | |
1839 // The caller's SP was adjusted upon method entry to accomodate | |
1840 // the callee's non-argument locals. Undo that adjustment. | |
1841 __ ret(); | |
1842 __ delayed()->restore(I5_savedSP, G0, SP); | |
1843 | |
1844 __ bind(caller_not_deoptimized); | |
1845 } | |
1846 | |
1847 // Clear the popframe condition flag | |
1848 __ stw(G0 /* popframe_inactive */, popframe_condition_addr); | |
1849 | |
1850 // Get out of the current method (how this is done depends on the particular compiler calling | |
1851 // convention that the interpreter currently follows) | |
1852 // The caller's SP was adjusted upon method entry to accomodate | |
1853 // the callee's non-argument locals. Undo that adjustment. | |
1854 __ restore(I5_savedSP, G0, SP); | |
1855 // The method data pointer was incremented already during | |
1856 // call profiling. We have to restore the mdp for the current bcp. | |
1857 if (ProfileInterpreter) { | |
1858 __ set_method_data_pointer_for_bcp(); | |
1859 } | |
1860 // Resume bytecode interpretation at the current bcp | |
1861 __ dispatch_next(vtos); | |
1862 // end of JVMTI PopFrame support | |
1863 | |
1864 Interpreter::_remove_activation_entry = __ pc(); | |
1865 | |
1866 // preserve exception over this code sequence (remove activation calls the vm, but oopmaps are not correct here) | |
1867 __ pop_ptr(Oexception); // get exception | |
1868 | |
1869 // Intel has the following comment: | |
1870 //// remove the activation (without doing throws on illegalMonitorExceptions) | |
1871 // They remove the activation without checking for bad monitor state. | |
1872 // %%% We should make sure this is the right semantics before implementing. | |
1873 | |
1874 __ set_vm_result(Oexception); | |
1875 __ unlock_if_synchronized_method(vtos, /* throw_monitor_exception */ false); | |
1876 | |
1877 __ notify_method_exit(false, vtos, InterpreterMacroAssembler::SkipNotifyJVMTI); | |
1878 | |
1879 __ get_vm_result(Oexception); | |
1880 __ verify_oop(Oexception); | |
1881 | |
1882 const int return_reg_adjustment = frame::pc_return_offset; | |
727 | 1883 Address issuing_pc_addr(I7, return_reg_adjustment); |
0 | 1884 |
1885 // We are done with this activation frame; find out where to go next. | |
1886 // The continuation point will be an exception handler, which expects | |
1887 // the following registers set up: | |
1888 // | |
1889 // Oexception: exception | |
1890 // Oissuing_pc: the local call that threw exception | |
1891 // Other On: garbage | |
1892 // In/Ln: the contents of the caller's register window | |
1893 // | |
1894 // We do the required restore at the last possible moment, because we | |
1895 // need to preserve some state across a runtime call. | |
1896 // (Remember that the caller activation is unknown--it might not be | |
1897 // interpreted, so things like Lscratch are useless in the caller.) | |
1898 | |
1899 // Although the Intel version uses call_C, we can use the more | |
1900 // compact call_VM. (The only real difference on SPARC is a | |
1901 // harmlessly ignored [re]set_last_Java_frame, compared with | |
1902 // the Intel code which lacks this.) | |
1903 __ mov(Oexception, Oexception ->after_save()); // get exception in I0 so it will be on O0 after restore | |
1904 __ add(issuing_pc_addr, Oissuing_pc->after_save()); // likewise set I1 to a value local to the caller | |
1905 __ super_call_VM_leaf(L7_thread_cache, | |
1906 CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), | |
1295 | 1907 G2_thread, Oissuing_pc->after_save()); |
0 | 1908 |
1909 // The caller's SP was adjusted upon method entry to accomodate | |
1910 // the callee's non-argument locals. Undo that adjustment. | |
1911 __ JMP(O0, 0); // return exception handler in caller | |
1912 __ delayed()->restore(I5_savedSP, G0, SP); | |
1913 | |
1914 // (same old exception object is already in Oexception; see above) | |
1915 // Note that an "issuing PC" is actually the next PC after the call | |
1916 } | |
1917 | |
1918 | |
1919 // | |
1920 // JVMTI ForceEarlyReturn support | |
1921 // | |
1922 | |
1923 address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state) { | |
1924 address entry = __ pc(); | |
1925 | |
1926 __ empty_expression_stack(); | |
1927 __ load_earlyret_value(state); | |
1928 | |
727 | 1929 __ ld_ptr(G2_thread, JavaThread::jvmti_thread_state_offset(), G3_scratch); |
1930 Address cond_addr(G3_scratch, JvmtiThreadState::earlyret_state_offset()); | |
0 | 1931 |
1932 // Clear the earlyret state | |
1933 __ stw(G0 /* JvmtiThreadState::earlyret_inactive */, cond_addr); | |
1934 | |
1935 __ remove_activation(state, | |
1936 /* throw_monitor_exception */ false, | |
1937 /* install_monitor_exception */ false); | |
1938 | |
1939 // The caller's SP was adjusted upon method entry to accomodate | |
1940 // the callee's non-argument locals. Undo that adjustment. | |
1941 __ ret(); // return to caller | |
1942 __ delayed()->restore(I5_savedSP, G0, SP); | |
1943 | |
1944 return entry; | |
1945 } // end of JVMTI ForceEarlyReturn support | |
1946 | |
1947 | |
1948 //------------------------------------------------------------------------------------------------------------------------ | |
1949 // Helper for vtos entry point generation | |
1950 | |
1951 void TemplateInterpreterGenerator::set_vtos_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) { | |
1952 assert(t->is_valid() && t->tos_in() == vtos, "illegal template"); | |
1953 Label L; | |
3839 | 1954 aep = __ pc(); __ push_ptr(); __ ba_short(L); |
1955 fep = __ pc(); __ push_f(); __ ba_short(L); | |
1956 dep = __ pc(); __ push_d(); __ ba_short(L); | |
1957 lep = __ pc(); __ push_l(); __ ba_short(L); | |
0 | 1958 iep = __ pc(); __ push_i(); |
1959 bep = cep = sep = iep; // there aren't any | |
1960 vep = __ pc(); __ bind(L); // fall through | |
1961 generate_and_dispatch(t); | |
1962 } | |
1963 | |
1964 // -------------------------------------------------------------------------------- | |
1965 | |
1966 | |
1967 InterpreterGenerator::InterpreterGenerator(StubQueue* code) | |
1968 : TemplateInterpreterGenerator(code) { | |
1969 generate_all(); // down here so it can be "virtual" | |
1970 } | |
1971 | |
1972 // -------------------------------------------------------------------------------- | |
1973 | |
1974 // Non-product code | |
1975 #ifndef PRODUCT | |
1976 address TemplateInterpreterGenerator::generate_trace_code(TosState state) { | |
1977 address entry = __ pc(); | |
1978 | |
1979 __ push(state); | |
1980 __ mov(O7, Lscratch); // protect return address within interpreter | |
1981 | |
1982 // Pass a 0 (not used in sparc) and the top of stack to the bytecode tracer | |
1983 __ mov( Otos_l2, G3_scratch ); | |
1984 __ call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode), G0, Otos_l1, G3_scratch); | |
1985 __ mov(Lscratch, O7); // restore return address | |
1986 __ pop(state); | |
1987 __ retl(); | |
1988 __ delayed()->nop(); | |
1989 | |
1990 return entry; | |
1991 } | |
1992 | |
1993 | |
1994 // helpers for generate_and_dispatch | |
1995 | |
1996 void TemplateInterpreterGenerator::count_bytecode() { | |
727 | 1997 __ inc_counter(&BytecodeCounter::_counter_value, G3_scratch, G4_scratch); |
0 | 1998 } |
1999 | |
2000 | |
2001 void TemplateInterpreterGenerator::histogram_bytecode(Template* t) { | |
727 | 2002 __ inc_counter(&BytecodeHistogram::_counters[t->bytecode()], G3_scratch, G4_scratch); |
0 | 2003 } |
2004 | |
2005 | |
2006 void TemplateInterpreterGenerator::histogram_bytecode_pair(Template* t) { | |
727 | 2007 AddressLiteral index (&BytecodePairHistogram::_index); |
2008 AddressLiteral counters((address) &BytecodePairHistogram::_counters); | |
0 | 2009 |
2010 // get index, shift out old bytecode, bring in new bytecode, and store it | |
2011 // _index = (_index >> log2_number_of_codes) | | |
2012 // (bytecode << log2_number_of_codes); | |
2013 | |
727 | 2014 __ load_contents(index, G4_scratch); |
0 | 2015 __ srl( G4_scratch, BytecodePairHistogram::log2_number_of_codes, G4_scratch ); |
2016 __ set( ((int)t->bytecode()) << BytecodePairHistogram::log2_number_of_codes, G3_scratch ); | |
2017 __ or3( G3_scratch, G4_scratch, G4_scratch ); | |
727 | 2018 __ store_contents(G4_scratch, index, G3_scratch); |
0 | 2019 |
2020 // bump bucket contents | |
2021 // _counters[_index] ++; | |
2022 | |
727 | 2023 __ set(counters, G3_scratch); // loads into G3_scratch |
0 | 2024 __ sll( G4_scratch, LogBytesPerWord, G4_scratch ); // Index is word address |
2025 __ add (G3_scratch, G4_scratch, G3_scratch); // Add in index | |
2026 __ ld (G3_scratch, 0, G4_scratch); | |
2027 __ inc (G4_scratch); | |
2028 __ st (G4_scratch, 0, G3_scratch); | |
2029 } | |
2030 | |
2031 | |
2032 void TemplateInterpreterGenerator::trace_bytecode(Template* t) { | |
2033 // Call a little run-time stub to avoid blow-up for each bytecode. | |
2034 // The run-time runtime saves the right registers, depending on | |
2035 // the tosca in-state for the given template. | |
2036 address entry = Interpreter::trace_code(t->tos_in()); | |
2037 guarantee(entry != NULL, "entry must have been generated"); | |
2038 __ call(entry, relocInfo::none); | |
2039 __ delayed()->nop(); | |
2040 } | |
2041 | |
2042 | |
2043 void TemplateInterpreterGenerator::stop_interpreter_at() { | |
727 | 2044 AddressLiteral counter(&BytecodeCounter::_counter_value); |
2045 __ load_contents(counter, G3_scratch); | |
2046 AddressLiteral stop_at(&StopInterpreterAt); | |
0 | 2047 __ load_ptr_contents(stop_at, G4_scratch); |
2048 __ cmp(G3_scratch, G4_scratch); | |
5923 | 2049 __ breakpoint_trap(Assembler::equal, Assembler::icc); |
0 | 2050 } |
2051 #endif // not PRODUCT | |
2052 #endif // !CC_INTERP |