Commit 6c922e39 authored by Seth Brenith's avatar Seth Brenith Committed by Commit Bot

Revert "Remove 'length' field from ScopeInfo"

This reverts commit f731e13f.

Reason for revert: perf regressions, chromium:1179757

Original change's description:
> Remove 'length' field from ScopeInfo
>
> ScopeInfo has a vestigial 'length' field from when it used to be a
> FixedArray. This change removes that field, which saves some memory.
>
> More specifically:
>
> - Make ScopeInfo inherit from HeapObject, not FixedArrayBase which
>   supplied the 'length' field.
> - Privatize the FixedArray-style functions that provide access to
>   ScopeInfo fields by index, and move them from scope-info-inl.h to
>   scope-info.cc. Those functions are still used pretty heavily during
>   initialization (ScopeInfo::Create, etc.), but at least we can avoid
>   presenting them to the rest of the world.
> - Change FactoryBase::NewScopeInfo to allocate the updated object shape.
>   It maintains the existing behavior of filling the newly-allocated
>   object with undefined, even though that's not a valid ScopeInfo and
>   further initialization is required.
> - Move part of AccessorAssembler::ScriptContextTableLookup into a new
>   Torque macro, because it used to rely on casting ScopeInfo to
>   FixedArrayBase.
> - In V8HeapExplorer::AddEntry, don't claim that ScopeInfo objects are
>   arrays. I think it makes more sense to list them under "(system)" in
>   the dev tools, like most other V8 internal types.
>
> Bug: v8:8952
> Change-Id: I8278e3a90027d4409f0d268da0fe7080754c6b8c
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2601880
> Reviewed-by: Toon Verwaest <verwaest@chromium.org>
> Reviewed-by: Peter Marshall <petermarshall@chromium.org>
> Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
> Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
> Reviewed-by: Mythri Alle <mythria@chromium.org>
> Commit-Queue: Seth Brenith <seth.brenith@microsoft.com>
> Cr-Commit-Position: refs/heads/master@{#72830}

Bug: v8:8952
Change-Id: I00a69da79e5ac6aaae4436a41ce773ae014cc775
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2706086
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Auto-Submit: Seth Brenith <seth.brenith@microsoft.com>
Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
Reviewed-by: 's avatarNico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72855}
parent 528ec99d
......@@ -2013,6 +2013,11 @@ TNode<IntPtrT> CodeStubAssembler::LoadArrayLength(
return LoadAndUntagWeakFixedArrayLength(array);
}
template <>
TNode<IntPtrT> CodeStubAssembler::LoadArrayLength(TNode<ScopeInfo> array) {
return LoadAndUntagFixedArrayBaseLength(array);
}
template <typename Array, typename TIndex, typename TValue>
TNode<TValue> CodeStubAssembler::LoadArrayElement(
TNode<Array> array, int array_header_size, TNode<TIndex> index_node,
......@@ -2043,6 +2048,10 @@ TNode<TValue> CodeStubAssembler::LoadArrayElement(
template V8_EXPORT_PRIVATE TNode<MaybeObject>
CodeStubAssembler::LoadArrayElement<TransitionArray, IntPtrT>(
TNode<TransitionArray>, int, TNode<IntPtrT>, int, LoadSensitivity);
template V8_EXPORT_PRIVATE TNode<MaybeObject>
CodeStubAssembler::LoadArrayElement<ScopeInfo, IntPtrT>(TNode<ScopeInfo>, int,
TNode<IntPtrT>, int,
LoadSensitivity);
template <typename TIndex>
TNode<Object> CodeStubAssembler::LoadFixedArrayElement(
......
......@@ -740,7 +740,8 @@ void ScopeIterator::VisitModuleScope(const Visitor& visitor) const {
if (VisitContextLocals(visitor, scope_info, context_, ScopeTypeModule))
return;
int module_variable_count = scope_info->ModuleVariableCount();
int count_index = scope_info->ModuleVariableCountIndex();
int module_variable_count = Smi::cast(scope_info->get(count_index)).value();
Handle<SourceTextModule> module(context_->module(), isolate_);
......
......@@ -578,6 +578,20 @@ void Context::ContextVerify(Isolate* isolate) {
}
}
void ScopeInfo::ScopeInfoVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::ScopeInfoVerify(*this, isolate);
// Make sure that the FixedArray-style length matches the length that we would
// compute based on the Torque indexed fields.
CHECK_EQ(FixedArray::SizeFor(length()), AllocatedSize());
// Code that treats ScopeInfo like a FixedArray expects all values to be
// tagged.
for (int i = 0; i < length(); ++i) {
Object::VerifyPointer(isolate, get(isolate, i));
}
}
void NativeContext::NativeContextVerify(Isolate* isolate) {
ContextVerify(isolate);
CHECK_EQ(length(), NativeContext::NATIVE_CONTEXT_SLOTS);
......
......@@ -2204,13 +2204,18 @@ void JSSegments::JSSegmentsPrint(std::ostream& os) { // NOLINT
namespace {
void PrintScopeInfoList(ScopeInfo scope_info, std::ostream& os,
const char* list_name, int length) {
const char* list_name, int nof_internal_slots,
int start, int length) {
if (length <= 0) return;
int end = start + length;
os << "\n - " << list_name;
if (nof_internal_slots > 0) {
os << " " << start << "-" << end << " [internal slots]";
}
os << " {\n";
for (int i = 0; i < length; ++i) {
for (int i = nof_internal_slots; start < end; ++i, ++start) {
os << " - " << i << ": ";
scope_info.context_local_names(i).ShortPrint(os);
String::cast(scope_info.get(start)).ShortPrint(os);
os << "\n";
}
os << " }";
......@@ -2267,7 +2272,8 @@ void ScopeInfo::ScopeInfoPrint(std::ostream& os) { // NOLINT
}
os << "\n - length: " << length();
if (length() > 0) {
PrintScopeInfoList(*this, os, "context slots", ContextLocalCount());
PrintScopeInfoList(*this, os, "context slots", Context::MIN_CONTEXT_SLOTS,
ContextLocalNamesIndex(), ContextLocalCount());
// TODO(neis): Print module stuff if present.
}
os << "\n";
......
......@@ -690,13 +690,11 @@ template <typename Impl>
Handle<ScopeInfo> FactoryBase<Impl>::NewScopeInfo(int length,
AllocationType type) {
DCHECK(type == AllocationType::kOld || type == AllocationType::kReadOnly);
int size = ScopeInfo::SizeFor(length);
HeapObject obj = AllocateRawWithImmortalMap(
size, type, read_only_roots().scope_info_map());
ScopeInfo scope_info = ScopeInfo::cast(obj);
MemsetTagged(scope_info.data_start(), read_only_roots().undefined_value(),
length);
return handle(scope_info, isolate());
Handle<HeapObject> result =
Handle<HeapObject>::cast(NewFixedArray(length, type));
result->set_map_after_allocation(*read_only_roots().scope_info_map_handle(),
SKIP_WRITE_BARRIER);
return Handle<ScopeInfo>::cast(result);
}
template <typename Impl>
......
......@@ -510,10 +510,11 @@ bool Heap::CreateInitialMaps() {
{
AllocationResult alloc =
AllocateRaw(ScopeInfo::SizeFor(ScopeInfo::kVariablePartIndex),
AllocateRaw(FixedArray::SizeFor(ScopeInfo::kVariablePartIndex),
AllocationType::kReadOnly);
if (!alloc.To(&obj)) return false;
obj.set_map_after_allocation(roots.scope_info_map(), SKIP_WRITE_BARRIER);
ScopeInfo::cast(obj).set_length(ScopeInfo::kVariablePartIndex);
int flags = ScopeInfo::IsEmptyBit::encode(true);
DCHECK_EQ(ScopeInfo::LanguageModeBit::decode(flags), LanguageMode::kSloppy);
DCHECK_EQ(ScopeInfo::ReceiverVariableBits::decode(flags),
......
......@@ -3074,14 +3074,34 @@ void AccessorAssembler::ScriptContextTableLookup(
TNode<ScopeInfo> scope_info =
CAST(LoadContextElement(script_context, Context::SCOPE_INFO_INDEX));
TNode<IntPtrT> context_local_index =
IndexOfLocalName(scope_info, name, &loop);
TNode<IntPtrT> var_index = IntPtrAdd(
IntPtrConstant(Context::MIN_CONTEXT_SLOTS), context_local_index);
TNode<Object> result = LoadContextElement(script_context, var_index);
GotoIf(IsTheHole(result), found_hole);
Return(result);
TVARIABLE(IntPtrT, scope_var_index,
IntPtrConstant(ScopeInfo::kVariablePartIndex - 1));
TNode<IntPtrT> num_scope_vars = SmiUntag(
CAST(LoadObjectField(scope_info, ScopeInfo::kContextLocalCountOffset)));
TNode<IntPtrT> end_index = IntPtrAdd(
num_scope_vars, IntPtrConstant(ScopeInfo::kVariablePartIndex));
Label loop_scope_info(this, &scope_var_index);
Goto(&loop_scope_info);
BIND(&loop_scope_info);
{
scope_var_index = IntPtrAdd(scope_var_index.value(), IntPtrConstant(1));
GotoIf(IntPtrGreaterThanOrEqual(scope_var_index.value(), end_index),
&loop);
FixedArrayBoundsCheck(scope_info, scope_var_index.value(), 0);
TNode<Object> var_name = CAST(LoadArrayElement(
scope_info, FixedArray::kHeaderSize, scope_var_index.value()));
GotoIf(TaggedNotEqual(var_name, name), &loop_scope_info);
TNode<IntPtrT> var_index =
IntPtrAdd(IntPtrConstant(Context::MIN_CONTEXT_SLOTS),
IntPtrSub(scope_var_index.value(),
IntPtrConstant(ScopeInfo::kVariablePartIndex)));
TNode<Object> result = LoadContextElement(script_context, var_index);
GotoIf(IsTheHole(result), found_hole);
Return(result);
}
}
}
......
......@@ -30,7 +30,49 @@ int ScopeInfo::Flags() const { return flags(); }
int ScopeInfo::ParameterCount() const { return parameter_count(); }
int ScopeInfo::ContextLocalCount() const { return context_local_count(); }
ObjectSlot ScopeInfo::data_start() { return RawField(OffsetOfElementAt(0)); }
Object ScopeInfo::get(int index) const {
IsolateRoot isolate = GetIsolateForPtrCompr(*this);
return get(isolate, index);
}
Object ScopeInfo::get(IsolateRoot isolate, int index) const {
DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length()));
return TaggedField<Object>::Relaxed_Load(
isolate, *this, FixedArray::OffsetOfElementAt(index));
}
void ScopeInfo::set(int index, Smi value) {
DCHECK_NE(map(), GetReadOnlyRoots().fixed_cow_array_map());
DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length()));
DCHECK(Object(value).IsSmi());
int offset = FixedArray::OffsetOfElementAt(index);
RELAXED_WRITE_FIELD(*this, offset, value);
}
void ScopeInfo::set(int index, Object value, WriteBarrierMode mode) {
DCHECK_NE(map(), GetReadOnlyRoots().fixed_cow_array_map());
DCHECK(IsScopeInfo());
DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length()));
int offset = FixedArray::OffsetOfElementAt(index);
RELAXED_WRITE_FIELD(*this, offset, value);
CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode);
}
void ScopeInfo::CopyElements(Isolate* isolate, int dst_index, ScopeInfo src,
int src_index, int len, WriteBarrierMode mode) {
if (len == 0) return;
DCHECK_LE(dst_index + len, length());
DCHECK_LE(src_index + len, src.length());
DisallowGarbageCollection no_gc;
ObjectSlot dst_slot(RawFieldOfElementAt(dst_index));
ObjectSlot src_slot(src.RawFieldOfElementAt(src_index));
isolate->heap()->CopyRange(*this, dst_slot, src_slot, len, mode);
}
ObjectSlot ScopeInfo::RawFieldOfElementAt(int index) {
return RawField(FixedArray::OffsetOfElementAt(index));
}
} // namespace internal
} // namespace v8
......
......@@ -15,12 +15,17 @@
#include "src/objects/string-set-inl.h"
#include "src/roots/roots.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
// An entry in ModuleVariableEntries consists of several slots:
enum ModuleVariableEntryOffset {
kModuleVariableNameOffset,
kModuleVariableIndexOffset,
kModuleVariablePropertiesOffset,
kModuleVariableEntryLength // Sentinel value.
};
#ifdef DEBUG
bool ScopeInfo::Equals(ScopeInfo other) const {
if (length() != other.length()) return false;
......@@ -159,12 +164,6 @@ Handle<ScopeInfo> ScopeInfo::Create(LocalIsolate* isolate, Zone* zone,
scope->AsModuleScope()->module());
}
// Make sure the Fields enum agrees with Torque-generated offsets.
#define ASSERT_MATCHED_FIELD(name) \
STATIC_ASSERT(OffsetOfElementAt(k##name) == k##name##Offset);
FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(ASSERT_MATCHED_FIELD)
#undef ASSERT_MATCHED_FIELD
const int length = kVariablePartIndex + 2 * context_local_count +
(should_save_class_variable_index ? 1 : 0) +
(has_receiver ? 1 : 0) +
......@@ -229,12 +228,6 @@ Handle<ScopeInfo> ScopeInfo::Create(LocalIsolate* isolate, Zone* zone,
scope_info.set_parameter_count(parameter_count);
scope_info.set_context_local_count(context_local_count);
// Jump ahead to set the number of module variables so that we can use range
// DCHECKs in future steps.
if (scope->is_module_scope()) {
scope_info.set_module_variable_count(0, module_vars_count);
}
// Add context locals' names and info, module variables' names and info.
// Context locals are added using their index.
int context_local_base = index;
......@@ -262,26 +255,18 @@ Handle<ScopeInfo> ScopeInfo::Create(LocalIsolate* isolate, Zone* zone,
break;
}
case VariableLocation::MODULE: {
scope_info.set(module_var_entry +
TorqueGeneratedModuleVariableOffsets::kNameOffset /
kTaggedSize,
scope_info.set(module_var_entry + kModuleVariableNameOffset,
*var->name(), mode);
scope_info.set(
module_var_entry +
TorqueGeneratedModuleVariableOffsets::kIndexOffset /
kTaggedSize,
Smi::FromInt(var->index()));
scope_info.set(module_var_entry + kModuleVariableIndexOffset,
Smi::FromInt(var->index()));
uint32_t properties =
VariableModeBits::encode(var->mode()) |
InitFlagBit::encode(var->initialization_flag()) |
MaybeAssignedFlagBit::encode(var->maybe_assigned()) |
ParameterNumberBits::encode(ParameterNumberBits::kMax) |
IsStaticFlagBit::encode(var->is_static_flag());
scope_info.set(
module_var_entry +
TorqueGeneratedModuleVariableOffsets::kPropertiesOffset /
kTaggedSize,
Smi::FromInt(properties));
scope_info.set(module_var_entry + kModuleVariablePropertiesOffset,
Smi::FromInt(properties));
module_var_entry += kModuleVariableEntryLength;
break;
}
......@@ -386,8 +371,7 @@ Handle<ScopeInfo> ScopeInfo::Create(LocalIsolate* isolate, Zone* zone,
DCHECK_EQ(index, scope_info.ModuleInfoIndex());
scope_info.set(index++, *module_info);
DCHECK_EQ(index, scope_info.ModuleVariableCountIndex());
// Module variable count was already written above.
index++;
scope_info.set(index++, Smi::FromInt(module_vars_count));
DCHECK_EQ(index, scope_info.ModuleVariablesIndex());
// The variable entries themselves have already been written above.
index += kModuleVariableEntryLength * module_vars_count;
......@@ -572,53 +556,6 @@ Handle<ScopeInfo> ScopeInfo::CreateForBootstrapping(Isolate* isolate,
return scope_info;
}
Object ScopeInfo::get(int index) const {
IsolateRoot isolate = GetIsolateForPtrCompr(*this);
return get(isolate, index);
}
Object ScopeInfo::get(IsolateRoot isolate, int index) const {
DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length()));
return TaggedField<Object>::Relaxed_Load(isolate, *this,
OffsetOfElementAt(index));
}
void ScopeInfo::set(int index, Smi value) {
DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length()));
DCHECK(Object(value).IsSmi());
int offset = OffsetOfElementAt(index);
RELAXED_WRITE_FIELD(*this, offset, value);
}
void ScopeInfo::set(int index, Object value, WriteBarrierMode mode) {
DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length()));
int offset = OffsetOfElementAt(index);
RELAXED_WRITE_FIELD(*this, offset, value);
CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode);
}
void ScopeInfo::CopyElements(Isolate* isolate, int dst_index, ScopeInfo src,
int src_index, int len, WriteBarrierMode mode) {
if (len == 0) return;
DCHECK_LE(src_index + len, src.length());
DisallowGarbageCollection no_gc;
ObjectSlot dst_slot(RawFieldOfElementAt(dst_index));
ObjectSlot src_slot(src.RawFieldOfElementAt(src_index));
isolate->heap()->CopyRange(*this, dst_slot, src_slot, len, mode);
}
ObjectSlot ScopeInfo::RawFieldOfElementAt(int index) {
return RawField(OffsetOfElementAt(index));
}
int ScopeInfo::length() const {
// AllocatedSize() is generated by Torque and represents the size in bytes of
// the object, as computed from flags, context_local_count, and possibly
// module_variable_count. Convert that size into a number of slots.
return (AllocatedSize() - HeapObject::kHeaderSize) / kTaggedSize;
}
// static
Handle<ScopeInfo> ScopeInfo::RecreateWithBlockList(
Isolate* isolate, Handle<ScopeInfo> original, Handle<StringSet> blocklist) {
......@@ -899,11 +836,6 @@ bool ScopeInfo::VariableIsSynthetic(String name) {
name.Equals(name.GetReadOnlyRoots().this_string());
}
int ScopeInfo::ModuleVariableCount() const {
DCHECK_EQ(scope_type(), MODULE_SCOPE);
return module_variable_count(0);
}
int ScopeInfo::ModuleIndex(String name, VariableMode* mode,
InitializationFlag* init_flag,
MaybeAssignedFlag* maybe_assigned_flag) {
......@@ -915,13 +847,15 @@ int ScopeInfo::ModuleIndex(String name, VariableMode* mode,
DCHECK_NOT_NULL(maybe_assigned_flag);
int module_vars_count = module_variable_count(0);
int entry = ModuleVariablesIndex();
for (int i = 0; i < module_vars_count; ++i) {
String var_name = module_variables_name(i);
String var_name = String::cast(get(entry + kModuleVariableNameOffset));
if (name.Equals(var_name)) {
int index;
ModuleVariable(i, nullptr, &index, mode, init_flag, maybe_assigned_flag);
return index;
}
entry += kModuleVariableEntryLength;
}
return 0;
......@@ -941,11 +875,11 @@ int ScopeInfo::ContextSlotIndex(ScopeInfo scope_info, String name,
if (scope_info.IsEmpty()) return -1;
int context_local_count = scope_info.context_local_count();
for (int var = 0; var < context_local_count; ++var) {
if (name != scope_info.context_local_names(var)) {
continue;
}
int start = scope_info.ContextLocalNamesIndex();
int end = start + scope_info.context_local_count();
for (int i = start; i < end; ++i) {
if (name != scope_info.get(i)) continue;
int var = i - start;
*mode = scope_info.ContextLocalMode(var);
*is_static_flag = scope_info.ContextLocalIsStaticFlag(var);
*init_flag = scope_info.ContextLocalInitFlag(var);
......@@ -1213,5 +1147,3 @@ FixedArray SourceTextModuleInfo::RegularExportExportNames(int i) const {
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
......@@ -38,11 +38,25 @@ class Zone;
// This object provides quick access to scope info details for runtime
// routines.
class ScopeInfo : public TorqueGeneratedScopeInfo<ScopeInfo, HeapObject> {
class ScopeInfo : public TorqueGeneratedScopeInfo<ScopeInfo, FixedArrayBase> {
public:
DEFINE_TORQUE_GENERATED_SCOPE_FLAGS()
DECL_PRINTER(ScopeInfo)
DECL_VERIFIER(ScopeInfo)
// For refactoring, clone some FixedArray member functions. Eventually this
// class will stop pretending to be a FixedArray, but we're not quite there.
inline Object get(int index) const;
inline Object get(IsolateRoot isolate, int index) const;
// Setter that doesn't need write barrier.
inline void set(int index, Smi value);
// Setter with explicit barrier mode.
inline void set(int index, Object value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline void CopyElements(Isolate* isolate, int dst_index, ScopeInfo src,
int src_index, int len, WriteBarrierMode mode);
inline ObjectSlot RawFieldOfElementAt(int index);
class BodyDescriptor;
......@@ -166,8 +180,6 @@ class ScopeInfo : public TorqueGeneratedScopeInfo<ScopeInfo, HeapObject> {
InitializationFlag* init_flag,
MaybeAssignedFlag* maybe_assigned_flag);
int ModuleVariableCount() const;
// Lookup support for serialized scope info. Returns the function context
// slot index if the function name is present and context-allocated (named
// function expressions, only), otherwise returns a value < 0. The name
......@@ -260,17 +272,17 @@ class ScopeInfo : public TorqueGeneratedScopeInfo<ScopeInfo, HeapObject> {
kVariablePartIndex
};
// Make sure the Fields enum agrees with Torque-generated offsets.
#define ASSERT_MATCHED_FIELD(name) \
STATIC_ASSERT(FixedArray::OffsetOfElementAt(k##name) == k##name##Offset);
FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(ASSERT_MATCHED_FIELD)
#undef ASSERT_MATCHED_FIELD
STATIC_ASSERT(LanguageModeSize == 1 << LanguageModeBit::kSize);
STATIC_ASSERT(kLastFunctionKind <= FunctionKindBits::kMax);
bool IsEmpty() const;
// Returns the size in bytes for a ScopeInfo with |length| slots.
static constexpr int SizeFor(int length) { return OffsetOfElementAt(length); }
// Gives access to raw memory which stores the ScopeInfo's data.
inline ObjectSlot data_start();
private:
int ContextLocalNamesIndex() const;
int ContextLocalInfosIndex() const;
......@@ -287,33 +299,10 @@ class ScopeInfo : public TorqueGeneratedScopeInfo<ScopeInfo, HeapObject> {
static bool NeedsPositionInfo(ScopeType type);
// Raw access by slot index. These functions rely on the fact that everything
// in ScopeInfo is tagged. Each slot is tagged-pointer sized. Slot 0 is
// 'flags', the first field defined by ScopeInfo after the standard-size
// HeapObject header.
V8_EXPORT_PRIVATE Object get(int index) const;
Object get(IsolateRoot isolate, int index) const;
// Setter that doesn't need write barrier.
void set(int index, Smi value);
// Setter with explicit barrier mode.
void set(int index, Object value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
void CopyElements(Isolate* isolate, int dst_index, ScopeInfo src,
int src_index, int len, WriteBarrierMode mode);
ObjectSlot RawFieldOfElementAt(int index);
// The number of tagged-pointer-sized slots in the ScopeInfo after its
// standard HeapObject header.
V8_EXPORT_PRIVATE int length() const;
// Conversions between offset (bytes from the beginning of the object) and
// index (number of tagged-pointer-sized slots starting after the standard
// HeapObject header).
static constexpr int OffsetOfElementAt(int index) {
return HeapObject::kHeaderSize + index * kTaggedSize;
}
// Converts byte offsets within the object to FixedArray-style indices.
static constexpr int ConvertOffsetToIndex(int offset) {
int index = (offset - HeapObject::kHeaderSize) / kTaggedSize;
CONSTEXPR_DCHECK(OffsetOfElementAt(index) == offset);
int index = (offset - FixedArray::kHeaderSize) / kTaggedSize;
CONSTEXPR_DCHECK(FixedArray::OffsetOfElementAt(index) == offset);
return index;
}
......@@ -333,12 +322,8 @@ class ScopeInfo : public TorqueGeneratedScopeInfo<ScopeInfo, HeapObject> {
InitializationFlag* init_flag = nullptr,
MaybeAssignedFlag* maybe_assigned_flag = nullptr);
static const int kFunctionNameEntries =
TorqueGeneratedFunctionVariableInfoOffsets::kSize / kTaggedSize;
static const int kPositionInfoEntries =
TorqueGeneratedPositionInfoOffsets::kSize / kTaggedSize;
static const int kModuleVariableEntryLength =
TorqueGeneratedModuleVariableOffsets::kSize / kTaggedSize;
static const int kFunctionNameEntries = 2;
static const int kPositionInfoEntries = 2;
// Properties of variables.
DEFINE_TORQUE_GENERATED_VARIABLE_PROPERTIES()
......
......@@ -99,7 +99,7 @@ struct ModuleVariable {
@generateCppClass
@generateBodyDescriptor
extern class ScopeInfo extends HeapObject {
extern class ScopeInfo extends FixedArrayBase {
const flags: SmiTagged<ScopeFlags>;
// The number of parameters. For non-function scopes this is 0.
......@@ -167,17 +167,3 @@ extern class ScopeInfo extends HeapObject {
module_variables[flags.scope_type == ScopeType::MODULE_SCOPE ? module_variable_count[0] : 0]:
ModuleVariable;
}
// Returns the index of the named local in a ScopeInfo.
// Assumes that the given name is internalized; uses pointer comparisons.
@export
macro IndexOfLocalName(scopeInfo: ScopeInfo, name: Name):
intptr labels NotFound {
const count: intptr = Convert<intptr>(scopeInfo.context_local_count);
for (let i: intptr = 0; i < count; ++i) {
if (TaggedEqual(name, scopeInfo.context_local_names[i])) {
return i;
}
}
goto NotFound;
}
......@@ -635,7 +635,7 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject object) {
} else if (object.IsContext()) {
return AddEntry(object, HeapEntry::kObject, "system / Context");
} else if (object.IsFixedArray() || object.IsFixedDoubleArray() ||
object.IsByteArray()) {
object.IsByteArray() || object.IsScopeInfo()) {
return AddEntry(object, HeapEntry::kArray, "");
} else if (object.IsHeapNumber()) {
return AddEntry(object, HeapEntry::kHeapNumber, "number");
......
......@@ -3912,9 +3912,9 @@ void CppClassGenerator::GenerateClass() {
const Field& last_field = type_->LastField();
std::string last_field_item_size =
std::get<1>(*SizeOf(last_field.name_and_type.type));
hdr_ << " inline int AllocatedSize() const;\n\n";
hdr_ << " inline int AllocatedSize();\n\n";
inl_ << "template <class D, class P>\n";
inl_ << "int " << gen_name_T_ << "::AllocatedSize() const {\n";
inl_ << "int " << gen_name_T_ << "::AllocatedSize() {\n";
inl_ << " auto slice = "
<< Callable::PrefixNameForCCOutput(
type_->GetSliceMacroName(last_field))
......@@ -3954,7 +3954,7 @@ void CppClassGenerator::GenerateClass() {
}
hdr_ << " return size;\n";
hdr_ << " }\n\n";
hdr_ << " V8_INLINE int32_t AllocatedSize() const {\n";
hdr_ << " V8_INLINE int32_t AllocatedSize() {\n";
hdr_ << " return SizeFor(";
first = true;
for (auto field : *index_fields) {
......
......@@ -459,13 +459,12 @@ TEST(HeapSnapshotCodeObjects) {
// Verify that non-compiled function doesn't contain references to "x"
// literal, while compiled function does. The scope info is stored in
// ScopeInfo objects attached to the SharedFunctionInfo.
// FixedArray objects attached to the SharedFunctionInfo.
bool compiled_references_x = false, lazy_references_x = false;
for (int i = 0, count = compiled_sfi->GetChildrenCount(); i < count; ++i) {
const v8::HeapGraphEdge* prop = compiled_sfi->GetChild(i);
const v8::HeapGraphNode* node = prop->GetToNode();
if (node->GetType() == v8::HeapGraphNode::kHidden &&
!strcmp("system / ScopeInfo", GetName(node))) {
if (node->GetType() == v8::HeapGraphNode::kArray) {
if (HasString(env->GetIsolate(), node, "x")) {
compiled_references_x = true;
break;
......@@ -475,8 +474,7 @@ TEST(HeapSnapshotCodeObjects) {
for (int i = 0, count = lazy_sfi->GetChildrenCount(); i < count; ++i) {
const v8::HeapGraphEdge* prop = lazy_sfi->GetChild(i);
const v8::HeapGraphNode* node = prop->GetToNode();
if (node->GetType() == v8::HeapGraphNode::kHidden &&
!strcmp("system / ScopeInfo", GetName(node))) {
if (node->GetType() == v8::HeapGraphNode::kArray) {
if (HasString(env->GetIsolate(), node, "x")) {
lazy_references_x = true;
break;
......
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