Line data Source code
1 : // Copyright 2015 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/profiler/strings-storage.h"
6 :
7 : #include <memory>
8 :
9 : #include "src/allocation.h"
10 : #include "src/objects-inl.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 4599164 : bool StringsStorage::StringsMatch(void* key1, void* key2) {
16 4599164 : return strcmp(reinterpret_cast<char*>(key1), reinterpret_cast<char*>(key2)) ==
17 4599164 : 0;
18 : }
19 :
20 129618 : StringsStorage::StringsStorage() : names_(StringsMatch) {}
21 :
22 64788 : StringsStorage::~StringsStorage() {
23 3062478 : for (base::HashMap::Entry* p = names_.Start(); p != nullptr;
24 : p = names_.Next(p)) {
25 2932902 : DeleteArray(reinterpret_cast<const char*>(p->value));
26 : }
27 64788 : }
28 :
29 25993 : const char* StringsStorage::GetCopy(const char* src) {
30 25993 : int len = static_cast<int>(strlen(src));
31 25993 : base::HashMap::Entry* entry = GetEntry(src, len);
32 25993 : if (entry->value == nullptr) {
33 51972 : Vector<char> dst = Vector<char>::New(len + 1);
34 25986 : StrNCpy(dst, src, len);
35 25986 : dst[len] = '\0';
36 25986 : entry->key = dst.start();
37 25986 : entry->value = entry->key;
38 : }
39 25993 : return reinterpret_cast<const char*>(entry->value);
40 : }
41 :
42 3886080 : const char* StringsStorage::GetFormatted(const char* format, ...) {
43 : va_list args;
44 3886080 : va_start(args, format);
45 3886080 : const char* result = GetVFormatted(format, args);
46 3886080 : va_end(args);
47 3886080 : return result;
48 : }
49 :
50 7497591 : const char* StringsStorage::AddOrDisposeString(char* str, int len) {
51 7497591 : base::HashMap::Entry* entry = GetEntry(str, len);
52 7497591 : if (entry->value == nullptr) {
53 : // New entry added.
54 2906916 : entry->key = str;
55 2906916 : entry->value = str;
56 : } else {
57 : DeleteArray(str);
58 : }
59 7497591 : return reinterpret_cast<const char*>(entry->value);
60 : }
61 :
62 3886080 : const char* StringsStorage::GetVFormatted(const char* format, va_list args) {
63 3886080 : Vector<char> str = Vector<char>::New(1024);
64 3886080 : int len = VSNPrintF(str, format, args);
65 3886080 : if (len == -1) {
66 : DeleteArray(str.start());
67 0 : return GetCopy(format);
68 : }
69 3886080 : return AddOrDisposeString(str.start(), len);
70 : }
71 :
72 3623744 : const char* StringsStorage::GetName(Name name) {
73 3623744 : if (name->IsString()) {
74 3595339 : String str = String::cast(name);
75 3595339 : int length = Min(FLAG_heap_snapshot_string_limit, str->length());
76 3595339 : int actual_length = 0;
77 : std::unique_ptr<char[]> data = str->ToCString(
78 3595339 : DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL, 0, length, &actual_length);
79 7190678 : return AddOrDisposeString(data.release(), actual_length);
80 28405 : } else if (name->IsSymbol()) {
81 : return "<symbol>";
82 : }
83 0 : return "";
84 : }
85 :
86 2070796 : const char* StringsStorage::GetName(int index) {
87 2070796 : return GetFormatted("%d", index);
88 : }
89 :
90 17668 : const char* StringsStorage::GetConsName(const char* prefix, Name name) {
91 17668 : if (name->IsString()) {
92 16172 : String str = String::cast(name);
93 16172 : int length = Min(FLAG_heap_snapshot_string_limit, str->length());
94 16172 : int actual_length = 0;
95 : std::unique_ptr<char[]> data = str->ToCString(
96 16172 : DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL, 0, length, &actual_length);
97 :
98 16172 : int cons_length = actual_length + static_cast<int>(strlen(prefix)) + 1;
99 16172 : char* cons_result = NewArray<char>(cons_length);
100 : snprintf(cons_result, cons_length, "%s%s", prefix, data.get());
101 :
102 16172 : return AddOrDisposeString(cons_result, cons_length);
103 1496 : } else if (name->IsSymbol()) {
104 : return "<symbol>";
105 : }
106 0 : return "";
107 : }
108 :
109 7523584 : base::HashMap::Entry* StringsStorage::GetEntry(const char* str, int len) {
110 7523584 : uint32_t hash = StringHasher::HashSequentialString(str, len, kZeroHashSeed);
111 15047168 : return names_.LookupOrInsert(const_cast<char*>(str), hash);
112 : }
113 :
114 : } // namespace internal
115 183867 : } // namespace v8
|