blob: d136b4c6f697e59f3bcd194d88fc4828c93b9520 [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 Geoffray60ef3992020-08-07 07:49:57 +000066 // Create a ProfilingInfo for 'method'.
67 static ProfilingInfo* Create(Thread* self, ArtMethod* method)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070068 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010069
70 // Add information from an executed INVOKE instruction to the profile.
Nicolas Geoffray26705e22015-10-28 12:50:11 +000071 void AddInvokeInfo(uint32_t dex_pc, mirror::Class* cls)
72 // Method should not be interruptible, as it manipulates the ProfilingInfo
73 // which can be concurrently collected.
74 REQUIRES(Roles::uninterruptible_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070075 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010076
Nicolas Geoffray26705e22015-10-28 12:50:11 +000077 ArtMethod* GetMethod() const {
78 return method_;
79 }
80
Nicolas Geoffrayfdb7d632017-02-08 15:07:18 +000081 // Mutator lock only required for debugging output.
82 InlineCache* GetInlineCache(uint32_t dex_pc)
83 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray73be1e82015-09-17 15:22:56 +010084
Nicolas Geoffrayf6d46682017-02-28 17:41:45 +000085 // Increments the number of times this method is currently being inlined.
86 // Returns whether it was successful, that is it could increment without
87 // overflowing.
88 bool IncrementInlineUse() {
89 if (current_inline_uses_ == std::numeric_limits<uint16_t>::max()) {
90 return false;
91 }
Nicolas Geoffrayb6e20ae2016-03-07 14:29:04 +000092 current_inline_uses_++;
Nicolas Geoffrayf6d46682017-02-28 17:41:45 +000093 return true;
Nicolas Geoffrayb6e20ae2016-03-07 14:29:04 +000094 }
95
96 void DecrementInlineUse() {
97 DCHECK_GT(current_inline_uses_, 0);
98 current_inline_uses_--;
99 }
100
101 bool IsInUseByCompiler() const {
Nicolas Geoffrayf8cc26e2020-06-10 15:37:37 +0100102 return current_inline_uses_ > 0;
Nicolas Geoffray511e41b2016-03-02 17:09:35 +0000103 }
104
Nicolas Geoffraya59af8a2019-11-27 17:42:32 +0000105 static constexpr MemberOffset BaselineHotnessCountOffset() {
106 return MemberOffset(OFFSETOF_MEMBER(ProfilingInfo, baseline_hotness_count_));
107 }
108
Nicolas Geoffrayb0a97472019-12-05 15:17:46 +0000109 void SetBaselineHotnessCount(uint16_t count) {
110 baseline_hotness_count_ = count;
111 }
112
113 uint16_t GetBaselineHotnessCount() const {
114 return baseline_hotness_count_;
115 }
116
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100117 private:
Mathieu Chartier65975772016-08-05 10:46:36 -0700118 ProfilingInfo(ArtMethod* method, const std::vector<uint32_t>& entries);
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100119
Nicolas Geoffraya59af8a2019-11-27 17:42:32 +0000120 // Hotness count for methods compiled with the JIT baseline compiler. Once
121 // a threshold is hit (currentily the maximum value of uint16_t), we will
122 // JIT compile optimized the method.
123 uint16_t baseline_hotness_count_;
124
Nicolas Geoffray26705e22015-10-28 12:50:11 +0000125 // Method this profiling info is for.
Alex Lightdba61482016-12-21 08:20:29 -0800126 // Not 'const' as JVMTI introduces obsolete methods that we implement by creating new ArtMethods.
127 // See JitCodeCache::MoveObsoleteMethod.
128 ArtMethod* method_;
Nicolas Geoffray26705e22015-10-28 12:50:11 +0000129
Andreas Gampee40f65f2018-05-07 17:02:22 -0700130 // Number of instructions we are profiling in the ArtMethod.
131 const uint32_t number_of_inline_caches_;
132
133 // When the compiler inlines the method associated to this ProfilingInfo,
134 // it updates this counter so that the GC does not try to clear the inline caches.
135 uint16_t current_inline_uses_;
136
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100137 // Dynamically allocated array of size `number_of_inline_caches_`.
138 InlineCache cache_[0];
139
Nicolas Geoffray26705e22015-10-28 12:50:11 +0000140 friend class jit::JitCodeCache;
141
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100142 DISALLOW_COPY_AND_ASSIGN(ProfilingInfo);
143};
144
145} // namespace art
146
147#endif // ART_RUNTIME_JIT_PROFILING_INFO_H_