Reviewers: Mads Ager,
Description:
Link function contexts directly to the previous context.
Instead of NULL in the previous field of function contexts, put the previous
context. This saves the indirection of fetching the previous through the
context's closure.
[email protected]
BUG=
TEST=
Please review this at http://codereview.chromium.org/7134042/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/arm/code-stubs-arm.cc
M src/arm/macro-assembler-arm.cc
M src/contexts.h
M src/contexts.cc
M src/heap.cc
M src/ia32/code-stubs-ia32.cc
M src/ia32/macro-assembler-ia32.cc
M src/runtime.cc
M src/x64/code-stubs-x64.cc
M src/x64/macro-assembler-x64.cc
Index: src/arm/code-stubs-arm.cc
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index
6f6d13d45ce56c9e9eff1b2f561ec19bdffe5360..4ecf2fb86cea1a42e29f5347d3c8fcdcb848d82b
100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -167,10 +167,10 @@ void FastNewContextStub::Generate(MacroAssembler*
masm) {
__ mov(r1, Operand(Smi::FromInt(0)));
__ str(r3, MemOperand(r0, Context::SlotOffset(Context::CLOSURE_INDEX)));
__ str(r0, MemOperand(r0, Context::SlotOffset(Context::FCONTEXT_INDEX)));
- __ str(r1, MemOperand(r0, Context::SlotOffset(Context::PREVIOUS_INDEX)));
+ __ str(cp, MemOperand(r0, Context::SlotOffset(Context::PREVIOUS_INDEX)));
__ str(r1, MemOperand(r0,
Context::SlotOffset(Context::EXTENSION_INDEX)));
- // Copy the global object from the surrounding context.
+ // Copy the global object from the previous context.
__ ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
__ str(r1, MemOperand(r0, Context::SlotOffset(Context::GLOBAL_INDEX)));
Index: src/arm/macro-assembler-arm.cc
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index
464478a310000dd872229e35edb8de3b106bd2a1..e10e2992ad5736f4d37b2a9b21fabebb9fd027cc
100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -2538,12 +2538,9 @@ void MacroAssembler::Abort(const char* msg) {
void MacroAssembler::LoadContext(Register dst, int context_chain_length) {
if (context_chain_length > 0) {
// Move up the chain of contexts to the context containing the slot.
- ldr(dst, MemOperand(cp, Context::SlotOffset(Context::CLOSURE_INDEX)));
- // Load the function context (which is the incoming, outer context).
- ldr(dst, FieldMemOperand(dst, JSFunction::kContextOffset));
+ ldr(dst, MemOperand(cp, Context::SlotOffset(Context::PREVIOUS_INDEX)));
for (int i = 1; i < context_chain_length; i++) {
- ldr(dst, MemOperand(dst,
Context::SlotOffset(Context::CLOSURE_INDEX)));
- ldr(dst, FieldMemOperand(dst, JSFunction::kContextOffset));
+ ldr(dst, MemOperand(dst,
Context::SlotOffset(Context::PREVIOUS_INDEX)));
}
} else {
// Slot is in the current function context. Move it into the
Index: src/contexts.cc
diff --git a/src/contexts.cc b/src/contexts.cc
index
ec9a1b35964ed1c32d6d62658765ed15720f861a..3f882e6f1e24a46704edd8ffee670b555aee6420
100644
--- a/src/contexts.cc
+++ b/src/contexts.cc
@@ -187,11 +187,9 @@ Handle<Object> Context::Lookup(Handle<String> name,
ContextLookupFlags flags,
}
}
- // proceed with enclosing context
+ // Proceed with the previous context.
if (context->IsGlobalContext()) {
follow_context_chain = false;
- } else if (context->IsFunctionContext()) {
- context = Handle<Context>(context->closure()->context(), isolate);
} else {
context = Handle<Context>(context->previous(), isolate);
}
@@ -234,7 +232,7 @@ bool Context::GlobalIfNotShadowedByEval(Handle<String>
name) {
// Check context only holding the function name variable.
index = scope_info->FunctionContextSlotIndex(*name);
if (index >= 0) return false;
- context = Context::cast(context->closure()->context());
+ context = context->previous();
}
// No local or potential with statement found so the variable is
@@ -259,7 +257,7 @@ void Context::ComputeEvalScopeInfo(bool*
outer_scope_calls_eval,
}
}
if (context->IsGlobalContext()) break;
- context = Context::cast(context->closure()->context());
+ context = context->previous();
}
}
Index: src/contexts.h
diff --git a/src/contexts.h b/src/contexts.h
index
64bfc4cd4f938d0c572f9ead9ad6e9263ba78570..94cd6307328102c36cd69c81f3deb5df214a4142
100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -166,9 +166,6 @@ enum ContextLookupFlags {
// the moment we also use it in generated code for context slot accesses
-
// and there we don't want a loop because of code bloat - but we may not
// need it there after all (see comment in codegen_*.cc).
-//
-// - If we cannot get rid of fcontext, consider making 'previous' never
NULL
-// except for the global context. This could simplify Context::Lookup.
class Context: public FixedArray {
public:
Index: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index
533e05d13949043bcb4df7248dc4f9163fd417c0..94136734f16ae23b8191de63adc32efa9f11e7bf
100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -3928,7 +3928,7 @@ MaybeObject* Heap::AllocateFunctionContext(int
length, JSFunction* function) {
context->set_map(function_context_map());
context->set_closure(function);
context->set_fcontext(context);
- context->set_previous(NULL);
+ context->set_previous(function->context());
context->set_extension(NULL);
context->set_global(function->context()->global());
return context;
Index: src/ia32/code-stubs-ia32.cc
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index
459ef15756a5b11d26cf238e33070a30816c9144..a20ab718e4ff2c5d520850b1c8b28e5360b9b725
100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -138,14 +138,11 @@ void FastNewContextStub::Generate(MacroAssembler*
masm) {
__ Set(ebx, Immediate(0)); // Set to NULL.
__ mov(Operand(eax, Context::SlotOffset(Context::CLOSURE_INDEX)), ecx);
__ mov(Operand(eax, Context::SlotOffset(Context::FCONTEXT_INDEX)), eax);
- __ mov(Operand(eax, Context::SlotOffset(Context::PREVIOUS_INDEX)), ebx);
+ __ mov(Operand(eax, Context::SlotOffset(Context::PREVIOUS_INDEX)), esi);
__ mov(Operand(eax, Context::SlotOffset(Context::EXTENSION_INDEX)), ebx);
- // Copy the global object from the surrounding context. We go through the
- // context in the function (ecx) to match the allocation behavior we have
- // in the runtime system (see Heap::AllocateFunctionContext).
- __ mov(ebx, FieldOperand(ecx, JSFunction::kContextOffset));
- __ mov(ebx, Operand(ebx, Context::SlotOffset(Context::GLOBAL_INDEX)));
+ // Copy the global object from the previous context.
+ __ mov(ebx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
__ mov(Operand(eax, Context::SlotOffset(Context::GLOBAL_INDEX)), ebx);
// Initialize the rest of the slots to undefined.
Index: src/ia32/macro-assembler-ia32.cc
diff --git a/src/ia32/macro-assembler-ia32.cc
b/src/ia32/macro-assembler-ia32.cc
index
4aba1d649615b7d01bc079f9b2c0d0cf41456013..219d65e57f5d7844ff2850341d8a917399afc5d2
100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -1759,12 +1759,9 @@ void MacroAssembler::GetBuiltinEntry(Register
target, Builtins::JavaScript id) {
void MacroAssembler::LoadContext(Register dst, int context_chain_length) {
if (context_chain_length > 0) {
// Move up the chain of contexts to the context containing the slot.
- mov(dst, Operand(esi, Context::SlotOffset(Context::CLOSURE_INDEX)));
- // Load the function context (which is the incoming, outer context).
- mov(dst, FieldOperand(dst, JSFunction::kContextOffset));
+ mov(dst, Operand(esi, Context::SlotOffset(Context::PREVIOUS_INDEX)));
for (int i = 1; i < context_chain_length; i++) {
- mov(dst, Operand(dst, Context::SlotOffset(Context::CLOSURE_INDEX)));
- mov(dst, FieldOperand(dst, JSFunction::kContextOffset));
+ mov(dst, Operand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX)));
}
} else {
// Slot is in the current function context. Move it into the
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index
7e9c02c5789a01e1f624b4d534538e56d046c9f4..c5e15e244d31f6174e54409e5997c36ca747b0a4
100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -8607,11 +8607,7 @@ RUNTIME_FUNCTION(ObjectPair,
Runtime_ResolvePossiblyDirectEval) {
// Stop search when eval is found or when the global context is
// reached.
if (attributes != ABSENT || context->IsGlobalContext()) break;
- if (context->IsFunctionContext()) {
- context = Handle<Context>(context->closure()->context(), isolate);
- } else {
- context = Handle<Context>(context->previous(), isolate);
- }
+ context = Handle<Context>(context->previous());
}
// If eval could not be resolved, it has been deleted and we need to
@@ -10268,11 +10264,7 @@ class ScopeIterator {
}
// Move to the next context.
- if (context_->IsFunctionContext()) {
- context_ = Handle<Context>(context_->closure()->context());
- } else {
- context_ = Handle<Context>(context_->previous());
- }
+ context_ = Handle<Context>(context_->previous());
// If passing the local scope indicate that the current scope is now
the
// local scope.
Index: src/x64/code-stubs-x64.cc
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index
35cff704681525c38b7141732432850f9c86293c..09b127779a87c1e67ab7281f6993c93f4c56f28d
100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -133,10 +133,10 @@ void FastNewContextStub::Generate(MacroAssembler*
masm) {
__ Set(rbx, 0); // Set to NULL.
__ movq(Operand(rax, Context::SlotOffset(Context::CLOSURE_INDEX)), rcx);
__ movq(Operand(rax, Context::SlotOffset(Context::FCONTEXT_INDEX)), rax);
- __ movq(Operand(rax, Context::SlotOffset(Context::PREVIOUS_INDEX)), rbx);
+ __ movq(Operand(rax, Context::SlotOffset(Context::PREVIOUS_INDEX)), rsi);
__ movq(Operand(rax, Context::SlotOffset(Context::EXTENSION_INDEX)),
rbx);
- // Copy the global object from the surrounding context.
+ // Copy the global object from the previous context.
__ movq(rbx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
__ movq(Operand(rax, Context::SlotOffset(Context::GLOBAL_INDEX)), rbx);
Index: src/x64/macro-assembler-x64.cc
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index
0fc75028b304bd965d9b937e2b70155d61134a5c..1d375e15f8a3e295ca346104838dd9f0873ba2da
100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -3617,15 +3617,10 @@ void MacroAssembler::CopyBytes(Register destination,
void MacroAssembler::LoadContext(Register dst, int context_chain_length) {
if (context_chain_length > 0) {
// Move up the chain of contexts to the context containing the slot.
- movq(dst, Operand(rsi, Context::SlotOffset(Context::CLOSURE_INDEX)));
- // Load the function context (which is the incoming, outer context).
- movq(dst, FieldOperand(dst, JSFunction::kContextOffset));
+ movq(dst, Operand(rsi, Context::SlotOffset(Context::PREVIOUS_INDEX)));
for (int i = 1; i < context_chain_length; i++) {
- movq(dst, Operand(dst, Context::SlotOffset(Context::CLOSURE_INDEX)));
- movq(dst, FieldOperand(dst, JSFunction::kContextOffset));
+ movq(dst, Operand(dst,
Context::SlotOffset(Context::PREVIOUS_INDEX)));
}
- // The context may be an intermediate context, not a function context.
- movq(dst, Operand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX)));
} else {
// Slot is in the current function context. Move it into the
// destination register in case we store into it (the write barrier
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev