| Index: runtime/vm/code_generator_ia32.cc
|
| ===================================================================
|
| --- runtime/vm/code_generator_ia32.cc (revision 5648)
|
| +++ runtime/vm/code_generator_ia32.cc (working copy)
|
| @@ -592,11 +592,9 @@
|
| // Unchain the context(s) up to context level 0.
|
| intptr_t current_context_level = context_level();
|
| ASSERT(current_context_level >= 0);
|
| - if (!parsed_function_.function().IsClosureFunction()) {
|
| - if (current_context_level > 0) {
|
| - // CTX on entry was saved on the stack, but not linked as context parent.
|
| - __ popl(CTX);
|
| - }
|
| + if (parsed_function_.saved_context_var() != NULL) {
|
| + // CTX on entry was saved, but not linked as context parent.
|
| + GenerateLoadVariable(CTX, *parsed_function_.saved_context_var());
|
| } else {
|
| while (current_context_level-- > 0) {
|
| __ movl(CTX, FieldAddress(CTX, Context::parent_offset()));
|
| @@ -808,10 +806,11 @@
|
| // If this node_sequence is the body of the function being compiled, and if
|
| // this function is not a closure, do not link the current context as the
|
| // parent of the newly allocated context, as it is not accessible. Instead,
|
| - // save it on the stack and restore it on exit.
|
| + // save it in a pre-allocated variable and restore it on exit.
|
| if ((node_sequence == parsed_function_.node_sequence()) &&
|
| - !parsed_function_.function().IsClosureFunction()) {
|
| - __ pushl(CTX);
|
| + (parsed_function_.saved_context_var() != NULL)) {
|
| + GenerateStoreVariable(
|
| + *parsed_function_.saved_context_var(), CTX, kNoRegister);
|
| const Immediate raw_null =
|
| Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| __ movl(CTX, raw_null);
|
| @@ -860,23 +859,25 @@
|
| state()->set_root_node(child_node);
|
| child_node->Visit(this);
|
| }
|
| - if (num_context_variables > 0) {
|
| - // Unchain the previously allocated context.
|
| - if ((node_sequence == parsed_function_.node_sequence()) &&
|
| - !parsed_function_.function().IsClosureFunction()) {
|
| - __ popl(CTX);
|
| - } else {
|
| - __ movl(CTX, FieldAddress(CTX, Context::parent_offset()));
|
| - }
|
| +
|
| + // Unchain the previously allocated context.
|
| + if ((node_sequence == parsed_function_.node_sequence()) &&
|
| + (parsed_function_.saved_context_var() != NULL)) {
|
| + ASSERT(num_context_variables > 0);
|
| + GenerateLoadVariable(CTX, *parsed_function_.saved_context_var());
|
| + } else if (num_context_variables > 0) {
|
| + __ movl(CTX, FieldAddress(CTX, Context::parent_offset()));
|
| }
|
| +
|
| // If this node sequence is labeled, a break out of the sequence will have
|
| // taken care of unchaining the context.
|
| if (node_sequence->label() != NULL) {
|
| __ Bind(node_sequence->label()->break_label());
|
| - if ((num_context_variables > 0) &&
|
| - (node_sequence == parsed_function_.node_sequence()) &&
|
| - !parsed_function_.function().IsClosureFunction()) {
|
| - __ popl(CTX);
|
| +
|
| + // The context saved on entry must be restored.
|
| + if ((node_sequence == parsed_function_.node_sequence()) &&
|
| + (parsed_function_.saved_context_var() != NULL)) {
|
| + GenerateLoadVariable(CTX, *parsed_function_.saved_context_var());
|
| }
|
| }
|
| set_context_level(previous_context_level);
|
| @@ -2538,12 +2539,6 @@
|
| __ movl(ESP, EBP);
|
| __ subl(ESP, Immediate(locals_space_size()));
|
|
|
| - if ((context_level() > 0) &&
|
| - !parsed_function_.function().IsClosureFunction()) {
|
| - // CTX was saved on entry.
|
| - __ subl(ESP, Immediate(kWordSize));
|
| - }
|
| -
|
| // The JumpToExceptionHandler trampoline code sets up
|
| // - the exception object in EAX (kExceptionObjectReg)
|
| // - the stacktrace object in register EDX (kStackTraceObjectReg)
|
|
|