1 /* |
1 /* |
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
342 // |
342 // |
343 // rbx,: method |
343 // rbx,: method |
344 // rcx: invocation counter |
344 // rcx: invocation counter |
345 // |
345 // |
346 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { |
346 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { |
347 const Address invocation_counter(rbx, in_bytes(Method::invocation_counter_offset()) + |
347 Label done; |
348 in_bytes(InvocationCounter::counter_offset())); |
348 // Note: In tiered we increment either counters in MethodCounters* or in MDO |
349 // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not. |
349 // depending if we're profiling or not. |
350 if (TieredCompilation) { |
350 if (TieredCompilation) { |
351 int increment = InvocationCounter::count_increment; |
351 int increment = InvocationCounter::count_increment; |
352 int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift; |
352 int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift; |
353 Label no_mdo, done; |
353 Label no_mdo; |
354 if (ProfileInterpreter) { |
354 if (ProfileInterpreter) { |
355 // Are we profiling? |
355 // Are we profiling? |
356 __ movptr(rax, Address(rbx, Method::method_data_offset())); |
356 __ movptr(rax, Address(rbx, Method::method_data_offset())); |
357 __ testptr(rax, rax); |
357 __ testptr(rax, rax); |
358 __ jccb(Assembler::zero, no_mdo); |
358 __ jccb(Assembler::zero, no_mdo); |
361 in_bytes(InvocationCounter::counter_offset())); |
361 in_bytes(InvocationCounter::counter_offset())); |
362 __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow); |
362 __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow); |
363 __ jmpb(done); |
363 __ jmpb(done); |
364 } |
364 } |
365 __ bind(no_mdo); |
365 __ bind(no_mdo); |
366 // Increment counter in Method* (we don't need to load it, it's in rcx). |
366 // Increment counter in MethodCounters |
367 __ increment_mask_and_jump(invocation_counter, increment, mask, rcx, true, Assembler::zero, overflow); |
367 const Address invocation_counter(rax, |
|
368 MethodCounters::invocation_counter_offset() + |
|
369 InvocationCounter::counter_offset()); |
|
370 |
|
371 __ get_method_counters(rbx, rax, done); |
|
372 __ increment_mask_and_jump(invocation_counter, increment, mask, |
|
373 rcx, false, Assembler::zero, overflow); |
368 __ bind(done); |
374 __ bind(done); |
369 } else { |
375 } else { |
370 const Address backedge_counter (rbx, Method::backedge_counter_offset() + |
376 const Address backedge_counter (rax, |
371 InvocationCounter::counter_offset()); |
377 MethodCounters::backedge_counter_offset() + |
372 |
378 InvocationCounter::counter_offset()); |
373 if (ProfileInterpreter) { // %%% Merge this into MethodData* |
379 const Address invocation_counter(rax, |
374 __ incrementl(Address(rbx,Method::interpreter_invocation_counter_offset())); |
380 MethodCounters::invocation_counter_offset() + |
|
381 InvocationCounter::counter_offset()); |
|
382 |
|
383 __ get_method_counters(rbx, rax, done); |
|
384 |
|
385 if (ProfileInterpreter) { |
|
386 __ incrementl(Address(rax, |
|
387 MethodCounters::interpreter_invocation_counter_offset())); |
375 } |
388 } |
|
389 |
376 // Update standard invocation counters |
390 // Update standard invocation counters |
|
391 __ movl(rcx, invocation_counter); |
|
392 __ incrementl(rcx, InvocationCounter::count_increment); |
|
393 __ movl(invocation_counter, rcx); // save invocation count |
|
394 |
377 __ movl(rax, backedge_counter); // load backedge counter |
395 __ movl(rax, backedge_counter); // load backedge counter |
378 |
|
379 __ incrementl(rcx, InvocationCounter::count_increment); |
|
380 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits |
396 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits |
381 |
397 |
382 __ movl(invocation_counter, rcx); // save invocation count |
|
383 __ addl(rcx, rax); // add both counters |
398 __ addl(rcx, rax); // add both counters |
384 |
399 |
385 // profile_method is non-null only for interpreted method so |
400 // profile_method is non-null only for interpreted method so |
386 // profile_method != NULL == !native_call |
401 // profile_method != NULL == !native_call |
387 // BytecodeInterpreter only calls for native so code is elided. |
402 // BytecodeInterpreter only calls for native so code is elided. |
866 // rsi: sender sp |
882 // rsi: sender sp |
867 // rsi: previous interpreter state (C++ interpreter) must preserve |
883 // rsi: previous interpreter state (C++ interpreter) must preserve |
868 address entry_point = __ pc(); |
884 address entry_point = __ pc(); |
869 |
885 |
870 const Address constMethod (rbx, Method::const_offset()); |
886 const Address constMethod (rbx, Method::const_offset()); |
871 const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset()); |
|
872 const Address access_flags (rbx, Method::access_flags_offset()); |
887 const Address access_flags (rbx, Method::access_flags_offset()); |
873 const Address size_of_parameters(rcx, ConstMethod::size_of_parameters_offset()); |
888 const Address size_of_parameters(rcx, ConstMethod::size_of_parameters_offset()); |
874 |
889 |
875 // get parameter size (always needed) |
890 // get parameter size (always needed) |
876 __ movptr(rcx, constMethod); |
891 __ movptr(rcx, constMethod); |
895 // NULL result handler |
910 // NULL result handler |
896 __ push((int32_t)NULL_WORD); |
911 __ push((int32_t)NULL_WORD); |
897 // NULL oop temp (mirror or jni oop result) |
912 // NULL oop temp (mirror or jni oop result) |
898 __ push((int32_t)NULL_WORD); |
913 __ push((int32_t)NULL_WORD); |
899 |
914 |
900 if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count |
|
901 // initialize fixed part of activation frame |
915 // initialize fixed part of activation frame |
902 |
|
903 generate_fixed_frame(true); |
916 generate_fixed_frame(true); |
904 |
917 |
905 // make sure method is native & not abstract |
918 // make sure method is native & not abstract |
906 #ifdef ASSERT |
919 #ifdef ASSERT |
907 __ movl(rax, access_flags); |
920 __ movl(rax, access_flags); |
1284 // rbx,: Method* |
1297 // rbx,: Method* |
1285 // rsi: sender sp |
1298 // rsi: sender sp |
1286 address entry_point = __ pc(); |
1299 address entry_point = __ pc(); |
1287 |
1300 |
1288 const Address constMethod (rbx, Method::const_offset()); |
1301 const Address constMethod (rbx, Method::const_offset()); |
1289 const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset()); |
|
1290 const Address access_flags (rbx, Method::access_flags_offset()); |
1302 const Address access_flags (rbx, Method::access_flags_offset()); |
1291 const Address size_of_parameters(rdx, ConstMethod::size_of_parameters_offset()); |
1303 const Address size_of_parameters(rdx, ConstMethod::size_of_parameters_offset()); |
1292 const Address size_of_locals (rdx, ConstMethod::size_of_locals_offset()); |
1304 const Address size_of_locals (rdx, ConstMethod::size_of_locals_offset()); |
1293 |
1305 |
1294 // get parameter size (always needed) |
1306 // get parameter size (always needed) |