Home | History | Annotate | Download | only in runtime
      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 the vdex filename for the given oat filename.
    177 std::string GetVdexFilename(const std::string& oat_filename);
    178 
    179 // Returns true if the file exists.
    180 bool FileExists(const std::string& filename);
    181 bool FileExistsAndNotEmpty(const std::string& filename);
    182 
    183 // Returns `filename` with the text after the last occurrence of '.' replaced with
    184 // `extension`. If `filename` does not contain a period, returns a string containing `filename`,
    185 // a period, and `new_extension`.
    186 // Example: ReplaceFileExtension("foo.bar", "abc") == "foo.abc"
    187 //          ReplaceFileExtension("foo", "abc") == "foo.abc"
    188 std::string ReplaceFileExtension(const std::string& filename, const std::string& new_extension);
    189 
    190 class VoidFunctor {
    191  public:
    192   template <typename A>
    193   inline void operator() (A a ATTRIBUTE_UNUSED) const {
    194   }
    195 
    196   template <typename A, typename B>
    197   inline void operator() (A a ATTRIBUTE_UNUSED, B b ATTRIBUTE_UNUSED) const {
    198   }
    199 
    200   template <typename A, typename B, typename C>
    201   inline void operator() (A a ATTRIBUTE_UNUSED, B b ATTRIBUTE_UNUSED, C c ATTRIBUTE_UNUSED) const {
    202   }
    203 };
    204 
    205 inline bool TestBitmap(size_t idx, const uint8_t* bitmap) {
    206   return ((bitmap[idx / kBitsPerByte] >> (idx % kBitsPerByte)) & 0x01) != 0;
    207 }
    208 
    209 static inline constexpr bool ValidPointerSize(size_t pointer_size) {
    210   return pointer_size == 4 || pointer_size == 8;
    211 }
    212 
    213 static inline const void* EntryPointToCodePointer(const void* entry_point) {
    214   uintptr_t code = reinterpret_cast<uintptr_t>(entry_point);
    215   // TODO: Make this Thumb2 specific. It is benign on other architectures as code is always at
    216   //       least 2 byte aligned.
    217   code &= ~0x1;
    218   return reinterpret_cast<const void*>(code);
    219 }
    220 
    221 using UsageFn = void (*)(const char*, ...);
    222 
    223 template <typename T>
    224 static void ParseIntOption(const StringPiece& option,
    225                             const std::string& option_name,
    226                             T* out,
    227                             UsageFn usage,
    228                             bool is_long_option = true) {
    229   std::string option_prefix = option_name + (is_long_option ? "=" : "");
    230   DCHECK(option.starts_with(option_prefix)) << option << " " << option_prefix;
    231   const char* value_string = option.substr(option_prefix.size()).data();
    232   int64_t parsed_integer_value = 0;
    233   if (!ParseInt(value_string, &parsed_integer_value)) {
    234     usage("Failed to parse %s '%s' as an integer", option_name.c_str(), value_string);
    235   }
    236   *out = dchecked_integral_cast<T>(parsed_integer_value);
    237 }
    238 
    239 template <typename T>
    240 static void ParseUintOption(const StringPiece& option,
    241                             const std::string& option_name,
    242                             T* out,
    243                             UsageFn usage,
    244                             bool is_long_option = true) {
    245   ParseIntOption(option, option_name, out, usage, is_long_option);
    246   if (*out < 0) {
    247     usage("%s passed a negative value %d", option_name.c_str(), *out);
    248     *out = 0;
    249   }
    250 }
    251 
    252 void ParseDouble(const std::string& option,
    253                  char after_char,
    254                  double min,
    255                  double max,
    256                  double* parsed_value,
    257                  UsageFn Usage);
    258 
    259 #if defined(__BIONIC__)
    260 struct Arc4RandomGenerator {
    261   typedef uint32_t result_type;
    262   static constexpr uint32_t min() { return std::numeric_limits<uint32_t>::min(); }
    263   static constexpr uint32_t max() { return std::numeric_limits<uint32_t>::max(); }
    264   uint32_t operator() () { return arc4random(); }
    265 };
    266 using RNG = Arc4RandomGenerator;
    267 #else
    268 using RNG = std::random_device;
    269 #endif
    270 
    271 template <typename T>
    272 static T GetRandomNumber(T min, T max) {
    273   CHECK_LT(min, max);
    274   std::uniform_int_distribution<T> dist(min, max);
    275   RNG rng;
    276   return dist(rng);
    277 }
    278 
    279 // Return the file size in bytes or -1 if the file does not exists.
    280 int64_t GetFileSizeBytes(const std::string& filename);
    281 
    282 // Sleep forever and never come back.
    283 NO_RETURN void SleepForever();
    284 
    285 inline void FlushInstructionCache(char* begin, char* end) {
    286   __builtin___clear_cache(begin, end);
    287 }
    288 
    289 inline void FlushDataCache(char* begin, char* end) {
    290   // Same as FlushInstructionCache for lack of other builtin. __builtin___clear_cache
    291   // flushes both caches.
    292   __builtin___clear_cache(begin, end);
    293 }
    294 
    295 template <typename T>
    296 constexpr PointerSize ConvertToPointerSize(T any) {
    297   if (any == 4 || any == 8) {
    298     return static_cast<PointerSize>(any);
    299   } else {
    300     LOG(FATAL);
    301     UNREACHABLE();
    302   }
    303 }
    304 
    305 // Returns a type cast pointer if object pointed to is within the provided bounds.
    306 // Otherwise returns nullptr.
    307 template <typename T>
    308 inline static T BoundsCheckedCast(const void* pointer,
    309                                   const void* lower,
    310                                   const void* upper) {
    311   const uint8_t* bound_begin = static_cast<const uint8_t*>(lower);
    312   const uint8_t* bound_end = static_cast<const uint8_t*>(upper);
    313   DCHECK(bound_begin <= bound_end);
    314 
    315   T result = reinterpret_cast<T>(pointer);
    316   const uint8_t* begin = static_cast<const uint8_t*>(pointer);
    317   const uint8_t* end = begin + sizeof(*result);
    318   if (begin < bound_begin || end > bound_end || begin > end) {
    319     return nullptr;
    320   }
    321   return result;
    322 }
    323 
    324 template <typename T, size_t size>
    325 constexpr size_t ArrayCount(const T (&)[size]) {
    326   return size;
    327 }
    328 
    329 // Return -1 if <, 0 if ==, 1 if >.
    330 template <typename T>
    331 inline static int32_t Compare(T lhs, T rhs) {
    332   return (lhs < rhs) ? -1 : ((lhs == rhs) ? 0 : 1);
    333 }
    334 
    335 // Return -1 if < 0, 0 if == 0, 1 if > 0.
    336 template <typename T>
    337 inline static int32_t Signum(T opnd) {
    338   return (opnd < 0) ? -1 : ((opnd == 0) ? 0 : 1);
    339 }
    340 
    341 }  // namespace art
    342 
    343 #endif  // ART_RUNTIME_UTILS_H_
    344