1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Common string pool for the profiler
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Hprof.h"
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic HashTable *gStringHashTable;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjecthprofStartup_String()
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    gStringHashTable = dvmHashTableCreate(512, free);
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (gStringHashTable == NULL) {
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return UNIQUE_ERROR();
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return 0;
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjecthprofShutdown_String()
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableFree(gStringHashTable);
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return 0;
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic u4
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectcomputeUtf8Hash(const char *str)
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 hash = 0;
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char *cp;
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char c;
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cp = str;
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while ((c = *cp++) != '\0') {
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hash = hash * 31 + c;
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return hash;
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecthprof_string_id
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjecthprofLookupStringId(const char *str)
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void *val;
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 hashValue;
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableLock(gStringHashTable);
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    hashValue = computeUtf8Hash(str);
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    val = dvmHashTableLookup(gStringHashTable, hashValue, (void *)str,
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (HashCompareFunc)strcmp, false);
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (val == NULL) {
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        const char *newStr;
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newStr = strdup(str);
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        val = dvmHashTableLookup(gStringHashTable, hashValue, (void *)newStr,
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                (HashCompareFunc)strcmp, true);
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(val != NULL);
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableUnlock(gStringHashTable);
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (hprof_string_id)val;
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjecthprofDumpStrings(hprof_context_t *ctx)
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HashIter iter;
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    hprof_record_t *rec = &ctx->curRec;
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int err;
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableLock(gStringHashTable);
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (err = 0, dvmHashIterBegin(gStringHashTable, &iter);
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         err == 0 && !dvmHashIterDone(&iter);
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         dvmHashIterNext(&iter))
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        err = hprofStartNewRecord(ctx, HPROF_TAG_STRING, HPROF_TIME);
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (err == 0) {
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            const char *str;
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            str = (const char *)dvmHashIterData(&iter);
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(str != NULL);
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* STRING format:
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             *
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * ID:     ID for this string
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * [u1]*:  UTF8 characters for string (NOT NULL terminated)
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             *         (the record format encodes the length)
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             *
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * We use the address of the string data as its ID.
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            err = hprofAddU4ToRecord(rec, (u4)str);
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (err == 0) {
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                err = hprofAddUtf8StringToRecord(rec, str);
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableUnlock(gStringHashTable);
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return err;
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
119