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