Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1018)

Side by Side Diff: runtime/vm/code_generator_ia32.cc

Issue 9705004: Do not chain the current context on entry in non-closure functions, but (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/code_generator_x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/code_generator.h" 8 #include "vm/code_generator.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 0, 588 0,
589 kStackOverflowRuntimeEntry); 589 kStackOverflowRuntimeEntry);
590 __ Bind(&no_stack_overflow); 590 __ Bind(&no_stack_overflow);
591 } 591 }
592 592
593 593
594 void CodeGenerator::GenerateReturnEpilog(ReturnNode* node) { 594 void CodeGenerator::GenerateReturnEpilog(ReturnNode* node) {
595 // Unchain the context(s) up to context level 0. 595 // Unchain the context(s) up to context level 0.
596 int context_level = state()->context_level(); 596 int context_level = state()->context_level();
597 ASSERT(context_level >= 0); 597 ASSERT(context_level >= 0);
598 while (context_level-- > 0) { 598 if (!parsed_function_.function().IsClosureFunction()) {
599 __ movl(CTX, FieldAddress(CTX, Context::parent_offset())); 599 if (context_level > 0) {
600 // CTX on entry was saved on the stack, but not linked as context parent.
601 __ popl(CTX);
602 }
603 } else {
604 while (context_level-- > 0) {
605 __ movl(CTX, FieldAddress(CTX, Context::parent_offset()));
606 }
600 } 607 }
601 #ifdef DEBUG 608 #ifdef DEBUG
602 // Check that the entry stack size matches the exit stack size. 609 // Check that the entry stack size matches the exit stack size.
603 __ movl(EDX, EBP); 610 __ movl(EDX, EBP);
604 __ subl(EDX, ESP); 611 __ subl(EDX, ESP);
605 ASSERT(locals_space_size() >= 0); 612 ASSERT(locals_space_size() >= 0);
606 __ cmpl(EDX, Immediate(locals_space_size())); 613 __ cmpl(EDX, Immediate(locals_space_size()));
607 Label wrong_stack; 614 Label wrong_stack;
608 __ j(NOT_EQUAL, &wrong_stack, Assembler::kNearJump); 615 __ j(NOT_EQUAL, &wrong_stack, Assembler::kNearJump);
609 #endif // DEBUG. 616 #endif // DEBUG.
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 const intptr_t num_context_variables = 800 const intptr_t num_context_variables =
794 (scope != NULL) ? scope->num_context_variables() : 0; 801 (scope != NULL) ? scope->num_context_variables() : 0;
795 if (num_context_variables > 0) { 802 if (num_context_variables > 0) {
796 // The loop local scope declares variables that are captured. 803 // The loop local scope declares variables that are captured.
797 // Allocate and chain a new context. 804 // Allocate and chain a new context.
798 __ movl(EDX, Immediate(num_context_variables)); 805 __ movl(EDX, Immediate(num_context_variables));
799 const ExternalLabel label("alloc_context", 806 const ExternalLabel label("alloc_context",
800 StubCode::AllocateContextEntryPoint()); 807 StubCode::AllocateContextEntryPoint());
801 GenerateCall(node_sequence->token_index(), &label, PcDescriptors::kOther); 808 GenerateCall(node_sequence->token_index(), &label, PcDescriptors::kOther);
802 809
810 // If this node_sequence is the body of the function being compiled, and if
811 // this function is not a closure, do not link the current context as the
812 // parent of the newly allocated context, as it is not accessible. Instead,
813 // save it on the stack and restore it on exit.
814 if ((node_sequence == parsed_function_.node_sequence()) &&
815 !parsed_function_.function().IsClosureFunction()) {
816 __ pushl(CTX);
817 const Immediate raw_null =
818 Immediate(reinterpret_cast<intptr_t>(Object::null()));
819 __ movl(CTX, raw_null);
820 }
821
803 // Chain the new context in EAX to its parent in CTX. 822 // Chain the new context in EAX to its parent in CTX.
804 __ StoreIntoObject(EAX, FieldAddress(EAX, Context::parent_offset()), CTX); 823 __ StoreIntoObject(EAX, FieldAddress(EAX, Context::parent_offset()), CTX);
805 // Set new context as current context. 824 // Set new context as current context.
806 __ movl(CTX, EAX); 825 __ movl(CTX, EAX);
807 state()->set_context_level(scope->context_level()); 826 state()->set_context_level(scope->context_level());
808 827
809 // If this node_sequence is the body of the function being compiled, copy 828 // If this node_sequence is the body of the function being compiled, copy
810 // the captured parameters from the frame into the context. 829 // the captured parameters from the frame into the context.
811 if (node_sequence == parsed_function_.node_sequence()) { 830 if (node_sequence == parsed_function_.node_sequence()) {
812 ASSERT(scope->context_level() == 1); 831 ASSERT(scope->context_level() == 1);
(...skipping 25 matching lines...) Expand all
838 (node_sequence == parsed_function_.node_sequence())) { 857 (node_sequence == parsed_function_.node_sequence())) {
839 GenerateArgumentTypeChecks(); 858 GenerateArgumentTypeChecks();
840 } 859 }
841 for (int i = 0; i < node_sequence->length(); i++) { 860 for (int i = 0; i < node_sequence->length(); i++) {
842 AstNode* child_node = node_sequence->NodeAt(i); 861 AstNode* child_node = node_sequence->NodeAt(i);
843 state()->set_root_node(child_node); 862 state()->set_root_node(child_node);
844 child_node->Visit(this); 863 child_node->Visit(this);
845 } 864 }
846 if (num_context_variables > 0) { 865 if (num_context_variables > 0) {
847 // Unchain the previously allocated context. 866 // Unchain the previously allocated context.
848 __ movl(CTX, FieldAddress(CTX, Context::parent_offset())); 867 if ((node_sequence == parsed_function_.node_sequence()) &&
868 !parsed_function_.function().IsClosureFunction()) {
869 __ popl(CTX);
870 } else {
871 __ movl(CTX, FieldAddress(CTX, Context::parent_offset()));
872 }
849 } 873 }
850 // If this node sequence is labeled, a break out of the sequence will have 874 // If this node sequence is labeled, a break out of the sequence will have
851 // taken care of unchaining the context. 875 // taken care of unchaining the context.
852 if (node_sequence->label() != NULL) { 876 if (node_sequence->label() != NULL) {
853 __ Bind(node_sequence->label()->break_label()); 877 __ Bind(node_sequence->label()->break_label());
878 if ((num_context_variables > 0) &&
879 (node_sequence == parsed_function_.node_sequence()) &&
880 !parsed_function_.function().IsClosureFunction()) {
881 __ popl(CTX);
882 }
854 } 883 }
855 } 884 }
856 885
857 886
858 void CodeGenerator::VisitArgumentListNode(ArgumentListNode* arguments) { 887 void CodeGenerator::VisitArgumentListNode(ArgumentListNode* arguments) {
859 for (int i = 0; i < arguments->length(); i++) { 888 for (int i = 0; i < arguments->length(); i++) {
860 AstNode* argument = arguments->NodeAt(i); 889 AstNode* argument = arguments->NodeAt(i);
861 argument->Visit(this); 890 argument->Visit(this);
862 } 891 }
863 } 892 }
(...skipping 1639 matching lines...) Expand 10 before | Expand all | Expand 10 after
2503 // and ':stacktrace_var' can never be captured variables. 2532 // and ':stacktrace_var' can never be captured variables.
2504 // Restore CTX from local variable ':saved_context'. 2533 // Restore CTX from local variable ':saved_context'.
2505 GenerateLoadVariable(CTX, node->context_var()); 2534 GenerateLoadVariable(CTX, node->context_var());
2506 2535
2507 // Restore ESP from EBP as we are coming from a throw and the code for 2536 // Restore ESP from EBP as we are coming from a throw and the code for
2508 // popping arguments has not been run. 2537 // popping arguments has not been run.
2509 ASSERT(locals_space_size() >= 0); 2538 ASSERT(locals_space_size() >= 0);
2510 __ movl(ESP, EBP); 2539 __ movl(ESP, EBP);
2511 __ subl(ESP, Immediate(locals_space_size())); 2540 __ subl(ESP, Immediate(locals_space_size()));
2512 2541
2542 if ((state()->context_level() > 0) &&
2543 !parsed_function_.function().IsClosureFunction()) {
2544 // CTX was saved on entry.
2545 __ subl(ESP, Immediate(kWordSize));
2546 }
2547
2513 // The JumpToExceptionHandler trampoline code sets up 2548 // The JumpToExceptionHandler trampoline code sets up
2514 // - the exception object in EAX (kExceptionObjectReg) 2549 // - the exception object in EAX (kExceptionObjectReg)
2515 // - the stacktrace object in register EDX (kStackTraceObjectReg) 2550 // - the stacktrace object in register EDX (kStackTraceObjectReg)
2516 // We now setup the exception object and the trace object 2551 // We now setup the exception object and the trace object
2517 // so that the handler code has access to these objects. 2552 // so that the handler code has access to these objects.
2518 GenerateStoreVariable(node->exception_var(), 2553 GenerateStoreVariable(node->exception_var(),
2519 kExceptionObjectReg, 2554 kExceptionObjectReg,
2520 kNoRegister); 2555 kNoRegister);
2521 GenerateStoreVariable(node->stacktrace_var(), 2556 GenerateStoreVariable(node->stacktrace_var(),
2522 kStackTraceObjectReg, 2557 kStackTraceObjectReg,
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2653 const Error& error = Error::Handle( 2688 const Error& error = Error::Handle(
2654 Parser::FormatError(script, token_index, "Error", format, args)); 2689 Parser::FormatError(script, token_index, "Error", format, args));
2655 va_end(args); 2690 va_end(args);
2656 Isolate::Current()->long_jump_base()->Jump(1, error); 2691 Isolate::Current()->long_jump_base()->Jump(1, error);
2657 UNREACHABLE(); 2692 UNREACHABLE();
2658 } 2693 }
2659 2694
2660 } // namespace dart 2695 } // namespace dart
2661 2696
2662 #endif // defined TARGET_ARCH_IA32 2697 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/code_generator_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698