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

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

Issue 9721004: Use a local variable to save/restore the context on entry/exit, instead of (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 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 0, 585 0,
586 kStackOverflowRuntimeEntry); 586 kStackOverflowRuntimeEntry);
587 __ Bind(&no_stack_overflow); 587 __ Bind(&no_stack_overflow);
588 } 588 }
589 589
590 590
591 void CodeGenerator::GenerateReturnEpilog(ReturnNode* node) { 591 void CodeGenerator::GenerateReturnEpilog(ReturnNode* node) {
592 // Unchain the context(s) up to context level 0. 592 // Unchain the context(s) up to context level 0.
593 intptr_t current_context_level = context_level(); 593 intptr_t current_context_level = context_level();
594 ASSERT(current_context_level >= 0); 594 ASSERT(current_context_level >= 0);
595 if (!parsed_function_.function().IsClosureFunction()) { 595 if (parsed_function_.saved_context_var() != NULL) {
596 if (current_context_level > 0) { 596 // CTX on entry was saved, but not linked as context parent.
597 // CTX on entry was saved on the stack, but not linked as context parent. 597 GenerateLoadVariable(CTX, *parsed_function_.saved_context_var());
598 __ popl(CTX);
599 }
600 } else { 598 } else {
601 while (current_context_level-- > 0) { 599 while (current_context_level-- > 0) {
602 __ movl(CTX, FieldAddress(CTX, Context::parent_offset())); 600 __ movl(CTX, FieldAddress(CTX, Context::parent_offset()));
603 } 601 }
604 } 602 }
605 #ifdef DEBUG 603 #ifdef DEBUG
606 // Check that the entry stack size matches the exit stack size. 604 // Check that the entry stack size matches the exit stack size.
607 __ movl(EDX, EBP); 605 __ movl(EDX, EBP);
608 __ subl(EDX, ESP); 606 __ subl(EDX, ESP);
609 ASSERT(locals_space_size() >= 0); 607 ASSERT(locals_space_size() >= 0);
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 // The loop local scope declares variables that are captured. 799 // The loop local scope declares variables that are captured.
802 // Allocate and chain a new context. 800 // Allocate and chain a new context.
803 __ movl(EDX, Immediate(num_context_variables)); 801 __ movl(EDX, Immediate(num_context_variables));
804 const ExternalLabel label("alloc_context", 802 const ExternalLabel label("alloc_context",
805 StubCode::AllocateContextEntryPoint()); 803 StubCode::AllocateContextEntryPoint());
806 GenerateCall(node_sequence->token_index(), &label, PcDescriptors::kOther); 804 GenerateCall(node_sequence->token_index(), &label, PcDescriptors::kOther);
807 805
808 // If this node_sequence is the body of the function being compiled, and if 806 // If this node_sequence is the body of the function being compiled, and if
809 // this function is not a closure, do not link the current context as the 807 // this function is not a closure, do not link the current context as the
810 // parent of the newly allocated context, as it is not accessible. Instead, 808 // parent of the newly allocated context, as it is not accessible. Instead,
811 // save it on the stack and restore it on exit. 809 // save it in a pre-allocated variable and restore it on exit.
812 if ((node_sequence == parsed_function_.node_sequence()) && 810 if ((node_sequence == parsed_function_.node_sequence()) &&
813 !parsed_function_.function().IsClosureFunction()) { 811 (parsed_function_.saved_context_var() != NULL)) {
814 __ pushl(CTX); 812 GenerateStoreVariable(
813 *parsed_function_.saved_context_var(), CTX, kNoRegister);
815 const Immediate raw_null = 814 const Immediate raw_null =
816 Immediate(reinterpret_cast<intptr_t>(Object::null())); 815 Immediate(reinterpret_cast<intptr_t>(Object::null()));
817 __ movl(CTX, raw_null); 816 __ movl(CTX, raw_null);
818 } 817 }
819 818
820 // Chain the new context in EAX to its parent in CTX. 819 // Chain the new context in EAX to its parent in CTX.
821 __ StoreIntoObject(EAX, FieldAddress(EAX, Context::parent_offset()), CTX); 820 __ StoreIntoObject(EAX, FieldAddress(EAX, Context::parent_offset()), CTX);
822 // Set new context as current context. 821 // Set new context as current context.
823 __ movl(CTX, EAX); 822 __ movl(CTX, EAX);
824 set_context_level(scope->context_level()); 823 set_context_level(scope->context_level());
(...skipping 28 matching lines...) Expand all
853 // code checking the type of the actual arguments. 852 // code checking the type of the actual arguments.
854 if (FLAG_enable_type_checks && 853 if (FLAG_enable_type_checks &&
855 (node_sequence == parsed_function_.node_sequence())) { 854 (node_sequence == parsed_function_.node_sequence())) {
856 GenerateArgumentTypeChecks(); 855 GenerateArgumentTypeChecks();
857 } 856 }
858 for (int i = 0; i < node_sequence->length(); i++) { 857 for (int i = 0; i < node_sequence->length(); i++) {
859 AstNode* child_node = node_sequence->NodeAt(i); 858 AstNode* child_node = node_sequence->NodeAt(i);
860 state()->set_root_node(child_node); 859 state()->set_root_node(child_node);
861 child_node->Visit(this); 860 child_node->Visit(this);
862 } 861 }
863 if (num_context_variables > 0) { 862
864 // Unchain the previously allocated context. 863 // Unchain the previously allocated context.
865 if ((node_sequence == parsed_function_.node_sequence()) && 864 if ((node_sequence == parsed_function_.node_sequence()) &&
866 !parsed_function_.function().IsClosureFunction()) { 865 (parsed_function_.saved_context_var() != NULL)) {
867 __ popl(CTX); 866 ASSERT(num_context_variables > 0);
868 } else { 867 GenerateLoadVariable(CTX, *parsed_function_.saved_context_var());
869 __ movl(CTX, FieldAddress(CTX, Context::parent_offset())); 868 } else if (num_context_variables > 0) {
870 } 869 __ movl(CTX, FieldAddress(CTX, Context::parent_offset()));
871 } 870 }
871
872 // If this node sequence is labeled, a break out of the sequence will have 872 // If this node sequence is labeled, a break out of the sequence will have
873 // taken care of unchaining the context. 873 // taken care of unchaining the context.
874 if (node_sequence->label() != NULL) { 874 if (node_sequence->label() != NULL) {
875 __ Bind(node_sequence->label()->break_label()); 875 __ Bind(node_sequence->label()->break_label());
876 if ((num_context_variables > 0) && 876
877 (node_sequence == parsed_function_.node_sequence()) && 877 // The context saved on entry must be restored.
878 !parsed_function_.function().IsClosureFunction()) { 878 if ((node_sequence == parsed_function_.node_sequence()) &&
879 __ popl(CTX); 879 (parsed_function_.saved_context_var() != NULL)) {
880 GenerateLoadVariable(CTX, *parsed_function_.saved_context_var());
880 } 881 }
881 } 882 }
882 set_context_level(previous_context_level); 883 set_context_level(previous_context_level);
883 } 884 }
884 885
885 886
886 void CodeGenerator::VisitArgumentListNode(ArgumentListNode* arguments) { 887 void CodeGenerator::VisitArgumentListNode(ArgumentListNode* arguments) {
887 for (int i = 0; i < arguments->length(); i++) { 888 for (int i = 0; i < arguments->length(); i++) {
888 AstNode* argument = arguments->NodeAt(i); 889 AstNode* argument = arguments->NodeAt(i);
889 argument->Visit(this); 890 argument->Visit(this);
(...skipping 1641 matching lines...) Expand 10 before | Expand all | Expand 10 after
2531 // and ':stacktrace_var' can never be captured variables. 2532 // and ':stacktrace_var' can never be captured variables.
2532 // Restore CTX from local variable ':saved_context'. 2533 // Restore CTX from local variable ':saved_context'.
2533 GenerateLoadVariable(CTX, node->context_var()); 2534 GenerateLoadVariable(CTX, node->context_var());
2534 2535
2535 // 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
2536 // popping arguments has not been run. 2537 // popping arguments has not been run.
2537 ASSERT(locals_space_size() >= 0); 2538 ASSERT(locals_space_size() >= 0);
2538 __ movl(ESP, EBP); 2539 __ movl(ESP, EBP);
2539 __ subl(ESP, Immediate(locals_space_size())); 2540 __ subl(ESP, Immediate(locals_space_size()));
2540 2541
2541 if ((context_level() > 0) &&
2542 !parsed_function_.function().IsClosureFunction()) {
2543 // CTX was saved on entry.
2544 __ subl(ESP, Immediate(kWordSize));
2545 }
2546
2547 // The JumpToExceptionHandler trampoline code sets up 2542 // The JumpToExceptionHandler trampoline code sets up
2548 // - the exception object in EAX (kExceptionObjectReg) 2543 // - the exception object in EAX (kExceptionObjectReg)
2549 // - the stacktrace object in register EDX (kStackTraceObjectReg) 2544 // - the stacktrace object in register EDX (kStackTraceObjectReg)
2550 // We now setup the exception object and the trace object 2545 // We now setup the exception object and the trace object
2551 // so that the handler code has access to these objects. 2546 // so that the handler code has access to these objects.
2552 GenerateStoreVariable(node->exception_var(), 2547 GenerateStoreVariable(node->exception_var(),
2553 kExceptionObjectReg, 2548 kExceptionObjectReg,
2554 kNoRegister); 2549 kNoRegister);
2555 GenerateStoreVariable(node->stacktrace_var(), 2550 GenerateStoreVariable(node->stacktrace_var(),
2556 kStackTraceObjectReg, 2551 kStackTraceObjectReg,
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2687 const Error& error = Error::Handle( 2682 const Error& error = Error::Handle(
2688 Parser::FormatError(script, token_index, "Error", format, args)); 2683 Parser::FormatError(script, token_index, "Error", format, args));
2689 va_end(args); 2684 va_end(args);
2690 Isolate::Current()->long_jump_base()->Jump(1, error); 2685 Isolate::Current()->long_jump_base()->Jump(1, error);
2691 UNREACHABLE(); 2686 UNREACHABLE();
2692 } 2687 }
2693 2688
2694 } // namespace dart 2689 } // namespace dart
2695 2690
2696 #endif // defined TARGET_ARCH_IA32 2691 #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