1 /*
2  * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
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
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  *
23  */
24 
25 #include "precompiled.hpp"
26 #include "compiler/compiler_globals.hpp"
27 #include "interpreter/invocationCounter.hpp"
28 
init()29 void InvocationCounter::init() {
30   _counter = 0;  // reset all the bits, including the sticky carry
31 }
32 
set(uint count,uint flag)33 void InvocationCounter::set(uint count, uint flag) {
34   _counter = (count << number_of_noncount_bits) | (flag & carry_mask);
35 }
36 
set(uint count)37 void InvocationCounter::set(uint count) {
38   uint carry = (_counter & carry_mask);    // the carry bit is sticky
39   _counter = (count << number_of_noncount_bits) | carry;
40 }
41 
update(uint new_count)42 void InvocationCounter::update(uint new_count) {
43   // Don't make the method look like it's never been executed
44   uint counter = raw_counter();
45   uint c = extract_count(counter);
46   uint f = extract_carry(counter);
47   // prevent from going to zero, to distinguish from never-executed methods
48   if (c > 0 && new_count == 0) new_count = 1;
49   set(new_count, f);
50 }
51 
set_carry_on_overflow()52 void InvocationCounter::set_carry_on_overflow() {
53   if (!carry() && count() > InvocationCounter::count_limit / 2) {
54     set_carry();
55   }
56 }
57 
reset()58 void InvocationCounter::reset() {
59   update(0);
60 }
61 
decay()62 void InvocationCounter::decay() {
63   update(count() >> 1);
64 }
65 
print()66 void InvocationCounter::print() {
67   uint counter = raw_counter();
68   tty->print_cr("invocation count: up = %d, limit = %d, carry = %s",
69                                    extract_count(counter), limit(),
70                                    extract_carry(counter) ? "true" : "false");
71 }
72