1 /*
 2  * Copyright (c) 2024, 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 #ifndef SHARE_COMPILER_RECOMPILATIONPOLICY_HPP
26 #define SHARE_COMPILER_RECOMPILATIONPOLICY_HPP
27 
28 #include "compiler/compileBroker.hpp"
29 #include "memory/allStatic.hpp"
30 #include "utilities/globalDefinitions.hpp"
31 
32 namespace CompilationPolicyUtils {
33 template<int SAMPLE_COUNT = 256>
34 class WeightedMovingAverage {
35   int _current;
36   int _samples[SAMPLE_COUNT];
37   int64_t _timestamps[SAMPLE_COUNT];
38 
39   void sample(int s, int64_t t) {
40     assert(s >= 0, "Negative sample values are not supported");
41     _samples[_current] = s;
42     _timestamps[_current] = t;
43     if (++_current >= SAMPLE_COUNT) {
44       _current = 0;
45     }
46   }
47 
48   // Since sampling happens at irregular invervals the solution is to
49   // discount the older samples proportionally to the time between
50   // the now and the time of the sample.
51   double value(int64_t t) const {
52     double decay_speed = 1;
53     double weighted_sum = 0;
54     int count = 0;
55     for (int i = 0; i < SAMPLE_COUNT; i++) {
56       if (_samples[i] >= 0) {
57         count++;
58         double delta_t = (t - _timestamps[i]) / 1000.0; // in seconds
59         if (delta_t < 1) delta_t = 1;
60         weighted_sum += (double) _samples[i] / (delta_t * decay_speed);
61       }
62     }
63     if (count > 0) {
64       return weighted_sum / count;
65     } else {
66       return 0;
67     }
68   }
69   static int64_t time() {
70     return nanos_to_millis(os::javaTimeNanos());
71   }
72 public:
73   WeightedMovingAverage() : _current(0) {
74     for (int i = 0; i < SAMPLE_COUNT; i++) {
75       _samples[i] = -1;
76     }
77   }
78   void sample(int s) { sample(s, time()); }
79   double value() const { return value(time()); }
80 };
81 } // namespace CompilationPolicyUtils
82 
83 
84 class RecompilationPolicy : AllStatic {
85   typedef CompilationPolicyUtils::WeightedMovingAverage<> LoadAverage;
86   static LoadAverage _load_average;
87   static volatile bool _recompilation_done;
88 public:
89   static void sample_load_average();
90   static void print_load_average();
91   static bool have_recompilation_work();
92   static bool recompilation_step(int step, TRAPS);
93 };
94 
95 #endif // SHARE_COMPILER_RECOMPILATIONPOLICY_HPP