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. |
1567 void TemplateTable::branch(bool is_jsr, bool is_wide) { |
1567 void TemplateTable::branch(bool is_jsr, bool is_wide) { |
1568 __ get_method(rcx); // rcx holds method |
1568 __ get_method(rcx); // rcx holds method |
1569 __ profile_taken_branch(rax, rbx); // rax holds updated MDP, rbx |
1569 __ profile_taken_branch(rax, rbx); // rax holds updated MDP, rbx |
1570 // holds bumped taken count |
1570 // holds bumped taken count |
1571 |
1571 |
1572 const ByteSize be_offset = Method::backedge_counter_offset() + |
1572 const ByteSize be_offset = MethodCounters::backedge_counter_offset() + |
1573 InvocationCounter::counter_offset(); |
1573 InvocationCounter::counter_offset(); |
1574 const ByteSize inv_offset = Method::invocation_counter_offset() + |
1574 const ByteSize inv_offset = MethodCounters::invocation_counter_offset() + |
1575 InvocationCounter::counter_offset(); |
1575 InvocationCounter::counter_offset(); |
1576 const int method_offset = frame::interpreter_frame_method_offset * wordSize; |
|
1577 |
1576 |
1578 // Load up edx with the branch displacement |
1577 // Load up edx with the branch displacement |
1579 __ movl(rdx, at_bcp(1)); |
1578 __ movl(rdx, at_bcp(1)); |
1580 __ bswapl(rdx); |
1579 __ bswapl(rdx); |
1581 |
1580 |
1621 // rdx: target offset |
1620 // rdx: target offset |
1622 // r13: target bcp |
1621 // r13: target bcp |
1623 // r14: locals pointer |
1622 // r14: locals pointer |
1624 __ testl(rdx, rdx); // check if forward or backward branch |
1623 __ testl(rdx, rdx); // check if forward or backward branch |
1625 __ jcc(Assembler::positive, dispatch); // count only if backward branch |
1624 __ jcc(Assembler::positive, dispatch); // count only if backward branch |
|
1625 |
|
1626 // check if MethodCounters exists |
|
1627 Label has_counters; |
|
1628 __ movptr(rax, Address(rcx, Method::method_counters_offset())); |
|
1629 __ testptr(rax, rax); |
|
1630 __ jcc(Assembler::notZero, has_counters); |
|
1631 __ push(rdx); |
|
1632 __ push(rcx); |
|
1633 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::build_method_counters), |
|
1634 rcx); |
|
1635 __ pop(rcx); |
|
1636 __ pop(rdx); |
|
1637 __ movptr(rax, Address(rcx, Method::method_counters_offset())); |
|
1638 __ jcc(Assembler::zero, dispatch); |
|
1639 __ bind(has_counters); |
|
1640 |
1626 if (TieredCompilation) { |
1641 if (TieredCompilation) { |
1627 Label no_mdo; |
1642 Label no_mdo; |
1628 int increment = InvocationCounter::count_increment; |
1643 int increment = InvocationCounter::count_increment; |
1629 int mask = ((1 << Tier0BackedgeNotifyFreqLog) - 1) << InvocationCounter::count_shift; |
1644 int mask = ((1 << Tier0BackedgeNotifyFreqLog) - 1) << InvocationCounter::count_shift; |
1630 if (ProfileInterpreter) { |
1645 if (ProfileInterpreter) { |
1638 __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, |
1653 __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, |
1639 rax, false, Assembler::zero, &backedge_counter_overflow); |
1654 rax, false, Assembler::zero, &backedge_counter_overflow); |
1640 __ jmp(dispatch); |
1655 __ jmp(dispatch); |
1641 } |
1656 } |
1642 __ bind(no_mdo); |
1657 __ bind(no_mdo); |
1643 // Increment backedge counter in Method* |
1658 // Increment backedge counter in MethodCounters* |
|
1659 __ movptr(rcx, Address(rcx, Method::method_counters_offset())); |
1644 __ increment_mask_and_jump(Address(rcx, be_offset), increment, mask, |
1660 __ increment_mask_and_jump(Address(rcx, be_offset), increment, mask, |
1645 rax, false, Assembler::zero, &backedge_counter_overflow); |
1661 rax, false, Assembler::zero, &backedge_counter_overflow); |
1646 } else { |
1662 } else { |
1647 // increment counter |
1663 // increment counter |
|
1664 __ movptr(rcx, Address(rcx, Method::method_counters_offset())); |
1648 __ movl(rax, Address(rcx, be_offset)); // load backedge counter |
1665 __ movl(rax, Address(rcx, be_offset)); // load backedge counter |
1649 __ incrementl(rax, InvocationCounter::count_increment); // increment counter |
1666 __ incrementl(rax, InvocationCounter::count_increment); // increment counter |
1650 __ movl(Address(rcx, be_offset), rax); // store counter |
1667 __ movl(Address(rcx, be_offset), rax); // store counter |
1651 |
1668 |
1652 __ movl(rax, Address(rcx, inv_offset)); // load invocation counter |
1669 __ movl(rax, Address(rcx, inv_offset)); // load invocation counter |
|
1670 |
1653 __ andl(rax, InvocationCounter::count_mask_value); // and the status bits |
1671 __ andl(rax, InvocationCounter::count_mask_value); // and the status bits |
1654 __ addl(rax, Address(rcx, be_offset)); // add both counters |
1672 __ addl(rax, Address(rcx, be_offset)); // add both counters |
1655 |
1673 |
1656 if (ProfileInterpreter) { |
1674 if (ProfileInterpreter) { |
1657 // Test to see if we should create a method data oop |
1675 // Test to see if we should create a method data oop |