Commit a98b6000 authored by rmcilroy's avatar rmcilroy Committed by Commit bot

[Parser] Cache and clone initial AstValueFactory string_table_.

Avoid reinserting the ast constant string values into the string_table_ of
each AstValueFactory that is created, instead clone an initial copy created
in AstStringConstants.

BUG=686658

Review-Url: https://codereview.chromium.org/2687933003
Cr-Commit-Position: refs/heads/master@{#43112}
parent 10e628eb
......@@ -129,6 +129,36 @@ bool AstRawString::IsOneByteEqualTo(const char* data) const {
return false;
}
bool AstRawString::Compare(void* a, void* b) {
const AstRawString* lhs = static_cast<AstRawString*>(a);
const AstRawString* rhs = static_cast<AstRawString*>(b);
DCHECK_EQ(lhs->hash(), rhs->hash());
if (lhs->length() != rhs->length()) return false;
const unsigned char* l = lhs->raw_data();
const unsigned char* r = rhs->raw_data();
size_t length = rhs->length();
if (lhs->is_one_byte()) {
if (rhs->is_one_byte()) {
return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(l),
reinterpret_cast<const uint8_t*>(r),
length) == 0;
} else {
return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(l),
reinterpret_cast<const uint16_t*>(r),
length) == 0;
}
} else {
if (rhs->is_one_byte()) {
return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(l),
reinterpret_cast<const uint8_t*>(r),
length) == 0;
} else {
return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(l),
reinterpret_cast<const uint16_t*>(r),
length) == 0;
}
}
}
void AstConsString::Internalize(Isolate* isolate) {
// AstRawStrings are internalized before AstConsStrings so left and right are
......@@ -351,7 +381,7 @@ AstRawString* AstValueFactory::GetString(uint32_t hash, bool is_one_byte,
// return this AstRawString.
AstRawString key(is_one_byte, literal_bytes, hash);
base::HashMap::Entry* entry = string_table_.LookupOrInsert(&key, hash);
if (entry->value == NULL) {
if (entry->value == nullptr) {
// Copy literal contents for later comparison.
int length = literal_bytes.length();
byte* new_literal_bytes = zone_->NewArray<byte>(length);
......@@ -366,36 +396,5 @@ AstRawString* AstValueFactory::GetString(uint32_t hash, bool is_one_byte,
return reinterpret_cast<AstRawString*>(entry->key);
}
bool AstValueFactory::AstRawStringCompare(void* a, void* b) {
const AstRawString* lhs = static_cast<AstRawString*>(a);
const AstRawString* rhs = static_cast<AstRawString*>(b);
DCHECK_EQ(lhs->hash(), rhs->hash());
if (lhs->length() != rhs->length()) return false;
const unsigned char* l = lhs->raw_data();
const unsigned char* r = rhs->raw_data();
size_t length = rhs->length();
if (lhs->is_one_byte()) {
if (rhs->is_one_byte()) {
return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(l),
reinterpret_cast<const uint8_t*>(r),
length) == 0;
} else {
return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(l),
reinterpret_cast<const uint16_t*>(r),
length) == 0;
}
} else {
if (rhs->is_one_byte()) {
return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(l),
reinterpret_cast<const uint8_t*>(r),
length) == 0;
} else {
return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(l),
reinterpret_cast<const uint16_t*>(r),
length) == 0;
}
}
}
} // namespace internal
} // namespace v8
......@@ -106,6 +106,8 @@ class AstRawString final : public AstString {
return *c;
}
static bool Compare(void* a, void* b);
// For storing AstRawStrings in a hash map.
uint32_t hash() const {
return hash_;
......@@ -344,7 +346,9 @@ class AstValue : public ZoneObject {
class AstStringConstants final {
public:
AstStringConstants(Isolate* isolate, uint32_t hash_seed)
: zone_(isolate->allocator(), ZONE_NAME), hash_seed_(hash_seed) {
: zone_(isolate->allocator(), ZONE_NAME),
string_table_(AstRawString::Compare),
hash_seed_(hash_seed) {
DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
#define F(name, str) \
{ \
......@@ -357,20 +361,28 @@ class AstStringConstants final {
/* The Handle returned by the factory is located on the roots */ \
/* array, not on the temporary HandleScope, so this is safe. */ \
name##_string_->set_string(isolate->factory()->name##_string()); \
base::HashMap::Entry* entry = \
string_table_.InsertNew(name##_string_, name##_string_->hash()); \
DCHECK(entry->value == nullptr); \
entry->value = reinterpret_cast<void*>(1); \
}
STRING_CONSTANTS(F)
#undef F
}
#define F(name, str) \
AstRawString* name##_string() { return name##_string_; }
const AstRawString* name##_string() const { return name##_string_; }
STRING_CONSTANTS(F)
#undef F
uint32_t hash_seed() const { return hash_seed_; }
const base::CustomMatcherHashMap* string_table() const {
return &string_table_;
}
private:
Zone zone_;
base::CustomMatcherHashMap string_table_;
uint32_t hash_seed_;
#define F(name, str) AstRawString* name##_string_;
......@@ -389,9 +401,9 @@ class AstStringConstants final {
class AstValueFactory {
public:
AstValueFactory(Zone* zone, AstStringConstants* string_constants,
AstValueFactory(Zone* zone, const AstStringConstants* string_constants,
uint32_t hash_seed)
: string_table_(AstRawStringCompare),
: string_table_(string_constants->string_table()),
values_(nullptr),
strings_(nullptr),
strings_end_(&strings_),
......@@ -406,7 +418,6 @@ class AstValueFactory {
std::fill(one_character_strings_,
one_character_strings_ + arraysize(one_character_strings_),
nullptr);
InitializeStringConstants();
}
Zone* zone() const { return zone_; }
......@@ -470,19 +481,6 @@ class AstValueFactory {
AstRawString* GetString(uint32_t hash, bool is_one_byte,
Vector<const byte> literal_bytes);
void InitializeStringConstants() {
#define F(name, str) \
AstRawString* raw_string_##name = string_constants_->name##_string(); \
base::HashMap::Entry* entry_##name = string_table_.LookupOrInsert( \
raw_string_##name, raw_string_##name->hash()); \
DCHECK(entry_##name->value == nullptr); \
entry_##name->value = reinterpret_cast<void*>(1);
STRING_CONSTANTS(F)
#undef F
}
static bool AstRawStringCompare(void* a, void* b);
// All strings are copied here, one after another (no NULLs inbetween).
base::CustomMatcherHashMap string_table_;
// For keeping track of all AstValues and AstRawStrings we've created (so that
......@@ -495,7 +493,7 @@ class AstValueFactory {
AstString** strings_end_;
// Holds constant string values which are shared across the isolate.
AstStringConstants* string_constants_;
const AstStringConstants* string_constants_;
// Caches for faster access: small numbers, one character lowercase strings
// (for minified code).
......
......@@ -40,6 +40,11 @@ class TemplateHashMapImpl {
MatchFun match = MatchFun(),
AllocationPolicy allocator = AllocationPolicy());
// Clones the given hashmap and creates a copy with the same entries.
TemplateHashMapImpl(const TemplateHashMapImpl<Key, Value, MatchFun,
AllocationPolicy>* original,
AllocationPolicy allocator = AllocationPolicy());
~TemplateHashMapImpl();
// If an entry with matching key is found, returns that entry.
......@@ -119,6 +124,8 @@ class TemplateHashMapImpl {
uint32_t hash,
AllocationPolicy allocator = AllocationPolicy());
void Resize(AllocationPolicy allocator);
DISALLOW_COPY_AND_ASSIGN(TemplateHashMapImpl);
};
template <typename Key, typename Value, typename MatchFun,
class AllocationPolicy>
......@@ -129,6 +136,19 @@ TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::
Initialize(initial_capacity, allocator);
}
template <typename Key, typename Value, typename MatchFun,
class AllocationPolicy>
TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::
TemplateHashMapImpl(const TemplateHashMapImpl<Key, Value, MatchFun,
AllocationPolicy>* original,
AllocationPolicy allocator)
: capacity_(original->capacity_),
occupancy_(original->occupancy_),
match_(original->match_) {
map_ = reinterpret_cast<Entry*>(allocator.New(capacity_ * sizeof(Entry)));
memcpy(map_, original->map_, capacity_ * sizeof(Entry));
}
template <typename Key, typename Value, typename MatchFun,
class AllocationPolicy>
TemplateHashMapImpl<Key, Value, MatchFun,
......@@ -382,6 +402,14 @@ class CustomMatcherTemplateHashMapImpl
AllocationPolicy allocator = AllocationPolicy())
: Base(capacity, HashEqualityThenKeyMatcher<void*, MatchFun>(match),
allocator) {}
CustomMatcherTemplateHashMapImpl(
const CustomMatcherTemplateHashMapImpl<AllocationPolicy>* original,
AllocationPolicy allocator = AllocationPolicy())
: Base(original, allocator) {}
private:
DISALLOW_COPY_AND_ASSIGN(CustomMatcherTemplateHashMapImpl);
};
typedef CustomMatcherTemplateHashMapImpl<DefaultAllocationPolicy>
......
......@@ -1167,7 +1167,7 @@ class Isolate {
return cancelable_task_manager_;
}
AstStringConstants* ast_string_constants() const {
const AstStringConstants* ast_string_constants() const {
return ast_string_constants_;
}
......@@ -1417,7 +1417,7 @@ class Isolate {
std::unique_ptr<CodeEventDispatcher> code_event_dispatcher_;
FunctionEntryHook function_entry_hook_;
AstStringConstants* ast_string_constants_;
const AstStringConstants* ast_string_constants_;
interpreter::Interpreter* interpreter_;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment