1 /* 2 * Copyright (C) 2008 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 /* 18 * Miscellaneous utility functions. 19 */ 20 #ifndef DALVIK_MISC_H_ 21 #define DALVIK_MISC_H_ 22 23 #include <string> 24 25 #include <stdarg.h> 26 #include <stdio.h> 27 #include <sys/types.h> 28 #include <sys/time.h> 29 30 #include "Inlines.h" 31 32 /* 33 * Used to shut up the compiler when a parameter isn't used. 34 */ 35 #define UNUSED_PARAMETER(p) (void)(p) 36 37 /* 38 * Floating point conversion functions. These are necessary to avoid 39 * strict-aliasing problems ("dereferencing type-punned pointer will break 40 * strict-aliasing rules"). According to the gcc info page, this usage 41 * is allowed, even with "-fstrict-aliasing". 42 * 43 * The code generated by gcc-4.1.1 appears to be much better than a 44 * type cast dereference ("int foo = *(int*)&myfloat") when the conversion 45 * function is inlined. It also allows us to take advantage of the 46 * optimizations that strict aliasing rules allow. 47 */ 48 INLINE float dvmU4ToFloat(u4 val) { 49 union { u4 in; float out; } conv; 50 conv.in = val; 51 return conv.out; 52 } 53 INLINE u4 dvmFloatToU4(float val) { 54 union { float in; u4 out; } conv; 55 conv.in = val; 56 return conv.out; 57 } 58 59 /* 60 * Print a hex dump to the log file. 61 * 62 * "local" mode prints a hex dump starting from offset 0 (roughly equivalent 63 * to "xxd -g1"). 64 * 65 * "mem" mode shows the actual memory address, and will offset the start 66 * so that the low nibble of the address is always zero. 67 * 68 * If "tag" is NULL the default tag ("dalvikvm") will be used. 69 */ 70 enum HexDumpMode { kHexDumpLocal, kHexDumpMem }; 71 void dvmPrintHexDumpEx(int priority, const char* tag, const void* vaddr, 72 size_t length, HexDumpMode mode); 73 74 /* 75 * Print a hex dump, at INFO level. 76 */ 77 INLINE void dvmPrintHexDump(const void* vaddr, size_t length) { 78 dvmPrintHexDumpEx(ANDROID_LOG_INFO, LOG_TAG, 79 vaddr, length, kHexDumpLocal); 80 } 81 82 /* 83 * Print a hex dump at VERBOSE level. This does nothing in non-debug builds. 84 */ 85 INLINE void dvmPrintHexDumpDbg(const void* vaddr, size_t length,const char* tag) 86 { 87 #if !LOG_NDEBUG 88 dvmPrintHexDumpEx(ANDROID_LOG_VERBOSE, (tag != NULL) ? tag : LOG_TAG, 89 vaddr, length, kHexDumpLocal); 90 #endif 91 } 92 93 enum DebugTargetKind { 94 kDebugTargetUnknown = 0, 95 kDebugTargetLog, 96 kDebugTargetFile, 97 }; 98 99 /* 100 * We pass one of these around when we want code to be able to write debug 101 * info to either the log or to a file (or stdout/stderr). 102 */ 103 struct DebugOutputTarget { 104 /* where to? */ 105 DebugTargetKind which; 106 107 /* additional bits */ 108 union { 109 struct { 110 int priority; 111 const char* tag; 112 } log; 113 struct { 114 FILE* fp; 115 } file; 116 } data; 117 }; 118 119 /* 120 * Fill in a DebugOutputTarget struct. 121 */ 122 void dvmCreateLogOutputTarget(DebugOutputTarget* target, int priority, 123 const char* tag); 124 void dvmCreateFileOutputTarget(DebugOutputTarget* target, FILE* fp); 125 126 /* 127 * Print a debug message. 128 */ 129 void dvmPrintDebugMessage(const DebugOutputTarget* target, const char* format, 130 ...) 131 #if defined(__GNUC__) 132 __attribute__ ((format(printf, 2, 3))) 133 #endif 134 ; 135 136 /* 137 * Return a newly-allocated string in which all occurrences of '.' have 138 * been changed to '/'. If we find a '/' in the original string, NULL 139 * is returned to avoid ambiguity. 140 */ 141 char* dvmDotToSlash(const char* str); 142 143 /* 144 * Return a newly-allocated string containing a human-readable equivalent 145 * of 'descriptor'. So "I" would be "int", "[[I" would be "int[][]", 146 * "[Ljava/lang/String;" would be "java.lang.String[]", and so forth. 147 */ 148 std::string dvmHumanReadableDescriptor(const char* descriptor); 149 150 /** 151 * Returns a human-readable string form of the name of the class of 152 * the given object. So given a java.lang.String, the output would 153 * be "java.lang.String". Given an array of int, the output would be "int[]". 154 * Given String.class, the output would be "java.lang.Class<java.lang.String>". 155 */ 156 std::string dvmHumanReadableType(const Object* obj); 157 158 /** 159 * Returns a human-readable string of the form "package.Class.fieldName". 160 */ 161 struct Field; 162 std::string dvmHumanReadableField(const Field* field); 163 164 /** 165 * Returns a human-readable string of the form "package.Class.methodName" 166 * or "package.Class.methodName(Ljava/lang/String;I)V". 167 */ 168 struct Method; 169 std::string dvmHumanReadableMethod(const Method* method, bool withSignature); 170 171 /* 172 * Return a newly-allocated string for the "dot version" of the class 173 * name for the given type descriptor. That is, The initial "L" and 174 * final ";" (if any) have been removed and all occurrences of '/' 175 * have been changed to '.'. 176 * 177 * "Dot version" names are used in the class loading machinery. 178 * See also dvmHumanReadableDescriptor. 179 */ 180 char* dvmDescriptorToDot(const char* str); 181 182 /* 183 * Return a newly-allocated string for the type descriptor 184 * corresponding to the "dot version" of the given class name. That 185 * is, non-array names are surrounded by "L" and ";", and all 186 * occurrences of '.' have been changed to '/'. 187 * 188 * "Dot version" names are used in the class loading machinery. 189 */ 190 char* dvmDotToDescriptor(const char* str); 191 192 /* 193 * Return a newly-allocated string for the internal-form class name for 194 * the given type descriptor. That is, the initial "L" and final ";" (if 195 * any) have been removed. 196 */ 197 char* dvmDescriptorToName(const char* str); 198 199 /* 200 * Return a newly-allocated string for the type descriptor for the given 201 * internal-form class name. That is, a non-array class name will get 202 * surrounded by "L" and ";", while array names are left as-is. 203 */ 204 char* dvmNameToDescriptor(const char* str); 205 206 /* 207 * Get the current time, in nanoseconds. This is "relative" time, meaning 208 * it could be wall-clock time or a monotonic counter, and is only suitable 209 * for computing time deltas. 210 */ 211 u8 dvmGetRelativeTimeNsec(void); 212 213 /* 214 * Get the current time, in microseconds. This is "relative" time, meaning 215 * it could be wall-clock time or a monotonic counter, and is only suitable 216 * for computing time deltas. 217 */ 218 INLINE u8 dvmGetRelativeTimeUsec(void) { 219 return dvmGetRelativeTimeNsec() / 1000; 220 } 221 222 /* 223 * Get the current time, in milliseconds. This is "relative" time, 224 * meaning it could be wall-clock time or a monotonic counter, and is 225 * only suitable for computing time deltas. The value returned from 226 * this function is a u4 and should only be used for debugging 227 * messages. TODO: make this value relative to the start-up time of 228 * the VM. 229 */ 230 INLINE u4 dvmGetRelativeTimeMsec(void) { 231 return (u4)(dvmGetRelativeTimeUsec() / 1000); 232 } 233 234 /* 235 * Get the current per-thread CPU time. This clock increases monotonically 236 * when the thread is running, but not when it's sleeping or blocked on a 237 * synchronization object. 238 * 239 * The absolute value of the clock may not be useful, so this should only 240 * be used for time deltas. 241 * 242 * If the thread CPU clock is not available, this always returns (u8)-1. 243 */ 244 u8 dvmGetThreadCpuTimeNsec(void); 245 246 /* 247 * Per-thread CPU time, in micros. 248 */ 249 INLINE u8 dvmGetThreadCpuTimeUsec(void) { 250 return dvmGetThreadCpuTimeNsec() / 1000; 251 } 252 253 /* 254 * Like dvmGetThreadCpuTimeNsec, but for a different thread. 255 */ 256 u8 dvmGetOtherThreadCpuTimeNsec(pthread_t thread); 257 INLINE u8 dvmGetOtherThreadCpuTimeUsec(pthread_t thread) { 258 return dvmGetOtherThreadCpuTimeNsec(thread) / 1000; 259 } 260 261 /* 262 * Sleep for increasingly longer periods, until "maxTotalSleep" microseconds 263 * have elapsed. Pass in the start time, which must be a value returned by 264 * dvmGetRelativeTimeUsec(). 265 * 266 * Returns "false" if we were unable to sleep because our time is up. 267 */ 268 bool dvmIterativeSleep(int iteration, int maxTotalSleep, u8 relStartTime); 269 270 /* 271 * Set the "close on exec" flag on a file descriptor. 272 */ 273 bool dvmSetCloseOnExec(int fd); 274 275 /* 276 * Unconditionally abort the entire VM. Try not to use this. 277 * 278 * NOTE: if this is marked ((noreturn)), gcc will merge multiple dvmAbort() 279 * calls in a single function together. This is good, in that it reduces 280 * code size slightly, but also bad, because the native stack trace we 281 * get from the abort may point at the wrong call site. Best to leave 282 * it undecorated. 283 */ 284 extern "C" void dvmAbort(void); 285 void dvmPrintNativeBackTrace(void); 286 287 #if (!HAVE_STRLCPY) 288 /* Implementation of strlcpy() for platforms that don't already have it. */ 289 extern "C" size_t strlcpy(char *dst, const char *src, size_t size); 290 #endif 291 292 /* 293 * Allocates a memory region using ashmem and mmap, initialized to 294 * zero. Actual allocation rounded up to page multiple. Returns 295 * NULL on failure. 296 */ 297 void *dvmAllocRegion(size_t size, int prot, const char *name); 298 299 /* 300 * Get some per-thread stats from /proc/self/task/N/stat. 301 */ 302 struct ProcStatData { 303 unsigned long utime; /* number of jiffies scheduled in user mode */ 304 unsigned long stime; /* number of jiffies scheduled in kernel mode */ 305 int processor; /* number of CPU that last executed thread */ 306 }; 307 bool dvmGetThreadStats(ProcStatData* pData, pid_t tid); 308 309 /* 310 * Returns the pointer to the "absolute path" part of the given path 311 * string, treating first (if any) instance of "/./" as a sentinel 312 * indicating the start of the absolute path. If the path isn't absolute 313 * in the usual way (i.e., starts with "/") and doesn't have the sentinel, 314 * then this returns NULL. 315 * 316 * For example: 317 * "/foo/bar/baz" returns "/foo/bar/baz" 318 * "foo/./bar/baz" returns "/bar/baz" 319 * "foo/bar/baz" returns NULL 320 * 321 * The sentinel is used specifically to aid in cross-optimization, where 322 * a host is processing dex files in a build tree, and where we don't want 323 * the build tree's directory structure to be baked into the output (such 324 * as, for example, in the dependency paths of optimized dex files). 325 */ 326 const char* dvmPathToAbsolutePortion(const char* path); 327 328 /** 329 * Returns a string corresponding to printf-like formatting of the arguments. 330 */ 331 std::string StringPrintf(const char* fmt, ...) 332 __attribute__((__format__ (__printf__, 1, 2))); 333 334 /** 335 * Appends a printf-like formatting of the arguments to 'dst'. 336 */ 337 void StringAppendF(std::string* dst, const char* fmt, ...) 338 __attribute__((__format__ (__printf__, 2, 3))); 339 340 /** 341 * Appends a printf-like formatting of the arguments to 'dst'. 342 */ 343 void StringAppendV(std::string* dst, const char* format, va_list ap); 344 345 #endif // DALVIK_MISC_H_ 346