OSDN Git Service

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