Commit 50ccf21d authored by Camillo Bruni's avatar Camillo Bruni Committed by V8 LUCI CQ

[templates] Clean up TemplateObjectDescription::GetTemplateObject

- Avoid lookup if there is no template_weakmap yet
- More explicit DisallowGarbageCollection scopes
- Avoid handles when settings properties
- Speed up Object::GetSimpleHash by loading only instance_type once

Change-Id: Ib588607340a0c56dc1ba26c3e89485560222a688
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3463717Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79189}
parent 9f902b74
...@@ -770,36 +770,44 @@ template EXPORT_TEMPLATE_DEFINE( ...@@ -770,36 +770,44 @@ template EXPORT_TEMPLATE_DEFINE(
template <typename IsolateT> template <typename IsolateT>
Handle<TemplateObjectDescription> GetTemplateObject::GetOrBuildDescription( Handle<TemplateObjectDescription> GetTemplateObject::GetOrBuildDescription(
IsolateT* isolate) { IsolateT* isolate) {
Handle<FixedArray> raw_strings = isolate->factory()->NewFixedArray( Handle<FixedArray> raw_strings_handle = isolate->factory()->NewFixedArray(
this->raw_strings()->length(), AllocationType::kOld); this->raw_strings()->length(), AllocationType::kOld);
bool raw_and_cooked_match = true; bool raw_and_cooked_match = true;
for (int i = 0; i < raw_strings->length(); ++i) { {
if (this->raw_strings()->at(i) != this->cooked_strings()->at(i)) { DisallowGarbageCollection no_gc;
// If the AstRawStrings don't match, then neither should the allocated FixedArray raw_strings = *raw_strings_handle;
// Strings, since the AstValueFactory should have deduplicated them
// already. for (int i = 0; i < raw_strings.length(); ++i) {
DCHECK_IMPLIES(this->cooked_strings()->at(i) != nullptr, if (this->raw_strings()->at(i) != this->cooked_strings()->at(i)) {
*this->cooked_strings()->at(i)->string() != // If the AstRawStrings don't match, then neither should the allocated
*this->raw_strings()->at(i)->string()); // Strings, since the AstValueFactory should have deduplicated them
// already.
raw_and_cooked_match = false; DCHECK_IMPLIES(this->cooked_strings()->at(i) != nullptr,
*this->cooked_strings()->at(i)->string() !=
*this->raw_strings()->at(i)->string());
raw_and_cooked_match = false;
}
raw_strings.set(i, *this->raw_strings()->at(i)->string());
} }
raw_strings->set(i, *this->raw_strings()->at(i)->string());
} }
Handle<FixedArray> cooked_strings = raw_strings; Handle<FixedArray> cooked_strings_handle = raw_strings_handle;
if (!raw_and_cooked_match) { if (!raw_and_cooked_match) {
cooked_strings = isolate->factory()->NewFixedArray( cooked_strings_handle = isolate->factory()->NewFixedArray(
this->cooked_strings()->length(), AllocationType::kOld); this->cooked_strings()->length(), AllocationType::kOld);
for (int i = 0; i < cooked_strings->length(); ++i) { DisallowGarbageCollection no_gc;
FixedArray cooked_strings = *cooked_strings_handle;
ReadOnlyRoots roots(isolate);
for (int i = 0; i < cooked_strings.length(); ++i) {
if (this->cooked_strings()->at(i) != nullptr) { if (this->cooked_strings()->at(i) != nullptr) {
cooked_strings->set(i, *this->cooked_strings()->at(i)->string()); cooked_strings.set(i, *this->cooked_strings()->at(i)->string());
} else { } else {
cooked_strings->set(i, ReadOnlyRoots(isolate).undefined_value()); cooked_strings.set_undefined(roots, i);
} }
} }
} }
return isolate->factory()->NewTemplateObjectDescription(raw_strings, return isolate->factory()->NewTemplateObjectDescription(
cooked_strings); raw_strings_handle, cooked_strings_handle);
} }
template EXPORT_TEMPLATE_DEFINE(V8_BASE_EXPORT) template EXPORT_TEMPLATE_DEFINE(V8_BASE_EXPORT)
Handle<TemplateObjectDescription> GetTemplateObject::GetOrBuildDescription( Handle<TemplateObjectDescription> GetTemplateObject::GetOrBuildDescription(
......
...@@ -141,10 +141,13 @@ class FixedArray ...@@ -141,10 +141,13 @@ class FixedArray
// Setters for frequently used oddballs located in old space. // Setters for frequently used oddballs located in old space.
inline void set_undefined(int index); inline void set_undefined(int index);
inline void set_undefined(Isolate* isolate, int index); inline void set_undefined(Isolate* isolate, int index);
inline void set_undefined(ReadOnlyRoots ro_roots, int index);
inline void set_null(int index); inline void set_null(int index);
inline void set_null(Isolate* isolate, int index); inline void set_null(Isolate* isolate, int index);
inline void set_null(ReadOnlyRoots ro_roots, int index);
inline void set_the_hole(int index); inline void set_the_hole(int index);
inline void set_the_hole(Isolate* isolate, int index); inline void set_the_hole(Isolate* isolate, int index);
inline void set_the_hole(ReadOnlyRoots ro_roots, int index);
inline ObjectSlot GetFirstElementAddress(); inline ObjectSlot GetFirstElementAddress();
inline bool ContainsOnlySmisOrHoles(); inline bool ContainsOnlySmisOrHoles();
...@@ -215,10 +218,6 @@ class FixedArray ...@@ -215,10 +218,6 @@ class FixedArray
private: private:
STATIC_ASSERT(kHeaderSize == Internals::kFixedArrayHeaderSize); STATIC_ASSERT(kHeaderSize == Internals::kFixedArrayHeaderSize);
inline void set_undefined(ReadOnlyRoots ro_roots, int index);
inline void set_null(ReadOnlyRoots ro_roots, int index);
inline void set_the_hole(ReadOnlyRoots ro_roots, int index);
TQ_OBJECT_CONSTRUCTORS(FixedArray) TQ_OBJECT_CONSTRUCTORS(FixedArray)
}; };
......
...@@ -1120,7 +1120,8 @@ Object Object::GetSimpleHash(Object object) { ...@@ -1120,7 +1120,8 @@ Object Object::GetSimpleHash(Object object) {
uint32_t hash = ComputeUnseededHash(Smi::ToInt(object)); uint32_t hash = ComputeUnseededHash(Smi::ToInt(object));
return Smi::FromInt(hash & Smi::kMaxValue); return Smi::FromInt(hash & Smi::kMaxValue);
} }
if (object.IsHeapNumber()) { auto instance_type = HeapObject::cast(object).map().instance_type();
if (InstanceTypeChecker::IsHeapNumber(instance_type)) {
double num = HeapNumber::cast(object).value(); double num = HeapNumber::cast(object).value();
if (std::isnan(num)) return Smi::FromInt(Smi::kMaxValue); if (std::isnan(num)) return Smi::FromInt(Smi::kMaxValue);
// Use ComputeUnseededHash for all values in Signed32 range, including -0, // Use ComputeUnseededHash for all values in Signed32 range, including -0,
...@@ -1133,20 +1134,16 @@ Object Object::GetSimpleHash(Object object) { ...@@ -1133,20 +1134,16 @@ Object Object::GetSimpleHash(Object object) {
hash = ComputeLongHash(base::double_to_uint64(num)); hash = ComputeLongHash(base::double_to_uint64(num));
} }
return Smi::FromInt(hash & Smi::kMaxValue); return Smi::FromInt(hash & Smi::kMaxValue);
} } else if (InstanceTypeChecker::IsName(instance_type)) {
if (object.IsName()) {
uint32_t hash = Name::cast(object).EnsureHash(); uint32_t hash = Name::cast(object).EnsureHash();
return Smi::FromInt(hash); return Smi::FromInt(hash);
} } else if (InstanceTypeChecker::IsOddball(instance_type)) {
if (object.IsOddball()) {
uint32_t hash = Oddball::cast(object).to_string().EnsureHash(); uint32_t hash = Oddball::cast(object).to_string().EnsureHash();
return Smi::FromInt(hash); return Smi::FromInt(hash);
} } else if (InstanceTypeChecker::IsBigInt(instance_type)) {
if (object.IsBigInt()) {
uint32_t hash = BigInt::cast(object).Hash(); uint32_t hash = BigInt::cast(object).Hash();
return Smi::FromInt(hash & Smi::kMaxValue); return Smi::FromInt(hash & Smi::kMaxValue);
} } else if (InstanceTypeChecker::IsSharedFunctionInfo(instance_type)) {
if (object.IsSharedFunctionInfo()) {
uint32_t hash = SharedFunctionInfo::cast(object).Hash(); uint32_t hash = SharedFunctionInfo::cast(object).Hash();
return Smi::FromInt(hash & Smi::kMaxValue); return Smi::FromInt(hash & Smi::kMaxValue);
} }
......
...@@ -19,22 +19,27 @@ Handle<JSArray> TemplateObjectDescription::GetTemplateObject( ...@@ -19,22 +19,27 @@ Handle<JSArray> TemplateObjectDescription::GetTemplateObject(
Isolate* isolate, Handle<NativeContext> native_context, Isolate* isolate, Handle<NativeContext> native_context,
Handle<TemplateObjectDescription> description, Handle<TemplateObjectDescription> description,
Handle<SharedFunctionInfo> shared_info, int slot_id) { Handle<SharedFunctionInfo> shared_info, int slot_id) {
// Check the template weakmap to see if the template object already exists.
Handle<EphemeronHashTable> template_weakmap =
native_context->template_weakmap().IsUndefined(isolate)
? EphemeronHashTable::New(isolate, 0)
: handle(EphemeronHashTable::cast(native_context->template_weakmap()),
isolate);
uint32_t hash = shared_info->Hash(); uint32_t hash = shared_info->Hash();
Object maybe_cached_template = template_weakmap->Lookup(shared_info, hash);
while (!maybe_cached_template.IsTheHole()) {
CachedTemplateObject cached_template =
CachedTemplateObject::cast(maybe_cached_template);
if (cached_template.slot_id() == slot_id)
return handle(cached_template.template_object(), isolate);
maybe_cached_template = cached_template.next(); // Check the template weakmap to see if the template object already exists.
Handle<EphemeronHashTable> template_weakmap;
if (native_context->template_weakmap().IsUndefined(isolate)) {
template_weakmap = EphemeronHashTable::New(isolate, 1);
} else {
DisallowGarbageCollection no_gc;
ReadOnlyRoots roots(isolate);
template_weakmap = handle(
EphemeronHashTable::cast(native_context->template_weakmap()), isolate);
Object maybe_cached_template = template_weakmap->Lookup(shared_info, hash);
while (!maybe_cached_template.IsTheHole(roots)) {
CachedTemplateObject cached_template =
CachedTemplateObject::cast(maybe_cached_template);
if (cached_template.slot_id() == slot_id) {
return handle(cached_template.template_object(), isolate);
}
maybe_cached_template = cached_template.next();
}
} }
// Create the raw object from the {raw_strings}. // Create the raw object from the {raw_strings}.
...@@ -83,13 +88,17 @@ Handle<CachedTemplateObject> CachedTemplateObject::New( ...@@ -83,13 +88,17 @@ Handle<CachedTemplateObject> CachedTemplateObject::New(
Isolate* isolate, int slot_id, Handle<JSArray> template_object, Isolate* isolate, int slot_id, Handle<JSArray> template_object,
Handle<HeapObject> next) { Handle<HeapObject> next) {
DCHECK(next->IsCachedTemplateObject() || next->IsTheHole()); DCHECK(next->IsCachedTemplateObject() || next->IsTheHole());
Factory* factory = isolate->factory(); Handle<CachedTemplateObject> result_handle =
Handle<CachedTemplateObject> result = Handle<CachedTemplateObject>::cast( Handle<CachedTemplateObject>::cast(isolate->factory()->NewStruct(
factory->NewStruct(CACHED_TEMPLATE_OBJECT_TYPE, AllocationType::kOld)); CACHED_TEMPLATE_OBJECT_TYPE, AllocationType::kOld));
result->set_slot_id(slot_id); {
result->set_template_object(*template_object); DisallowGarbageCollection no_gc;
result->set_next(*next); auto result = *result_handle;
return result; result.set_slot_id(slot_id);
result.set_template_object(*template_object);
result.set_next(*next);
}
return result_handle;
} }
} // namespace internal } // namespace internal
......
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