OSDN Git Service

Differentiate between native alloc and normal background GC
[android-x86/art.git] / runtime / utils.h
1 /*
2  * Copyright (C) 2011 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_UTILS_H_
18 #define ART_RUNTIME_UTILS_H_
19
20 #include <pthread.h>
21 #include <stdlib.h>
22
23 #include <limits>
24 #include <memory>
25 #include <random>
26 #include <string>
27 #include <type_traits>
28 #include <vector>
29
30 #include "arch/instruction_set.h"
31 #include "base/casts.h"
32 #include "base/logging.h"
33 #include "base/stringpiece.h"
34 #include "globals.h"
35 #include "primitive.h"
36
37 namespace art {
38
39 template <typename T>
40 bool ParseUint(const char *in, T* out) {
41   char* end;
42   unsigned long long int result = strtoull(in, &end, 0);  // NOLINT(runtime/int)
43   if (in == end || *end != '\0') {
44     return false;
45   }
46   if (std::numeric_limits<T>::max() < result) {
47     return false;
48   }
49   *out = static_cast<T>(result);
50   return true;
51 }
52
53 template <typename T>
54 bool ParseInt(const char* in, T* out) {
55   char* end;
56   long long int result = strtoll(in, &end, 0);  // NOLINT(runtime/int)
57   if (in == end || *end != '\0') {
58     return false;
59   }
60   if (result < std::numeric_limits<T>::min() || std::numeric_limits<T>::max() < result) {
61     return false;
62   }
63   *out = static_cast<T>(result);
64   return true;
65 }
66
67 static inline uint32_t PointerToLowMemUInt32(const void* p) {
68   uintptr_t intp = reinterpret_cast<uintptr_t>(p);
69   DCHECK_LE(intp, 0xFFFFFFFFU);
70   return intp & 0xFFFFFFFFU;
71 }
72
73 std::string PrintableChar(uint16_t ch);
74
75 // Returns an ASCII string corresponding to the given UTF-8 string.
76 // Java escapes are used for non-ASCII characters.
77 std::string PrintableString(const char* utf8);
78
79 // Used to implement PrettyClass, PrettyField, PrettyMethod, and PrettyTypeOf,
80 // one of which is probably more useful to you.
81 // Returns a human-readable equivalent of 'descriptor'. So "I" would be "int",
82 // "[[I" would be "int[][]", "[Ljava/lang/String;" would be
83 // "java.lang.String[]", and so forth.
84 std::string PrettyDescriptor(const char* descriptor);
85 std::string PrettyDescriptor(Primitive::Type type);
86
87 // Utilities for printing the types for method signatures.
88 std::string PrettyArguments(const char* signature);
89 std::string PrettyReturnType(const char* signature);
90
91 // Returns a human-readable version of the Java part of the access flags, e.g., "private static "
92 // (note the trailing whitespace).
93 std::string PrettyJavaAccessFlags(uint32_t access_flags);
94
95 // Returns a human-readable size string such as "1MB".
96 std::string PrettySize(int64_t size_in_bytes);
97
98 // Performs JNI name mangling as described in section 11.3 "Linking Native Methods"
99 // of the JNI spec.
100 std::string MangleForJni(const std::string& s);
101
102 std::string GetJniShortName(const std::string& class_name, const std::string& method_name);
103
104 // Turn "java.lang.String" into "Ljava/lang/String;".
105 std::string DotToDescriptor(const char* class_name);
106
107 // Turn "Ljava/lang/String;" into "java.lang.String" using the conventions of
108 // java.lang.Class.getName().
109 std::string DescriptorToDot(const char* descriptor);
110
111 // Turn "Ljava/lang/String;" into "java/lang/String" using the opposite conventions of
112 // java.lang.Class.getName().
113 std::string DescriptorToName(const char* descriptor);
114
115 // Tests for whether 's' is a valid class name in the three common forms:
116 bool IsValidBinaryClassName(const char* s);  // "java.lang.String"
117 bool IsValidJniClassName(const char* s);     // "java/lang/String"
118 bool IsValidDescriptor(const char* s);       // "Ljava/lang/String;"
119
120 // Returns whether the given string is a valid field or method name,
121 // additionally allowing names that begin with '<' and end with '>'.
122 bool IsValidMemberName(const char* s);
123
124 bool ReadFileToString(const std::string& file_name, std::string* result);
125 bool PrintFileToLog(const std::string& file_name, LogSeverity level);
126
127 // Splits a string using the given separator character into a vector of
128 // strings. Empty strings will be omitted.
129 void Split(const std::string& s, char separator, std::vector<std::string>* result);
130
131 // Returns the calling thread's tid. (The C libraries don't expose this.)
132 pid_t GetTid();
133
134 // Returns the given thread's name.
135 std::string GetThreadName(pid_t tid);
136
137 // Reads data from "/proc/self/task/${tid}/stat".
138 void GetTaskStats(pid_t tid, char* state, int* utime, int* stime, int* task_cpu);
139
140 // Sets the name of the current thread. The name may be truncated to an
141 // implementation-defined limit.
142 void SetThreadName(const char* thread_name);
143
144 // Find $ANDROID_ROOT, /system, or abort.
145 const char* GetAndroidRoot();
146 // Find $ANDROID_ROOT, /system, or return null.
147 const char* GetAndroidRootSafe(std::string* error_msg);
148
149 // Find $ANDROID_DATA, /data, or abort.
150 const char* GetAndroidData();
151 // Find $ANDROID_DATA, /data, or return null.
152 const char* GetAndroidDataSafe(std::string* error_msg);
153
154 // Returns the default boot image location (ANDROID_ROOT/framework/boot.art).
155 // Returns an empty string if ANDROID_ROOT is not set.
156 std::string GetDefaultBootImageLocation(std::string* error_msg);
157
158 // Returns the dalvik-cache location, with subdir appended. Returns the empty string if the cache
159 // could not be found.
160 std::string GetDalvikCache(const char* subdir);
161 // Return true if we found the dalvik cache and stored it in the dalvik_cache argument.
162 // have_android_data will be set to true if we have an ANDROID_DATA that exists,
163 // dalvik_cache_exists will be true if there is a dalvik-cache directory that is present.
164 // The flag is_global_cache tells whether this cache is /data/dalvik-cache.
165 void GetDalvikCache(const char* subdir, bool create_if_absent, std::string* dalvik_cache,
166                     bool* have_android_data, bool* dalvik_cache_exists, bool* is_global_cache);
167
168 // Returns the absolute dalvik-cache path for a DexFile or OatFile. The path returned will be
169 // rooted at cache_location.
170 bool GetDalvikCacheFilename(const char* file_location, const char* cache_location,
171                             std::string* filename, std::string* error_msg);
172
173 // Returns the system location for an image
174 std::string GetSystemImageFilename(const char* location, InstructionSet isa);
175
176 // Returns true if the file exists.
177 bool FileExists(const std::string& filename);
178 bool FileExistsAndNotEmpty(const std::string& filename);
179
180 // Returns `filename` with the text after the last occurrence of '.' replaced with
181 // `extension`. If `filename` does not contain a period, returns a string containing `filename`,
182 // a period, and `new_extension`.
183 // Example: ReplaceFileExtension("foo.bar", "abc") == "foo.abc"
184 //          ReplaceFileExtension("foo", "abc") == "foo.abc"
185 std::string ReplaceFileExtension(const std::string& filename, const std::string& new_extension);
186
187 class VoidFunctor {
188  public:
189   template <typename A>
190   inline void operator() (A a ATTRIBUTE_UNUSED) const {
191   }
192
193   template <typename A, typename B>
194   inline void operator() (A a ATTRIBUTE_UNUSED, B b ATTRIBUTE_UNUSED) const {
195   }
196
197   template <typename A, typename B, typename C>
198   inline void operator() (A a ATTRIBUTE_UNUSED, B b ATTRIBUTE_UNUSED, C c ATTRIBUTE_UNUSED) const {
199   }
200 };
201
202 inline bool TestBitmap(size_t idx, const uint8_t* bitmap) {
203   return ((bitmap[idx / kBitsPerByte] >> (idx % kBitsPerByte)) & 0x01) != 0;
204 }
205
206 static inline constexpr bool ValidPointerSize(size_t pointer_size) {
207   return pointer_size == 4 || pointer_size == 8;
208 }
209
210 static inline const void* EntryPointToCodePointer(const void* entry_point) {
211   uintptr_t code = reinterpret_cast<uintptr_t>(entry_point);
212   // TODO: Make this Thumb2 specific. It is benign on other architectures as code is always at
213   //       least 2 byte aligned.
214   code &= ~0x1;
215   return reinterpret_cast<const void*>(code);
216 }
217
218 using UsageFn = void (*)(const char*, ...);
219
220 template <typename T>
221 static void ParseIntOption(const StringPiece& option,
222                             const std::string& option_name,
223                             T* out,
224                             UsageFn usage,
225                             bool is_long_option = true) {
226   std::string option_prefix = option_name + (is_long_option ? "=" : "");
227   DCHECK(option.starts_with(option_prefix)) << option << " " << option_prefix;
228   const char* value_string = option.substr(option_prefix.size()).data();
229   int64_t parsed_integer_value = 0;
230   if (!ParseInt(value_string, &parsed_integer_value)) {
231     usage("Failed to parse %s '%s' as an integer", option_name.c_str(), value_string);
232   }
233   *out = dchecked_integral_cast<T>(parsed_integer_value);
234 }
235
236 template <typename T>
237 static void ParseUintOption(const StringPiece& option,
238                             const std::string& option_name,
239                             T* out,
240                             UsageFn usage,
241                             bool is_long_option = true) {
242   ParseIntOption(option, option_name, out, usage, is_long_option);
243   if (*out < 0) {
244     usage("%s passed a negative value %d", option_name.c_str(), *out);
245     *out = 0;
246   }
247 }
248
249 void ParseDouble(const std::string& option,
250                  char after_char,
251                  double min,
252                  double max,
253                  double* parsed_value,
254                  UsageFn Usage);
255
256 #if defined(__BIONIC__)
257 struct Arc4RandomGenerator {
258   typedef uint32_t result_type;
259   static constexpr uint32_t min() { return std::numeric_limits<uint32_t>::min(); }
260   static constexpr uint32_t max() { return std::numeric_limits<uint32_t>::max(); }
261   uint32_t operator() () { return arc4random(); }
262 };
263 using RNG = Arc4RandomGenerator;
264 #else
265 using RNG = std::random_device;
266 #endif
267
268 template <typename T>
269 static T GetRandomNumber(T min, T max) {
270   CHECK_LT(min, max);
271   std::uniform_int_distribution<T> dist(min, max);
272   RNG rng;
273   return dist(rng);
274 }
275
276 // Return the file size in bytes or -1 if the file does not exists.
277 int64_t GetFileSizeBytes(const std::string& filename);
278
279 // Sleep forever and never come back.
280 NO_RETURN void SleepForever();
281
282 inline void FlushInstructionCache(char* begin, char* end) {
283   __builtin___clear_cache(begin, end);
284 }
285
286 inline void FlushDataCache(char* begin, char* end) {
287   // Same as FlushInstructionCache for lack of other builtin. __builtin___clear_cache
288   // flushes both caches.
289   __builtin___clear_cache(begin, end);
290 }
291
292 template <typename T>
293 constexpr PointerSize ConvertToPointerSize(T any) {
294   if (any == 4 || any == 8) {
295     return static_cast<PointerSize>(any);
296   } else {
297     LOG(FATAL);
298     UNREACHABLE();
299   }
300 }
301
302 // Returns a type cast pointer if object pointed to is within the provided bounds.
303 // Otherwise returns nullptr.
304 template <typename T>
305 inline static T BoundsCheckedCast(const void* pointer,
306                                   const void* lower,
307                                   const void* upper) {
308   const uint8_t* bound_begin = static_cast<const uint8_t*>(lower);
309   const uint8_t* bound_end = static_cast<const uint8_t*>(upper);
310   DCHECK(bound_begin <= bound_end);
311
312   T result = reinterpret_cast<T>(pointer);
313   const uint8_t* begin = static_cast<const uint8_t*>(pointer);
314   const uint8_t* end = begin + sizeof(*result);
315   if (begin < bound_begin || end > bound_end || begin > end) {
316     return nullptr;
317   }
318   return result;
319 }
320
321 template <typename T, size_t size>
322 constexpr size_t ArrayCount(const T (&)[size]) {
323   return size;
324 }
325
326 // Return -1 if <, 0 if ==, 1 if >.
327 template <typename T>
328 inline static int32_t Compare(T lhs, T rhs) {
329   return (lhs < rhs) ? -1 : ((lhs == rhs) ? 0 : 1);
330 }
331
332 // Return -1 if < 0, 0 if == 0, 1 if > 0.
333 template <typename T>
334 inline static int32_t Signum(T opnd) {
335   return (opnd < 0) ? -1 : ((opnd == 0) ? 0 : 1);
336 }
337
338 }  // namespace art
339
340 #endif  // ART_RUNTIME_UTILS_H_