OSDN Git Service

Merge "Undecoded jobject leaking in through attachThread"
[android-x86/dalvik.git] / vm / Misc.c
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  * Miscellaneous utility functions.
18  */
19 #include "Dalvik.h"
20
21 #include <stdlib.h>
22 #include <stddef.h>
23 #include <string.h>
24 #include <strings.h>
25 #include <ctype.h>
26 #include <time.h>
27 #include <sys/time.h>
28 #include <fcntl.h>
29 #include <cutils/ashmem.h>
30 #include <sys/mman.h>
31
32 #define ALIGN_UP_TO_PAGE_SIZE(p) \
33     (((size_t)(p) + (SYSTEM_PAGE_SIZE - 1)) & ~(SYSTEM_PAGE_SIZE - 1))
34
35 /*
36  * Print a hex dump in this format:
37  *
38 01234567: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff  0123456789abcdef\n
39  *
40  * If "mode" is kHexDumpLocal, we start at offset zero, and show a full
41  * 16 bytes on the first line.  If it's kHexDumpMem, we make this look
42  * like a memory dump, using the actual address, outputting a partial line
43  * if "vaddr" isn't aligned on a 16-byte boundary.
44  *
45  * "priority" and "tag" determine the values passed to the log calls.
46  *
47  * Does not use printf() or other string-formatting calls.
48  */
49 void dvmPrintHexDumpEx(int priority, const char* tag, const void* vaddr,
50     size_t length, HexDumpMode mode)
51 {
52     static const char gHexDigit[] = "0123456789abcdef";
53     const unsigned char* addr = vaddr;
54     char out[77];           /* exact fit */
55     unsigned int offset;    /* offset to show while printing */
56     char* hex;
57     char* asc;
58     int gap;
59     //int trickle = 0;
60
61     if (mode == kHexDumpLocal)
62         offset = 0;
63     else
64         offset = (int) addr;
65
66     memset(out, ' ', sizeof(out)-1);
67     out[8] = ':';
68     out[sizeof(out)-2] = '\n';
69     out[sizeof(out)-1] = '\0';
70
71     gap = (int) offset & 0x0f;
72     while (length) {
73         unsigned int lineOffset = offset & ~0x0f;
74         int i, count;
75
76         hex = out;
77         asc = out + 59;
78
79         for (i = 0; i < 8; i++) {
80             *hex++ = gHexDigit[lineOffset >> 28];
81             lineOffset <<= 4;
82         }
83         hex++;
84         hex++;
85
86         count = ((int)length > 16-gap) ? 16-gap : (int)length; /* cap length */
87         assert(count != 0);
88         assert(count+gap <= 16);
89
90         if (gap) {
91             /* only on first line */
92             hex += gap * 3;
93             asc += gap;
94         }
95
96         for (i = gap ; i < count+gap; i++) {
97             *hex++ = gHexDigit[*addr >> 4];
98             *hex++ = gHexDigit[*addr & 0x0f];
99             hex++;
100             if (*addr >= 0x20 && *addr < 0x7f /*isprint(*addr)*/)
101                 *asc++ = *addr;
102             else
103                 *asc++ = '.';
104             addr++;
105         }
106         for ( ; i < 16; i++) {
107             /* erase extra stuff; only happens on last line */
108             *hex++ = ' ';
109             *hex++ = ' ';
110             hex++;
111             *asc++ = ' ';
112         }
113
114         LOG_PRI(priority, tag, "%s", out);
115 #if 0 //def HAVE_ANDROID_OS
116         /*
117          * We can overrun logcat easily by writing at full speed.  On the
118          * other hand, we can make Eclipse time out if we're showing
119          * packet dumps while debugging JDWP.
120          */
121         {
122             if (trickle++ == 8) {
123                 trickle = 0;
124                 usleep(20000);
125             }
126         }
127 #endif
128
129         gap = 0;
130         length -= count;
131         offset += count;
132     }
133 }
134
135
136 /*
137  * Fill out a DebugOutputTarget, suitable for printing to the log.
138  */
139 void dvmCreateLogOutputTarget(DebugOutputTarget* target, int priority,
140     const char* tag)
141 {
142     assert(target != NULL);
143     assert(tag != NULL);
144
145     target->which = kDebugTargetLog;
146     target->data.log.priority = priority;
147     target->data.log.tag = tag;
148 }
149
150 /*
151  * Fill out a DebugOutputTarget suitable for printing to a file pointer.
152  */
153 void dvmCreateFileOutputTarget(DebugOutputTarget* target, FILE* fp)
154 {
155     assert(target != NULL);
156     assert(fp != NULL);
157
158     target->which = kDebugTargetFile;
159     target->data.file.fp = fp;
160 }
161
162 /*
163  * Free "target" and any associated data.
164  */
165 void dvmFreeOutputTarget(DebugOutputTarget* target)
166 {
167     free(target);
168 }
169
170 /*
171  * Print a debug message, to either a file or the log.
172  */
173 void dvmPrintDebugMessage(const DebugOutputTarget* target, const char* format,
174     ...)
175 {
176     va_list args;
177
178     va_start(args, format);
179
180     switch (target->which) {
181     case kDebugTargetLog:
182         LOG_PRI_VA(target->data.log.priority, target->data.log.tag,
183             format, args);
184         break;
185     case kDebugTargetFile:
186         vfprintf(target->data.file.fp, format, args);
187         break;
188     default:
189         LOGE("unexpected 'which' %d\n", target->which);
190         break;
191     }
192
193     va_end(args);
194 }
195
196
197 /*
198  * Allocate a bit vector with enough space to hold at least the specified
199  * number of bits.
200  */
201 BitVector* dvmAllocBitVector(int startBits, bool expandable)
202 {
203     BitVector* bv;
204     int count;
205
206     assert(sizeof(bv->storage[0]) == 4);        /* assuming 32-bit units */
207     assert(startBits >= 0);
208
209     bv = (BitVector*) malloc(sizeof(BitVector));
210
211     count = (startBits + 31) >> 5;
212
213     bv->storageSize = count;
214     bv->expandable = expandable;
215     bv->storage = (u4*) malloc(count * sizeof(u4));
216     memset(bv->storage, 0x00, count * sizeof(u4));
217     return bv;
218 }
219
220 /*
221  * Free a BitVector.
222  */
223 void dvmFreeBitVector(BitVector* pBits)
224 {
225     if (pBits == NULL)
226         return;
227
228     free(pBits->storage);
229     free(pBits);
230 }
231
232 /*
233  * "Allocate" the first-available bit in the bitmap.
234  *
235  * This is not synchronized.  The caller is expected to hold some sort of
236  * lock that prevents multiple threads from executing simultaneously in
237  * dvmAllocBit/dvmFreeBit.
238  */
239 int dvmAllocBit(BitVector* pBits)
240 {
241     int word, bit;
242
243 retry:
244     for (word = 0; word < pBits->storageSize; word++) {
245         if (pBits->storage[word] != 0xffffffff) {
246             /*
247              * There are unallocated bits in this word.  Return the first.
248              */
249             bit = ffs(~(pBits->storage[word])) -1;
250             assert(bit >= 0 && bit < 32);
251             pBits->storage[word] |= 1 << bit;
252             return (word << 5) | bit;
253         }
254     }
255
256     /*
257      * Ran out of space, allocate more if we're allowed to.
258      */
259     if (!pBits->expandable)
260         return -1;
261
262     pBits->storage = realloc(pBits->storage,
263                     (pBits->storageSize + kBitVectorGrowth) * sizeof(u4));
264     memset(&pBits->storage[pBits->storageSize], 0x00,
265         kBitVectorGrowth * sizeof(u4));
266     pBits->storageSize += kBitVectorGrowth;
267     goto retry;
268 }
269
270 /*
271  * Mark the specified bit as "set".
272  *
273  * Returns "false" if the bit is outside the range of the vector and we're
274  * not allowed to expand.
275  */
276 bool dvmSetBit(BitVector* pBits, int num)
277 {
278     assert(num >= 0);
279     if (num >= pBits->storageSize * (int)sizeof(u4) * 8) {
280         if (!pBits->expandable)
281             return false;
282
283         int newSize = (num + 31) >> 5;
284         assert(newSize > pBits->storageSize);
285         pBits->storage = realloc(pBits->storage, newSize * sizeof(u4));
286         memset(&pBits->storage[pBits->storageSize], 0x00,
287             (newSize - pBits->storageSize) * sizeof(u4));
288         pBits->storageSize = newSize;
289     }
290
291     pBits->storage[num >> 5] |= 1 << (num & 0x1f);
292     return true;
293 }
294
295 /*
296  * Mark the specified bit as "clear".
297  */
298 void dvmClearBit(BitVector* pBits, int num)
299 {
300     assert(num >= 0 && num < (int) pBits->storageSize * (int)sizeof(u4) * 8);
301
302     pBits->storage[num >> 5] &= ~(1 << (num & 0x1f));
303 }
304
305 /*
306  * Mark all bits bit as "clear".
307  */
308 void dvmClearAllBits(BitVector* pBits)
309 {
310     int count = pBits->storageSize;
311     memset(pBits->storage, 0, count * sizeof(u4));
312 }
313
314 /*
315  * Determine whether or not the specified bit is set.
316  */
317 bool dvmIsBitSet(const BitVector* pBits, int num)
318 {
319     assert(num >= 0 && num < (int) pBits->storageSize * (int)sizeof(u4) * 8);
320
321     int val = pBits->storage[num >> 5] & (1 << (num & 0x1f));
322     return (val != 0);
323 }
324
325 /*
326  * Count the number of bits that are set.
327  */
328 int dvmCountSetBits(const BitVector* pBits)
329 {
330     int word;
331     int count = 0;
332
333     for (word = 0; word < pBits->storageSize; word++) {
334         u4 val = pBits->storage[word];
335
336         if (val != 0) {
337             if (val == 0xffffffff) {
338                 count += 32;
339             } else {
340                 /* count the number of '1' bits */
341                 while (val != 0) {
342                     val &= val - 1;
343                     count++;
344                 }
345             }
346         }
347     }
348
349     return count;
350 }
351
352 /*
353  * Copy a whole vector to the other. Only do that when the both vectors have
354  * the same size and attribute.
355  */
356 bool dvmCopyBitVector(BitVector *dest, const BitVector *src)
357 {
358     if (dest->storageSize != src->storageSize ||
359         dest->expandable != src->expandable)
360         return false;
361     memcpy(dest->storage, src->storage, sizeof(u4) * dest->storageSize);
362     return true;
363 }
364
365 /*
366  * Intersect two bit vectores and merge the result on top of the pre-existing
367  * value in the dest vector.
368  */
369 bool dvmIntersectBitVectors(BitVector *dest, const BitVector *src1,
370                             const BitVector *src2)
371 {
372     if (dest->storageSize != src1->storageSize ||
373         dest->storageSize != src2->storageSize ||
374         dest->expandable != src1->expandable ||
375         dest->expandable != src2->expandable)
376         return false;
377
378     int i;
379     for (i = 0; i < dest->storageSize; i++) {
380         dest->storage[i] |= src1->storage[i] & src2->storage[i];
381     }
382     return true;
383 }
384
385 /*
386  * Return a newly-allocated string in which all occurrences of '.' have
387  * been changed to '/'.  If we find a '/' in the original string, NULL
388  * is returned to avoid ambiguity.
389  */
390 char* dvmDotToSlash(const char* str)
391 {
392     char* newStr = strdup(str);
393     char* cp = newStr;
394
395     if (newStr == NULL)
396         return NULL;
397
398     while (*cp != '\0') {
399         if (*cp == '/') {
400             assert(false);
401             return NULL;
402         }
403         if (*cp == '.')
404             *cp = '/';
405         cp++;
406     }
407
408     return newStr;
409 }
410
411 /*
412  * Return a newly-allocated string for the "dot version" of the class
413  * name for the given type descriptor. That is, The initial "L" and
414  * final ";" (if any) have been removed and all occurrences of '/'
415  * have been changed to '.'.
416  */
417 char* dvmDescriptorToDot(const char* str)
418 {
419     size_t at = strlen(str);
420     char* newStr;
421
422     if ((at >= 2) && (str[0] == 'L') && (str[at - 1] == ';')) {
423         at -= 2; /* Two fewer chars to copy. */
424         str++; /* Skip the 'L'. */
425     }
426
427     newStr = malloc(at + 1); /* Add one for the '\0'. */
428     if (newStr == NULL)
429         return NULL;
430
431     newStr[at] = '\0';
432
433     while (at > 0) {
434         at--;
435         newStr[at] = (str[at] == '/') ? '.' : str[at];
436     }
437
438     return newStr;
439 }
440
441 /*
442  * Return a newly-allocated string for the type descriptor
443  * corresponding to the "dot version" of the given class name. That
444  * is, non-array names are surrounded by "L" and ";", and all
445  * occurrences of '.' are changed to '/'.
446  */
447 char* dvmDotToDescriptor(const char* str)
448 {
449     size_t length = strlen(str);
450     int wrapElSemi = 0;
451     char* newStr;
452     char* at;
453
454     if (str[0] != '[') {
455         length += 2; /* for "L" and ";" */
456         wrapElSemi = 1;
457     }
458
459     newStr = at = malloc(length + 1); /* + 1 for the '\0' */
460
461     if (newStr == NULL) {
462         return NULL;
463     }
464
465     if (wrapElSemi) {
466         *(at++) = 'L';
467     }
468
469     while (*str) {
470         char c = *(str++);
471         if (c == '.') {
472             c = '/';
473         }
474         *(at++) = c;
475     }
476
477     if (wrapElSemi) {
478         *(at++) = ';';
479     }
480
481     *at = '\0';
482     return newStr;
483 }
484
485 /*
486  * Return a newly-allocated string for the internal-form class name for
487  * the given type descriptor. That is, the initial "L" and final ";" (if
488  * any) have been removed.
489  */
490 char* dvmDescriptorToName(const char* str)
491 {
492     if (str[0] == 'L') {
493         size_t length = strlen(str) - 1;
494         char* newStr = malloc(length);
495
496         if (newStr == NULL) {
497             return NULL;
498         }
499
500         strlcpy(newStr, str + 1, length);
501         return newStr;
502     }
503
504     return strdup(str);
505 }
506
507 /*
508  * Return a newly-allocated string for the type descriptor for the given
509  * internal-form class name. That is, a non-array class name will get
510  * surrounded by "L" and ";", while array names are left as-is.
511  */
512 char* dvmNameToDescriptor(const char* str)
513 {
514     if (str[0] != '[') {
515         size_t length = strlen(str);
516         char* descriptor = malloc(length + 3);
517
518         if (descriptor == NULL) {
519             return NULL;
520         }
521
522         descriptor[0] = 'L';
523         strcpy(descriptor + 1, str);
524         descriptor[length + 1] = ';';
525         descriptor[length + 2] = '\0';
526
527         return descriptor;
528     }
529
530     return strdup(str);
531 }
532
533 /*
534  * Get a notion of the current time, in nanoseconds.  This is meant for
535  * computing durations (e.g. "operation X took 52nsec"), so the result
536  * should not be used to get the current date/time.
537  */
538 u8 dvmGetRelativeTimeNsec(void)
539 {
540 #ifdef HAVE_POSIX_CLOCKS
541     struct timespec now;
542     clock_gettime(CLOCK_MONOTONIC, &now);
543     return (u8)now.tv_sec*1000000000LL + now.tv_nsec;
544 #else
545     struct timeval now;
546     gettimeofday(&now, NULL);
547     return (u8)now.tv_sec*1000000000LL + now.tv_usec * 1000LL;
548 #endif
549 }
550
551 /*
552  * Get the per-thread CPU time, in nanoseconds.
553  *
554  * Only useful for time deltas.
555  */
556 u8 dvmGetThreadCpuTimeNsec(void)
557 {
558 #ifdef HAVE_POSIX_CLOCKS
559     struct timespec now;
560     clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now);
561     return (u8)now.tv_sec*1000000000LL + now.tv_nsec;
562 #else
563     return (u8) -1;
564 #endif
565 }
566
567 /*
568  * Get the per-thread CPU time, in nanoseconds, for the specified thread.
569  */
570 u8 dvmGetOtherThreadCpuTimeNsec(pthread_t thread)
571 {
572 #if 0 /*def HAVE_POSIX_CLOCKS*/
573     int clockId;
574
575     if (pthread_getcpuclockid(thread, &clockId) != 0)
576         return (u8) -1;
577
578     struct timespec now;
579     clock_gettime(clockId, &now);
580     return (u8)now.tv_sec*1000000000LL + now.tv_nsec;
581 #else
582     return (u8) -1;
583 #endif
584 }
585
586
587 /*
588  * Call this repeatedly, with successively higher values for "iteration",
589  * to sleep for a period of time not to exceed "maxTotalSleep".
590  *
591  * For example, when called with iteration==0 we will sleep for a very
592  * brief time.  On the next call we will sleep for a longer time.  When
593  * the sum total of all sleeps reaches "maxTotalSleep", this returns false.
594  *
595  * The initial start time value for "relStartTime" MUST come from the
596  * dvmGetRelativeTimeUsec call.  On the device this must come from the
597  * monotonic clock source, not the wall clock.
598  *
599  * This should be used wherever you might be tempted to call sched_yield()
600  * in a loop.  The problem with sched_yield is that, for a high-priority
601  * thread, the kernel might not actually transfer control elsewhere.
602  *
603  * Returns "false" if we were unable to sleep because our time was up.
604  */
605 bool dvmIterativeSleep(int iteration, int maxTotalSleep, u8 relStartTime)
606 {
607     const int minSleep = 10000;
608     u8 curTime;
609     int curDelay;
610
611     /*
612      * Get current time, and see if we've already exceeded the limit.
613      */
614     curTime = dvmGetRelativeTimeUsec();
615     if (curTime >= relStartTime + maxTotalSleep) {
616         LOGVV("exsl: sleep exceeded (start=%llu max=%d now=%llu)\n",
617             relStartTime, maxTotalSleep, curTime);
618         return false;
619     }
620
621     /*
622      * Compute current delay.  We're bounded by "maxTotalSleep", so no
623      * real risk of overflow assuming "usleep" isn't returning early.
624      * (Besides, 2^30 usec is about 18 minutes by itself.)
625      *
626      * For iteration==0 we just call sched_yield(), so the first sleep
627      * at iteration==1 is actually (minSleep * 2).
628      */
629     curDelay = minSleep;
630     while (iteration-- > 0)
631         curDelay *= 2;
632     assert(curDelay > 0);
633
634     if (curTime + curDelay >= relStartTime + maxTotalSleep) {
635         LOGVV("exsl: reduced delay from %d to %d\n",
636             curDelay, (int) ((relStartTime + maxTotalSleep) - curTime));
637         curDelay = (int) ((relStartTime + maxTotalSleep) - curTime);
638     }
639
640     if (iteration == 0) {
641         LOGVV("exsl: yield\n");
642         sched_yield();
643     } else {
644         LOGVV("exsl: sleep for %d\n", curDelay);
645         usleep(curDelay);
646     }
647     return true;
648 }
649
650
651 /*
652  * Set the "close on exec" flag so we don't expose our file descriptors
653  * to processes launched by us.
654  */
655 bool dvmSetCloseOnExec(int fd)
656 {
657     int flags;
658
659     /*
660      * There's presently only one flag defined, so getting the previous
661      * value of the fd flags is probably unnecessary.
662      */
663     flags = fcntl(fd, F_GETFD);
664     if (flags < 0) {
665         LOGW("Unable to get fd flags for fd %d\n", fd);
666         return false;
667     }
668     if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
669         LOGW("Unable to set close-on-exec for fd %d\n", fd);
670         return false;
671     }
672     return true;
673 }
674
675 #if (!HAVE_STRLCPY)
676 /* Implementation of strlcpy() for platforms that don't already have it. */
677 size_t strlcpy(char *dst, const char *src, size_t size) {
678     size_t srcLength = strlen(src);
679     size_t copyLength = srcLength;
680
681     if (srcLength > (size - 1)) {
682         copyLength = size - 1;
683     }
684
685     if (size != 0) {
686         strncpy(dst, src, copyLength);
687         dst[copyLength] = '\0';
688     }
689
690     return srcLength;
691 }
692 #endif
693
694 /*
695  *  Allocates a memory region using ashmem and mmap, initialized to
696  *  zero.  Actual allocation rounded up to page multiple.  Returns
697  *  NULL on failure.
698  */
699 void *dvmAllocRegion(size_t size, int prot, const char *name) {
700     void *base;
701     int fd, ret;
702
703     size = ALIGN_UP_TO_PAGE_SIZE(size);
704     fd = ashmem_create_region(name, size);
705     if (fd == -1) {
706         return NULL;
707     }
708     base = mmap(NULL, size, prot, MAP_PRIVATE, fd, 0);
709     ret = close(fd);
710     if (base == MAP_FAILED) {
711         return NULL;
712     }
713     if (ret == -1) {
714         return NULL;
715     }
716     return base;
717 }
718
719 /* documented in header file */
720 const char* dvmPathToAbsolutePortion(const char* path) {
721     if (path == NULL) {
722         return NULL;
723     }
724
725     if (path[0] == '/') {
726         /* It's a regular absolute path. Return it. */
727         return path;
728     }
729
730     const char* sentinel = strstr(path, "/./");
731
732     if (sentinel != NULL) {
733         /* It's got the sentinel. Return a pointer to the second slash. */
734         return sentinel + 2;
735     }
736
737     return NULL;
738 }