1 /*
2  * Copyright (c) 1997, 2020, 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 "interpreter/invocationCounter.hpp"
27 
init()28 void InvocationCounter::init() {
29   _counter = 0;  // reset all the bits, including the sticky carry
30 }
31 
set(uint count,uint flag)32 void InvocationCounter::set(uint count, uint flag) {
33   _counter = (count << number_of_noncount_bits) | (flag & carry_mask);
34 }
35 
set(uint count)36 void InvocationCounter::set(uint count) {
37   uint carry = (_counter & carry_mask);    // the carry bit is sticky
38   _counter = (count << number_of_noncount_bits) | carry;
39 }
40 
update(uint new_count)41 void InvocationCounter::update(uint new_count) {
42   // Don't make the method look like it's never been executed
43   uint counter = raw_counter();
44   uint c = extract_count(counter);
45   uint f = extract_carry(counter);
46   // prevent from going to zero, to distinguish from never-executed methods
47   if (c > 0 && new_count == 0) new_count = 1;
48   set(new_count, f);
49 }
50 
set_carry_and_reduce()51 void InvocationCounter::set_carry_and_reduce() {
52   uint counter = raw_counter();
53   // The carry bit now indicates that this counter had achieved a very
54   // large value.  Now reduce the value, so that the method can be
55   // executed many more times before re-entering the VM.
56   uint old_count = extract_count(counter);
57   uint new_count = MIN2(old_count, (uint)(CompileThreshold / 2));
58   // prevent from going to zero, to distinguish from never-executed methods
59   if (new_count == 0)  new_count = 1;
60   if (old_count != new_count)  set(new_count, carry_mask);
61 }
62 
set_carry_on_overflow()63 void InvocationCounter::set_carry_on_overflow() {
64   if (!carry() && count() > InvocationCounter::count_limit / 2) {
65     set_carry();
66   }
67 }
68 
reset()69 void InvocationCounter::reset() {
70   update(0);
71 }
72 
decay()73 void InvocationCounter::decay() {
74   update(count() >> 1);
75 }
76 
print()77 void InvocationCounter::print() {
78   uint counter = raw_counter();
79   tty->print_cr("invocation count: up = %d, limit = %d, carry = %s",
80                                    extract_count(counter), limit(),
81                                    extract_carry(counter) ? "true" : "false");
82 }
83