2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * Miscellaneous utility functions.
24 #include <sys/types.h>
29 * Used to shut up the compiler when a parameter isn't used.
31 #define UNUSED_PARAMETER(p) (void)(p)
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".
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.
44 INLINE float dvmU4ToFloat(u4 val) {
45 union { u4 in; float out; } conv;
49 INLINE u4 dvmFloatToU4(float val) {
50 union { float in; u4 out; } conv;
56 * Print a hex dump to the log file.
58 * "local" mode prints a hex dump starting from offset 0 (roughly equivalent
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.
64 * If "tag" is NULL the default tag ("dalvikvm") will be used.
66 enum HexDumpMode { kHexDumpLocal, kHexDumpMem };
67 void dvmPrintHexDumpEx(int priority, const char* tag, const void* vaddr,
68 size_t length, HexDumpMode mode);
71 * Print a hex dump, at INFO level.
73 INLINE void dvmPrintHexDump(const void* vaddr, size_t length) {
74 dvmPrintHexDumpEx(ANDROID_LOG_INFO, LOG_TAG,
75 vaddr, length, kHexDumpLocal);
79 * Print a hex dump at VERBOSE level. This does nothing in non-debug builds.
81 INLINE void dvmPrintHexDumpDbg(const void* vaddr, size_t length,const char* tag)
84 dvmPrintHexDumpEx(ANDROID_LOG_VERBOSE, (tag != NULL) ? tag : LOG_TAG,
85 vaddr, length, kHexDumpLocal);
89 enum DebugTargetKind {
90 kDebugTargetUnknown = 0,
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).
99 struct DebugOutputTarget {
101 DebugTargetKind which;
103 /* additional bits */
116 * Fill in a DebugOutputTarget struct.
118 void dvmCreateLogOutputTarget(DebugOutputTarget* target, int priority,
120 void dvmCreateFileOutputTarget(DebugOutputTarget* target, FILE* fp);
123 * Print a debug message.
125 void dvmPrintDebugMessage(const DebugOutputTarget* target, const char* format,
127 #if defined(__GNUC__)
128 __attribute__ ((format(printf, 2, 3)))
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.
137 char* dvmDotToSlash(const char* str);
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.
144 extern "C" char* dvmHumanReadableDescriptor(const char* descriptor);
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 '.'.
152 * "Dot version" names are used in the class loading machinery.
153 * See also dvmHumanReadableDescriptor.
155 char* dvmDescriptorToDot(const char* str);
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 '/'.
163 * "Dot version" names are used in the class loading machinery.
165 char* dvmDotToDescriptor(const char* str);
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.
172 char* dvmDescriptorToName(const char* str);
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.
179 char* dvmNameToDescriptor(const char* str);
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.
186 u8 dvmGetRelativeTimeNsec(void);
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.
193 INLINE u8 dvmGetRelativeTimeUsec(void) {
194 return dvmGetRelativeTimeNsec() / 1000;
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
205 INLINE u4 dvmGetRelativeTimeMsec(void) {
206 return (u4)(dvmGetRelativeTimeUsec() / 1000);
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.
214 * The absolute value of the clock may not be useful, so this should only
215 * be used for time deltas.
217 * If the thread CPU clock is not available, this always returns (u8)-1.
219 u8 dvmGetThreadCpuTimeNsec(void);
222 * Per-thread CPU time, in micros.
224 INLINE u8 dvmGetThreadCpuTimeUsec(void) {
225 return dvmGetThreadCpuTimeNsec() / 1000;
229 * Like dvmGetThreadCpuTimeNsec, but for a different thread.
231 u8 dvmGetOtherThreadCpuTimeNsec(pthread_t thread);
232 INLINE u8 dvmGetOtherThreadCpuTimeUsec(pthread_t thread) {
233 return dvmGetOtherThreadCpuTimeNsec(thread) / 1000;
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().
241 * Returns "false" if we were unable to sleep because our time is up.
243 bool dvmIterativeSleep(int iteration, int maxTotalSleep, u8 relStartTime);
246 * Set the "close on exec" flag on a file descriptor.
248 bool dvmSetCloseOnExec(int fd);
251 * Unconditionally abort the entire VM. Try not to use this.
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
259 extern "C" void dvmAbort(void);
260 void dvmPrintNativeBackTrace(void);
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);
268 * Allocates a memory region using ashmem and mmap, initialized to
269 * zero. Actual allocation rounded up to page multiple. Returns
272 void *dvmAllocRegion(size_t size, int prot, const char *name);
275 * Get some per-thread stats from /proc/self/task/N/stat.
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 */
282 bool dvmGetThreadStats(ProcStatData* pData, pid_t tid);
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.
292 * "/foo/bar/baz" returns "/foo/bar/baz"
293 * "foo/./bar/baz" returns "/bar/baz"
294 * "foo/bar/baz" returns NULL
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).
301 const char* dvmPathToAbsolutePortion(const char* path);
303 #endif /*_DALVIK_MISC*/