1 /*
2 * Copyright 2024 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 #include "jit_options.h"
18
19 #include "runtime_options.h"
20
21 namespace art HIDDEN {
22 namespace jit {
23
24 // Maximum permitted threshold value.
25 static constexpr uint32_t kJitMaxThreshold = std::numeric_limits<uint16_t>::max();
26
27 static constexpr uint32_t kJitDefaultOptimizeThreshold = 0xffff;
28 // Different optimization threshold constants. These default to the equivalent optimization
29 // thresholds divided by 2, but can be overridden at the command-line.
30 static constexpr uint32_t kJitStressDefaultOptimizeThreshold = kJitDefaultOptimizeThreshold / 2;
31 static constexpr uint32_t kJitSlowStressDefaultOptimizeThreshold =
32 kJitStressDefaultOptimizeThreshold / 2;
33
34 static constexpr uint32_t kJitDefaultWarmupThreshold = 0xffff;
35 // Different warm-up threshold constants. These default to the equivalent warmup thresholds divided
36 // by 2, but can be overridden at the command-line.
37 static constexpr uint32_t kJitStressDefaultWarmupThreshold = kJitDefaultWarmupThreshold / 2;
38 static constexpr uint32_t kJitSlowStressDefaultWarmupThreshold =
39 kJitStressDefaultWarmupThreshold / 2;
40
41 static constexpr size_t kDefaultPriorityThreadWeightRatio = 1000;
42 static constexpr size_t kDefaultInvokeTransitionWeightRatio = 500;
43
44 DEFINE_RUNTIME_DEBUG_FLAG(JitOptions, kSlowMode);
45
CreateFromRuntimeArguments(const RuntimeArgumentMap & options)46 JitOptions* JitOptions::CreateFromRuntimeArguments(const RuntimeArgumentMap& options) {
47 auto* jit_options = new JitOptions;
48 jit_options->use_jit_compilation_ = options.GetOrDefault(RuntimeArgumentMap::UseJitCompilation);
49 jit_options->use_profiled_jit_compilation_ =
50 options.GetOrDefault(RuntimeArgumentMap::UseProfiledJitCompilation);
51
52 jit_options->code_cache_initial_capacity_ =
53 options.GetOrDefault(RuntimeArgumentMap::JITCodeCacheInitialCapacity);
54 jit_options->code_cache_max_capacity_ =
55 options.GetOrDefault(RuntimeArgumentMap::JITCodeCacheMaxCapacity);
56 jit_options->dump_info_on_shutdown_ =
57 options.Exists(RuntimeArgumentMap::DumpJITInfoOnShutdown);
58 jit_options->profile_saver_options_ =
59 options.GetOrDefault(RuntimeArgumentMap::ProfileSaverOpts);
60 jit_options->thread_pool_pthread_priority_ =
61 options.GetOrDefault(RuntimeArgumentMap::JITPoolThreadPthreadPriority);
62 jit_options->zygote_thread_pool_pthread_priority_ =
63 options.GetOrDefault(RuntimeArgumentMap::JITZygotePoolThreadPthreadPriority);
64
65 // Set default optimize threshold to aid with checking defaults.
66 jit_options->optimize_threshold_ = kIsDebugBuild
67 ? (kSlowMode ? kJitSlowStressDefaultOptimizeThreshold : kJitStressDefaultOptimizeThreshold)
68 : kJitDefaultOptimizeThreshold;
69
70 // Set default warm-up threshold to aid with checking defaults.
71 jit_options->warmup_threshold_ = kIsDebugBuild
72 ? (kSlowMode ? kJitSlowStressDefaultWarmupThreshold : kJitStressDefaultWarmupThreshold)
73 : kJitDefaultWarmupThreshold;
74
75 if (options.Exists(RuntimeArgumentMap::JITOptimizeThreshold)) {
76 jit_options->optimize_threshold_ = *options.Get(RuntimeArgumentMap::JITOptimizeThreshold);
77 }
78 DCHECK_LE(jit_options->optimize_threshold_, kJitMaxThreshold);
79
80 if (options.Exists(RuntimeArgumentMap::JITWarmupThreshold)) {
81 jit_options->warmup_threshold_ = *options.Get(RuntimeArgumentMap::JITWarmupThreshold);
82 }
83 DCHECK_LE(jit_options->warmup_threshold_, kJitMaxThreshold);
84
85 if (options.Exists(RuntimeArgumentMap::JITPriorityThreadWeight)) {
86 jit_options->priority_thread_weight_ =
87 *options.Get(RuntimeArgumentMap::JITPriorityThreadWeight);
88 if (jit_options->priority_thread_weight_ > jit_options->warmup_threshold_) {
89 LOG(FATAL) << "Priority thread weight is above the warmup threshold.";
90 } else if (jit_options->priority_thread_weight_ == 0) {
91 LOG(FATAL) << "Priority thread weight cannot be 0.";
92 }
93 } else {
94 jit_options->priority_thread_weight_ = std::max(
95 jit_options->warmup_threshold_ / kDefaultPriorityThreadWeightRatio,
96 static_cast<size_t>(1));
97 }
98
99 if (options.Exists(RuntimeArgumentMap::JITInvokeTransitionWeight)) {
100 jit_options->invoke_transition_weight_ =
101 *options.Get(RuntimeArgumentMap::JITInvokeTransitionWeight);
102 if (jit_options->invoke_transition_weight_ > jit_options->warmup_threshold_) {
103 LOG(FATAL) << "Invoke transition weight is above the warmup threshold.";
104 } else if (jit_options->invoke_transition_weight_ == 0) {
105 LOG(FATAL) << "Invoke transition weight cannot be 0.";
106 }
107 } else {
108 jit_options->invoke_transition_weight_ = std::max(
109 jit_options->warmup_threshold_ / kDefaultInvokeTransitionWeightRatio,
110 static_cast<size_t>(1));
111 }
112
113 return jit_options;
114 }
115
116 } // namespace jit
117 } // namespace art
118