Commit 2fdc823a authored by Victor Gomes's avatar Victor Gomes Committed by V8 LUCI CQ

[runtime] Update SavedClassVariable in ScopeInfo

ScopeInfo will contain either inlined (array) local names or
a hash table (names => index) containing the local names.

If we have the local names inlined, we should save the class
variable context slot index.

If we have a hash table instead, we should save the class
variable offset in the internal hash table storage.

Bug: v8:12315
Change-Id: Ifd9ae4f285d11fc034e8560c8558038b38a474fb
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3386599Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78621}
parent 549ee6f3
...@@ -206,11 +206,10 @@ ClassScope::ClassScope(IsolateT* isolate, Zone* zone, ...@@ -206,11 +206,10 @@ ClassScope::ClassScope(IsolateT* isolate, Zone* zone,
// If the class variable is context-allocated and its index is // If the class variable is context-allocated and its index is
// saved for deserialization, deserialize it. // saved for deserialization, deserialize it.
if (scope_info->HasSavedClassVariableIndex()) { if (scope_info->HasSavedClassVariable()) {
int index = scope_info->SavedClassVariableContextLocalIndex(); String name;
DCHECK_GE(index, 0); int index;
DCHECK_LT(index, scope_info->ContextLocalCount()); std::tie(name, index) = scope_info->SavedClassVariable();
String name = scope_info->ContextLocalName(index);
DCHECK_EQ(scope_info->ContextLocalMode(index), VariableMode::kConst); DCHECK_EQ(scope_info->ContextLocalMode(index), VariableMode::kConst);
DCHECK_EQ(scope_info->ContextLocalInitFlag(index), DCHECK_EQ(scope_info->ContextLocalInitFlag(index),
InitializationFlag::kNeedsInitialization); InitializationFlag::kNeedsInitialization);
......
...@@ -2350,7 +2350,7 @@ void ScopeInfo::ScopeInfoPrint(std::ostream& os) { ...@@ -2350,7 +2350,7 @@ void ScopeInfo::ScopeInfoPrint(std::ostream& os) {
os << "\n - receiver: " << ReceiverVariableBits::decode(flags); os << "\n - receiver: " << ReceiverVariableBits::decode(flags);
} }
if (HasClassBrand()) os << "\n - has class brand"; if (HasClassBrand()) os << "\n - has class brand";
if (HasSavedClassVariableIndex()) os << "\n - has saved class variable index"; if (HasSavedClassVariable()) os << "\n - has saved class variable";
if (HasNewTarget()) os << "\n - needs new target"; if (HasNewTarget()) os << "\n - needs new target";
if (HasFunctionName()) { if (HasFunctionName()) {
os << "\n - function name(" << FunctionVariableBits::decode(flags) << "): "; os << "\n - function name(" << FunctionVariableBits::decode(flags) << "): ";
......
...@@ -204,8 +204,7 @@ Handle<ScopeInfo> ScopeInfo::Create(IsolateT* isolate, Zone* zone, Scope* scope, ...@@ -204,8 +204,7 @@ Handle<ScopeInfo> ScopeInfo::Create(IsolateT* isolate, Zone* zone, Scope* scope,
DeclarationScopeBit::encode(scope->is_declaration_scope()) | DeclarationScopeBit::encode(scope->is_declaration_scope()) |
ReceiverVariableBits::encode(receiver_info) | ReceiverVariableBits::encode(receiver_info) |
HasClassBrandBit::encode(has_brand) | HasClassBrandBit::encode(has_brand) |
HasSavedClassVariableIndexBit::encode( HasSavedClassVariableBit::encode(should_save_class_variable_index) |
should_save_class_variable_index) |
HasNewTargetBit::encode(has_new_target) | HasNewTargetBit::encode(has_new_target) |
FunctionVariableBits::encode(function_name_info) | FunctionVariableBits::encode(function_name_info) |
HasInferredFunctionNameBit::encode(has_inferred_function_name) | HasInferredFunctionNameBit::encode(has_inferred_function_name) |
...@@ -397,8 +396,7 @@ Handle<ScopeInfo> ScopeInfo::CreateForWithScope( ...@@ -397,8 +396,7 @@ Handle<ScopeInfo> ScopeInfo::CreateForWithScope(
DeclarationScopeBit::encode(false) | DeclarationScopeBit::encode(false) |
ReceiverVariableBits::encode(VariableAllocationInfo::NONE) | ReceiverVariableBits::encode(VariableAllocationInfo::NONE) |
HasClassBrandBit::encode(false) | HasClassBrandBit::encode(false) |
HasSavedClassVariableIndexBit::encode(false) | HasSavedClassVariableBit::encode(false) | HasNewTargetBit::encode(false) |
HasNewTargetBit::encode(false) |
FunctionVariableBits::encode(VariableAllocationInfo::NONE) | FunctionVariableBits::encode(VariableAllocationInfo::NONE) |
IsAsmModuleBit::encode(false) | HasSimpleParametersBit::encode(true) | IsAsmModuleBit::encode(false) | HasSimpleParametersBit::encode(true) |
FunctionKindBits::encode(FunctionKind::kNormalFunction) | FunctionKindBits::encode(FunctionKind::kNormalFunction) |
...@@ -471,8 +469,7 @@ Handle<ScopeInfo> ScopeInfo::CreateForBootstrapping(Isolate* isolate, ...@@ -471,8 +469,7 @@ Handle<ScopeInfo> ScopeInfo::CreateForBootstrapping(Isolate* isolate,
ReceiverVariableBits::encode(is_script ? VariableAllocationInfo::CONTEXT ReceiverVariableBits::encode(is_script ? VariableAllocationInfo::CONTEXT
: VariableAllocationInfo::UNUSED) | : VariableAllocationInfo::UNUSED) |
HasClassBrandBit::encode(false) | HasClassBrandBit::encode(false) |
HasSavedClassVariableIndexBit::encode(false) | HasSavedClassVariableBit::encode(false) | HasNewTargetBit::encode(false) |
HasNewTargetBit::encode(false) |
FunctionVariableBits::encode(is_empty_function FunctionVariableBits::encode(is_empty_function
? VariableAllocationInfo::UNUSED ? VariableAllocationInfo::UNUSED
: VariableAllocationInfo::NONE) | : VariableAllocationInfo::NONE) |
...@@ -685,8 +682,8 @@ bool ScopeInfo::HasClassBrand() const { ...@@ -685,8 +682,8 @@ bool ScopeInfo::HasClassBrand() const {
return HasClassBrandBit::decode(Flags()); return HasClassBrandBit::decode(Flags());
} }
bool ScopeInfo::HasSavedClassVariableIndex() const { bool ScopeInfo::HasSavedClassVariable() const {
return HasSavedClassVariableIndexBit::decode(Flags()); return HasSavedClassVariableBit::decode(Flags());
} }
bool ScopeInfo::HasNewTarget() const { bool ScopeInfo::HasNewTarget() const {
...@@ -919,12 +916,21 @@ int ScopeInfo::ContextSlotIndex(ScopeInfo scope_info, String name, ...@@ -919,12 +916,21 @@ int ScopeInfo::ContextSlotIndex(ScopeInfo scope_info, String name,
return -1; return -1;
} }
int ScopeInfo::SavedClassVariableContextLocalIndex() const { std::pair<String, int> ScopeInfo::SavedClassVariable() const {
if (HasSavedClassVariableIndexBit::decode(Flags())) { DCHECK(HasSavedClassVariableBit::decode(Flags()));
int index = saved_class_variable_info(); if (HasInlinedLocalNames()) {
return index - Context::MIN_CONTEXT_SLOTS; // The saved class variable info corresponds to the context slot index.
int index = saved_class_variable_info() - Context::MIN_CONTEXT_SLOTS;
DCHECK_GE(index, 0);
DCHECK_LT(index, ContextLocalCount());
String name = ContextLocalName(index);
return std::make_pair(name, index);
} else {
// The saved class variable info corresponds to the offset in the hash
// table storage.
// TODO(victorgomes, v8:12315): Implement this once we have a hash table.
UNREACHABLE();
} }
return -1;
} }
int ScopeInfo::ReceiverContextSlotIndex() const { int ScopeInfo::ReceiverContextSlotIndex() const {
......
...@@ -91,9 +91,9 @@ class ScopeInfo : public TorqueGeneratedScopeInfo<ScopeInfo, HeapObject> { ...@@ -91,9 +91,9 @@ class ScopeInfo : public TorqueGeneratedScopeInfo<ScopeInfo, HeapObject> {
// Does this scope has class brand (for private methods)? // Does this scope has class brand (for private methods)?
bool HasClassBrand() const; bool HasClassBrand() const;
// Does this scope contain a saved class variable context local slot index // Does this scope contain a saved class variable for checking receivers of
// for checking receivers of static private methods? // static private methods?
bool HasSavedClassVariableIndex() const; bool HasSavedClassVariable() const;
// Does this scope declare a "new.target" binding? // Does this scope declare a "new.target" binding?
bool HasNewTarget() const; bool HasNewTarget() const;
...@@ -140,6 +140,12 @@ class ScopeInfo : public TorqueGeneratedScopeInfo<ScopeInfo, HeapObject> { ...@@ -140,6 +140,12 @@ class ScopeInfo : public TorqueGeneratedScopeInfo<ScopeInfo, HeapObject> {
SourceTextModuleInfo ModuleDescriptorInfo() const; SourceTextModuleInfo ModuleDescriptorInfo() const;
// Return true if the local names are inlined in the scope info object.
bool HasInlinedLocalNames() const {
// TODO(victorgomes, v8:12315): Currently, local names are always inlined.
return true;
}
// Return the name of the given context local. // Return the name of the given context local.
String ContextLocalName(int var) const; String ContextLocalName(int var) const;
...@@ -193,11 +199,10 @@ class ScopeInfo : public TorqueGeneratedScopeInfo<ScopeInfo, HeapObject> { ...@@ -193,11 +199,10 @@ class ScopeInfo : public TorqueGeneratedScopeInfo<ScopeInfo, HeapObject> {
// Returns the first parameter context slot index. // Returns the first parameter context slot index.
int ParametersStartIndex() const; int ParametersStartIndex() const;
// Lookup support for serialized scope info. Returns the index of the // Lookup support for serialized scope info. Returns the name and index of
// saved class variable in context local slots if scope is a class scope // the saved class variable in context local slots if scope is a class scope
// and it contains static private methods that may be accessed. // and it contains static private methods that may be accessed.
// Otherwise returns a value < 0. std::pair<String, int> SavedClassVariable() const;
int SavedClassVariableContextLocalIndex() const;
FunctionKind function_kind() const; FunctionKind function_kind() const;
......
...@@ -54,7 +54,7 @@ bitfield struct ScopeFlags extends uint31 { ...@@ -54,7 +54,7 @@ bitfield struct ScopeFlags extends uint31 {
declaration_scope: bool: 1 bit; declaration_scope: bool: 1 bit;
receiver_variable: VariableAllocationInfo: 2 bit; receiver_variable: VariableAllocationInfo: 2 bit;
has_class_brand: bool: 1 bit; has_class_brand: bool: 1 bit;
has_saved_class_variable_index: bool: 1 bit; has_saved_class_variable: bool: 1 bit;
has_new_target: bool: 1 bit; has_new_target: bool: 1 bit;
// TODO(cbruni): Combine with function variable field when only storing the // TODO(cbruni): Combine with function variable field when only storing the
// function name. // function name.
...@@ -119,8 +119,9 @@ extern class ScopeInfo extends HeapObject { ...@@ -119,8 +119,9 @@ extern class ScopeInfo extends HeapObject {
// If the scope is a class scope and it has static private methods that // If the scope is a class scope and it has static private methods that
// may be accessed directly or through eval, one slot is reserved to hold // may be accessed directly or through eval, one slot is reserved to hold
// the context slot index for the class variable. // the offset in the field storage of the hash table (or the slot index if
saved_class_variable_info?[flags.has_saved_class_variable_index]: Smi; // local names are inlined) for the class variable.
saved_class_variable_info?[flags.has_saved_class_variable]: Smi;
// If the scope belongs to a named function expression this part contains // If the scope belongs to a named function expression this part contains
// information about the function variable. It always occupies two array // information about the function variable. It always occupies two array
......
...@@ -1346,7 +1346,7 @@ Handle<ScopeInfo> WebSnapshotDeserializer::CreateScopeInfo( ...@@ -1346,7 +1346,7 @@ Handle<ScopeInfo> WebSnapshotDeserializer::CreateScopeInfo(
ScopeInfo::DeclarationScopeBit::encode(false) | ScopeInfo::DeclarationScopeBit::encode(false) |
ScopeInfo::ReceiverVariableBits::encode(VariableAllocationInfo::NONE) | ScopeInfo::ReceiverVariableBits::encode(VariableAllocationInfo::NONE) |
ScopeInfo::HasClassBrandBit::encode(false) | ScopeInfo::HasClassBrandBit::encode(false) |
ScopeInfo::HasSavedClassVariableIndexBit::encode(false) | ScopeInfo::HasSavedClassVariableBit::encode(false) |
ScopeInfo::HasNewTargetBit::encode(false) | ScopeInfo::HasNewTargetBit::encode(false) |
ScopeInfo::FunctionVariableBits::encode(VariableAllocationInfo::NONE) | ScopeInfo::FunctionVariableBits::encode(VariableAllocationInfo::NONE) |
ScopeInfo::HasInferredFunctionNameBit::encode(false) | ScopeInfo::HasInferredFunctionNameBit::encode(false) |
......
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