292 // |
292 // |
293 // Lmethod: method |
293 // Lmethod: method |
294 // ??: invocation counter |
294 // ??: invocation counter |
295 // |
295 // |
296 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { |
296 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { |
297 // Update standard invocation counters |
297 // Note: In tiered we increment either counters in methodOop or in MDO depending if we're profiling or not. |
298 __ increment_invocation_counter(O0, G3_scratch); |
298 if (TieredCompilation) { |
299 if (ProfileInterpreter) { // %%% Merge this into methodDataOop |
299 const int increment = InvocationCounter::count_increment; |
300 Address interpreter_invocation_counter(Lmethod, methodOopDesc::interpreter_invocation_counter_offset()); |
300 const int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift; |
301 __ ld(interpreter_invocation_counter, G3_scratch); |
301 Label no_mdo, done; |
302 __ inc(G3_scratch); |
302 if (ProfileInterpreter) { |
303 __ st(G3_scratch, interpreter_invocation_counter); |
303 // If no method data exists, go to profile_continue. |
304 } |
304 __ ld_ptr(Lmethod, methodOopDesc::method_data_offset(), G4_scratch); |
305 |
305 __ br_null(G4_scratch, false, Assembler::pn, no_mdo); |
306 if (ProfileInterpreter && profile_method != NULL) { |
306 __ delayed()->nop(); |
307 // Test to see if we should create a method data oop |
307 // Increment counter |
308 AddressLiteral profile_limit(&InvocationCounter::InterpreterProfileLimit); |
308 Address mdo_invocation_counter(G4_scratch, |
309 __ sethi(profile_limit, G3_scratch); |
309 in_bytes(methodDataOopDesc::invocation_counter_offset()) + |
310 __ ld(G3_scratch, profile_limit.low10(), G3_scratch); |
310 in_bytes(InvocationCounter::counter_offset())); |
|
311 __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, |
|
312 G3_scratch, Lscratch, |
|
313 Assembler::zero, overflow); |
|
314 __ ba(false, done); |
|
315 __ delayed()->nop(); |
|
316 } |
|
317 |
|
318 // Increment counter in methodOop |
|
319 __ bind(no_mdo); |
|
320 Address invocation_counter(Lmethod, |
|
321 in_bytes(methodOopDesc::invocation_counter_offset()) + |
|
322 in_bytes(InvocationCounter::counter_offset())); |
|
323 __ increment_mask_and_jump(invocation_counter, increment, mask, |
|
324 G3_scratch, Lscratch, |
|
325 Assembler::zero, overflow); |
|
326 __ bind(done); |
|
327 } else { |
|
328 // Update standard invocation counters |
|
329 __ increment_invocation_counter(O0, G3_scratch); |
|
330 if (ProfileInterpreter) { // %%% Merge this into methodDataOop |
|
331 Address interpreter_invocation_counter(Lmethod,in_bytes(methodOopDesc::interpreter_invocation_counter_offset())); |
|
332 __ ld(interpreter_invocation_counter, G3_scratch); |
|
333 __ inc(G3_scratch); |
|
334 __ st(G3_scratch, interpreter_invocation_counter); |
|
335 } |
|
336 |
|
337 if (ProfileInterpreter && profile_method != NULL) { |
|
338 // Test to see if we should create a method data oop |
|
339 AddressLiteral profile_limit((address)&InvocationCounter::InterpreterProfileLimit); |
|
340 __ load_contents(profile_limit, G3_scratch); |
|
341 __ cmp(O0, G3_scratch); |
|
342 __ br(Assembler::lessUnsigned, false, Assembler::pn, *profile_method_continue); |
|
343 __ delayed()->nop(); |
|
344 |
|
345 // if no method data exists, go to profile_method |
|
346 __ test_method_data_pointer(*profile_method); |
|
347 } |
|
348 |
|
349 AddressLiteral invocation_limit((address)&InvocationCounter::InterpreterInvocationLimit); |
|
350 __ load_contents(invocation_limit, G3_scratch); |
311 __ cmp(O0, G3_scratch); |
351 __ cmp(O0, G3_scratch); |
312 __ br(Assembler::lessUnsigned, false, Assembler::pn, *profile_method_continue); |
352 __ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow); |
313 __ delayed()->nop(); |
353 __ delayed()->nop(); |
314 |
354 } |
315 // if no method data exists, go to profile_method |
|
316 __ test_method_data_pointer(*profile_method); |
|
317 } |
|
318 |
|
319 AddressLiteral invocation_limit(&InvocationCounter::InterpreterInvocationLimit); |
|
320 __ sethi(invocation_limit, G3_scratch); |
|
321 __ ld(G3_scratch, invocation_limit.low10(), G3_scratch); |
|
322 __ cmp(O0, G3_scratch); |
|
323 __ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow); |
|
324 __ delayed()->nop(); |
|
325 |
355 |
326 } |
356 } |
327 |
357 |
328 // Allocate monitor and lock method (asm interpreter) |
358 // Allocate monitor and lock method (asm interpreter) |
329 // ebx - methodOop |
359 // ebx - methodOop |