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 * Common string pool for the profiler 18 */ 19 #include "Hprof.h" 20 21 static HashTable *gStringHashTable; 22 23 int hprofStartup_String() 24 { 25 gStringHashTable = dvmHashTableCreate(512, free); 26 if (gStringHashTable == NULL) { 27 return UNIQUE_ERROR(); 28 } 29 return 0; 30 } 31 32 int hprofShutdown_String() 33 { 34 dvmHashTableFree(gStringHashTable); 35 return 0; 36 } 37 38 static u4 computeUtf8Hash(const char *str) 39 { 40 u4 hash = 0; 41 const char *cp; 42 char c; 43 44 cp = str; 45 while ((c = *cp++) != '\0') { 46 hash = hash * 31 + c; 47 } 48 49 return hash; 50 } 51 52 hprof_string_id hprofLookupStringId(const char *str) 53 { 54 void *val; 55 u4 hashValue; 56 57 dvmHashTableLock(gStringHashTable); 58 59 hashValue = computeUtf8Hash(str); 60 val = dvmHashTableLookup(gStringHashTable, hashValue, (void *)str, 61 (HashCompareFunc)strcmp, false); 62 if (val == NULL) { 63 const char *newStr; 64 65 newStr = strdup(str); 66 val = dvmHashTableLookup(gStringHashTable, hashValue, (void *)newStr, 67 (HashCompareFunc)strcmp, true); 68 assert(val != NULL); 69 } 70 71 dvmHashTableUnlock(gStringHashTable); 72 73 return (hprof_string_id)val; 74 } 75 76 int hprofDumpStrings(hprof_context_t *ctx) 77 { 78 HashIter iter; 79 hprof_record_t *rec = &ctx->curRec; 80 int err; 81 82 dvmHashTableLock(gStringHashTable); 83 84 for (err = 0, dvmHashIterBegin(gStringHashTable, &iter); 85 err == 0 && !dvmHashIterDone(&iter); 86 dvmHashIterNext(&iter)) 87 { 88 err = hprofStartNewRecord(ctx, HPROF_TAG_STRING, HPROF_TIME); 89 if (err == 0) { 90 const char *str; 91 92 str = (const char *)dvmHashIterData(&iter); 93 assert(str != NULL); 94 95 /* STRING format: 96 * 97 * ID: ID for this string 98 * [u1]*: UTF8 characters for string (NOT NULL terminated) 99 * (the record format encodes the length) 100 * 101 * We use the address of the string data as its ID. 102 */ 103 err = hprofAddU4ToRecord(rec, (u4)str); 104 if (err == 0) { 105 err = hprofAddUtf8StringToRecord(rec, str); 106 } 107 } 108 } 109 110 dvmHashTableUnlock(gStringHashTable); 111 112 return err; 113 } 114