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