/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * Common string pool for the profiler */ #include "Hprof.h" static HashTable *gStringHashTable; int hprofStartup_String() { gStringHashTable = dvmHashTableCreate(512, free); if (gStringHashTable == NULL) { return UNIQUE_ERROR(); } return 0; } int hprofShutdown_String() { dvmHashTableFree(gStringHashTable); return 0; } static u4 computeUtf8Hash(const char *str) { u4 hash = 0; const char *cp; char c; cp = str; while ((c = *cp++) != '\0') { hash = hash * 31 + c; } return hash; } hprof_string_id hprofLookupStringId(const char *str) { void *val; u4 hashValue; dvmHashTableLock(gStringHashTable); hashValue = computeUtf8Hash(str); val = dvmHashTableLookup(gStringHashTable, hashValue, (void *)str, (HashCompareFunc)strcmp, false); if (val == NULL) { const char *newStr; newStr = strdup(str); val = dvmHashTableLookup(gStringHashTable, hashValue, (void *)newStr, (HashCompareFunc)strcmp, true); assert(val != NULL); } dvmHashTableUnlock(gStringHashTable); return (hprof_string_id)val; } int hprofDumpStrings(hprof_context_t *ctx) { HashIter iter; hprof_record_t *rec = &ctx->curRec; int err; dvmHashTableLock(gStringHashTable); for (err = 0, dvmHashIterBegin(gStringHashTable, &iter); err == 0 && !dvmHashIterDone(&iter); dvmHashIterNext(&iter)) { err = hprofStartNewRecord(ctx, HPROF_TAG_STRING, HPROF_TIME); if (err == 0) { const char *str; str = (const char *)dvmHashIterData(&iter); assert(str != NULL); /* STRING format: * * ID: ID for this string * [u1]*: UTF8 characters for string (NOT NULL terminated) * (the record format encodes the length) * * We use the address of the string data as its ID. */ err = hprofAddU4ToRecord(rec, (u4)str); if (err == 0) { err = hprofAddUtf8StringToRecord(rec, str); } } } dvmHashTableUnlock(gStringHashTable); return err; }