blob: ada103658aa5c27a2409c97bbfd1ec6560c64492 [file] [log] [blame]
Nicolas Geoffray5550ca82015-08-21 18:38:30 +01001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_RUNTIME_JIT_PROFILING_INFO_H_
18#define ART_RUNTIME_JIT_PROFILING_INFO_H_
19
20#include <vector>
21
22#include "base/macros.h"
23#include "gc_root.h"
Nicolas Geoffraye2a3aa92019-11-25 17:52:58 +000024#include "offsets.h"
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010025
26namespace art {
27
28class ArtMethod;
Nicolas Geoffray73be1e82015-09-17 15:22:56 +010029class ProfilingInfo;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010030
Nicolas Geoffray26705e22015-10-28 12:50:11 +000031namespace jit {
32class JitCodeCache;
Andreas Gampedeae7db2017-05-30 09:56:41 -070033} // namespace jit
Nicolas Geoffray26705e22015-10-28 12:50:11 +000034
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010035namespace mirror {
36class Class;
Andreas Gampedeae7db2017-05-30 09:56:41 -070037} // namespace mirror
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010038
Nicolas Geoffray73be1e82015-09-17 15:22:56 +010039// Structure to store the classes seen at runtime for a specific instruction.
40// Once the classes_ array is full, we consider the INVOKE to be megamorphic.
41class InlineCache {
42 public:
Nicolas Geoffraye2a3aa92019-11-25 17:52:58 +000043 // This is hard coded in the assembly stub art_quick_update_inline_cache.
Calin Juravle940eb0c2017-01-30 19:30:44 -080044 static constexpr uint8_t kIndividualCacheSize = 5;
Nicolas Geoffraya42363f2015-12-17 14:57:09 +000045
Nicolas Geoffraye2a3aa92019-11-25 17:52:58 +000046 static constexpr MemberOffset ClassesOffset() {
47 return MemberOffset(OFFSETOF_MEMBER(InlineCache, classes_));
48 }
49
Nicolas Geoffraya42363f2015-12-17 14:57:09 +000050 private:
Nicolas Geoffray73be1e82015-09-17 15:22:56 +010051 uint32_t dex_pc_;
52 GcRoot<mirror::Class> classes_[kIndividualCacheSize];
53
Nicolas Geoffraye51ca8b2016-11-22 14:49:31 +000054 friend class jit::JitCodeCache;
Nicolas Geoffray73be1e82015-09-17 15:22:56 +010055 friend class ProfilingInfo;
56
57 DISALLOW_COPY_AND_ASSIGN(InlineCache);
58};
59
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010060/**
61 * Profiling info for a method, created and filled by the interpreter once the
62 * method is warm, and used by the compiler to drive optimizations.
63 */
64class ProfilingInfo {
65 public:
Nicolas Geoffray26705e22015-10-28 12:50:11 +000066 // Create a ProfilingInfo for 'method'. Return whether it succeeded, or if it is
67 // not needed in case the method does not have virtual/interface invocations.
68 static bool Create(Thread* self, ArtMethod* method, bool retry_allocation)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070069 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010070
71 // Add information from an executed INVOKE instruction to the profile.
Nicolas Geoffray26705e22015-10-28 12:50:11 +000072 void AddInvokeInfo(uint32_t dex_pc, mirror::Class* cls)
73 // Method should not be interruptible, as it manipulates the ProfilingInfo
74 // which can be concurrently collected.
75 REQUIRES(Roles::uninterruptible_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070076 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010077
Nicolas Geoffray26705e22015-10-28 12:50:11 +000078 ArtMethod* GetMethod() const {
79 return method_;
80 }
81
Nicolas Geoffrayfdb7d632017-02-08 15:07:18 +000082 // Mutator lock only required for debugging output.
83 InlineCache* GetInlineCache(uint32_t dex_pc)
84 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray73be1e82015-09-17 15:22:56 +010085
buzbee454b3b62016-04-07 14:42:47 -070086 bool IsMethodBeingCompiled(bool osr) const {
87 return osr
88 ? is_osr_method_being_compiled_
89 : is_method_being_compiled_;
Nicolas Geoffray73be1e82015-09-17 15:22:56 +010090 }
91
buzbee454b3b62016-04-07 14:42:47 -070092 void SetIsMethodBeingCompiled(bool value, bool osr) {
93 if (osr) {
94 is_osr_method_being_compiled_ = value;
95 } else {
96 is_method_being_compiled_ = value;
97 }
Nicolas Geoffray73be1e82015-09-17 15:22:56 +010098 }
99
Nicolas Geoffray35122442016-03-02 12:05:30 +0000100 void SetSavedEntryPoint(const void* entry_point) {
101 saved_entry_point_ = entry_point;
102 }
103
104 const void* GetSavedEntryPoint() const {
105 return saved_entry_point_;
106 }
107
Nicolas Geoffrayf6d46682017-02-28 17:41:45 +0000108 // Increments the number of times this method is currently being inlined.
109 // Returns whether it was successful, that is it could increment without
110 // overflowing.
111 bool IncrementInlineUse() {
112 if (current_inline_uses_ == std::numeric_limits<uint16_t>::max()) {
113 return false;
114 }
Nicolas Geoffrayb6e20ae2016-03-07 14:29:04 +0000115 current_inline_uses_++;
Nicolas Geoffrayf6d46682017-02-28 17:41:45 +0000116 return true;
Nicolas Geoffrayb6e20ae2016-03-07 14:29:04 +0000117 }
118
119 void DecrementInlineUse() {
120 DCHECK_GT(current_inline_uses_, 0);
121 current_inline_uses_--;
122 }
123
124 bool IsInUseByCompiler() const {
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700125 return IsMethodBeingCompiled(/*osr=*/ true) || IsMethodBeingCompiled(/*osr=*/ false) ||
buzbee454b3b62016-04-07 14:42:47 -0700126 (current_inline_uses_ > 0);
Nicolas Geoffray511e41b2016-03-02 17:09:35 +0000127 }
128
Nicolas Geoffraya59af8a2019-11-27 17:42:32 +0000129 static constexpr MemberOffset BaselineHotnessCountOffset() {
130 return MemberOffset(OFFSETOF_MEMBER(ProfilingInfo, baseline_hotness_count_));
131 }
132
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100133 private:
Mathieu Chartier65975772016-08-05 10:46:36 -0700134 ProfilingInfo(ArtMethod* method, const std::vector<uint32_t>& entries);
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100135
Nicolas Geoffraya59af8a2019-11-27 17:42:32 +0000136 // Hotness count for methods compiled with the JIT baseline compiler. Once
137 // a threshold is hit (currentily the maximum value of uint16_t), we will
138 // JIT compile optimized the method.
139 uint16_t baseline_hotness_count_;
140
Nicolas Geoffray26705e22015-10-28 12:50:11 +0000141 // Method this profiling info is for.
Alex Lightdba61482016-12-21 08:20:29 -0800142 // Not 'const' as JVMTI introduces obsolete methods that we implement by creating new ArtMethods.
143 // See JitCodeCache::MoveObsoleteMethod.
144 ArtMethod* method_;
Nicolas Geoffray26705e22015-10-28 12:50:11 +0000145
Andreas Gampee40f65f2018-05-07 17:02:22 -0700146 // Entry point of the corresponding ArtMethod, while the JIT code cache
147 // is poking for the liveness of compiled code.
148 const void* saved_entry_point_;
149
150 // Number of instructions we are profiling in the ArtMethod.
151 const uint32_t number_of_inline_caches_;
152
153 // When the compiler inlines the method associated to this ProfilingInfo,
154 // it updates this counter so that the GC does not try to clear the inline caches.
155 uint16_t current_inline_uses_;
156
Nicolas Geoffray73be1e82015-09-17 15:22:56 +0100157 // Whether the ArtMethod is currently being compiled. This flag
158 // is implicitly guarded by the JIT code cache lock.
159 // TODO: Make the JIT code cache lock global.
160 bool is_method_being_compiled_;
buzbee454b3b62016-04-07 14:42:47 -0700161 bool is_osr_method_being_compiled_;
Nicolas Geoffray73be1e82015-09-17 15:22:56 +0100162
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100163 // Dynamically allocated array of size `number_of_inline_caches_`.
164 InlineCache cache_[0];
165
Nicolas Geoffray26705e22015-10-28 12:50:11 +0000166 friend class jit::JitCodeCache;
167
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100168 DISALLOW_COPY_AND_ASSIGN(ProfilingInfo);
169};
170
171} // namespace art
172
173#endif // ART_RUNTIME_JIT_PROFILING_INFO_H_