OSDN Git Service

am 548d70b0: am 23966773: Rename absoluteMaxSize to maximumSize.
[android-x86/dalvik.git] / vm / Misc.h
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  */
45 INLINE float dvmU4ToFloat(u4 val) {
46     union { u4 in; float out; } conv;
47     conv.in = val;
48     return conv.out;
49 }
50 INLINE 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  */
67 typedef enum { kHexDumpLocal, kHexDumpMem } HexDumpMode;
68 void 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  */
74 INLINE 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  */
82 INLINE 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  */
94 typedef 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  */
117 void dvmCreateLogOutputTarget(DebugOutputTarget* target, int priority,
118     const char* tag);
119 void dvmCreateFileOutputTarget(DebugOutputTarget* target, FILE* fp);
120
121 /*
122  * Print a debug message.
123  */
124 void 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  */
138 typedef 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 */
145 BitVector* dvmAllocBitVector(int startBits, bool expandable);
146 void 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  */
158 int dvmAllocBit(BitVector* pBits);
159 bool dvmSetBit(BitVector* pBits, int num);
160 void dvmClearBit(BitVector* pBits, int num);
161 void dvmClearAllBits(BitVector* pBits);
162 bool dvmIsBitSet(const BitVector* pBits, int num);
163
164 /* count the number of bits that have been set */
165 int dvmCountSetBits(const BitVector* pBits);
166
167 /* copy one vector to the other compatible one */
168 bool 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  */
174 bool 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  */
185 char* 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  */
192 char* 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  */
203 char* 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  */
213 char* 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  */
220 char* 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  */
227 char* 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  */
234 u8 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  */
241 INLINE 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  */
253 INLINE 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  */
267 u8 dvmGetThreadCpuTimeNsec(void);
268
269 /*
270  * Per-thread CPU time, in micros.
271  */
272 INLINE u8 dvmGetThreadCpuTimeUsec(void) {
273     return dvmGetThreadCpuTimeNsec() / 1000;
274 }
275
276 /*
277  * Like dvmGetThreadCpuTimeNsec, but for a different thread.
278  */
279 u8 dvmGetOtherThreadCpuTimeNsec(pthread_t thread);
280 INLINE 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  */
291 bool dvmIterativeSleep(int iteration, int maxTotalSleep, u8 relStartTime);
292
293 /*
294  * Set the "close on exec" flag on a file descriptor.
295  */
296 bool 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  */
307 void dvmAbort(void);
308
309 #if (!HAVE_STRLCPY)
310 /* Implementation of strlcpy() for platforms that don't already have it. */
311 size_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  */
319 void *dvmAllocRegion(size_t size, int prot, const char *name);
320
321 /*
322  * Get some per-thread stats from /proc/self/task/N/stat.
323  */
324 typedef 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;
329 bool 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  */
348 const char* dvmPathToAbsolutePortion(const char* path);
349
350 #endif /*_DALVIK_MISC*/