OSDN Git Service

am 11fb99d5: [JIT] Fix volatile test
[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 <stdio.h>
24 #include <sys/types.h>
25 #include <sys/time.h>
26 #include "Inlines.h"
27
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
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 typedef enum { kHexDumpLocal, kHexDumpMem } HexDumpMode;
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 /*
94  * We pass one of these around when we want code to be able to write debug
95  * info to either the log or to a file (or stdout/stderr).
96  */
97 typedef struct DebugOutputTarget {
98     /* where to? */
99     enum {
100         kDebugTargetUnknown = 0,
101         kDebugTargetLog,
102         kDebugTargetFile,
103     } which;
104
105     /* additional bits */
106     union {
107         struct {
108             int priority;
109             const char* tag;
110         } log;
111         struct {
112             FILE* fp;
113         } file;
114     } data;
115 } DebugOutputTarget;
116
117 /*
118  * Fill in a DebugOutputTarget struct.
119  */
120 void dvmCreateLogOutputTarget(DebugOutputTarget* target, int priority,
121     const char* tag);
122 void dvmCreateFileOutputTarget(DebugOutputTarget* target, FILE* fp);
123
124 /*
125  * Print a debug message.
126  */
127 void dvmPrintDebugMessage(const DebugOutputTarget* target, const char* format,
128     ...)
129 #if defined(__GNUC__)
130     __attribute__ ((format(printf, 2, 3)))
131 #endif
132     ;
133
134 /*
135  * Return a newly-allocated string in which all occurrences of '.' have
136  * been changed to '/'.  If we find a '/' in the original string, NULL
137  * is returned to avoid ambiguity.
138  */
139 char* dvmDotToSlash(const char* str);
140
141 /*
142  * Return a newly-allocated string containing a human-readable equivalent
143  * of 'descriptor'. So "I" would be "int", "[[I" would be "int[][]",
144  * "[Ljava/lang/String;" would be "java.lang.String[]", and so forth.
145  */
146 char* dvmHumanReadableDescriptor(const char* descriptor);
147
148 /*
149  * Return a newly-allocated string for the "dot version" of the class
150  * name for the given type descriptor. That is, The initial "L" and
151  * final ";" (if any) have been removed and all occurrences of '/'
152  * have been changed to '.'.
153  *
154  * "Dot version" names are used in the class loading machinery.
155  * See also dvmHumanReadableDescriptor.
156  */
157 char* dvmDescriptorToDot(const char* str);
158
159 /*
160  * Return a newly-allocated string for the type descriptor
161  * corresponding to the "dot version" of the given class name. That
162  * is, non-array names are surrounded by "L" and ";", and all
163  * occurrences of '.' have been changed to '/'.
164  *
165  * "Dot version" names are used in the class loading machinery.
166  */
167 char* dvmDotToDescriptor(const char* str);
168
169 /*
170  * Return a newly-allocated string for the internal-form class name for
171  * the given type descriptor. That is, the initial "L" and final ";" (if
172  * any) have been removed.
173  */
174 char* dvmDescriptorToName(const char* str);
175
176 /*
177  * Return a newly-allocated string for the type descriptor for the given
178  * internal-form class name. That is, a non-array class name will get
179  * surrounded by "L" and ";", while array names are left as-is.
180  */
181 char* dvmNameToDescriptor(const char* str);
182
183 /*
184  * Get the current time, in nanoseconds.  This is "relative" time, meaning
185  * it could be wall-clock time or a monotonic counter, and is only suitable
186  * for computing time deltas.
187  */
188 u8 dvmGetRelativeTimeNsec(void);
189
190 /*
191  * Get the current time, in microseconds.  This is "relative" time, meaning
192  * it could be wall-clock time or a monotonic counter, and is only suitable
193  * for computing time deltas.
194  */
195 INLINE u8 dvmGetRelativeTimeUsec(void) {
196     return dvmGetRelativeTimeNsec() / 1000;
197 }
198
199 /*
200  * Get the current time, in milliseconds.  This is "relative" time,
201  * meaning it could be wall-clock time or a monotonic counter, and is
202  * only suitable for computing time deltas.  The value returned from
203  * this function is a u4 and should only be used for debugging
204  * messages.  TODO: make this value relative to the start-up time of
205  * the VM.
206  */
207 INLINE u4 dvmGetRelativeTimeMsec(void) {
208     return (u4)(dvmGetRelativeTimeUsec() / 1000);
209 }
210
211 /*
212  * Get the current per-thread CPU time.  This clock increases monotonically
213  * when the thread is running, but not when it's sleeping or blocked on a
214  * synchronization object.
215  *
216  * The absolute value of the clock may not be useful, so this should only
217  * be used for time deltas.
218  *
219  * If the thread CPU clock is not available, this always returns (u8)-1.
220  */
221 u8 dvmGetThreadCpuTimeNsec(void);
222
223 /*
224  * Per-thread CPU time, in micros.
225  */
226 INLINE u8 dvmGetThreadCpuTimeUsec(void) {
227     return dvmGetThreadCpuTimeNsec() / 1000;
228 }
229
230 /*
231  * Like dvmGetThreadCpuTimeNsec, but for a different thread.
232  */
233 u8 dvmGetOtherThreadCpuTimeNsec(pthread_t thread);
234 INLINE u8 dvmGetOtherThreadCpuTimeUsec(pthread_t thread) {
235     return dvmGetOtherThreadCpuTimeNsec(thread) / 1000;
236 }
237
238 /*
239  * Sleep for increasingly longer periods, until "maxTotalSleep" microseconds
240  * have elapsed.  Pass in the start time, which must be a value returned by
241  * dvmGetRelativeTimeUsec().
242  *
243  * Returns "false" if we were unable to sleep because our time is up.
244  */
245 bool dvmIterativeSleep(int iteration, int maxTotalSleep, u8 relStartTime);
246
247 /*
248  * Set the "close on exec" flag on a file descriptor.
249  */
250 bool dvmSetCloseOnExec(int fd);
251
252 /*
253  * Unconditionally abort the entire VM.  Try not to use this.
254  *
255  * NOTE: if this is marked ((noreturn)), gcc will merge multiple dvmAbort()
256  * calls in a single function together.  This is good, in that it reduces
257  * code size slightly, but also bad, because the native stack trace we
258  * get from the abort may point at the wrong call site.  Best to leave
259  * it undecorated.
260  */
261 void dvmAbort(void);
262 void dvmPrintNativeBackTrace(void);
263
264 #if (!HAVE_STRLCPY)
265 /* Implementation of strlcpy() for platforms that don't already have it. */
266 size_t strlcpy(char *dst, const char *src, size_t size);
267 #endif
268
269 /*
270  *  Allocates a memory region using ashmem and mmap, initialized to
271  *  zero.  Actual allocation rounded up to page multiple.  Returns
272  *  NULL on failure.
273  */
274 void *dvmAllocRegion(size_t size, int prot, const char *name);
275
276 /*
277  * Get some per-thread stats from /proc/self/task/N/stat.
278  */
279 typedef struct {
280     unsigned long utime;    /* number of jiffies scheduled in user mode */
281     unsigned long stime;    /* number of jiffies scheduled in kernel mode */
282     int processor;          /* number of CPU that last executed thread */
283 } ProcStatData;
284 bool dvmGetThreadStats(ProcStatData* pData, pid_t tid);
285
286 /*
287  * Returns the pointer to the "absolute path" part of the given path
288  * string, treating first (if any) instance of "/./" as a sentinel
289  * indicating the start of the absolute path. If the path isn't absolute
290  * in the usual way (i.e., starts with "/") and doesn't have the sentinel,
291  * then this returns NULL.
292  *
293  * For example:
294  *     "/foo/bar/baz" returns "/foo/bar/baz"
295  *     "foo/./bar/baz" returns "/bar/baz"
296  *     "foo/bar/baz" returns NULL
297  *
298  * The sentinel is used specifically to aid in cross-optimization, where
299  * a host is processing dex files in a build tree, and where we don't want
300  * the build tree's directory structure to be baked into the output (such
301  * as, for example, in the dependency paths of optimized dex files).
302  */
303 const char* dvmPathToAbsolutePortion(const char* path);
304
305 #ifdef __cplusplus
306 }
307 #endif
308
309 #endif /*_DALVIK_MISC*/