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