Home | History | Annotate | Download | only in vm
      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 }
    739