Replace CollectVariables with locals(), update callsites to walk locals instead

This additionally gets rid of old approach to global shortcuts.

BUG=v8:5209

Review-Url: https://codereview.chromium.org/2287173002
Cr-Commit-Position: refs/heads/master@{#38980}
This commit is contained in:
verwaest 2016-08-29 05:49:18 -07:00 committed by Commit bot
parent ee7dc92f9e
commit 1493bc8c8b
27 changed files with 143 additions and 317 deletions

View File

@ -83,18 +83,14 @@ bool Expression::IsNullLiteral() const {
}
bool Expression::IsUndefinedLiteral() const {
if (IsLiteral()) {
if (AsLiteral()->raw_value()->IsUndefined()) {
return true;
}
}
if (IsLiteral() && AsLiteral()->raw_value()->IsUndefined()) return true;
const VariableProxy* var_proxy = AsVariableProxy();
if (var_proxy == NULL) return false;
if (var_proxy == nullptr) return false;
Variable* var = var_proxy->var();
// The global identifier "undefined" is immutable. Everything
// else could be reassigned.
return var != NULL && var->IsUnallocatedOrGlobalSlot() &&
return var != NULL && var->IsUnallocated() &&
var_proxy->raw_name()->IsOneByteEqualTo("undefined");
}
@ -913,7 +909,7 @@ Call::CallType Call::GetCallType() const {
if (proxy != NULL) {
if (is_possibly_eval()) {
return POSSIBLY_EVAL_CALL;
} else if (proxy->var()->IsUnallocatedOrGlobalSlot()) {
} else if (proxy->var()->IsUnallocated()) {
return GLOBAL_CALL;
} else if (proxy->var()->IsLookupSlot()) {
return LOOKUP_SLOT_CALL;

View File

@ -1790,15 +1790,6 @@ class Call final : public Expression {
return !target_.is_null();
}
bool global_call() const {
VariableProxy* proxy = expression_->AsVariableProxy();
return proxy != NULL && proxy->var()->IsUnallocatedOrGlobalSlot();
}
bool known_global_function() const {
return global_call() && !target_.is_null();
}
Handle<JSFunction> target() { return target_; }
Handle<AllocationSite> allocation_site() { return allocation_site_; }

View File

@ -15,16 +15,26 @@ namespace internal {
Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
Scope* scope) {
// Collect variables.
ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone);
ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone);
ZoneList<Variable*> context_globals(scope->ContextGlobalCount(), zone);
scope->CollectVariables(&stack_locals, &context_locals, &context_globals);
const int stack_local_count = stack_locals.length();
const int context_local_count = context_locals.length();
const int context_global_count = context_globals.length();
ZoneList<Variable*>* locals = scope->locals();
int stack_local_count = 0;
int context_local_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 (int i = 0; i < locals->length(); i++) {
Variable* var = locals->at(i);
if (var->IsStackLocal()) {
if (stack_local_count == 0) first_slot_index = var->index();
stack_local_count++;
} else if (var->IsContextSlot()) {
context_local_count++;
}
}
// Make sure we allocate the correct amount.
DCHECK_EQ(scope->ContextLocalCount(), context_local_count);
DCHECK_EQ(scope->ContextGlobalCount(), context_global_count);
// Determine use and location of the "this" binding if it is present.
VariableAllocationInfo receiver_info;
@ -66,14 +76,12 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
function_name_info = NONE;
function_variable_mode = VAR;
}
DCHECK(context_global_count == 0 || scope->scope_type() == SCRIPT_SCOPE);
const bool has_function_name = function_name_info != NONE;
const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT;
const int parameter_count = scope->num_parameters();
const int length = kVariablePartIndex + parameter_count +
(1 + stack_local_count) + 2 * context_local_count +
2 * context_global_count +
(has_receiver ? 1 : 0) + (has_function_name ? 2 : 0);
Factory* factory = isolate->factory();
@ -108,7 +116,6 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
scope_info->SetParameterCount(parameter_count);
scope_info->SetStackLocalCount(stack_local_count);
scope_info->SetContextLocalCount(context_local_count);
scope_info->SetContextGlobalCount(context_global_count);
int index = kVariablePartIndex;
// Add parameters.
@ -120,59 +127,44 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
}
}
// Add stack locals' names. We are assuming that the stack locals'
// slots are allocated in increasing order, so we can simply add
// them to the ScopeInfo object.
int first_slot_index;
if (stack_local_count > 0) {
first_slot_index = stack_locals[0]->index();
} else {
first_slot_index = 0;
}
// Add stack locals' names, context locals' 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. 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->StackLocalEntriesIndex());
for (int i = 0; i < stack_local_count; ++i) {
DCHECK(stack_locals[i]->index() == first_slot_index + i);
scope_info->set(index++, *stack_locals[i]->name());
int stack_local_base = index;
int context_local_base = stack_local_base + stack_local_count;
int context_local_info_base = context_local_base + context_local_count;
for (int i = 0; i < locals->length(); ++i) {
Variable* var = locals->at(i);
if (var->IsStackLocal()) {
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());
} else if (var->IsContextSlot()) {
// Due to duplicate parameters, context locals aren't guaranteed to come
// in order.
int local_index = var->index() - Context::MIN_CONTEXT_SLOTS;
DCHECK_LE(0, local_index);
DCHECK_LT(local_index, context_local_count);
uint32_t info = VariableModeField::encode(var->mode()) |
InitFlagField::encode(var->initialization_flag()) |
MaybeAssignedFlagField::encode(var->maybe_assigned());
scope_info->set(context_local_base + local_index, *var->name());
scope_info->set(context_local_info_base + local_index,
Smi::FromInt(info));
}
}
// Add context locals' names and info. Info lies beyond context globals'
// names.
// Make sure to store them in the order that they appear in the context.
DCHECK_EQ(index, scope_info->ContextLocalNameEntriesIndex());
int info_index = index + context_local_count + context_global_count;
DCHECK_EQ(info_index, scope_info->ContextLocalInfoEntriesIndex());
for (int i = 0; i < context_local_count; ++i) {
Variable* var = context_locals[i];
int context_index = var->index() - Context::MIN_CONTEXT_SLOTS;
uint32_t info = VariableModeField::encode(var->mode()) |
InitFlagField::encode(var->initialization_flag()) |
MaybeAssignedFlagField::encode(var->maybe_assigned());
scope_info->set(index + context_index, *var->name());
scope_info->set(info_index + context_index, Smi::FromInt(info));
}
index += context_local_count;
// Add context globals' names and info. Info lies beyond context locals' info.
DCHECK_EQ(index, scope_info->ContextGlobalNameEntriesIndex());
info_index = index + context_global_count + context_local_count;
DCHECK_EQ(info_index, scope_info->ContextGlobalInfoEntriesIndex());
for (int i = 0; i < context_global_count; ++i) {
Variable* var = context_globals[i];
scope_info->set(index + i, *var->name());
// TODO(ishell): do we need this kind of info for globals here?
uint32_t info = VariableModeField::encode(var->mode()) |
InitFlagField::encode(var->initialization_flag()) |
MaybeAssignedFlagField::encode(var->maybe_assigned());
scope_info->set(info_index + i, Smi::FromInt(info));
}
index += context_local_count + 2 * context_global_count;
index += stack_local_count + 2 * context_local_count;
// If the receiver is allocated, add its index.
DCHECK(index == scope_info->ReceiverEntryIndex());
DCHECK_EQ(index, scope_info->ReceiverEntryIndex());
if (has_receiver) {
int var_index = scope->AsDeclarationScope()->receiver()->index();
scope_info->set(index++, Smi::FromInt(var_index));
@ -181,7 +173,7 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
}
// If present, add the function variable name and its index.
DCHECK(index == scope_info->FunctionNameEntryIndex());
DCHECK_EQ(index, scope_info->FunctionNameEntryIndex());
if (has_function_name) {
int var_index = scope->AsDeclarationScope()->function_var()->index();
scope_info->set(index++,
@ -191,9 +183,9 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
var_index == scope_info->ContextLength() - 1);
}
DCHECK(index == scope_info->length());
DCHECK(scope->num_parameters() == scope_info->ParameterCount());
DCHECK(scope->num_heap_slots() == scope_info->ContextLength());
DCHECK_EQ(index, scope_info->length());
DCHECK_EQ(scope->num_parameters(), scope_info->ParameterCount());
DCHECK_EQ(scope->num_heap_slots(), scope_info->ContextLength());
return scope_info;
}
@ -203,7 +195,6 @@ Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
const int stack_local_count = 0;
const int context_local_count = 1;
const int context_global_count = 0;
const bool has_simple_parameters = true;
const VariableAllocationInfo receiver_info = CONTEXT;
const VariableAllocationInfo function_name_info = NONE;
@ -213,7 +204,6 @@ Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
const int parameter_count = 0;
const int length = kVariablePartIndex + parameter_count +
(1 + stack_local_count) + 2 * context_local_count +
2 * context_global_count +
(has_receiver ? 1 : 0) + (has_function_name ? 2 : 0);
Factory* factory = isolate->factory();
@ -234,29 +224,28 @@ Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
scope_info->SetParameterCount(parameter_count);
scope_info->SetStackLocalCount(stack_local_count);
scope_info->SetContextLocalCount(context_local_count);
scope_info->SetContextGlobalCount(context_global_count);
int index = kVariablePartIndex;
const int first_slot_index = 0;
DCHECK(index == scope_info->StackLocalFirstSlotIndex());
DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex());
scope_info->set(index++, Smi::FromInt(first_slot_index));
DCHECK(index == scope_info->StackLocalEntriesIndex());
DCHECK_EQ(index, scope_info->StackLocalEntriesIndex());
// Here we add info for context-allocated "this".
DCHECK(index == scope_info->ContextLocalNameEntriesIndex());
DCHECK_EQ(index, scope_info->ContextLocalNameEntriesIndex());
scope_info->set(index++, *isolate->factory()->this_string());
DCHECK(index == scope_info->ContextLocalInfoEntriesIndex());
DCHECK_EQ(index, scope_info->ContextLocalInfoEntriesIndex());
const uint32_t value = VariableModeField::encode(CONST) |
InitFlagField::encode(kCreatedInitialized) |
MaybeAssignedFlagField::encode(kNotAssigned);
scope_info->set(index++, Smi::FromInt(value));
// And here we record that this scopeinfo binds a receiver.
DCHECK(index == scope_info->ReceiverEntryIndex());
DCHECK_EQ(index, scope_info->ReceiverEntryIndex());
const int receiver_index = Context::MIN_CONTEXT_SLOTS + 0;
scope_info->set(index++, Smi::FromInt(receiver_index));
DCHECK(index == scope_info->FunctionNameEntryIndex());
DCHECK_EQ(index, scope_info->FunctionNameEntryIndex());
DCHECK_EQ(index, scope_info->length());
DCHECK_EQ(scope_info->ParameterCount(), 0);
@ -272,7 +261,7 @@ ScopeInfo* ScopeInfo::Empty(Isolate* isolate) {
ScopeType ScopeInfo::scope_type() {
DCHECK(length() > 0);
DCHECK_LT(0, length());
return ScopeTypeField::decode(Flags());
}
@ -310,19 +299,17 @@ int ScopeInfo::StackSlotCount() {
int ScopeInfo::ContextLength() {
if (length() > 0) {
int context_locals = ContextLocalCount();
int context_globals = ContextGlobalCount();
bool function_name_context_slot =
FunctionVariableField::decode(Flags()) == CONTEXT;
bool has_context = context_locals > 0 || context_globals > 0 ||
function_name_context_slot ||
bool has_context = context_locals > 0 || function_name_context_slot ||
scope_type() == WITH_SCOPE ||
(scope_type() == BLOCK_SCOPE && CallsSloppyEval() &&
is_declaration_scope()) ||
is_declaration_scope()) ||
(scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) ||
scope_type() == MODULE_SCOPE;
if (has_context) {
return Context::MIN_CONTEXT_SLOTS + context_locals + context_globals +
return Context::MIN_CONTEXT_SLOTS + context_locals +
(function_name_context_slot ? 1 : 0);
}
}
@ -382,14 +369,16 @@ String* ScopeInfo::FunctionName() {
String* ScopeInfo::ParameterName(int var) {
DCHECK(0 <= var && var < ParameterCount());
DCHECK_LE(0, var);
DCHECK_LT(var, ParameterCount());
int info_index = ParameterEntriesIndex() + var;
return String::cast(get(info_index));
}
String* ScopeInfo::LocalName(int var) {
DCHECK(0 <= var && var < LocalCount());
DCHECK_LE(0, var);
DCHECK_LT(var, LocalCount());
DCHECK(StackLocalEntriesIndex() + StackLocalCount() ==
ContextLocalNameEntriesIndex());
int info_index = StackLocalEntriesIndex() + var;
@ -398,28 +387,32 @@ String* ScopeInfo::LocalName(int var) {
String* ScopeInfo::StackLocalName(int var) {
DCHECK(0 <= var && var < StackLocalCount());
DCHECK_LE(0, var);
DCHECK_LT(var, StackLocalCount());
int info_index = StackLocalEntriesIndex() + var;
return String::cast(get(info_index));
}
int ScopeInfo::StackLocalIndex(int var) {
DCHECK(0 <= var && var < StackLocalCount());
DCHECK_LE(0, var);
DCHECK_LT(var, StackLocalCount());
int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value();
return first_slot_index + var;
}
String* ScopeInfo::ContextLocalName(int var) {
DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
DCHECK_LE(0, var);
DCHECK_LT(var, ContextLocalCount());
int info_index = ContextLocalNameEntriesIndex() + var;
return String::cast(get(info_index));
}
VariableMode ScopeInfo::ContextLocalMode(int var) {
DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
DCHECK_LE(0, var);
DCHECK_LT(var, ContextLocalCount());
int info_index = ContextLocalInfoEntriesIndex() + var;
int value = Smi::cast(get(info_index))->value();
return VariableModeField::decode(value);
@ -427,7 +420,8 @@ VariableMode ScopeInfo::ContextLocalMode(int var) {
InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) {
DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
DCHECK_LE(0, var);
DCHECK_LT(var, ContextLocalCount());
int info_index = ContextLocalInfoEntriesIndex() + var;
int value = Smi::cast(get(info_index))->value();
return InitFlagField::decode(value);
@ -435,7 +429,8 @@ InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) {
MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) {
DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
DCHECK_LE(0, var);
DCHECK_LT(var, ContextLocalCount());
int info_index = ContextLocalInfoEntriesIndex() + var;
int value = Smi::cast(get(info_index))->value();
return MaybeAssignedFlagField::decode(value);
@ -482,7 +477,7 @@ int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
int result = context_slot_cache->Lookup(*scope_info, *name, mode, init_flag,
maybe_assigned_flag);
if (result != ContextSlotCache::kNotFound) {
DCHECK(result < scope_info->ContextLength());
DCHECK_LT(result, scope_info->ContextLength());
return result;
}
@ -498,7 +493,7 @@ int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
context_slot_cache->Update(scope_info, name, *mode, *init_flag,
*maybe_assigned_flag, result);
DCHECK(result < scope_info->ContextLength());
DCHECK_LT(result, scope_info->ContextLength());
return result;
}
}
@ -510,42 +505,10 @@ int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
return -1;
}
int ScopeInfo::ContextGlobalSlotIndex(Handle<ScopeInfo> scope_info,
Handle<String> name, VariableMode* mode,
InitializationFlag* init_flag,
MaybeAssignedFlag* maybe_assigned_flag) {
DCHECK(name->IsInternalizedString());
DCHECK_NOT_NULL(mode);
DCHECK_NOT_NULL(init_flag);
DCHECK_NOT_NULL(maybe_assigned_flag);
if (scope_info->length() > 0) {
// This is to ensure that ContextLocalMode() and co. queries would work.
DCHECK_EQ(scope_info->ContextGlobalNameEntriesIndex(),
scope_info->ContextLocalNameEntriesIndex() +
scope_info->ContextLocalCount());
int base = scope_info->ContextLocalNameEntriesIndex();
int start = scope_info->ContextGlobalNameEntriesIndex();
int end = start + scope_info->ContextGlobalCount();
for (int i = start; i < end; ++i) {
if (*name == scope_info->get(i)) {
int var = i - base;
*mode = scope_info->ContextLocalMode(var);
*init_flag = scope_info->ContextLocalInitFlag(var);
*maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var);
int result = Context::MIN_CONTEXT_SLOTS + var;
DCHECK(result < scope_info->ContextLength());
return result;
}
}
}
return -1;
}
String* ScopeInfo::ContextSlotName(int slot_index) {
int const var = slot_index - Context::MIN_CONTEXT_SLOTS;
DCHECK_LE(0, var);
DCHECK_LT(var, ContextLocalCount() + ContextGlobalCount());
DCHECK_LT(var, ContextLocalCount());
return ContextLocalName(var);
}
@ -579,7 +542,7 @@ int ScopeInfo::ReceiverContextSlotIndex() {
int ScopeInfo::FunctionContextSlotIndex(String* name, VariableMode* mode) {
DCHECK(name->IsInternalizedString());
DCHECK(mode != NULL);
DCHECK_NOT_NULL(mode);
if (length() > 0) {
if (FunctionVariableField::decode(Flags()) == CONTEXT &&
FunctionName() == name) {
@ -597,7 +560,7 @@ FunctionKind ScopeInfo::function_kind() {
int ScopeInfo::ParameterEntriesIndex() {
DCHECK(length() > 0);
DCHECK_LT(0, length());
return kVariablePartIndex;
}
@ -617,23 +580,13 @@ int ScopeInfo::ContextLocalNameEntriesIndex() {
}
int ScopeInfo::ContextGlobalNameEntriesIndex() {
int ScopeInfo::ContextLocalInfoEntriesIndex() {
return ContextLocalNameEntriesIndex() + ContextLocalCount();
}
int ScopeInfo::ContextLocalInfoEntriesIndex() {
return ContextGlobalNameEntriesIndex() + ContextGlobalCount();
}
int ScopeInfo::ContextGlobalInfoEntriesIndex() {
return ContextLocalInfoEntriesIndex() + ContextLocalCount();
}
int ScopeInfo::ReceiverEntryIndex() {
return ContextGlobalInfoEntriesIndex() + ContextGlobalCount();
return ContextLocalInfoEntriesIndex() + ContextLocalCount();
}

View File

@ -232,7 +232,6 @@ void Scope::SetDefaults() {
num_stack_slots_ = 0;
num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
num_global_slots_ = 0;
set_language_mode(SLOPPY);
@ -340,10 +339,8 @@ void Scope::DeserializeScopeInfo(Isolate* isolate,
DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
// Internalize context local & globals variables.
for (int var = 0; var < scope_info_->ContextLocalCount() +
scope_info_->ContextGlobalCount();
++var) {
// Internalize context local variables.
for (int var = 0; var < scope_info_->ContextLocalCount(); ++var) {
Handle<String> name_handle(scope_info_->ContextLocalName(var), isolate);
const AstRawString* name = ast_value_factory->GetString(name_handle);
int index = Context::MIN_CONTEXT_SLOTS + var;
@ -351,9 +348,7 @@ void Scope::DeserializeScopeInfo(Isolate* isolate,
InitializationFlag init_flag = scope_info_->ContextLocalInitFlag(var);
MaybeAssignedFlag maybe_assigned_flag =
scope_info_->ContextLocalMaybeAssignedFlag(var);
VariableLocation location = var < scope_info_->ContextLocalCount()
? VariableLocation::CONTEXT
: VariableLocation::GLOBAL;
VariableLocation location = VariableLocation::CONTEXT;
Variable::Kind kind = Variable::NORMAL;
if (index == scope_info_->ReceiverContextSlotIndex()) {
kind = Variable::THIS;
@ -603,12 +598,6 @@ Variable* Scope::LookupInScopeInfo(const AstRawString* name) {
VariableLocation location = VariableLocation::CONTEXT;
int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode,
&init_flag, &maybe_assigned_flag);
if (index < 0) {
location = VariableLocation::GLOBAL;
index = ScopeInfo::ContextGlobalSlotIndex(scope_info_, name_handle, &mode,
&init_flag, &maybe_assigned_flag);
DCHECK(index < 0 || (is_script_scope() && mode == VAR));
}
if (index < 0 && scope_type() == MODULE_SCOPE) {
location = VariableLocation::MODULE;
index = -1; // TODO(neis): Find module variables in scope info.
@ -888,26 +877,6 @@ Declaration* Scope::CheckLexDeclarationsConflictingWith(
return nullptr;
}
void Scope::CollectVariables(ZoneList<Variable*>* stack_locals,
ZoneList<Variable*>* context_locals,
ZoneList<Variable*>* context_globals) {
// TODO(verwaest): Just pass out locals_ directly and walk it?
DCHECK_NOT_NULL(stack_locals);
DCHECK_NOT_NULL(context_locals);
DCHECK_NOT_NULL(context_globals);
for (int i = 0; i < locals_.length(); i++) {
Variable* var = locals_[i];
if (var->IsStackLocal()) {
stack_locals->Add(var, zone());
} else if (var->IsContextSlot()) {
context_locals->Add(var, zone());
} else if (var->IsGlobalSlot()) {
context_globals->Add(var, zone());
}
}
}
void DeclarationScope::AllocateVariables(ParseInfo* info) {
// 1) Propagate scope information.
PropagateScopeInfo();
@ -1214,8 +1183,7 @@ void Scope::Print(int n) {
}
if (num_heap_slots_ > 0) {
Indent(n1, "// ");
PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_,
num_global_slots_);
PrintF("%d heap slots\n", num_heap_slots_);
}
// Print locals.
@ -1566,8 +1534,6 @@ void DeclarationScope::AllocateParameter(Variable* var, int index) {
var->AllocateTo(VariableLocation::PARAMETER, index);
}
}
} else {
DCHECK(!var->IsGlobalSlot());
}
}
@ -1589,32 +1555,11 @@ void Scope::AllocateNonParameterLocal(Variable* var) {
}
}
void Scope::AllocateDeclaredGlobal(Variable* var) {
DCHECK(var->scope() == this);
if (var->IsUnallocated()) {
if (var->IsStaticGlobalObjectProperty()) {
DCHECK_EQ(-1, var->index());
DCHECK(var->name()->IsString());
var->AllocateTo(VariableLocation::GLOBAL, num_heap_slots_++);
num_global_slots_++;
} else {
// There must be only DYNAMIC_GLOBAL in the script scope.
DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode());
}
}
}
void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() {
for (int i = 0; i < locals_.length(); i++) {
AllocateNonParameterLocal(locals_[i]);
}
if (FLAG_global_var_shortcuts) {
for (int i = 0; i < locals_.length(); i++) {
AllocateDeclaredGlobal(locals_[i]);
}
}
if (is_declaration_scope()) {
AsDeclarationScope()->AllocateLocals();
}
@ -1712,12 +1657,9 @@ int Scope::ContextLocalCount() const {
is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
bool is_function_var_in_context =
function != nullptr && function->IsContextSlot();
return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() -
return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
(is_function_var_in_context ? 1 : 0);
}
int Scope::ContextGlobalCount() const { return num_global_slots(); }
} // namespace internal
} // namespace v8

View File

@ -150,6 +150,8 @@ class Scope: public ZoneObject {
// Declarations list.
ZoneList<Declaration*>* declarations() { return &decls_; }
ZoneList<Variable*>* locals() { return &locals_; }
// Create a new unresolved variable.
VariableProxy* NewUnresolved(AstNodeFactory* factory,
const AstRawString* name,
@ -341,20 +343,12 @@ class Scope: public ZoneObject {
// ---------------------------------------------------------------------------
// Variable allocation.
// Collect variables in this scope. Note that the function variable - if
// present - is not collected and should be handled separately.
void CollectVariables(ZoneList<Variable*>* stack_locals,
ZoneList<Variable*>* context_locals,
ZoneList<Variable*>* context_globals);
// Result of variable allocation.
int num_stack_slots() const { return num_stack_slots_; }
int num_heap_slots() const { return num_heap_slots_; }
int num_global_slots() const { return num_global_slots_; }
int StackLocalCount() const;
int ContextLocalCount() const;
int ContextGlobalCount() const;
// Determine if we can parse a function literal in this scope lazily.
bool AllowsLazyParsing() const;
@ -484,7 +478,6 @@ class Scope: public ZoneObject {
// Computed via AllocateVariables.
int num_stack_slots_;
int num_heap_slots_;
int num_global_slots_;
// The scope type.
const ScopeType scope_type_;

View File

@ -71,10 +71,6 @@ class Variable final : public ZoneObject {
bool IsStackLocal() const { return location() == VariableLocation::LOCAL; }
bool IsStackAllocated() const { return IsParameter() || IsStackLocal(); }
bool IsContextSlot() const { return location() == VariableLocation::CONTEXT; }
bool IsGlobalSlot() const { return location() == VariableLocation::GLOBAL; }
bool IsUnallocatedOrGlobalSlot() const {
return IsUnallocated() || IsGlobalSlot();
}
bool IsLookupSlot() const { return location() == VariableLocation::LOOKUP; }
bool IsGlobalObjectProperty() const;
bool IsStaticGlobalObjectProperty() const;

View File

@ -4003,9 +4003,7 @@ Genesis::Genesis(Isolate* isolate,
// Check that the script context table is empty except for the 'this' binding.
// We do not need script contexts for native scripts.
if (!FLAG_global_var_shortcuts) {
DCHECK_EQ(1, native_context()->script_context_table()->used());
}
DCHECK_EQ(1, native_context()->script_context_table()->used());
result_ = native_context();
}

View File

@ -627,8 +627,7 @@ void AstGraphBuilder::ClearNonLiveSlotsInFrameStates() {
// Gets the bailout id just before reading a variable proxy, but only for
// unallocated variables.
static BailoutId BeforeId(VariableProxy* proxy) {
return proxy->var()->IsUnallocatedOrGlobalSlot() ? proxy->BeforeId()
: BailoutId::None();
return proxy->var()->IsUnallocated() ? proxy->BeforeId() : BailoutId::None();
}
static const char* GetDebugParameterName(Zone* zone, DeclarationScope* scope,

View File

@ -387,25 +387,6 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags,
}
void Context::InitializeGlobalSlots() {
DCHECK(IsScriptContext());
DisallowHeapAllocation no_gc;
ScopeInfo* scope_info = this->scope_info();
int context_globals = scope_info->ContextGlobalCount();
if (context_globals > 0) {
PropertyCell* empty_cell = GetHeap()->empty_property_cell();
int context_locals = scope_info->ContextLocalCount();
int index = Context::MIN_CONTEXT_SLOTS + context_locals;
for (int i = 0; i < context_globals; i++) {
set(index++, empty_cell);
}
}
}
void Context::AddOptimizedFunction(JSFunction* function) {
DCHECK(IsNativeContext());
Isolate* isolate = GetIsolate();

View File

@ -423,9 +423,6 @@ class Context: public FixedArray {
inline bool HasSameSecurityTokenAs(Context* that);
// Initializes global variable bindings in given script context.
void InitializeGlobalSlots();
// A native context holds a list of all functions with optimized code.
void AddOptimizedFunction(JSFunction* function);
void RemoveOptimizedFunction(JSFunction* function);

View File

@ -10590,7 +10590,7 @@ void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) {
return ast_context()->ReturnInstruction(instr, expr->id());
} else if (proxy != NULL) {
Variable* var = proxy->var();
if (var->IsUnallocatedOrGlobalSlot()) {
if (var->IsUnallocated()) {
Bailout(kDeleteWithGlobalVariable);
} else if (var->IsStackAllocated() || var->IsContextSlot()) {
// Result of deleting non-global variables is false. 'this' is not really

View File

@ -84,14 +84,16 @@ void AstTyper::ObserveTypesAtOsrEntry(IterationStatement* stmt) {
store_.LookupBounds(parameter_index(i)).lower);
}
ZoneList<Variable*> local_vars(locals, zone());
ZoneList<Variable*> context_vars(scope_->ContextLocalCount(), zone());
ZoneList<Variable*> global_vars(scope_->ContextGlobalCount(), zone());
scope_->CollectVariables(&local_vars, &context_vars, &global_vars);
for (int i = 0; i < locals; i++) {
PrintObserved(local_vars.at(i),
frame->GetExpression(i),
store_.LookupBounds(stack_local_index(i)).lower);
ZoneList<Variable*>* local_vars = scope_->locals();
int local_index = 0;
for (int i = 0; i < local_vars->length(); i++) {
Variable* var = local_vars->at(i);
if (var->IsStackLocal()) {
PrintObserved(
var, frame->GetExpression(local_index),
store_.LookupBounds(stack_local_index(local_index)).lower);
local_index++;
}
}
}
#endif // OBJECT_PRINT

View File

@ -1900,22 +1900,19 @@ Handle<Object> LiveEditFunctionTracker::SerializeFunctionScope(Scope* scope) {
Scope* current_scope = scope;
while (current_scope != NULL) {
HandleScope handle_scope(isolate_);
ZoneList<Variable*> stack_list(current_scope->StackLocalCount(), zone_);
ZoneList<Variable*> context_list(current_scope->ContextLocalCount(), zone_);
ZoneList<Variable*> globals_list(current_scope->ContextGlobalCount(),
zone_);
current_scope->CollectVariables(&stack_list, &context_list, &globals_list);
for (int i = 0; i < context_list.length(); i++) {
int context_index = context_list[i]->index() - Context::MIN_CONTEXT_SLOTS;
ZoneList<Variable*>* locals = current_scope->locals();
for (int i = 0; i < locals->length(); i++) {
Variable* var = locals->at(i);
if (!var->IsContextSlot()) continue;
int context_index = var->index() - Context::MIN_CONTEXT_SLOTS;
int location = scope_info_length + context_index * 2;
SetElementSloppy(scope_info_list, location, context_list[i]->name());
SetElementSloppy(
scope_info_list, location + 1,
handle(Smi::FromInt(context_list[i]->index()), isolate_));
SetElementSloppy(scope_info_list, location, var->name());
SetElementSloppy(scope_info_list, location + 1,
handle(Smi::FromInt(var->index()), isolate_));
}
scope_info_length += context_list.length() * 2;
scope_info_length += current_scope->ContextLocalCount() * 2;
SetElementSloppy(scope_info_list, scope_info_length,
Handle<Object>(isolate_->heap()->null_value(), isolate_));
isolate_->factory()->null_value());
scope_info_length++;
current_scope = current_scope->outer_scope();

View File

@ -1190,8 +1190,6 @@ DEFINE_BOOL(unbox_double_fields, V8_DOUBLE_FIELDS_UNBOXING,
"enable in-object double fields unboxing (64-bit only)")
DEFINE_IMPLICATION(unbox_double_fields, track_double_fields)
DEFINE_BOOL(global_var_shortcuts, false, "use ic-less global loads and stores")
// Cleanup...
#undef FLAG_FULL

View File

@ -1267,7 +1267,7 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
DCHECK(var->IsUnallocated() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
#endif
__ mov(LoadGlobalDescriptor::SlotRegister(),
@ -3042,7 +3042,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
// "delete this" is allowed.
bool is_this = var->is_this();
DCHECK(is_sloppy(language_mode()) || is_this);
if (var->IsUnallocatedOrGlobalSlot()) {
if (var->IsUnallocated()) {
__ LoadGlobalObject(r2);
__ mov(r1, Operand(var->name()));
__ Push(r2, r1);

View File

@ -1254,7 +1254,7 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
DCHECK(var->IsUnallocated() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
#endif
__ Mov(LoadGlobalDescriptor::SlotRegister(),
@ -2966,7 +2966,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
// "delete this" is allowed.
bool is_this = var->is_this();
DCHECK(is_sloppy(language_mode()) || is_this);
if (var->IsUnallocatedOrGlobalSlot()) {
if (var->IsUnallocated()) {
__ LoadGlobalObject(x12);
__ Mov(x11, Operand(var->name()));
__ Push(x12, x11);

View File

@ -839,8 +839,8 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
DCHECK(!context()->IsEffect());
DCHECK(!context()->IsTest());
if (proxy != NULL && (proxy->var()->IsUnallocatedOrGlobalSlot() ||
proxy->var()->IsLookupSlot())) {
if (proxy != NULL &&
(proxy->var()->IsUnallocated() || proxy->var()->IsLookupSlot())) {
EmitVariableLoad(proxy, INSIDE_TYPEOF);
PrepareForBailout(proxy, BailoutState::TOS_REGISTER);
} else {

View File

@ -1189,7 +1189,7 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
DCHECK(var->IsUnallocated() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
#endif
__ mov(LoadGlobalDescriptor::SlotRegister(),
@ -2931,7 +2931,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
// "delete this" is allowed.
bool is_this = var->is_this();
DCHECK(is_sloppy(language_mode()) || is_this);
if (var->IsUnallocatedOrGlobalSlot()) {
if (var->IsUnallocated()) {
__ mov(eax, NativeContextOperand());
__ push(ContextOperand(eax, Context::EXTENSION_INDEX));
__ push(Immediate(var->name()));

View File

@ -1263,7 +1263,7 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
DCHECK(var->IsUnallocated() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
#endif
__ li(LoadGlobalDescriptor::SlotRegister(),
@ -3050,7 +3050,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
// "delete this" is allowed.
bool is_this = var->is_this();
DCHECK(is_sloppy(language_mode()) || is_this);
if (var->IsUnallocatedOrGlobalSlot()) {
if (var->IsUnallocated()) {
__ LoadGlobalObject(a2);
__ li(a1, Operand(var->name()));
__ Push(a2, a1);

View File

@ -1264,7 +1264,7 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
DCHECK(var->IsUnallocated() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
#endif
__ li(LoadGlobalDescriptor::SlotRegister(),
@ -3049,7 +3049,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
// "delete this" is allowed.
bool is_this = var->is_this();
DCHECK(is_sloppy(language_mode()) || is_this);
if (var->IsUnallocatedOrGlobalSlot()) {
if (var->IsUnallocated()) {
__ LoadGlobalObject(a2);
__ li(a1, Operand(var->name()));
__ Push(a2, a1);

View File

@ -1230,7 +1230,7 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
DCHECK(var->IsUnallocated() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
#endif
__ mov(LoadGlobalDescriptor::SlotRegister(),
@ -3041,7 +3041,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
// "delete this" is allowed.
bool is_this = var->is_this();
DCHECK(is_sloppy(language_mode()) || is_this);
if (var->IsUnallocatedOrGlobalSlot()) {
if (var->IsUnallocated()) {
__ LoadGlobalObject(r5);
__ mov(r4, Operand(var->name()));
__ Push(r5, r4);

View File

@ -1194,7 +1194,7 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
DCHECK(var->IsUnallocated() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
#endif
__ mov(LoadGlobalDescriptor::SlotRegister(),
@ -2962,7 +2962,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
// "delete this" is allowed.
bool is_this = var->is_this();
DCHECK(is_sloppy(language_mode()) || is_this);
if (var->IsUnallocatedOrGlobalSlot()) {
if (var->IsUnallocated()) {
__ LoadGlobalObject(r4);
__ mov(r3, Operand(var->name()));
__ Push(r4, r3);

View File

@ -1217,7 +1217,7 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
DCHECK(var->IsUnallocated() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
#endif
__ Move(LoadGlobalDescriptor::SlotRegister(),
@ -2924,7 +2924,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
// "delete this" is allowed.
bool is_this = var->is_this();
DCHECK(is_sloppy(language_mode()) || is_this);
if (var->IsUnallocatedOrGlobalSlot()) {
if (var->IsUnallocated()) {
__ movp(rax, NativeContextOperand());
__ Push(ContextOperand(rax, Context::EXTENSION_INDEX));
__ Push(var->name());

View File

@ -1180,7 +1180,7 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
DCHECK(var->IsUnallocated() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
#endif
__ mov(LoadGlobalDescriptor::SlotRegister(),
@ -2922,7 +2922,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
// "delete this" is allowed.
bool is_this = var->is_this();
DCHECK(is_sloppy(language_mode()) || is_this);
if (var->IsUnallocatedOrGlobalSlot()) {
if (var->IsUnallocated()) {
__ mov(eax, NativeContextOperand());
__ push(ContextOperand(eax, Context::EXTENSION_INDEX));
__ push(Immediate(var->name()));

View File

@ -4360,16 +4360,6 @@ class ScopeInfo : public FixedArray {
VariableMode* mode, InitializationFlag* init_flag,
MaybeAssignedFlag* maybe_assigned_flag);
// Similar to ContextSlotIndex() but this method searches only among
// global slots of the serialized scope info. Returns the 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. If the slot is present
// and mode != NULL, sets *mode to the corresponding mode for that variable.
static int ContextGlobalSlotIndex(Handle<ScopeInfo> scope_info,
Handle<String> name, VariableMode* mode,
InitializationFlag* init_flag,
MaybeAssignedFlag* maybe_assigned_flag);
// Lookup the name of a certain context slot by its index.
String* ContextSlotName(int slot_index);
@ -4413,8 +4403,7 @@ class ScopeInfo : public FixedArray {
V(Flags) \
V(ParameterCount) \
V(StackLocalCount) \
V(ContextLocalCount) \
V(ContextGlobalCount)
V(ContextLocalCount)
#define FIELD_ACCESSORS(name) \
inline void Set##name(int value); \
@ -4441,8 +4430,8 @@ class ScopeInfo : public FixedArray {
// this scope are located on a stack at slots starting from this index.
// 3. StackLocalEntries:
// 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).
// 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. ContextLocalNameEntries:
@ -4468,9 +4457,7 @@ class ScopeInfo : public FixedArray {
int StackLocalFirstSlotIndex();
int StackLocalEntriesIndex();
int ContextLocalNameEntriesIndex();
int ContextGlobalNameEntriesIndex();
int ContextLocalInfoEntriesIndex();
int ContextGlobalInfoEntriesIndex();
int ReceiverEntryIndex();
int FunctionNameEntryIndex();

View File

@ -665,8 +665,6 @@ RUNTIME_FUNCTION(Runtime_NewScriptContext) {
Handle<Context> result =
isolate->factory()->NewScriptContext(closure, scope_info);
result->InitializeGlobalSlots();
DCHECK(function->context() == isolate->context());
DCHECK(*global_object == result->global_object());

View File

@ -168,8 +168,6 @@ consts_misc = [
'value': 'ScopeInfo::kStackLocalCount' },
{ 'name': 'scopeinfo_idx_ncontextlocals',
'value': 'ScopeInfo::kContextLocalCount' },
{ 'name': 'scopeinfo_idx_ncontextglobals',
'value': 'ScopeInfo::kContextGlobalCount' },
{ 'name': 'scopeinfo_idx_first_vars',
'value': 'ScopeInfo::kVariablePartIndex' },