Commit b413ab64 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[ptr-compr] Improving literals creation

.. by using isolate-full accessors.

Bug: v8:9353
Change-Id: I3b31c21df687e06f322d03daec4b9b532ac022d9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1683996Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62487}
parent 433403dc
...@@ -32,7 +32,11 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) Dictionary ...@@ -32,7 +32,11 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) Dictionary
using Key = typename Shape::Key; using Key = typename Shape::Key;
// Returns the value at entry. // Returns the value at entry.
Object ValueAt(int entry) { Object ValueAt(int entry) {
return this->get(DerivedHashTable::EntryToIndex(entry) + 1); Isolate* isolate = GetIsolateForPtrCompr(*this);
return ValueAt(isolate, entry);
}
Object ValueAt(Isolate* isolate, int entry) {
return this->get(isolate, DerivedHashTable::EntryToIndex(entry) + 1);
} }
// Set the value for entry. // Set the value for entry.
......
...@@ -71,14 +71,19 @@ void EphemeronHashTable::set_key(int index, Object value, ...@@ -71,14 +71,19 @@ void EphemeronHashTable::set_key(int index, Object value,
} }
int HashTableBase::NumberOfElements() const { int HashTableBase::NumberOfElements() const {
return Smi::ToInt(get(kNumberOfElementsIndex)); int offset = OffsetOfElementAt(kNumberOfElementsIndex);
return TaggedField<Smi>::load(*this, offset).value();
} }
int HashTableBase::NumberOfDeletedElements() const { int HashTableBase::NumberOfDeletedElements() const {
return Smi::ToInt(get(kNumberOfDeletedElementsIndex)); int offset = OffsetOfElementAt(kNumberOfDeletedElementsIndex);
return TaggedField<Smi>::load(*this, offset).value();
} }
int HashTableBase::Capacity() const { return Smi::ToInt(get(kCapacityIndex)); } int HashTableBase::Capacity() const {
int offset = OffsetOfElementAt(kCapacityIndex);
return TaggedField<Smi>::load(*this, offset).value();
}
void HashTableBase::ElementAdded() { void HashTableBase::ElementAdded() {
SetNumberOfElements(NumberOfElements() + 1); SetNumberOfElements(NumberOfElements() + 1);
...@@ -164,6 +169,15 @@ bool HashTable<Derived, Shape>::ToKey(ReadOnlyRoots roots, int entry, ...@@ -164,6 +169,15 @@ bool HashTable<Derived, Shape>::ToKey(ReadOnlyRoots roots, int entry,
return true; return true;
} }
template <typename Derived, typename Shape>
bool HashTable<Derived, Shape>::ToKey(Isolate* isolate, int entry,
Object* out_k) {
Object k = KeyAt(isolate, entry);
if (!IsKey(GetReadOnlyRoots(isolate), k)) return false;
*out_k = Shape::Unwrap(k);
return true;
}
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
void HashTable<Derived, Shape>::set_key(int index, Object value) { void HashTable<Derived, Shape>::set_key(int index, Object value) {
DCHECK(!IsEphemeronHashTable()); DCHECK(!IsEphemeronHashTable());
......
...@@ -160,9 +160,16 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable ...@@ -160,9 +160,16 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable
static bool IsKey(ReadOnlyRoots roots, Object k); static bool IsKey(ReadOnlyRoots roots, Object k);
inline bool ToKey(ReadOnlyRoots roots, int entry, Object* out_k); inline bool ToKey(ReadOnlyRoots roots, int entry, Object* out_k);
inline bool ToKey(Isolate* isolate, int entry, Object* out_k);
// Returns the key at entry. // Returns the key at entry.
Object KeyAt(int entry) { return get(EntryToIndex(entry) + kEntryKeyIndex); } Object KeyAt(int entry) {
Isolate* isolate = GetIsolateForPtrCompr(*this);
return KeyAt(isolate, entry);
}
Object KeyAt(Isolate* isolate, int entry) {
return get(isolate, EntryToIndex(entry) + kEntryKeyIndex);
}
static const int kElementsStartIndex = kPrefixStartIndex + Shape::kPrefixSize; static const int kElementsStartIndex = kPrefixStartIndex + Shape::kPrefixSize;
static const int kEntrySize = Shape::kEntrySize; static const int kEntrySize = Shape::kEntrySize;
......
...@@ -33,10 +33,6 @@ void PreInitializeLiteralSite(Handle<FeedbackVector> vector, ...@@ -33,10 +33,6 @@ void PreInitializeLiteralSite(Handle<FeedbackVector> vector,
vector->Set(slot, Smi::FromInt(1)); vector->Set(slot, Smi::FromInt(1));
} }
Handle<Object> InnerCreateBoilerplate(Isolate* isolate,
Handle<Object> description,
AllocationType allocation);
enum DeepCopyHints { kNoHints = 0, kObjectIsShallow = 1 }; enum DeepCopyHints { kNoHints = 0, kObjectIsShallow = 1 };
template <class ContextObject> template <class ContextObject>
...@@ -86,14 +82,14 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk( ...@@ -86,14 +82,14 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
} }
} }
if (object->map().is_deprecated()) { if (object->map(isolate).is_deprecated()) {
JSObject::MigrateInstance(isolate, object); JSObject::MigrateInstance(isolate, object);
} }
Handle<JSObject> copy; Handle<JSObject> copy;
if (copying) { if (copying) {
// JSFunction objects are not allowed to be in normal boilerplates at all. // JSFunction objects are not allowed to be in normal boilerplates at all.
DCHECK(!object->IsJSFunction()); DCHECK(!object->IsJSFunction(isolate));
Handle<AllocationSite> site_to_pass; Handle<AllocationSite> site_to_pass;
if (site_context()->ShouldCreateMemento(object)) { if (site_context()->ShouldCreateMemento(object)) {
site_to_pass = site_context()->current(); site_to_pass = site_context()->current();
...@@ -111,23 +107,23 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk( ...@@ -111,23 +107,23 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
HandleScope scope(isolate); HandleScope scope(isolate);
// Deep copy own properties. Arrays only have 1 property "length". // Deep copy own properties. Arrays only have 1 property "length".
if (!copy->IsJSArray()) { if (!copy->IsJSArray(isolate)) {
if (copy->HasFastProperties()) { if (copy->HasFastProperties(isolate)) {
Handle<DescriptorArray> descriptors(copy->map().instance_descriptors(), Handle<DescriptorArray> descriptors(
isolate); copy->map(isolate).instance_descriptors(isolate), isolate);
int limit = copy->map().NumberOfOwnDescriptors(); int limit = copy->map(isolate).NumberOfOwnDescriptors();
for (int i = 0; i < limit; i++) { for (int i = 0; i < limit; i++) {
DCHECK_EQ(kField, descriptors->GetDetails(i).location()); DCHECK_EQ(kField, descriptors->GetDetails(i).location());
DCHECK_EQ(kData, descriptors->GetDetails(i).kind()); DCHECK_EQ(kData, descriptors->GetDetails(i).kind());
FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i); FieldIndex index = FieldIndex::ForDescriptor(copy->map(isolate), i);
if (copy->IsUnboxedDoubleField(index)) continue; if (copy->IsUnboxedDoubleField(isolate, index)) continue;
Object raw = copy->RawFastPropertyAt(index); Object raw = copy->RawFastPropertyAt(isolate, index);
if (raw.IsJSObject()) { if (raw.IsJSObject(isolate)) {
Handle<JSObject> value(JSObject::cast(raw), isolate); Handle<JSObject> value(JSObject::cast(raw), isolate);
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, value, VisitElementOrProperty(copy, value), JSObject); isolate, value, VisitElementOrProperty(copy, value), JSObject);
if (copying) copy->FastPropertyAtPut(index, *value); if (copying) copy->FastPropertyAtPut(index, *value);
} else if (copying && raw.IsMutableHeapNumber()) { } else if (copying && raw.IsMutableHeapNumber(isolate)) {
DCHECK(descriptors->GetDetails(i).representation().IsDouble()); DCHECK(descriptors->GetDetails(i).representation().IsDouble());
uint64_t double_value = MutableHeapNumber::cast(raw).value_as_bits(); uint64_t double_value = MutableHeapNumber::cast(raw).value_as_bits();
auto value = auto value =
...@@ -136,11 +132,12 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk( ...@@ -136,11 +132,12 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
} }
} }
} else { } else {
Handle<NameDictionary> dict(copy->property_dictionary(), isolate); Handle<NameDictionary> dict(copy->property_dictionary(isolate), isolate);
for (int i = 0; i < dict->Capacity(); i++) { int capacity = dict->Capacity();
Object raw = dict->ValueAt(i); for (int i = 0; i < capacity; i++) {
if (!raw.IsJSObject()) continue; Object raw = dict->ValueAt(isolate, i);
DCHECK(dict->KeyAt(i).IsName()); if (!raw.IsJSObject(isolate)) continue;
DCHECK(dict->KeyAt(isolate, i).IsName());
Handle<JSObject> value(JSObject::cast(raw), isolate); Handle<JSObject> value(JSObject::cast(raw), isolate);
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, value, VisitElementOrProperty(copy, value), JSObject); isolate, value, VisitElementOrProperty(copy, value), JSObject);
...@@ -149,19 +146,21 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk( ...@@ -149,19 +146,21 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
} }
// Assume non-arrays don't end up having elements. // Assume non-arrays don't end up having elements.
if (copy->elements().length() == 0) return copy; if (copy->elements(isolate).length() == 0) return copy;
} }
// Deep copy own elements. // Deep copy own elements.
switch (copy->GetElementsKind()) { switch (copy->GetElementsKind(isolate)) {
case PACKED_ELEMENTS: case PACKED_ELEMENTS:
case PACKED_FROZEN_ELEMENTS: case PACKED_FROZEN_ELEMENTS:
case PACKED_SEALED_ELEMENTS: case PACKED_SEALED_ELEMENTS:
case HOLEY_FROZEN_ELEMENTS: case HOLEY_FROZEN_ELEMENTS:
case HOLEY_SEALED_ELEMENTS: case HOLEY_SEALED_ELEMENTS:
case HOLEY_ELEMENTS: { case HOLEY_ELEMENTS: {
Handle<FixedArray> elements(FixedArray::cast(copy->elements()), isolate); Handle<FixedArray> elements(FixedArray::cast(copy->elements(isolate)),
if (elements->map() == ReadOnlyRoots(isolate).fixed_cow_array_map()) { isolate);
if (elements->map(isolate) ==
ReadOnlyRoots(isolate).fixed_cow_array_map()) {
#ifdef DEBUG #ifdef DEBUG
for (int i = 0; i < elements->length(); i++) { for (int i = 0; i < elements->length(); i++) {
DCHECK(!elements->get(i).IsJSObject()); DCHECK(!elements->get(i).IsJSObject());
...@@ -169,8 +168,8 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk( ...@@ -169,8 +168,8 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
#endif #endif
} else { } else {
for (int i = 0; i < elements->length(); i++) { for (int i = 0; i < elements->length(); i++) {
Object raw = elements->get(i); Object raw = elements->get(isolate, i);
if (!raw.IsJSObject()) continue; if (!raw.IsJSObject(isolate)) continue;
Handle<JSObject> value(JSObject::cast(raw), isolate); Handle<JSObject> value(JSObject::cast(raw), isolate);
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, value, VisitElementOrProperty(copy, value), JSObject); isolate, value, VisitElementOrProperty(copy, value), JSObject);
...@@ -180,12 +179,12 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk( ...@@ -180,12 +179,12 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
break; break;
} }
case DICTIONARY_ELEMENTS: { case DICTIONARY_ELEMENTS: {
Handle<NumberDictionary> element_dictionary(copy->element_dictionary(), Handle<NumberDictionary> element_dictionary(
isolate); copy->element_dictionary(isolate), isolate);
int capacity = element_dictionary->Capacity(); int capacity = element_dictionary->Capacity();
for (int i = 0; i < capacity; i++) { for (int i = 0; i < capacity; i++) {
Object raw = element_dictionary->ValueAt(i); Object raw = element_dictionary->ValueAt(isolate, i);
if (!raw.IsJSObject()) continue; if (!raw.IsJSObject(isolate)) continue;
Handle<JSObject> value(JSObject::cast(raw), isolate); Handle<JSObject> value(JSObject::cast(raw), isolate);
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, value, VisitElementOrProperty(copy, value), JSObject); isolate, value, VisitElementOrProperty(copy, value), JSObject);
...@@ -392,13 +391,26 @@ Handle<JSObject> CreateObjectLiteral( ...@@ -392,13 +391,26 @@ Handle<JSObject> CreateObjectLiteral(
int length = object_boilerplate_description->size(); int length = object_boilerplate_description->size();
// TODO(verwaest): Support tracking representations in the boilerplate. // TODO(verwaest): Support tracking representations in the boilerplate.
for (int index = 0; index < length; index++) { for (int index = 0; index < length; index++) {
Handle<Object> key(object_boilerplate_description->name(index), isolate); Handle<Object> key(object_boilerplate_description->name(isolate, index),
Handle<Object> value(object_boilerplate_description->value(index), isolate); isolate);
Handle<Object> value(object_boilerplate_description->value(isolate, index),
if (value->IsObjectBoilerplateDescription() || isolate);
value->IsArrayBoilerplateDescription()) {
value = InnerCreateBoilerplate(isolate, value, allocation); if (value->IsHeapObject()) {
if (HeapObject::cast(*value).IsArrayBoilerplateDescription(isolate)) {
Handle<ArrayBoilerplateDescription> boilerplate =
Handle<ArrayBoilerplateDescription>::cast(value);
value = CreateArrayLiteral(isolate, boilerplate, allocation);
} else if (HeapObject::cast(*value).IsObjectBoilerplateDescription(
isolate)) {
Handle<ObjectBoilerplateDescription> boilerplate =
Handle<ObjectBoilerplateDescription>::cast(value);
value = CreateObjectLiteral(isolate, boilerplate, boilerplate->flags(),
allocation);
}
} }
uint32_t element_index = 0; uint32_t element_index = 0;
if (key->ToArrayIndex(&element_index)) { if (key->ToArrayIndex(&element_index)) {
// Array index (uint32). // Array index (uint32).
...@@ -433,7 +445,7 @@ Handle<JSObject> CreateArrayLiteral( ...@@ -433,7 +445,7 @@ Handle<JSObject> CreateArrayLiteral(
array_boilerplate_description->elements_kind(); array_boilerplate_description->elements_kind();
Handle<FixedArrayBase> constant_elements_values( Handle<FixedArrayBase> constant_elements_values(
array_boilerplate_description->constant_elements(), isolate); array_boilerplate_description->constant_elements(isolate), isolate);
// Create the JSArray. // Create the JSArray.
Handle<FixedArrayBase> copied_elements_values; Handle<FixedArrayBase> copied_elements_values;
...@@ -442,7 +454,7 @@ Handle<JSObject> CreateArrayLiteral( ...@@ -442,7 +454,7 @@ Handle<JSObject> CreateArrayLiteral(
Handle<FixedDoubleArray>::cast(constant_elements_values)); Handle<FixedDoubleArray>::cast(constant_elements_values));
} else { } else {
DCHECK(IsSmiOrObjectElementsKind(constant_elements_kind)); DCHECK(IsSmiOrObjectElementsKind(constant_elements_kind));
const bool is_cow = (constant_elements_values->map() == const bool is_cow = (constant_elements_values->map(isolate) ==
ReadOnlyRoots(isolate).fixed_cow_array_map()); ReadOnlyRoots(isolate).fixed_cow_array_map());
if (is_cow) { if (is_cow) {
copied_elements_values = constant_elements_values; copied_elements_values = constant_elements_values;
...@@ -459,44 +471,36 @@ Handle<JSObject> CreateArrayLiteral( ...@@ -459,44 +471,36 @@ Handle<JSObject> CreateArrayLiteral(
Handle<FixedArray> fixed_array_values_copy = Handle<FixedArray> fixed_array_values_copy =
isolate->factory()->CopyFixedArray(fixed_array_values); isolate->factory()->CopyFixedArray(fixed_array_values);
copied_elements_values = fixed_array_values_copy; copied_elements_values = fixed_array_values_copy;
FOR_WITH_HANDLE_SCOPE( for (int i = 0; i < fixed_array_values->length(); i++) {
isolate, int, i = 0, i, i < fixed_array_values->length(), i++, { Object value = fixed_array_values_copy->get(isolate, i);
Handle<Object> value(fixed_array_values->get(i), isolate); HeapObject value_heap_object;
if (value.GetHeapObject(isolate, &value_heap_object)) {
if (value->IsArrayBoilerplateDescription() || if (value_heap_object.IsArrayBoilerplateDescription(isolate)) {
value->IsObjectBoilerplateDescription()) { HandleScope sub_scope(isolate);
Handle<Object> result = Handle<ArrayBoilerplateDescription> boilerplate(
InnerCreateBoilerplate(isolate, value, allocation); ArrayBoilerplateDescription::cast(value_heap_object), isolate);
fixed_array_values_copy->set(i, *result); Handle<JSObject> result =
} CreateArrayLiteral(isolate, boilerplate, allocation);
}); fixed_array_values_copy->set(i, *result);
} else if (value_heap_object.IsObjectBoilerplateDescription(
isolate)) {
HandleScope sub_scope(isolate);
Handle<ObjectBoilerplateDescription> boilerplate(
ObjectBoilerplateDescription::cast(value_heap_object), isolate);
Handle<JSObject> result = CreateObjectLiteral(
isolate, boilerplate, boilerplate->flags(), allocation);
fixed_array_values_copy->set(i, *result);
}
}
}
} }
} }
return isolate->factory()->NewJSArrayWithElements( return isolate->factory()->NewJSArrayWithElements(
copied_elements_values, constant_elements_kind, copied_elements_values, constant_elements_kind,
copied_elements_values->length(), allocation); copied_elements_values->length(), allocation);
} }
Handle<Object> InnerCreateBoilerplate(Isolate* isolate,
Handle<Object> description,
AllocationType allocation) {
if (description->IsObjectBoilerplateDescription()) {
Handle<ObjectBoilerplateDescription> object_boilerplate_description =
Handle<ObjectBoilerplateDescription>::cast(description);
return ObjectLiteralHelper::Create(isolate, object_boilerplate_description,
object_boilerplate_description->flags(),
allocation);
} else {
DCHECK(description->IsArrayBoilerplateDescription());
Handle<ArrayBoilerplateDescription> array_boilerplate_description =
Handle<ArrayBoilerplateDescription>::cast(description);
return ArrayLiteralHelper::Create(
isolate, array_boilerplate_description,
array_boilerplate_description->elements_kind(), allocation);
}
}
inline DeepCopyHints DecodeCopyHints(int flags) { inline DeepCopyHints DecodeCopyHints(int flags) {
DeepCopyHints copy_hints = DeepCopyHints copy_hints =
(flags & AggregateLiteral::kIsShallow) ? kObjectIsShallow : kNoHints; (flags & AggregateLiteral::kIsShallow) ? kObjectIsShallow : kNoHints;
......
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