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