Home | History | Annotate | Download | only in vm
      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     char state;             /* process state, e.g. 'R', 'S', 'D' */
    304     unsigned long utime;    /* number of jiffies scheduled in user mode */
    305     unsigned long stime;    /* number of jiffies scheduled in kernel mode */
    306     int processor;          /* number of CPU that last executed thread */
    307 };
    308 bool dvmGetThreadStats(ProcStatData* pData, pid_t tid);
    309 
    310 /*
    311  * Returns the pointer to the "absolute path" part of the given path
    312  * string, treating first (if any) instance of "/./" as a sentinel
    313  * indicating the start of the absolute path. If the path isn't absolute
    314  * in the usual way (i.e., starts with "/") and doesn't have the sentinel,
    315  * then this returns NULL.
    316  *
    317  * For example:
    318  *     "/foo/bar/baz" returns "/foo/bar/baz"
    319  *     "foo/./bar/baz" returns "/bar/baz"
    320  *     "foo/bar/baz" returns NULL
    321  *
    322  * The sentinel is used specifically to aid in cross-optimization, where
    323  * a host is processing dex files in a build tree, and where we don't want
    324  * the build tree's directory structure to be baked into the output (such
    325  * as, for example, in the dependency paths of optimized dex files).
    326  */
    327 const char* dvmPathToAbsolutePortion(const char* path);
    328 
    329 /**
    330  * Returns a string corresponding to printf-like formatting of the arguments.
    331  */
    332 std::string StringPrintf(const char* fmt, ...)
    333         __attribute__((__format__ (__printf__, 1, 2)));
    334 
    335 /**
    336  * Appends a printf-like formatting of the arguments to 'dst'.
    337  */
    338 void StringAppendF(std::string* dst, const char* fmt, ...)
    339         __attribute__((__format__ (__printf__, 2, 3)));
    340 
    341 /**
    342  * Appends a printf-like formatting of the arguments to 'dst'.
    343  */
    344 void StringAppendV(std::string* dst, const char* format, va_list ap);
    345 
    346 #endif  // DALVIK_MISC_H_
    347