1 /* |
1 /* |
2 * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2007, 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. |
568 // |
568 // |
569 // rbx,: method |
569 // rbx,: method |
570 // rcx: invocation counter |
570 // rcx: invocation counter |
571 // |
571 // |
572 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { |
572 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { |
573 |
573 Label done; |
574 const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset()); |
574 const Address invocation_counter(rax, |
575 const Address backedge_counter (rbx, Method::backedge_counter_offset() + InvocationCounter::counter_offset()); |
575 MethodCounters::invocation_counter_offset() + |
576 |
576 InvocationCounter::counter_offset()); |
577 if (ProfileInterpreter) { // %%% Merge this into MethodData* |
577 const Address backedge_counter (rax, |
578 __ incrementl(Address(rbx,Method::interpreter_invocation_counter_offset())); |
578 MethodCounter::backedge_counter_offset() + |
|
579 InvocationCounter::counter_offset()); |
|
580 |
|
581 __ get_method_counters(rbx, rax, done); |
|
582 |
|
583 if (ProfileInterpreter) { |
|
584 __ incrementl(Address(rax, |
|
585 MethodCounters::interpreter_invocation_counter_offset())); |
579 } |
586 } |
580 // Update standard invocation counters |
587 // Update standard invocation counters |
|
588 __ movl(rcx, invocation_counter); |
|
589 __ increment(rcx, InvocationCounter::count_increment); |
|
590 __ movl(invocation_counter, rcx); // save invocation count |
|
591 |
581 __ movl(rax, backedge_counter); // load backedge counter |
592 __ movl(rax, backedge_counter); // load backedge counter |
582 |
|
583 __ increment(rcx, InvocationCounter::count_increment); |
|
584 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits |
593 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits |
585 |
594 |
586 __ movl(invocation_counter, rcx); // save invocation count |
|
587 __ addl(rcx, rax); // add both counters |
595 __ addl(rcx, rax); // add both counters |
588 |
596 |
589 // profile_method is non-null only for interpreted method so |
597 // profile_method is non-null only for interpreted method so |
590 // profile_method != NULL == !native_call |
598 // profile_method != NULL == !native_call |
591 // BytecodeInterpreter only calls for native so code is elided. |
599 // BytecodeInterpreter only calls for native so code is elided. |
592 |
600 |
593 __ cmp32(rcx, |
601 __ cmp32(rcx, |
594 ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit)); |
602 ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit)); |
595 __ jcc(Assembler::aboveEqual, *overflow); |
603 __ jcc(Assembler::aboveEqual, *overflow); |
596 |
604 __ bind(done); |
597 } |
605 } |
598 |
606 |
599 void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { |
607 void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { |
600 |
608 |
601 // C++ interpreter on entry |
609 // C++ interpreter on entry |
975 // in any case. If called via c1/c2/call_stub rsi/r13 is junk (to use) but harmless |
983 // in any case. If called via c1/c2/call_stub rsi/r13 is junk (to use) but harmless |
976 // to save/restore. |
984 // to save/restore. |
977 address entry_point = __ pc(); |
985 address entry_point = __ pc(); |
978 |
986 |
979 const Address constMethod (rbx, Method::const_offset()); |
987 const Address constMethod (rbx, Method::const_offset()); |
980 const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset()); |
|
981 const Address access_flags (rbx, Method::access_flags_offset()); |
988 const Address access_flags (rbx, Method::access_flags_offset()); |
982 const Address size_of_parameters(rcx, ConstMethod::size_of_parameters_offset()); |
989 const Address size_of_parameters(rcx, ConstMethod::size_of_parameters_offset()); |
983 |
990 |
984 // rsi/r13 == state/locals rdi == prevstate |
991 // rsi/r13 == state/locals rdi == prevstate |
985 const Register locals = rdi; |
992 const Register locals = rdi; |
1026 __ jcc(Assembler::equal, L); |
1033 __ jcc(Assembler::equal, L); |
1027 __ stop("broken stack frame setup in interpreter"); |
1034 __ stop("broken stack frame setup in interpreter"); |
1028 __ bind(L); |
1035 __ bind(L); |
1029 } |
1036 } |
1030 #endif |
1037 #endif |
1031 |
|
1032 if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count |
|
1033 |
1038 |
1034 const Register unlock_thread = LP64_ONLY(r15_thread) NOT_LP64(rax); |
1039 const Register unlock_thread = LP64_ONLY(r15_thread) NOT_LP64(rax); |
1035 NOT_LP64(__ movptr(unlock_thread, STATE(_thread));) // get thread |
1040 NOT_LP64(__ movptr(unlock_thread, STATE(_thread));) // get thread |
1036 // Since at this point in the method invocation the exception handler |
1041 // Since at this point in the method invocation the exception handler |
1037 // would try to exit the monitor of synchronized methods which hasn't |
1042 // would try to exit the monitor of synchronized methods which hasn't |