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

[runtime] Add ReadOnlyRoots.empty_array_list()

- Simplify HeapObject::IsArrayList check
- Dehandlify ArrayList initialization
- Prevent auto-formatting of v8heapconst.py

Change-Id: I9849ad82dae1a2dc671433e8d5eb8ec63ed830c9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3447906Reviewed-by: 's avatarShu-yu Guo <syg@chromium.org>
Reviewed-by: 's avatarSimon Zünd <szuend@chromium.org>
Reviewed-by: 's avatarOmer Katz <omerkatz@chromium.org>
Auto-Submit: Camillo Bruni <cbruni@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79114}
parent c680e6d3
......@@ -612,7 +612,8 @@ std::unique_ptr<Coverage> Coverage::CollectPrecise(Isolate* isolate) {
isolate->is_block_binary_code_coverage())) {
// We do not have to hold onto feedback vectors for invocations we already
// reported. So we can reset the list.
isolate->SetFeedbackVectorsForProfilingTools(*ArrayList::New(isolate, 0));
isolate->SetFeedbackVectorsForProfilingTools(
ReadOnlyRoots(isolate).empty_array_list());
}
return result;
}
......
......@@ -570,6 +570,16 @@ void EmbedderDataArray::EmbedderDataArrayVerify(Isolate* isolate) {
}
}
void FixedArray::FixedArrayVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::FixedArrayVerify(*this, isolate);
if (*this == ReadOnlyRoots(isolate).empty_fixed_array()) {
CHECK_EQ(length(), 0);
CHECK_EQ(map(), ReadOnlyRoots(isolate).fixed_array_map());
} else if (IsArrayList()) {
ArrayList::cast(*this).ArrayListVerify(isolate);
}
}
void WeakFixedArray::WeakFixedArrayVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::WeakFixedArrayVerify(*this, isolate);
for (int i = 0; i < length(); i++) {
......@@ -577,6 +587,17 @@ void WeakFixedArray::WeakFixedArrayVerify(Isolate* isolate) {
}
}
void ArrayList::ArrayListVerify(Isolate* isolate) {
// Avoid calling the torque-generated ArrayListVerify to prevent an endlessly
// recursion verification.
CHECK(IsArrayList());
CHECK_LE(ArrayList::kLengthIndex, length());
CHECK_LE(0, Length());
if (Length() == 0 && length() == ArrayList::kLengthIndex) {
CHECK_EQ(*this, ReadOnlyRoots(isolate).empty_array_list());
}
}
void PropertyArray::PropertyArrayVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::PropertyArrayVerify(*this, isolate);
if (length() == 0) {
......
......@@ -252,9 +252,6 @@ Handle<Script> FactoryBase<Impl>::NewScriptWithId(
DCHECK(source->IsString() || source->IsUndefined());
// Create and initialize script object.
ReadOnlyRoots roots = read_only_roots();
#ifdef V8_SCRIPTORMODULE_LEGACY_LIFETIME
Handle<ArrayList> list = NewArrayList(0, AllocationType::kOld);
#endif
Handle<Script> script = handle(
NewStructInternal<Script>(SCRIPT_TYPE, AllocationType::kOld), isolate());
{
......@@ -276,7 +273,7 @@ Handle<Script> FactoryBase<Impl>::NewScriptWithId(
raw.set_flags(0);
raw.set_host_defined_options(roots.empty_fixed_array(), SKIP_WRITE_BARRIER);
#ifdef V8_SCRIPTORMODULE_LEGACY_LIFETIME
raw.set_script_or_modules(*list);
raw.set_script_or_modules(roots.empty_array_list());
#endif
}
......@@ -291,12 +288,16 @@ Handle<Script> FactoryBase<Impl>::NewScriptWithId(
template <typename Impl>
Handle<ArrayList> FactoryBase<Impl>::NewArrayList(int size,
AllocationType allocation) {
if (size == 0) return impl()->empty_array_list();
Handle<FixedArray> fixed_array =
NewFixedArray(size + ArrayList::kFirstIndex, allocation);
fixed_array->set_map_no_write_barrier(read_only_roots().array_list_map());
Handle<ArrayList> result = Handle<ArrayList>::cast(fixed_array);
result->SetLength(0);
return result;
{
DisallowGarbageCollection no_gc;
FixedArray raw = *fixed_array;
raw.set_map_no_write_barrier(read_only_roots().array_list_map());
ArrayList::cast(raw).SetLength(0);
}
return Handle<ArrayList>::cast(fixed_array);
}
template <typename Impl>
......
......@@ -1488,7 +1488,6 @@ Handle<WasmTypeInfo> Factory::NewWasmTypeInfo(
// The supertypes list is constant after initialization, so we pretenure
// that too. The subtypes list, however, is expected to grow (and hence be
// replaced), so we don't pretenure it.
Handle<ArrayList> subtypes = ArrayList::New(isolate(), 0);
Handle<FixedArray> supertypes;
if (opt_parent.is_null()) {
supertypes = NewFixedArray(wasm::kMinimumSupertypeArraySize);
......@@ -1517,7 +1516,7 @@ Handle<WasmTypeInfo> Factory::NewWasmTypeInfo(
result.AllocateExternalPointerEntries(isolate());
result.set_foreign_address(isolate(), type_address);
result.set_supertypes(*supertypes);
result.set_subtypes(*subtypes);
result.set_subtypes(ReadOnlyRoots(isolate()).empty_array_list());
result.set_instance_size(instance_size_bytes);
result.set_instance(*instance);
return handle(result, isolate());
......@@ -2746,7 +2745,6 @@ Handle<SourceTextModule> Factory::NewSourceTextModule(
Handle<FixedArray> requested_modules =
requested_modules_length > 0 ? NewFixedArray(requested_modules_length)
: empty_fixed_array();
Handle<ArrayList> async_parent_modules = ArrayList::New(isolate(), 0);
ReadOnlyRoots roots(isolate());
SourceTextModule module = SourceTextModule::cast(
......@@ -2770,7 +2768,7 @@ Handle<SourceTextModule> Factory::NewSourceTextModule(
module.set_async(IsAsyncModule(sfi->kind()));
module.set_async_evaluating_ordinal(SourceTextModule::kNotAsyncEvaluated);
module.set_cycle_root(roots.the_hole_value(), SKIP_WRITE_BARRIER);
module.set_async_parent_modules(*async_parent_modules);
module.set_async_parent_modules(roots.empty_array_list());
module.set_pending_async_dependencies(0);
return handle(module, isolate());
}
......
......@@ -250,7 +250,6 @@ bool Heap::CreateInitialMaps() {
#undef ALLOCATE_PARTIAL_MAP
}
// Allocate the empty array.
{
AllocationResult alloc =
AllocateRaw(FixedArray::SizeFor(0), AllocationType::kReadOnly);
......@@ -534,6 +533,15 @@ bool Heap::CreateInitialMaps() {
#undef ALLOCATE_VARSIZE_MAP
#undef ALLOCATE_MAP
}
{
AllocationResult alloc = AllocateRaw(
ArrayList::SizeFor(ArrayList::kFirstIndex), AllocationType::kReadOnly);
if (!alloc.To(&obj)) return false;
obj.set_map_after_allocation(roots.array_list_map(), SKIP_WRITE_BARRIER);
ArrayList::cast(obj).set_length(ArrayList::kFirstIndex);
ArrayList::cast(obj).SetLength(0);
}
set_empty_array_list(ArrayList::cast(obj));
{
AllocationResult alloc =
......@@ -785,6 +793,7 @@ void Heap::CreateInitialObjects() {
Handle<NameDictionary> empty_property_dictionary = NameDictionary::New(
isolate(), 1, AllocationType::kReadOnly, USE_CUSTOM_MINIMUM_CAPACITY);
DCHECK(!empty_property_dictionary->HasSufficientCapacityToAdd(1));
set_empty_property_dictionary(*empty_property_dictionary);
set_public_symbol_table(*empty_property_dictionary);
......@@ -794,7 +803,7 @@ void Heap::CreateInitialObjects() {
set_number_string_cache(*factory->NewFixedArray(
kInitialNumberStringCacheSize * 2, AllocationType::kOld));
set_basic_block_profiling_data(ArrayList::cast(roots.empty_fixed_array()));
set_basic_block_profiling_data(roots.empty_array_list());
// Allocate cache for string split and regexp-multiple.
set_string_split_cache(*factory->NewFixedArray(
......
......@@ -198,6 +198,7 @@ class FixedArray
// Dispatched behavior.
DECL_PRINTER(FixedArray)
DECL_VERIFIER(FixedArray)
int AllocatedSize();
......@@ -383,7 +384,7 @@ class WeakArrayList
inline void CopyElements(Isolate* isolate, int dst_index, WeakArrayList src,
int src_index, int len, WriteBarrierMode mode);
V8_EXPORT_PRIVATE bool IsFull();
V8_EXPORT_PRIVATE bool IsFull() const;
int AllocatedSize();
......@@ -485,6 +486,8 @@ class ArrayList : public TorqueGeneratedArrayList<ArrayList, FixedArray> {
static const int kFirstIndex = 1;
STATIC_ASSERT(kHeaderFields == kFirstIndex);
DECL_VERIFIER(ArrayList)
private:
static Handle<ArrayList> EnsureSpace(Isolate* isolate,
Handle<ArrayList> array, int length);
......
......@@ -303,9 +303,8 @@ bool Object::IsNumeric(PtrComprCageBase cage_base) const {
}
DEF_GETTER(HeapObject, IsArrayList, bool) {
ReadOnlyRoots roots = GetReadOnlyRoots(cage_base);
return *this == roots.empty_fixed_array() ||
map(cage_base) == roots.array_list_map();
return map(cage_base) ==
GetReadOnlyRoots(cage_base).unchecked_array_list_map();
}
DEF_GETTER(HeapObject, IsRegExpMatchInfo, bool) {
......
......@@ -4056,15 +4056,11 @@ Handle<FixedArray> EnsureSpaceInFixedArray(Isolate* isolate,
// static
Handle<ArrayList> ArrayList::EnsureSpace(Isolate* isolate,
Handle<ArrayList> array, int length) {
const bool empty = (array->length() == 0);
Handle<FixedArray> ret =
EnsureSpaceInFixedArray(isolate, array, kFirstIndex + length);
if (empty) {
ret->set_map_no_write_barrier(array->GetReadOnlyRoots().array_list_map());
Handle<ArrayList>::cast(ret)->SetLength(0);
}
return Handle<ArrayList>::cast(ret);
DCHECK_LT(0, length);
auto new_array = Handle<ArrayList>::cast(
EnsureSpaceInFixedArray(isolate, array, kFirstIndex + length));
DCHECK_EQ(array->Length(), new_array->Length());
return new_array;
}
// static
......@@ -4073,10 +4069,14 @@ Handle<WeakArrayList> WeakArrayList::AddToEnd(Isolate* isolate,
const MaybeObjectHandle& value) {
int length = array->length();
array = EnsureSpace(isolate, array, length + 1);
// Reload length; GC might have removed elements from the array.
length = array->length();
array->Set(length, *value);
array->set_length(length + 1);
{
DisallowGarbageCollection no_gc;
WeakArrayList raw = *array;
// Reload length; GC might have removed elements from the array.
length = raw.length();
raw.Set(length, *value);
raw.set_length(length + 1);
}
return array;
}
......@@ -4086,11 +4086,15 @@ Handle<WeakArrayList> WeakArrayList::AddToEnd(Isolate* isolate,
const MaybeObjectHandle& value2) {
int length = array->length();
array = EnsureSpace(isolate, array, length + 2);
// Reload length; GC might have removed elements from the array.
length = array->length();
array->Set(length, *value1);
array->Set(length + 1, *value2);
array->set_length(length + 2);
{
DisallowGarbageCollection no_gc;
WeakArrayList raw = *array;
// Reload length; GC might have removed elements from the array.
length = array->length();
raw.Set(length, *value1);
raw.Set(length + 1, *value2);
raw.set_length(length + 2);
}
return array;
}
......@@ -4099,17 +4103,23 @@ Handle<WeakArrayList> WeakArrayList::Append(Isolate* isolate,
Handle<WeakArrayList> array,
const MaybeObjectHandle& value,
AllocationType allocation) {
int length = array->length();
int length = 0;
int new_length = 0;
{
DisallowGarbageCollection no_gc;
WeakArrayList raw = *array;
length = raw.length();
if (length < array->capacity()) {
array->Set(length, *value);
array->set_length(length + 1);
return array;
}
if (length < raw.capacity()) {
raw.Set(length, *value);
raw.set_length(length + 1);
return array;
}
// Not enough space in the array left, either grow, shrink or
// compact the array.
int new_length = array->CountLiveElements() + 1;
// Not enough space in the array left, either grow, shrink or
// compact the array.
new_length = raw.CountLiveElements() + 1;
}
bool shrink = new_length < length / 4;
bool grow = 3 * (length / 4) < new_length;
......@@ -4128,14 +4138,19 @@ Handle<WeakArrayList> WeakArrayList::Append(Isolate* isolate,
// Now append value to the array, there should always be enough space now.
DCHECK_LT(array->length(), array->capacity());
// Reload length, allocation might have killed some weak refs.
int index = array->length();
array->Set(index, *value);
array->set_length(index + 1);
{
DisallowGarbageCollection no_gc;
WeakArrayList raw = *array;
// Reload length, allocation might have killed some weak refs.
int index = raw.length();
raw.Set(index, *value);
raw.set_length(index + 1);
}
return array;
}
void WeakArrayList::Compact(Isolate* isolate) {
DisallowGarbageCollection no_gc;
int length = this->length();
int new_length = 0;
......@@ -4153,7 +4168,7 @@ void WeakArrayList::Compact(Isolate* isolate) {
set_length(new_length);
}
bool WeakArrayList::IsFull() { return length() == capacity(); }
bool WeakArrayList::IsFull() const { return length() == capacity(); }
// static
Handle<WeakArrayList> WeakArrayList::EnsureSpace(Isolate* isolate,
......
......@@ -1038,8 +1038,7 @@ MaybeHandle<Object> SourceTextModule::InnerModuleEvaluation(
DCHECK(!module->HasPendingAsyncDependencies());
// 9. Set module.[[AsyncParentModules]] to a new empty List.
Handle<ArrayList> async_parent_modules = ArrayList::New(isolate, 0);
module->set_async_parent_modules(*async_parent_modules);
module->set_async_parent_modules(ReadOnlyRoots(isolate).empty_array_list());
// 10. Set index to index + 1.
(*dfs_index)++;
......
......@@ -187,6 +187,7 @@ class Symbol;
V(SwissNameDictionary, empty_swiss_property_dictionary, \
EmptySwissPropertyDictionary) \
V(InterceptorInfo, noop_interceptor_info, NoOpInterceptorInfo) \
V(ArrayList, empty_array_list, EmptyArrayList) \
V(WeakFixedArray, empty_weak_fixed_array, EmptyWeakFixedArray) \
V(WeakArrayList, empty_weak_array_list, EmptyWeakArrayList) \
/* Special numbers */ \
......
......@@ -15,8 +15,7 @@ TEST(ArrayList) {
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
Handle<ArrayList> array(
ArrayList::cast(ReadOnlyRoots(isolate).empty_fixed_array()), isolate);
Handle<ArrayList> array = ReadOnlyRoots(isolate).empty_array_list_handle();
CHECK_EQ(0, array->Length());
array = ArrayList::Add(isolate, array, handle(Smi::FromInt(100), isolate));
CHECK_EQ(1, array->Length());
......
......@@ -26,7 +26,8 @@ static const char* kHeader =
"# This file is automatically generated by mkgrokdump and should not\n"
"# be modified manually.\n"
"\n"
"# List of known V8 instance types.\n";
"# List of known V8 instance types.\n"
"# yapf: disable\n\n";
// Debug builds emit debug code, affecting code object sizes.
#ifndef DEBUG
......@@ -59,8 +60,8 @@ static void DumpKnownMap(FILE* out, i::Heap* heap, const char* space_name,
MUTABLE_ROOT_LIST(MUTABLE_ROOT_LIST_CASE)
if (root_name == nullptr) return;
i::PrintF(out, " (\"%s\", 0x%05" V8PRIxPTR "): (%d, \"%s\"),\n", space_name,
root_ptr, map.instance_type(), root_name);
i::PrintF(out, " (\"%s\", 0x%05" V8PRIxPTR "): (%d, \"%s\"),\n",
space_name, root_ptr, map.instance_type(), root_name);
#undef MUTABLE_ROOT_LIST_CASE
#undef RO_ROOT_LIST_CASE
......
This diff is collapsed.
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