xref: /aosp_15_r20/art/libartpalette/apex/palette.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1 /*
2  * Copyright (C) 2019 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 "palette/palette.h"
18 
19 #include <dlfcn.h>
20 #include <stdlib.h>
21 
22 #include <android/log.h>
23 #include <android-base/macros.h>
24 
25 namespace {
26 
27 // Logging tag.
28 static constexpr const char* kLogTag = "libartpalette";
29 
30 // Name of the palette library present in the /system partition.
31 static constexpr const char* kPaletteSystemLibrary = "libartpalette-system.so";
32 
33 // Generic method used when a dynamically loaded palette instance does not
34 // support a method.
PaletteMethodNotSupported()35 palette_status_t PaletteMethodNotSupported() {
36   return PALETTE_STATUS_NOT_SUPPORTED;
37 }
38 
39 // Declare type aliases for pointers to each function in the interface.
40 #define PALETTE_METHOD_TYPE_ALIAS(Name, ...) \
41   using Name ## Method = palette_status_t(*)(__VA_ARGS__);
42 PALETTE_METHOD_LIST(PALETTE_METHOD_TYPE_ALIAS)
43 #undef PALETTE_METHOD_TYPE_ALIAS
44 
45 // Singleton class responsible for dynamically loading the palette library and
46 // binding functions there to method pointers.
47 class PaletteLoader {
48  public:
Instance()49   static PaletteLoader& Instance() {
50     static PaletteLoader instance;
51     return instance;
52   }
53 
54   // Accessor methods to get instances of palette methods.
55 #define PALETTE_LOADER_METHOD_ACCESSOR(Name, ...)                       \
56   Name ## Method Get ## Name ## Method() const { return Name ## Method ## _; }
57 PALETTE_METHOD_LIST(PALETTE_LOADER_METHOD_ACCESSOR)
58 #undef PALETTE_LOADER_METHOD_ACCESSOR
59 
60  private:
61   PaletteLoader();
62 
63   static void* OpenLibrary();
64   static void* GetMethod(void* palette_lib, const char* name);
65 
66   // Handle to the palette library from dlopen().
67   void* palette_lib_;
68 
69   // Fields to store pointers to palette methods.
70 #define PALETTE_LOADER_METHOD_FIELD(Name, ...) \
71   const Name ## Method Name ## Method ## _;
72   PALETTE_METHOD_LIST(PALETTE_LOADER_METHOD_FIELD)
73 #undef PALETTE_LOADER_METHOD_FIELD
74 
75   DISALLOW_COPY_AND_ASSIGN(PaletteLoader);
76 };
77 
OpenLibrary()78 void* PaletteLoader::OpenLibrary() {
79   void* handle = dlopen(kPaletteSystemLibrary, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
80   if (handle == nullptr) {
81     // dlerror message includes details of error and file being opened.
82     __android_log_assert(nullptr, kLogTag, "%s", dlerror());
83   }
84   return handle;
85 }
86 
GetMethod(void * palette_lib,const char * name)87 void* PaletteLoader::GetMethod(void* palette_lib, const char* name) {
88   void* method = nullptr;
89   if (palette_lib != nullptr) {
90     method = dlsym(palette_lib, name);
91   }
92   if (method == nullptr) {
93     return reinterpret_cast<void*>(PaletteMethodNotSupported);
94   }
95   // TODO(oth): consider new GetMethodSignature() in the Palette API which
96   // would allow checking the validity of the type signatures.
97   return method;
98 }
99 
PaletteLoader()100 PaletteLoader::PaletteLoader() :
101     palette_lib_(OpenLibrary())
102 #define PALETTE_LOADER_BIND_METHOD(Name, ...)                           \
103     , Name ## Method ## _(reinterpret_cast<Name ## Method>(GetMethod(palette_lib_, #Name)))
104     PALETTE_METHOD_LIST(PALETTE_LOADER_BIND_METHOD)
105 #undef PALETTE_LOADER_BIND_METHOD
106 {
107 }
108 
109 }  // namespace
110 
111 extern "C" {
112 
113 // Unless explicitly mentioned otherwise, the following methods have been
114 // introduced in version 1 API, corresponding to SDK level 31.
115 
PaletteSchedSetPriority(int32_t tid,int32_t java_priority)116 palette_status_t PaletteSchedSetPriority(int32_t tid, int32_t java_priority) {
117   PaletteSchedSetPriorityMethod m = PaletteLoader::Instance().GetPaletteSchedSetPriorityMethod();
118   return m(tid, java_priority);
119 }
120 
PaletteSchedGetPriority(int32_t tid,int32_t * java_priority)121 palette_status_t PaletteSchedGetPriority(int32_t tid, /*out*/int32_t* java_priority) {
122   PaletteSchedGetPriorityMethod m = PaletteLoader::Instance().GetPaletteSchedGetPriorityMethod();
123   return m(tid, java_priority);
124 }
125 
PaletteWriteCrashThreadStacks(const char * stack,size_t stack_len)126 palette_status_t PaletteWriteCrashThreadStacks(/*in*/const char* stack, size_t stack_len) {
127   PaletteWriteCrashThreadStacksMethod m =
128       PaletteLoader::Instance().GetPaletteWriteCrashThreadStacksMethod();
129   return m(stack, stack_len);
130 }
131 
PaletteTraceEnabled(bool * enabled)132 palette_status_t PaletteTraceEnabled(/*out*/bool* enabled) {
133   PaletteTraceEnabledMethod m = PaletteLoader::Instance().GetPaletteTraceEnabledMethod();
134   return m(enabled);
135 }
136 
PaletteTraceBegin(const char * name)137 palette_status_t PaletteTraceBegin(/*in*/const char* name) {
138   PaletteTraceBeginMethod m = PaletteLoader::Instance().GetPaletteTraceBeginMethod();
139   return m(name);
140 }
141 
PaletteTraceEnd()142 palette_status_t PaletteTraceEnd() {
143   PaletteTraceEndMethod m = PaletteLoader::Instance().GetPaletteTraceEndMethod();
144   return m();
145 }
146 
PaletteTraceIntegerValue(const char * name,int32_t value)147 palette_status_t PaletteTraceIntegerValue(/*in*/const char* name, int32_t value) {
148   PaletteTraceIntegerValueMethod m = PaletteLoader::Instance().GetPaletteTraceIntegerValueMethod();
149   return m(name, value);
150 }
151 
PaletteAshmemCreateRegion(const char * name,size_t size,int * fd)152 palette_status_t PaletteAshmemCreateRegion(const char* name, size_t size, int* fd) {
153   PaletteAshmemCreateRegionMethod m =
154       PaletteLoader::Instance().GetPaletteAshmemCreateRegionMethod();
155   return m(name, size, fd);
156 }
157 
PaletteAshmemSetProtRegion(int fd,int prot)158 palette_status_t PaletteAshmemSetProtRegion(int fd, int prot) {
159   PaletteAshmemSetProtRegionMethod m =
160       PaletteLoader::Instance().GetPaletteAshmemSetProtRegionMethod();
161   return m(fd, prot);
162 }
163 
PaletteCreateOdrefreshStagingDirectory(const char ** staging_dir)164 palette_status_t PaletteCreateOdrefreshStagingDirectory(const char** staging_dir) {
165   PaletteCreateOdrefreshStagingDirectoryMethod m =
166       PaletteLoader::Instance().GetPaletteCreateOdrefreshStagingDirectoryMethod();
167   return m(staging_dir);
168 }
169 
PaletteShouldReportDex2oatCompilation(bool * value)170 palette_status_t PaletteShouldReportDex2oatCompilation(bool* value) {
171   PaletteShouldReportDex2oatCompilationMethod m =
172       PaletteLoader::Instance().GetPaletteShouldReportDex2oatCompilationMethod();
173   return m(value);
174 }
175 
PaletteNotifyStartDex2oatCompilation(int source_fd,int art_fd,int oat_fd,int vdex_fd)176 palette_status_t PaletteNotifyStartDex2oatCompilation(int source_fd,
177                                                       int art_fd,
178                                                       int oat_fd,
179                                                       int vdex_fd) {
180   PaletteNotifyStartDex2oatCompilationMethod m =
181       PaletteLoader::Instance().GetPaletteNotifyStartDex2oatCompilationMethod();
182   return m(source_fd, art_fd, oat_fd, vdex_fd);
183 }
184 
PaletteNotifyEndDex2oatCompilation(int source_fd,int art_fd,int oat_fd,int vdex_fd)185 palette_status_t PaletteNotifyEndDex2oatCompilation(int source_fd,
186                                                     int art_fd,
187                                                     int oat_fd,
188                                                     int vdex_fd) {
189   PaletteNotifyEndDex2oatCompilationMethod m =
190       PaletteLoader::Instance().GetPaletteNotifyEndDex2oatCompilationMethod();
191   return m(source_fd, art_fd, oat_fd, vdex_fd);
192 }
193 
PaletteNotifyDexFileLoaded(const char * path)194 palette_status_t PaletteNotifyDexFileLoaded(const char* path) {
195   PaletteNotifyDexFileLoadedMethod m =
196       PaletteLoader::Instance().GetPaletteNotifyDexFileLoadedMethod();
197   return m(path);
198 }
199 
PaletteNotifyOatFileLoaded(const char * path)200 palette_status_t PaletteNotifyOatFileLoaded(const char* path) {
201   PaletteNotifyOatFileLoadedMethod m =
202       PaletteLoader::Instance().GetPaletteNotifyOatFileLoadedMethod();
203   return m(path);
204 }
205 
PaletteShouldReportJniInvocations(bool * value)206 palette_status_t PaletteShouldReportJniInvocations(bool* value) {
207   PaletteShouldReportJniInvocationsMethod m =
208       PaletteLoader::Instance().GetPaletteShouldReportJniInvocationsMethod();
209   return m(value);
210 }
211 
PaletteNotifyBeginJniInvocation(JNIEnv * env)212 palette_status_t PaletteNotifyBeginJniInvocation(JNIEnv* env) {
213   PaletteNotifyBeginJniInvocationMethod m =
214       PaletteLoader::Instance().GetPaletteNotifyBeginJniInvocationMethod();
215   return m(env);
216 }
217 
PaletteNotifyEndJniInvocation(JNIEnv * env)218 palette_status_t PaletteNotifyEndJniInvocation(JNIEnv* env) {
219   PaletteNotifyEndJniInvocationMethod m =
220       PaletteLoader::Instance().GetPaletteNotifyEndJniInvocationMethod();
221   return m(env);
222 }
223 
224 // Introduced in version 2 API, corresponding to SDK level 33.
PaletteReportLockContention(JNIEnv * env,int32_t wait_ms,const char * filename,int32_t line_number,const char * method_name,const char * owner_filename,int32_t owner_line_number,const char * owner_method_name,const char * proc_name,const char * thread_name)225 palette_status_t PaletteReportLockContention(JNIEnv* env,
226                                              int32_t wait_ms,
227                                              const char* filename,
228                                              int32_t line_number,
229                                              const char* method_name,
230                                              const char* owner_filename,
231                                              int32_t owner_line_number,
232                                              const char* owner_method_name,
233                                              const char* proc_name,
234                                              const char* thread_name) {
235   PaletteReportLockContentionMethod m =
236       PaletteLoader::Instance().GetPaletteReportLockContentionMethod();
237   return m(env,
238            wait_ms,
239            filename,
240            line_number,
241            method_name,
242            owner_filename,
243            owner_line_number,
244            owner_method_name,
245            proc_name,
246            thread_name);
247 }
248 
249 // Introduced in version 3 API, corresponding to SDK level 34.
PaletteSetTaskProfiles(int32_t tid,const char * const profiles[],size_t profiles_len)250 palette_status_t PaletteSetTaskProfiles(int32_t tid,
251                                         const char* const profiles[],
252                                         size_t profiles_len) {
253   PaletteSetTaskProfilesMethod m = PaletteLoader::Instance().GetPaletteSetTaskProfilesMethod();
254   return m(tid, profiles, profiles_len);
255 }
256 
257 // Methods in version 4 API, corresponding to SDK level 36.
PaletteDebugStoreGetString(char * result,size_t max_size)258 palette_status_t PaletteDebugStoreGetString(char* result, size_t max_size) {
259   PaletteDebugStoreGetStringMethod m =
260       PaletteLoader::Instance().GetPaletteDebugStoreGetStringMethod();
261   return m(result, max_size);
262 }
263 
264 }  // extern "C"
265