Revision: 8238
Author: [email protected]
Date: Thu Jun 9 05:45:26 2011
Log: 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=
Review URL: http://codereview.chromium.org/7134042
http://code.google.com/p/v8/source/detail?r=8238
Modified:
/branches/bleeding_edge/src/arm/code-stubs-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.cc
/branches/bleeding_edge/src/contexts.cc
/branches/bleeding_edge/src/contexts.h
/branches/bleeding_edge/src/heap.cc
/branches/bleeding_edge/src/ia32/code-stubs-ia32.cc
/branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/src/x64/code-stubs-x64.cc
/branches/bleeding_edge/src/x64/macro-assembler-x64.cc
=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.cc Thu Jun 9 04:26:01
2011
+++ /branches/bleeding_edge/src/arm/code-stubs-arm.cc Thu Jun 9 05:45:26
2011
@@ -167,10 +167,10 @@
__ 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)));
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Wed Jun 8
06:55:33 2011
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Thu Jun 9
05:45:26 2011
@@ -2538,12 +2538,9 @@
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
=======================================
--- /branches/bleeding_edge/src/contexts.cc Thu Jun 9 04:26:01 2011
+++ /branches/bleeding_edge/src/contexts.cc Thu Jun 9 05:45:26 2011
@@ -187,11 +187,9 @@
}
}
- // 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 @@
// 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
@@ -245,8 +243,10 @@
void Context::ComputeEvalScopeInfo(bool* outer_scope_calls_eval,
bool*
outer_scope_calls_non_strict_eval) {
- Context* context = this;
- while (true) {
+ // Skip up the context chain checking all the function contexts to see
+ // whether they call eval.
+ Context* context = fcontext();
+ while (!context->IsGlobalContext()) {
Handle<SerializedScopeInfo> scope_info(
context->closure()->shared()->scope_info());
if (scope_info->CallsEval()) {
@@ -258,8 +258,7 @@
return;
}
}
- if (context->IsGlobalContext()) break;
- context = Context::cast(context->closure()->context());
+ context = context->previous()->fcontext();
}
}
=======================================
--- /branches/bleeding_edge/src/contexts.h Thu Jun 9 04:26:01 2011
+++ /branches/bleeding_edge/src/contexts.h Thu Jun 9 05:45:26 2011
@@ -166,9 +166,6 @@
// 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:
=======================================
--- /branches/bleeding_edge/src/heap.cc Thu Jun 9 04:26:01 2011
+++ /branches/bleeding_edge/src/heap.cc Thu Jun 9 05:45:26 2011
@@ -3928,7 +3928,7 @@
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;
=======================================
--- /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Thu Jun 9 04:26:01
2011
+++ /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Thu Jun 9 05:45:26
2011
@@ -138,14 +138,11 @@
__ 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.
=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Fri Jun 3
00:41:37 2011
+++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Thu Jun 9
05:45:26 2011
@@ -1759,12 +1759,9 @@
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
=======================================
--- /branches/bleeding_edge/src/runtime.cc Thu Jun 9 04:26:01 2011
+++ /branches/bleeding_edge/src/runtime.cc Thu Jun 9 05:45:26 2011
@@ -8607,11 +8607,7 @@
// 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(), isolate);
}
// If eval could not be resolved, it has been deleted and we need to
@@ -10268,11 +10264,7 @@
}
// 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(), isolate_);
// If passing the local scope indicate that the current scope is now
the
// local scope.
=======================================
--- /branches/bleeding_edge/src/x64/code-stubs-x64.cc Thu Jun 9 04:26:01
2011
+++ /branches/bleeding_edge/src/x64/code-stubs-x64.cc Thu Jun 9 05:45:26
2011
@@ -133,10 +133,10 @@
__ 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);
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Fri Jun 3
00:41:37 2011
+++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Thu Jun 9
05:45:26 2011
@@ -3617,15 +3617,10 @@
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));
- }
- // The context may be an intermediate context, not a function context.
- movq(dst, Operand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX)));
+ movq(dst, Operand(dst,
Context::SlotOffset(Context::PREVIOUS_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