Commit 467eb149 authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

Drop stack-locals from ScopeInfo

For now we keep params since NewSloppyArguments uses it to figure out how to structure the arguments object. We should be able to only keep params in case we have a special case though. E.g., leaf functions with no duplicate parameters don't need special treatment. Or we simply encode the parameter index for each context slot. (I'm not sure duplicates need special treatment.)


Change-Id: Icfbb844e5331aeb93c50bc07edd58246c8aeb1d7
Reviewed-on: https://chromium-review.googlesource.com/1104420
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53802}
parent 6be6ec00
......@@ -439,7 +439,6 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
ModuleScope(isolate, handle(scope_info, isolate), ast_value_factory);
} else {
DCHECK_EQ(scope_info->scope_type(), CATCH_SCOPE);
DCHECK_EQ(scope_info->LocalCount(), 1);
DCHECK_EQ(scope_info->ContextLocalCount(), 1);
DCHECK_EQ(scope_info->ContextLocalMode(0), VariableMode::kVar);
DCHECK_EQ(scope_info->ContextLocalInitFlag(0), kCreatedInitialized);
......@@ -958,10 +957,6 @@ Variable* Scope::LookupInScopeInfo(const AstRawString* name) {
// The Scope is backed up by ScopeInfo. This means it cannot operate in a
// heap-independent mode, and all strings must be internalized immediately. So
// it's ok to get the Handle<String> here.
// If we have a serialized scope info, we might find the variable there.
// There should be no local slot with the given name.
DCHECK_LT(scope_info_->StackSlotIndex(*name_handle), 0);
bool found = false;
VariableLocation location;
......
......@@ -2028,26 +2028,9 @@ void JavaScriptFrame::Print(StringStream* accumulator,
accumulator->Add(" {\n");
// Compute the number of locals and expression stack elements.
int stack_locals_count = scope_info->StackLocalCount();
int heap_locals_count = scope_info->ContextLocalCount();
int expressions_count = ComputeExpressionsCount();
// Print stack-allocated local variables.
if (stack_locals_count > 0) {
accumulator->Add(" // stack-allocated locals\n");
}
for (int i = 0; i < stack_locals_count; i++) {
accumulator->Add(" var ");
accumulator->PrintName(scope_info->StackLocalName(i));
accumulator->Add(" = ");
if (i < expressions_count) {
accumulator->Add("%o", GetExpression(i));
} else {
accumulator->Add("// no expression found - inconsistent frame?");
}
accumulator->Add("\n");
}
// Try to get hold of the context of this frame.
Context* context = nullptr;
if (this->context() != nullptr && this->context()->IsContext()) {
......@@ -2081,11 +2064,10 @@ void JavaScriptFrame::Print(StringStream* accumulator,
}
// Print the expression stack.
int expressions_start = stack_locals_count;
if (expressions_start < expressions_count) {
if (0 < expressions_count) {
accumulator->Add(" // expression stack (top to bottom)\n");
}
for (int i = expressions_count - 1; i >= expressions_start; i--) {
for (int i = expressions_count - 1; i >= 0; i--) {
accumulator->Add(" [%02d] : %o\n", i, GetExpression(i));
}
......
......@@ -1171,11 +1171,9 @@ class DebugInfoSection : public DebugSection {
fb_block_size.set(static_cast<uint32_t>(w->position() - fb_block_start));
int params = scope->ParameterCount();
int slots = scope->StackLocalCount();
int context_slots = scope->ContextLocalCount();
// The real slot ID is internal_slots + context_slot_id.
int internal_slots = Context::MIN_CONTEXT_SLOTS;
int locals = scope->StackLocalCount();
int current_abbreviation = 4;
for (int param = 0; param < params; ++param) {
......@@ -1195,13 +1193,6 @@ class DebugInfoSection : public DebugSection {
EmbeddedVector<char, 256> buffer;
StringBuilder builder(buffer.start(), buffer.length());
for (int slot = 0; slot < slots; ++slot) {
w->WriteULEB128(current_abbreviation++);
builder.Reset();
builder.AddFormatted("slot%d", slot);
w->WriteString(builder.Finalize());
}
// See contexts.h for more information.
DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, 4);
DCHECK_EQ(Context::SCOPE_INFO_INDEX, 0);
......@@ -1226,20 +1217,6 @@ class DebugInfoSection : public DebugSection {
w->WriteString(builder.Finalize());
}
for (int local = 0; local < locals; ++local) {
w->WriteULEB128(current_abbreviation++);
w->WriteString(
scope->StackLocalName(local)->ToCString(DISALLOW_NULLS).get());
w->Write<uint32_t>(ty_offset);
Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
uintptr_t block_start = w->position();
w->Write<uint8_t>(DW_OP_fbreg);
w->WriteSLEB128(
JavaScriptFrameConstants::kLocal0Offset -
kPointerSize * local);
block_size.set(static_cast<uint32_t>(w->position() - block_start));
}
{
w->WriteULEB128(current_abbreviation++);
w->WriteString("__function");
......@@ -1370,13 +1347,11 @@ class DebugAbbrevSection : public DebugSection {
if (extra_info) {
ScopeInfo* scope = desc_->scope_info();
int params = scope->ParameterCount();
int slots = scope->StackLocalCount();
int context_slots = scope->ContextLocalCount();
// The real slot ID is internal_slots + context_slot_id.
int internal_slots = Context::MIN_CONTEXT_SLOTS;
int locals = scope->StackLocalCount();
// Total children is params + slots + context_slots + internal_slots +
// locals + 2 (__function and __context).
// Total children is params + context_slots + internal_slots + 2
// (__function and __context).
// The extra duplication below seems to be necessary to keep
// gdb from getting upset on OSX.
......@@ -1408,10 +1383,6 @@ class DebugAbbrevSection : public DebugSection {
WriteVariableAbbreviation(w, current_abbreviation++, true, true);
}
for (int slot = 0; slot < slots; ++slot) {
WriteVariableAbbreviation(w, current_abbreviation++, false, false);
}
for (int internal_slot = 0;
internal_slot < internal_slots;
++internal_slot) {
......@@ -1424,10 +1395,6 @@ class DebugAbbrevSection : public DebugSection {
WriteVariableAbbreviation(w, current_abbreviation++, false, false);
}
for (int local = 0; local < locals; ++local) {
WriteVariableAbbreviation(w, current_abbreviation++, true, false);
}
// The function.
WriteVariableAbbreviation(w, current_abbreviation++, true, false);
......
......@@ -1993,7 +1993,6 @@ void ScopeInfo::ScopeInfoPrint(std::ostream& os) { // NOLINT
int flags = Flags();
os << "\n - parameters: " << ParameterCount();
os << "\n - stack locals: " << StackLocalCount();
os << "\n - context locals : " << ContextLocalCount();
os << "\n - scope type: " << scope_type();
......@@ -2030,8 +2029,6 @@ void ScopeInfo::ScopeInfoPrint(std::ostream& os) { // NOLINT
if (length() > 0) {
PrintScopeInfoList(this, os, "parameters", 0, ParameterNamesIndex(),
ParameterCount());
PrintScopeInfoList(this, os, "stack slots", 0, StackLocalNamesIndex(),
StackLocalCount());
PrintScopeInfoList(this, os, "context slots", Context::MIN_CONTEXT_SLOTS,
ContextLocalNamesIndex(), ContextLocalCount());
// TODO(neis): Print module stuff if present.
......
......@@ -63,20 +63,14 @@ bool ScopeInfo::Equals(ScopeInfo* other) const {
Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
MaybeHandle<ScopeInfo> outer_scope) {
// Collect variables.
int stack_local_count = 0;
int context_local_count = 0;
int module_vars_count = 0;
// Stack allocated block scope variables are allocated in the parent
// declaration scope, but are recorded in the block scope's scope info. First
// slot index indicates at which offset a particular scope starts in the
// parent declaration scope.
int first_slot_index = 0;
for (Variable* var : *scope->locals()) {
switch (var->location()) {
case VariableLocation::LOCAL:
if (stack_local_count == 0) first_slot_index = var->index();
stack_local_count++;
break;
case VariableLocation::CONTEXT:
context_local_count++;
break;
......@@ -146,8 +140,7 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
const int parameter_count = scope->num_parameters();
const bool has_outer_scope_info = !outer_scope.is_null();
const int length = kVariablePartIndex + parameter_count +
(1 + stack_local_count) + 2 * context_local_count +
(has_receiver ? 1 : 0) +
2 * context_local_count + (has_receiver ? 1 : 0) +
(has_function_name ? kFunctionNameEntries : 0) +
(has_inferred_function_name ? 1 : 0) +
(has_position_info ? kPositionInfoEntries : 0) +
......@@ -191,7 +184,6 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
scope_info->SetFlags(flags);
scope_info->SetParameterCount(parameter_count);
scope_info->SetStackLocalCount(stack_local_count);
scope_info->SetContextLocalCount(context_local_count);
int index = kVariablePartIndex;
......@@ -204,28 +196,14 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
}
}
// Add stack locals' names, context locals' names and info, module variables'
// names and info. We are assuming that the stack locals' slots are allocated
// in increasing order, so we can simply add them to the ScopeInfo object.
// Add context locals' names and info, module variables' names and info.
// Context locals are added using their index.
DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex());
scope_info->set(index++, Smi::FromInt(first_slot_index));
DCHECK_EQ(index, scope_info->StackLocalNamesIndex());
int stack_local_base = index;
int context_local_base = stack_local_base + stack_local_count;
int context_local_base = index;
int context_local_info_base = context_local_base + context_local_count;
int module_var_entry = scope_info->ModuleVariablesIndex();
for (Variable* var : *scope->locals()) {
switch (var->location()) {
case VariableLocation::LOCAL: {
int local_index = var->index() - first_slot_index;
DCHECK_LE(0, local_index);
DCHECK_LT(local_index, stack_local_count);
scope_info->set(stack_local_base + local_index, *var->name());
break;
}
case VariableLocation::CONTEXT: {
// Due to duplicate parameters, context locals aren't guaranteed to come
// in order.
......@@ -259,7 +237,7 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
}
}
index += stack_local_count + 2 * context_local_count;
index += 2 * context_local_count;
// If the receiver is allocated, add its index.
DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
......@@ -328,7 +306,7 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
Handle<ScopeInfo> ScopeInfo::CreateForWithScope(
Isolate* isolate, MaybeHandle<ScopeInfo> outer_scope) {
const bool has_outer_scope_info = !outer_scope.is_null();
const int length = kVariablePartIndex + 1 + (has_outer_scope_info ? 1 : 0);
const int length = kVariablePartIndex + (has_outer_scope_info ? 1 : 0);
Factory* factory = isolate->factory();
Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
......@@ -347,14 +325,10 @@ Handle<ScopeInfo> ScopeInfo::CreateForWithScope(
scope_info->SetFlags(flags);
scope_info->SetParameterCount(0);
scope_info->SetStackLocalCount(0);
scope_info->SetContextLocalCount(0);
int index = kVariablePartIndex;
DCHECK_EQ(index, scope_info->ParameterNamesIndex());
DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex());
scope_info->set(index++, Smi::kZero);
DCHECK_EQ(index, scope_info->StackLocalNamesIndex());
DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
DCHECK_EQ(index, scope_info->InferredFunctionNameIndex());
......@@ -386,15 +360,13 @@ Handle<ScopeInfo> ScopeInfo::CreateForBootstrapping(Isolate* isolate,
DCHECK(type == SCRIPT_SCOPE || type == FUNCTION_SCOPE);
const int parameter_count = 0;
const int stack_local_count = 0;
const bool is_empty_function = type == FUNCTION_SCOPE;
const int context_local_count = is_empty_function ? 0 : 1;
const bool has_receiver = !is_empty_function;
const bool has_inferred_function_name = is_empty_function;
const bool has_position_info = true;
const int length = kVariablePartIndex + parameter_count +
(1 + stack_local_count) + 2 * context_local_count +
(has_receiver ? 1 : 0) +
2 * context_local_count + (has_receiver ? 1 : 0) +
(is_empty_function ? kFunctionNameEntries : 0) +
(has_inferred_function_name ? 1 : 0) +
(has_position_info ? kPositionInfoEntries : 0);
......@@ -417,14 +389,9 @@ Handle<ScopeInfo> ScopeInfo::CreateForBootstrapping(Isolate* isolate,
IsDebugEvaluateScopeField::encode(false);
scope_info->SetFlags(flags);
scope_info->SetParameterCount(parameter_count);
scope_info->SetStackLocalCount(stack_local_count);
scope_info->SetContextLocalCount(context_local_count);
int index = kVariablePartIndex;
const int first_slot_index = 0;
DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex());
scope_info->set(index++, Smi::FromInt(first_slot_index));
DCHECK_EQ(index, scope_info->StackLocalNamesIndex());
// Here we add info for context-allocated "this".
DCHECK_EQ(index, scope_info->ContextLocalNamesIndex());
......@@ -497,19 +464,6 @@ bool ScopeInfo::is_declaration_scope() const {
return DeclarationScopeField::decode(Flags());
}
int ScopeInfo::LocalCount() const {
return StackLocalCount() + ContextLocalCount();
}
int ScopeInfo::StackSlotCount() const {
if (length() > 0) {
bool function_name_stack_slot =
FunctionVariableField::decode(Flags()) == STACK;
return StackLocalCount() + (function_name_stack_slot ? 1 : 0);
}
return 0;
}
int ScopeInfo::ContextLength() const {
if (length() > 0) {
int context_locals = ContextLocalCount();
......@@ -659,29 +613,6 @@ String* ScopeInfo::ParameterName(int var) const {
return String::cast(get(info_index));
}
String* ScopeInfo::LocalName(int var) const {
DCHECK_LE(0, var);
DCHECK_LT(var, LocalCount());
DCHECK(StackLocalNamesIndex() + StackLocalCount() ==
ContextLocalNamesIndex());
int info_index = StackLocalNamesIndex() + var;
return String::cast(get(info_index));
}
String* ScopeInfo::StackLocalName(int var) const {
DCHECK_LE(0, var);
DCHECK_LT(var, StackLocalCount());
int info_index = StackLocalNamesIndex() + var;
return String::cast(get(info_index));
}
int ScopeInfo::StackLocalIndex(int var) const {
DCHECK_LE(0, var);
DCHECK_LT(var, StackLocalCount());
int first_slot_index = Smi::ToInt(get(StackLocalFirstSlotIndex()));
return first_slot_index + var;
}
String* ScopeInfo::ContextLocalName(int var) const {
DCHECK_LE(0, var);
DCHECK_LT(var, ContextLocalCount());
......@@ -723,20 +654,6 @@ bool ScopeInfo::VariableIsSynthetic(String* name) {
name->Equals(name->GetHeap()->this_string());
}
int ScopeInfo::StackSlotIndex(String* name) const {
DCHECK(name->IsInternalizedString());
if (length() == 0) return -1;
int first_slot_index = Smi::ToInt(get(StackLocalFirstSlotIndex()));
int start = StackLocalNamesIndex();
int end = start + StackLocalCount();
for (int i = start; i < end; ++i) {
if (name == get(i)) {
return i - start + first_slot_index;
}
}
return -1;
}
int ScopeInfo::ModuleIndex(Handle<String> name, VariableMode* mode,
InitializationFlag* init_flag,
MaybeAssignedFlag* maybe_assigned_flag) {
......@@ -850,16 +767,8 @@ int ScopeInfo::ParameterNamesIndex() const {
return kVariablePartIndex;
}
int ScopeInfo::StackLocalFirstSlotIndex() const {
return ParameterNamesIndex() + ParameterCount();
}
int ScopeInfo::StackLocalNamesIndex() const {
return StackLocalFirstSlotIndex() + 1;
}
int ScopeInfo::ContextLocalNamesIndex() const {
return StackLocalNamesIndex() + StackLocalCount();
return ParameterNamesIndex() + ParameterCount();
}
int ScopeInfo::ContextLocalInfosIndex() const {
......
......@@ -49,16 +49,6 @@ class ScopeInfo : public FixedArray {
// Does this scope make a sloppy eval call?
bool CallsSloppyEval() const;
// Return the total number of locals allocated on the stack and in the
// context. This includes the parameters that are allocated in the context.
int LocalCount() const;
// Return the number of stack slots for code. This number consists of two
// parts:
// 1. One stack slot per stack allocated local.
// 2. One stack slot for the function name if it is stack allocated.
int StackSlotCount() const;
// Return the number of context slots for code if a context is allocated. This
// number consists of three parts:
// 1. Size of fixed header for every context: Context::MIN_CONTEXT_SLOTS
......@@ -121,15 +111,6 @@ class ScopeInfo : public FixedArray {
// Return the name of the given parameter.
String* ParameterName(int var) const;
// Return the name of the given local.
String* LocalName(int var) const;
// Return the name of the given stack local.
String* StackLocalName(int var) const;
// Return the name of the given stack local.
int StackLocalIndex(int var) const;
// Return the name of the given context local.
String* ContextLocalName(int var) const;
......@@ -146,12 +127,6 @@ class ScopeInfo : public FixedArray {
// exposed to the user in a debugger.
static bool VariableIsSynthetic(String* name);
// Lookup support for serialized scope info. Returns the
// the stack slot index for a given slot name if the slot is
// present; otherwise returns a value < 0. The name must be an internalized
// string.
int StackSlotIndex(String* name) const;
// Lookup support for serialized scope info. Returns the local context slot
// index for a given slot name if the slot is present; otherwise
// returns a value < 0. The name must be an internalized string.
......@@ -217,13 +192,11 @@ class ScopeInfo : public FixedArray {
// numeric and occupies one array slot.
// 1. A set of properties of the scope.
// 2. The number of parameters. For non-function scopes this is 0.
// 3. The number of non-parameter variables allocated on the stack.
// 4. The number of non-parameter and parameter variables allocated in the
// 3. The number of non-parameter and parameter variables allocated in the
// context.
#define FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(V) \
V(Flags) \
V(ParameterCount) \
V(StackLocalCount) \
V(ContextLocalCount)
#define FIELD_ACCESSORS(name) \
......@@ -246,48 +219,37 @@ class ScopeInfo : public FixedArray {
// slot is used per parameter, so in total this part occupies
// ParameterCount() slots in the array. For other scopes than function
// scopes ParameterCount() is 0.
// 2. StackLocalFirstSlot:
// Index of a first stack slot for stack local. Stack locals belonging to
// this scope are located on a stack at slots starting from this index.
// 3. StackLocalNames:
// Contains the names of local variables that are allocated on the stack,
// in increasing order of the stack slot index. First local variable has a
// stack slot index defined in StackLocalFirstSlot (point 2 above).
// One slot is used per stack local, so in total this part occupies
// StackLocalCount() slots in the array.
// 4. ContextLocalNames:
// 2. ContextLocalNames:
// Contains the names of local variables and parameters that are allocated
// in the context. They are stored in increasing order of the context slot
// index starting with Context::MIN_CONTEXT_SLOTS. One slot is used per
// context local, so in total this part occupies ContextLocalCount() slots
// in the array.
// 5. ContextLocalInfos:
// 3. ContextLocalInfos:
// Contains the variable modes and initialization flags corresponding to
// the context locals in ContextLocalNames. One slot is used per
// context local, so in total this part occupies ContextLocalCount()
// slots in the array.
// 6. ReceiverInfo:
// 4. ReceiverInfo:
// If the scope binds a "this" value, one slot is reserved to hold the
// context or stack slot index for the variable.
// 7. FunctionNameInfo:
// 5. FunctionNameInfo:
// If the scope belongs to a named function expression this part contains
// information about the function variable. It always occupies two array
// slots: a. The name of the function variable.
// b. The context or stack slot index for the variable.
// 8. InferredFunctionName:
// 6. InferredFunctionName:
// Contains the function's inferred name.
// 9. SourcePosition:
// 7. SourcePosition:
// Contains two slots with a) the startPosition and b) the endPosition if
// the scope belongs to a function or script.
// 10. OuterScopeInfoIndex:
// 8. OuterScopeInfoIndex:
// The outer scope's ScopeInfo or the hole if there's none.
// 11. ModuleInfo, ModuleVariableCount, and ModuleVariables:
// 9. ModuleInfo, ModuleVariableCount, and ModuleVariables:
// For a module scope, this part contains the ModuleInfo, the number of
// MODULE-allocated variables, and the metadata of those variables. For
// non-module scopes it is empty.
int ParameterNamesIndex() const;
int StackLocalFirstSlotIndex() const;
int StackLocalNamesIndex() const;
int ContextLocalNamesIndex() const;
int ContextLocalInfosIndex() const;
int ReceiverInfoIndex() const;
......
......@@ -163,8 +163,6 @@ TEST_F(TestWithNativeContext, EmptyFunctionScopeInfo) {
EXPECT_EQ(scope_info->Flags(), empty_function_scope_info->Flags());
EXPECT_EQ(scope_info->ParameterCount(),
empty_function_scope_info->ParameterCount());
EXPECT_EQ(scope_info->StackLocalCount(),
empty_function_scope_info->StackLocalCount());
EXPECT_EQ(scope_info->ContextLocalCount(),
empty_function_scope_info->ContextLocalCount());
}
......
......@@ -184,8 +184,6 @@ consts_misc = [
{ 'name': 'scopeinfo_idx_nparams',
'value': 'ScopeInfo::kParameterCount' },
{ 'name': 'scopeinfo_idx_nstacklocals',
'value': 'ScopeInfo::kStackLocalCount' },
{ 'name': 'scopeinfo_idx_ncontextlocals',
'value': 'ScopeInfo::kContextLocalCount' },
{ 'name': 'scopeinfo_idx_first_vars',
......
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