blob: 634b6ee24b989e51cd67cf90619989363edc4062 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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 "src/base/smart-pointers.h"
8#include "src/objects-inl.h"
9
10namespace v8 {
11namespace internal {
12
13
14bool StringsStorage::StringsMatch(void* key1, void* key2) {
15 return strcmp(reinterpret_cast<char*>(key1), reinterpret_cast<char*>(key2)) ==
16 0;
17}
18
19
20StringsStorage::StringsStorage(Heap* heap)
21 : hash_seed_(heap->HashSeed()), names_(StringsMatch) {}
22
23
24StringsStorage::~StringsStorage() {
Ben Murdoch61f157c2016-09-16 13:49:30 +010025 for (base::HashMap::Entry* p = names_.Start(); p != NULL;
26 p = names_.Next(p)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000027 DeleteArray(reinterpret_cast<const char*>(p->value));
28 }
29}
30
31
32const char* StringsStorage::GetCopy(const char* src) {
33 int len = static_cast<int>(strlen(src));
Ben Murdoch61f157c2016-09-16 13:49:30 +010034 base::HashMap::Entry* entry = GetEntry(src, len);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000035 if (entry->value == NULL) {
36 Vector<char> dst = Vector<char>::New(len + 1);
37 StrNCpy(dst, src, len);
38 dst[len] = '\0';
39 entry->key = dst.start();
40 entry->value = entry->key;
41 }
42 return reinterpret_cast<const char*>(entry->value);
43}
44
45
46const char* StringsStorage::GetFormatted(const char* format, ...) {
47 va_list args;
48 va_start(args, format);
49 const char* result = GetVFormatted(format, args);
50 va_end(args);
51 return result;
52}
53
54
55const char* StringsStorage::AddOrDisposeString(char* str, int len) {
Ben Murdoch61f157c2016-09-16 13:49:30 +010056 base::HashMap::Entry* entry = GetEntry(str, len);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000057 if (entry->value == NULL) {
58 // New entry added.
59 entry->key = str;
60 entry->value = str;
61 } else {
62 DeleteArray(str);
63 }
64 return reinterpret_cast<const char*>(entry->value);
65}
66
67
68const char* StringsStorage::GetVFormatted(const char* format, va_list args) {
69 Vector<char> str = Vector<char>::New(1024);
70 int len = VSNPrintF(str, format, args);
71 if (len == -1) {
72 DeleteArray(str.start());
73 return GetCopy(format);
74 }
75 return AddOrDisposeString(str.start(), len);
76}
77
78
79const char* StringsStorage::GetName(Name* name) {
80 if (name->IsString()) {
81 String* str = String::cast(name);
82 int length = Min(kMaxNameSize, str->length());
83 int actual_length = 0;
84 base::SmartArrayPointer<char> data = str->ToCString(
85 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL, 0, length, &actual_length);
86 return AddOrDisposeString(data.Detach(), actual_length);
87 } else if (name->IsSymbol()) {
88 return "<symbol>";
89 }
90 return "";
91}
92
93
94const char* StringsStorage::GetName(int index) {
95 return GetFormatted("%d", index);
96}
97
98
99const char* StringsStorage::GetFunctionName(Name* name) {
100 return GetName(name);
101}
102
103
104const char* StringsStorage::GetFunctionName(const char* name) {
105 return GetCopy(name);
106}
107
108
109size_t StringsStorage::GetUsedMemorySize() const {
110 size_t size = sizeof(*this);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100111 size += sizeof(base::HashMap::Entry) * names_.capacity();
112 for (base::HashMap::Entry* p = names_.Start(); p != NULL;
113 p = names_.Next(p)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000114 size += strlen(reinterpret_cast<const char*>(p->value)) + 1;
115 }
116 return size;
117}
118
Ben Murdoch61f157c2016-09-16 13:49:30 +0100119base::HashMap::Entry* StringsStorage::GetEntry(const char* str, int len) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000120 uint32_t hash = StringHasher::HashSequentialString(str, len, hash_seed_);
121 return names_.LookupOrInsert(const_cast<char*>(str), hash);
122}
123} // namespace internal
124} // namespace v8