Misc.h revision 837eabb829417c1542037423c55536649de404b8
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 */ 48INLINE float dvmU4ToFloat(u4 val) { 49 union { u4 in; float out; } conv; 50 conv.in = val; 51 return conv.out; 52} 53INLINE 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 */ 70enum HexDumpMode { kHexDumpLocal, kHexDumpMem }; 71void 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 */ 77INLINE 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 */ 85INLINE 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 93enum 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 */ 103struct 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 */ 122void dvmCreateLogOutputTarget(DebugOutputTarget* target, int priority, 123 const char* tag); 124void dvmCreateFileOutputTarget(DebugOutputTarget* target, FILE* fp); 125 126/* 127 * Print a debug message. 128 */ 129void 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 */ 141char* 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 */ 148std::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 */ 156std::string dvmHumanReadableType(const Object* obj); 157 158/* 159 * Return a newly-allocated string for the "dot version" of the class 160 * name for the given type descriptor. That is, The initial "L" and 161 * final ";" (if any) have been removed and all occurrences of '/' 162 * have been changed to '.'. 163 * 164 * "Dot version" names are used in the class loading machinery. 165 * See also dvmHumanReadableDescriptor. 166 */ 167char* dvmDescriptorToDot(const char* str); 168 169/* 170 * Return a newly-allocated string for the type descriptor 171 * corresponding to the "dot version" of the given class name. That 172 * is, non-array names are surrounded by "L" and ";", and all 173 * occurrences of '.' have been changed to '/'. 174 * 175 * "Dot version" names are used in the class loading machinery. 176 */ 177char* dvmDotToDescriptor(const char* str); 178 179/* 180 * Return a newly-allocated string for the internal-form class name for 181 * the given type descriptor. That is, the initial "L" and final ";" (if 182 * any) have been removed. 183 */ 184char* dvmDescriptorToName(const char* str); 185 186/* 187 * Return a newly-allocated string for the type descriptor for the given 188 * internal-form class name. That is, a non-array class name will get 189 * surrounded by "L" and ";", while array names are left as-is. 190 */ 191char* dvmNameToDescriptor(const char* str); 192 193/* 194 * Get the current time, in nanoseconds. This is "relative" time, meaning 195 * it could be wall-clock time or a monotonic counter, and is only suitable 196 * for computing time deltas. 197 */ 198u8 dvmGetRelativeTimeNsec(void); 199 200/* 201 * Get the current time, in microseconds. This is "relative" time, meaning 202 * it could be wall-clock time or a monotonic counter, and is only suitable 203 * for computing time deltas. 204 */ 205INLINE u8 dvmGetRelativeTimeUsec(void) { 206 return dvmGetRelativeTimeNsec() / 1000; 207} 208 209/* 210 * Get the current time, in milliseconds. This is "relative" time, 211 * meaning it could be wall-clock time or a monotonic counter, and is 212 * only suitable for computing time deltas. The value returned from 213 * this function is a u4 and should only be used for debugging 214 * messages. TODO: make this value relative to the start-up time of 215 * the VM. 216 */ 217INLINE u4 dvmGetRelativeTimeMsec(void) { 218 return (u4)(dvmGetRelativeTimeUsec() / 1000); 219} 220 221/* 222 * Get the current per-thread CPU time. This clock increases monotonically 223 * when the thread is running, but not when it's sleeping or blocked on a 224 * synchronization object. 225 * 226 * The absolute value of the clock may not be useful, so this should only 227 * be used for time deltas. 228 * 229 * If the thread CPU clock is not available, this always returns (u8)-1. 230 */ 231u8 dvmGetThreadCpuTimeNsec(void); 232 233/* 234 * Per-thread CPU time, in micros. 235 */ 236INLINE u8 dvmGetThreadCpuTimeUsec(void) { 237 return dvmGetThreadCpuTimeNsec() / 1000; 238} 239 240/* 241 * Like dvmGetThreadCpuTimeNsec, but for a different thread. 242 */ 243u8 dvmGetOtherThreadCpuTimeNsec(pthread_t thread); 244INLINE u8 dvmGetOtherThreadCpuTimeUsec(pthread_t thread) { 245 return dvmGetOtherThreadCpuTimeNsec(thread) / 1000; 246} 247 248/* 249 * Sleep for increasingly longer periods, until "maxTotalSleep" microseconds 250 * have elapsed. Pass in the start time, which must be a value returned by 251 * dvmGetRelativeTimeUsec(). 252 * 253 * Returns "false" if we were unable to sleep because our time is up. 254 */ 255bool dvmIterativeSleep(int iteration, int maxTotalSleep, u8 relStartTime); 256 257/* 258 * Set the "close on exec" flag on a file descriptor. 259 */ 260bool dvmSetCloseOnExec(int fd); 261 262/* 263 * Unconditionally abort the entire VM. Try not to use this. 264 * 265 * NOTE: if this is marked ((noreturn)), gcc will merge multiple dvmAbort() 266 * calls in a single function together. This is good, in that it reduces 267 * code size slightly, but also bad, because the native stack trace we 268 * get from the abort may point at the wrong call site. Best to leave 269 * it undecorated. 270 */ 271extern "C" void dvmAbort(void); 272void dvmPrintNativeBackTrace(void); 273 274#if (!HAVE_STRLCPY) 275/* Implementation of strlcpy() for platforms that don't already have it. */ 276extern "C" size_t strlcpy(char *dst, const char *src, size_t size); 277#endif 278 279/* 280 * Allocates a memory region using ashmem and mmap, initialized to 281 * zero. Actual allocation rounded up to page multiple. Returns 282 * NULL on failure. 283 */ 284void *dvmAllocRegion(size_t size, int prot, const char *name); 285 286/* 287 * Get some per-thread stats from /proc/self/task/N/stat. 288 */ 289struct ProcStatData { 290 unsigned long utime; /* number of jiffies scheduled in user mode */ 291 unsigned long stime; /* number of jiffies scheduled in kernel mode */ 292 int processor; /* number of CPU that last executed thread */ 293}; 294bool dvmGetThreadStats(ProcStatData* pData, pid_t tid); 295 296/* 297 * Returns the pointer to the "absolute path" part of the given path 298 * string, treating first (if any) instance of "/./" as a sentinel 299 * indicating the start of the absolute path. If the path isn't absolute 300 * in the usual way (i.e., starts with "/") and doesn't have the sentinel, 301 * then this returns NULL. 302 * 303 * For example: 304 * "/foo/bar/baz" returns "/foo/bar/baz" 305 * "foo/./bar/baz" returns "/bar/baz" 306 * "foo/bar/baz" returns NULL 307 * 308 * The sentinel is used specifically to aid in cross-optimization, where 309 * a host is processing dex files in a build tree, and where we don't want 310 * the build tree's directory structure to be baked into the output (such 311 * as, for example, in the dependency paths of optimized dex files). 312 */ 313const char* dvmPathToAbsolutePortion(const char* path); 314 315/** 316 * Returns a string corresponding to printf-like formatting of the arguments. 317 */ 318std::string StringPrintf(const char* fmt, ...) 319 __attribute__((__format__ (__printf__, 1, 2))); 320 321/** 322 * Appends a printf-like formatting of the arguments to 'dst'. 323 */ 324void StringAppendF(std::string* dst, const char* fmt, ...) 325 __attribute__((__format__ (__printf__, 2, 3))); 326 327#endif // DALVIK_MISC_H_ 328