Don't use different read/write slots for context globals, but
let them share the same slot, which reduces the number of
initial misses, and also saves some memory for large scripts.
R=yangguo@chromium.org
Review URL: https://codereview.chromium.org/
1258213002
Cr-Commit-Position: refs/heads/master@{#29889}
13 files changed:
int slot_index = -1;
if (variable->index() > 0) {
DCHECK(variable->IsStaticGlobalObjectProperty());
int slot_index = -1;
if (variable->index() > 0) {
DCHECK(variable->IsStaticGlobalObjectProperty());
- // Each var occupies two slots in the context: for reads and writes.
slot_index = variable->index();
int depth = current_scope()->ContextChainLength(variable->scope());
if (depth > 0) {
slot_index = variable->index();
int depth = current_scope()->ContextChainLength(variable->scope());
if (depth > 0) {
int slot_index = -1;
if (variable->index() > 0) {
DCHECK(variable->IsStaticGlobalObjectProperty());
int slot_index = -1;
if (variable->index() > 0) {
DCHECK(variable->IsStaticGlobalObjectProperty());
- // Each var occupies two slots in the context: for reads and writes.
slot_index = variable->index();
int depth = current_scope()->ContextChainLength(variable->scope());
if (depth > 0) {
slot_index = variable->index();
int depth = current_scope()->ContextChainLength(variable->scope());
if (depth > 0) {
int context_locals = scope_info->ContextLocalCount();
int index = Context::MIN_CONTEXT_SLOTS + context_locals;
for (int i = 0; i < context_globals; i++) {
int context_locals = scope_info->ContextLocalCount();
int index = Context::MIN_CONTEXT_SLOTS + context_locals;
for (int i = 0; i < context_globals; i++) {
- // Clear both read and write slots.
- set(index++, empty_cell);
set(index++, empty_cell);
}
}
set(index++, empty_cell);
}
}
if (var->IsGlobalSlot()) {
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
if (var->IsGlobalSlot()) {
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
- // Each var occupies two slots in the context: for reads and writes.
const int slot = var->index();
const int depth = scope()->ContextChainLength(var->scope());
if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
const int slot = var->index();
const int depth = scope()->ContextChainLength(var->scope());
if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
// Global var, const, or let.
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
// Global var, const, or let.
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
- // Each var occupies two slots in the context: for reads and writes.
- const int slot = var->index() + 1;
+ const int slot = var->index();
const int depth = scope()->ContextChainLength(var->scope());
if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
__ mov(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
const int depth = scope()->ContextChainLength(var->scope());
if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
__ mov(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
if (var->IsGlobalSlot()) {
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
if (var->IsGlobalSlot()) {
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
- // Each var occupies two slots in the context: for reads and writes.
int const slot = var->index();
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
int const slot = var->index();
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
// Global var, const, or let.
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
// Global var, const, or let.
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
- // Each var occupies two slots in the context: for reads and writes.
- int const slot = var->index() + 1;
+ int const slot = var->index();
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
__ Mov(StoreGlobalViaContextDescriptor::SlotRegister(), slot);
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
__ Mov(StoreGlobalViaContextDescriptor::SlotRegister(), slot);
if (var->IsGlobalSlot()) {
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
if (var->IsGlobalSlot()) {
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
- // Each var occupies two slots in the context: for reads and writes.
int const slot = var->index();
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
int const slot = var->index();
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
// Global var, const, or let.
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
// Global var, const, or let.
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
- // Each var occupies two slots in the context: for reads and writes.
- int const slot = var->index() + 1;
+ int const slot = var->index();
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
__ Move(StoreGlobalViaContextDescriptor::SlotRegister(), Immediate(slot));
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
__ Move(StoreGlobalViaContextDescriptor::SlotRegister(), Immediate(slot));
if (var->IsGlobalSlot()) {
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
if (var->IsGlobalSlot()) {
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
- // Each var occupies two slots in the context: for reads and writes.
int const slot = var->index();
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
int const slot = var->index();
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
DCHECK(var->IsStaticGlobalObjectProperty());
DCHECK(StoreGlobalViaContextDescriptor::ValueRegister().is(a0));
__ mov(StoreGlobalViaContextDescriptor::ValueRegister(), result_register());
DCHECK(var->IsStaticGlobalObjectProperty());
DCHECK(StoreGlobalViaContextDescriptor::ValueRegister().is(a0));
__ mov(StoreGlobalViaContextDescriptor::ValueRegister(), result_register());
- // Each var occupies two slots in the context: for reads and writes.
- int const slot = var->index() + 1;
+ int const slot = var->index();
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
__ li(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
__ li(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
if (var->IsGlobalSlot()) {
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
if (var->IsGlobalSlot()) {
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
- // Each var occupies two slots in the context: for reads and writes.
int const slot = var->index();
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
int const slot = var->index();
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
DCHECK(var->IsStaticGlobalObjectProperty());
DCHECK(StoreGlobalViaContextDescriptor::ValueRegister().is(a0));
__ mov(StoreGlobalViaContextDescriptor::ValueRegister(), result_register());
DCHECK(var->IsStaticGlobalObjectProperty());
DCHECK(StoreGlobalViaContextDescriptor::ValueRegister().is(a0));
__ mov(StoreGlobalViaContextDescriptor::ValueRegister(), result_register());
- // Each var occupies two slots in the context: for reads and writes.
- int const slot = var->index() + 1;
+ int const slot = var->index();
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
__ li(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
__ li(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
if (var->IsGlobalSlot()) {
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
if (var->IsGlobalSlot()) {
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
- // Each var occupies two slots in the context: for reads and writes.
const int slot = var->index();
const int depth = scope()->ContextChainLength(var->scope());
if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
const int slot = var->index();
const int depth = scope()->ContextChainLength(var->scope());
if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
// Global var, const, or let.
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
// Global var, const, or let.
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
- // Each var occupies two slots in the context: for reads and writes.
- const int slot = var->index() + 1;
+ const int slot = var->index();
const int depth = scope()->ContextChainLength(var->scope());
if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
__ mov(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
const int depth = scope()->ContextChainLength(var->scope());
if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
__ mov(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
// Global var, const, or let.
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
// Global var, const, or let.
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
- // Each var occupies two slots in the context: for reads and writes.
- int const slot = var->index() + 1;
+ int const slot = var->index();
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
__ Set(StoreGlobalViaContextDescriptor::SlotRegister(), slot);
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
__ Set(StoreGlobalViaContextDescriptor::SlotRegister(), slot);
if (var->IsGlobalSlot()) {
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
if (var->IsGlobalSlot()) {
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
- // Each var occupies two slots in the context: for reads and writes.
int const slot = var->index();
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
int const slot = var->index();
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
// Global var, const, or let.
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
// Global var, const, or let.
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
- // Each var occupies two slots in the context: for reads and writes.
- int const slot = var->index() + 1;
+ int const slot = var->index();
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
__ Move(StoreGlobalViaContextDescriptor::SlotRegister(), Immediate(slot));
int const depth = scope()->ContextChainLength(var->scope());
if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
__ Move(StoreGlobalViaContextDescriptor::SlotRegister(), Immediate(slot));
} else if (variable->IsGlobalSlot()) {
DCHECK(variable->index() > 0);
DCHECK(variable->IsStaticGlobalObjectProperty());
} else if (variable->IsGlobalSlot()) {
DCHECK(variable->index() > 0);
DCHECK(variable->IsStaticGlobalObjectProperty());
- // Each var occupies two slots in the context: for reads and writes.
int slot_index = variable->index();
int depth = scope()->ContextChainLength(variable->scope());
int slot_index = variable->index();
int depth = scope()->ContextChainLength(variable->scope());
} else if (var->IsGlobalSlot()) {
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
} else if (var->IsGlobalSlot()) {
DCHECK(var->index() > 0);
DCHECK(var->IsStaticGlobalObjectProperty());
- // Each var occupies two slots in the context: for reads and writes.
- int slot_index = var->index() + 1;
+ int slot_index = var->index();
int depth = scope()->ContextChainLength(var->scope());
HStoreGlobalViaContext* instr = Add<HStoreGlobalViaContext>(
int depth = scope()->ContextChainLength(var->scope());
HStoreGlobalViaContext* instr = Add<HStoreGlobalViaContext>(
scope_type() == MODULE_SCOPE;
if (has_context) {
scope_type() == MODULE_SCOPE;
if (has_context) {
- return Context::MIN_CONTEXT_SLOTS + context_locals + 2 * context_globals +
+ return Context::MIN_CONTEXT_SLOTS + context_locals + context_globals +
(function_name_context_slot ? 1 : 0);
}
}
(function_name_context_slot ? 1 : 0);
}
}
var -= scope_info->ContextLocalCount();
*location = VariableLocation::GLOBAL;
result = Context::MIN_CONTEXT_SLOTS +
var -= scope_info->ContextLocalCount();
*location = VariableLocation::GLOBAL;
result = Context::MIN_CONTEXT_SLOTS +
- scope_info->ContextLocalCount() + 2 * var;
+ scope_info->ContextLocalCount() + var;
}
context_slot_cache->Update(scope_info, name, *mode, *location,
}
context_slot_cache->Update(scope_info, name, *mode, *location,
String* ScopeInfo::ContextSlotName(int slot_index) {
String* ScopeInfo::ContextSlotName(int slot_index) {
- // TODO(bmeurer): Simplify this once we have only a single slot for both reads
- // and writes to context globals; currently we have 2 slots per context
- // global, and these are located after the common context slots (of which we
- // always have Context::MIN_CONTEXT_SLOTS) and the context locals.
- int const var =
- slot_index - (Context::MIN_CONTEXT_SLOTS + ContextLocalCount());
+ int const var = slot_index - Context::MIN_CONTEXT_SLOTS;
- DCHECK_LT(var, 2 * ContextGlobalCount());
- return ContextLocalName(ContextLocalCount() + var / 2);
+ DCHECK_LT(var, ContextLocalCount() + ContextGlobalCount());
+ return ContextLocalName(var);
if (var->IsStaticGlobalObjectProperty()) {
DCHECK_EQ(-1, var->index());
DCHECK(var->name()->IsString());
if (var->IsStaticGlobalObjectProperty()) {
DCHECK_EQ(-1, var->index());
DCHECK(var->name()->IsString());
- var->AllocateTo(VariableLocation::GLOBAL, num_heap_slots_);
+ var->AllocateTo(VariableLocation::GLOBAL, num_heap_slots_++);
- // Each global variable occupies two slots in the context: for reads
- // and writes.
- num_heap_slots_ += 2;
} else {
// There must be only DYNAMIC_GLOBAL in the script scope.
DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode());
} else {
// There must be only DYNAMIC_GLOBAL in the script scope.
DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode());
if (num_heap_slots() == 0) return 0;
bool is_function_var_in_context =
function_ != NULL && function_->proxy()->var()->IsContextSlot();
if (num_heap_slots() == 0) return 0;
bool is_function_var_in_context =
function_ != NULL && function_->proxy()->var()->IsContextSlot();
- return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
- 2 * num_global_slots() - (is_function_var_in_context ? 1 : 0);
+ return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() -
+ (is_function_var_in_context ? 1 : 0);
}
int Scope::ContextGlobalCount() const { return num_global_slots(); }
}
int Scope::ContextGlobalCount() const { return num_global_slots(); }
} // namespace internal
} // namespace v8
} // namespace internal
} // namespace v8