1 /* |
1 /* |
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2003, 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. |
298 // |
298 // |
299 void InterpreterGenerator::generate_counter_incr( |
299 void InterpreterGenerator::generate_counter_incr( |
300 Label* overflow, |
300 Label* overflow, |
301 Label* profile_method, |
301 Label* profile_method, |
302 Label* profile_method_continue) { |
302 Label* profile_method_continue) { |
303 const Address invocation_counter(rbx, in_bytes(Method::invocation_counter_offset()) + |
303 Label done; |
304 in_bytes(InvocationCounter::counter_offset())); |
|
305 // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not. |
304 // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not. |
306 if (TieredCompilation) { |
305 if (TieredCompilation) { |
307 int increment = InvocationCounter::count_increment; |
306 int increment = InvocationCounter::count_increment; |
308 int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift; |
307 int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift; |
309 Label no_mdo, done; |
308 Label no_mdo; |
310 if (ProfileInterpreter) { |
309 if (ProfileInterpreter) { |
311 // Are we profiling? |
310 // Are we profiling? |
312 __ movptr(rax, Address(rbx, Method::method_data_offset())); |
311 __ movptr(rax, Address(rbx, Method::method_data_offset())); |
313 __ testptr(rax, rax); |
312 __ testptr(rax, rax); |
314 __ jccb(Assembler::zero, no_mdo); |
313 __ jccb(Assembler::zero, no_mdo); |
317 in_bytes(InvocationCounter::counter_offset())); |
316 in_bytes(InvocationCounter::counter_offset())); |
318 __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow); |
317 __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow); |
319 __ jmpb(done); |
318 __ jmpb(done); |
320 } |
319 } |
321 __ bind(no_mdo); |
320 __ bind(no_mdo); |
322 // Increment counter in Method* (we don't need to load it, it's in ecx). |
321 // Increment counter in MethodCounters |
323 __ increment_mask_and_jump(invocation_counter, increment, mask, rcx, true, Assembler::zero, overflow); |
322 const Address invocation_counter(rax, |
|
323 MethodCounters::invocation_counter_offset() + |
|
324 InvocationCounter::counter_offset()); |
|
325 __ get_method_counters(rbx, rax, done); |
|
326 __ increment_mask_and_jump(invocation_counter, increment, mask, rcx, |
|
327 false, Assembler::zero, overflow); |
324 __ bind(done); |
328 __ bind(done); |
325 } else { |
329 } else { |
326 const Address backedge_counter(rbx, |
330 const Address backedge_counter(rax, |
327 Method::backedge_counter_offset() + |
331 MethodCounters::backedge_counter_offset() + |
328 InvocationCounter::counter_offset()); |
332 InvocationCounter::counter_offset()); |
329 |
333 const Address invocation_counter(rax, |
330 if (ProfileInterpreter) { // %%% Merge this into MethodData* |
334 MethodCounters::invocation_counter_offset() + |
331 __ incrementl(Address(rbx, |
335 InvocationCounter::counter_offset()); |
332 Method::interpreter_invocation_counter_offset())); |
336 |
|
337 __ get_method_counters(rbx, rax, done); |
|
338 |
|
339 if (ProfileInterpreter) { |
|
340 __ incrementl(Address(rax, |
|
341 MethodCounters::interpreter_invocation_counter_offset())); |
333 } |
342 } |
334 // Update standard invocation counters |
343 // Update standard invocation counters |
|
344 __ movl(rcx, invocation_counter); |
|
345 __ incrementl(rcx, InvocationCounter::count_increment); |
|
346 __ movl(invocation_counter, rcx); // save invocation count |
|
347 |
335 __ movl(rax, backedge_counter); // load backedge counter |
348 __ movl(rax, backedge_counter); // load backedge counter |
336 |
|
337 __ incrementl(rcx, InvocationCounter::count_increment); |
|
338 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits |
349 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits |
339 |
350 |
340 __ movl(invocation_counter, rcx); // save invocation count |
|
341 __ addl(rcx, rax); // add both counters |
351 __ addl(rcx, rax); // add both counters |
342 |
352 |
343 // profile_method is non-null only for interpreted method so |
353 // profile_method is non-null only for interpreted method so |
344 // profile_method != NULL == !native_call |
354 // profile_method != NULL == !native_call |
345 |
355 |
841 // r13: sender sp |
852 // r13: sender sp |
842 |
853 |
843 address entry_point = __ pc(); |
854 address entry_point = __ pc(); |
844 |
855 |
845 const Address constMethod (rbx, Method::const_offset()); |
856 const Address constMethod (rbx, Method::const_offset()); |
846 const Address invocation_counter(rbx, Method:: |
|
847 invocation_counter_offset() + |
|
848 InvocationCounter::counter_offset()); |
|
849 const Address access_flags (rbx, Method::access_flags_offset()); |
857 const Address access_flags (rbx, Method::access_flags_offset()); |
850 const Address size_of_parameters(rcx, ConstMethod:: |
858 const Address size_of_parameters(rcx, ConstMethod:: |
851 size_of_parameters_offset()); |
859 size_of_parameters_offset()); |
852 |
860 |
853 |
861 |
873 // initialize result_handler slot |
881 // initialize result_handler slot |
874 __ push((int) NULL_WORD); |
882 __ push((int) NULL_WORD); |
875 // slot for oop temp |
883 // slot for oop temp |
876 // (static native method holder mirror/jni oop result) |
884 // (static native method holder mirror/jni oop result) |
877 __ push((int) NULL_WORD); |
885 __ push((int) NULL_WORD); |
878 |
|
879 if (inc_counter) { |
|
880 __ movl(rcx, invocation_counter); // (pre-)fetch invocation count |
|
881 } |
|
882 |
886 |
883 // initialize fixed part of activation frame |
887 // initialize fixed part of activation frame |
884 generate_fixed_frame(true); |
888 generate_fixed_frame(true); |
885 |
889 |
886 // make sure method is native & not abstract |
890 // make sure method is native & not abstract |
1294 // ebx: Method* |
1298 // ebx: Method* |
1295 // r13: sender sp |
1299 // r13: sender sp |
1296 address entry_point = __ pc(); |
1300 address entry_point = __ pc(); |
1297 |
1301 |
1298 const Address constMethod(rbx, Method::const_offset()); |
1302 const Address constMethod(rbx, Method::const_offset()); |
1299 const Address invocation_counter(rbx, |
|
1300 Method::invocation_counter_offset() + |
|
1301 InvocationCounter::counter_offset()); |
|
1302 const Address access_flags(rbx, Method::access_flags_offset()); |
1303 const Address access_flags(rbx, Method::access_flags_offset()); |
1303 const Address size_of_parameters(rdx, |
1304 const Address size_of_parameters(rdx, |
1304 ConstMethod::size_of_parameters_offset()); |
1305 ConstMethod::size_of_parameters_offset()); |
1305 const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset()); |
1306 const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset()); |
1306 |
1307 |