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