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:
parent
ee7dc92f9e
commit
1493bc8c8b
@ -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;
|
||||
|
@ -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_; }
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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_;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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()));
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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()));
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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' },
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user