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

Side by Side Diff: runtime/vm/code_generator_x64.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 | « runtime/vm/code_generator_ia32.cc ('k') | runtime/vm/parser.h » ('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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
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 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 0, 605 0,
606 kStackOverflowRuntimeEntry); 606 kStackOverflowRuntimeEntry);
607 __ Bind(&no_stack_overflow); 607 __ Bind(&no_stack_overflow);
608 } 608 }
609 609
610 610
611 void CodeGenerator::GenerateReturnEpilog(ReturnNode* node) { 611 void CodeGenerator::GenerateReturnEpilog(ReturnNode* node) {
612 // Unchain the context(s) up to context level 0. 612 // Unchain the context(s) up to context level 0.
613 intptr_t current_context_level = context_level(); 613 intptr_t current_context_level = context_level();
614 ASSERT(current_context_level >= 0); 614 ASSERT(current_context_level >= 0);
615 if (!parsed_function_.function().IsClosureFunction()) { 615 if (parsed_function_.saved_context_var() != NULL) {
616 if (current_context_level > 0) { 616 // CTX on entry was saved, but not linked as context parent.
617 // CTX on entry was saved on the stack, but not linked as context parent. 617 GenerateLoadVariable(CTX, *parsed_function_.saved_context_var());
618 __ popq(CTX);
619 }
620 } else { 618 } else {
621 while (current_context_level-- > 0) { 619 while (current_context_level-- > 0) {
622 __ movq(CTX, FieldAddress(CTX, Context::parent_offset())); 620 __ movq(CTX, FieldAddress(CTX, Context::parent_offset()));
623 } 621 }
624 } 622 }
625 #ifdef DEBUG 623 #ifdef DEBUG
626 // Check that the entry stack size matches the exit stack size. 624 // Check that the entry stack size matches the exit stack size.
627 __ movq(R10, RBP); 625 __ movq(R10, RBP);
628 __ subq(R10, RSP); 626 __ subq(R10, RSP);
629 ASSERT(locals_space_size() >= 0); 627 ASSERT(locals_space_size() >= 0);
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
807 // The loop local scope declares variables that are captured. 805 // The loop local scope declares variables that are captured.
808 // Allocate and chain a new context. 806 // Allocate and chain a new context.
809 __ movq(R10, Immediate(num_context_variables)); 807 __ movq(R10, Immediate(num_context_variables));
810 const ExternalLabel label("alloc_context", 808 const ExternalLabel label("alloc_context",
811 StubCode::AllocateContextEntryPoint()); 809 StubCode::AllocateContextEntryPoint());
812 GenerateCall(node_sequence->token_index(), &label, PcDescriptors::kOther); 810 GenerateCall(node_sequence->token_index(), &label, PcDescriptors::kOther);
813 811
814 // If this node_sequence is the body of the function being compiled, and if 812 // If this node_sequence is the body of the function being compiled, and if
815 // this function is not a closure, do not link the current context as the 813 // this function is not a closure, do not link the current context as the
816 // parent of the newly allocated context, as it is not accessible. Instead, 814 // parent of the newly allocated context, as it is not accessible. Instead,
817 // save it on the stack and restore it on exit. 815 // save it in a pre-allocated variable and restore it on exit.
818 if ((node_sequence == parsed_function_.node_sequence()) && 816 if ((node_sequence == parsed_function_.node_sequence()) &&
819 !parsed_function_.function().IsClosureFunction()) { 817 (parsed_function_.saved_context_var() != NULL)) {
820 __ pushq(CTX); 818 GenerateStoreVariable(
819 *parsed_function_.saved_context_var(), CTX, kNoRegister);
821 const Immediate raw_null = 820 const Immediate raw_null =
822 Immediate(reinterpret_cast<intptr_t>(Object::null())); 821 Immediate(reinterpret_cast<intptr_t>(Object::null()));
823 __ movq(CTX, raw_null); 822 __ movq(CTX, raw_null);
824 } 823 }
825 824
826 // Chain the new context in RAX to its parent in CTX. 825 // Chain the new context in RAX to its parent in CTX.
827 __ StoreIntoObject(RAX, 826 __ StoreIntoObject(RAX,
828 FieldAddress(RAX, Context::parent_offset()), 827 FieldAddress(RAX, Context::parent_offset()),
829 CTX); 828 CTX);
830 // Set new context as current context. 829 // Set new context as current context.
(...skipping 30 matching lines...) Expand all
861 // code checking the type of the actual arguments. 860 // code checking the type of the actual arguments.
862 if (FLAG_enable_type_checks && 861 if (FLAG_enable_type_checks &&
863 (node_sequence == parsed_function_.node_sequence())) { 862 (node_sequence == parsed_function_.node_sequence())) {
864 GenerateArgumentTypeChecks(); 863 GenerateArgumentTypeChecks();
865 } 864 }
866 for (int i = 0; i < node_sequence->length(); i++) { 865 for (int i = 0; i < node_sequence->length(); i++) {
867 AstNode* child_node = node_sequence->NodeAt(i); 866 AstNode* child_node = node_sequence->NodeAt(i);
868 state()->set_root_node(child_node); 867 state()->set_root_node(child_node);
869 child_node->Visit(this); 868 child_node->Visit(this);
870 } 869 }
871 if (num_context_variables > 0) { 870
872 // Unchain the previously allocated context. 871 // Unchain the previously allocated context.
873 if ((node_sequence == parsed_function_.node_sequence()) && 872 if ((node_sequence == parsed_function_.node_sequence()) &&
874 !parsed_function_.function().IsClosureFunction()) { 873 (parsed_function_.saved_context_var() != NULL)) {
875 __ popq(CTX); 874 ASSERT(num_context_variables > 0);
876 } else { 875 GenerateLoadVariable(CTX, *parsed_function_.saved_context_var());
877 __ movq(CTX, FieldAddress(CTX, Context::parent_offset())); 876 } else if (num_context_variables > 0) {
878 } 877 __ movq(CTX, FieldAddress(CTX, Context::parent_offset()));
879 } 878 }
879
880 // If this node sequence is labeled, a break out of the sequence will have 880 // If this node sequence is labeled, a break out of the sequence will have
881 // taken care of unchaining the context. 881 // taken care of unchaining the context.
882 if (node_sequence->label() != NULL) { 882 if (node_sequence->label() != NULL) {
883 __ Bind(node_sequence->label()->break_label()); 883 __ Bind(node_sequence->label()->break_label());
884 if ((num_context_variables > 0) && 884
885 (node_sequence == parsed_function_.node_sequence()) && 885 // The context saved on entry must be restored.
886 !parsed_function_.function().IsClosureFunction()) { 886 if ((node_sequence == parsed_function_.node_sequence()) &&
887 __ popq(CTX); 887 (parsed_function_.saved_context_var() != NULL)) {
888 GenerateLoadVariable(CTX, *parsed_function_.saved_context_var());
888 } 889 }
889 } 890 }
890 set_context_level(previous_context_level); 891 set_context_level(previous_context_level);
891 } 892 }
892 893
893 894
894 void CodeGenerator::VisitArgumentListNode(ArgumentListNode* arguments) { 895 void CodeGenerator::VisitArgumentListNode(ArgumentListNode* arguments) {
895 for (int i = 0; i < arguments->length(); i++) { 896 for (int i = 0; i < arguments->length(); i++) {
896 AstNode* argument = arguments->NodeAt(i); 897 AstNode* argument = arguments->NodeAt(i);
897 argument->Visit(this); 898 argument->Visit(this);
(...skipping 1641 matching lines...) Expand 10 before | Expand all | Expand 10 after
2539 // and ':stacktrace_var' can never be captured variables. 2540 // and ':stacktrace_var' can never be captured variables.
2540 // Restore CTX from local variable ':saved_context'. 2541 // Restore CTX from local variable ':saved_context'.
2541 GenerateLoadVariable(CTX, node->context_var()); 2542 GenerateLoadVariable(CTX, node->context_var());
2542 2543
2543 // Restore RSP from RBP as we are coming from a throw and the code for 2544 // Restore RSP from RBP as we are coming from a throw and the code for
2544 // popping arguments has not been run. 2545 // popping arguments has not been run.
2545 ASSERT(locals_space_size() >= 0); 2546 ASSERT(locals_space_size() >= 0);
2546 __ movq(RSP, RBP); 2547 __ movq(RSP, RBP);
2547 __ subq(RSP, Immediate(locals_space_size())); 2548 __ subq(RSP, Immediate(locals_space_size()));
2548 2549
2549 if ((context_level() > 0) &&
2550 !parsed_function_.function().IsClosureFunction()) {
2551 // CTX was saved on entry.
2552 __ subq(RSP, Immediate(kWordSize));
2553 }
2554
2555 // The JumpToExceptionHandler trampoline code sets up 2550 // The JumpToExceptionHandler trampoline code sets up
2556 // - the exception object in RAX (kExceptionObjectReg) 2551 // - the exception object in RAX (kExceptionObjectReg)
2557 // - the stacktrace object in register RDX (kStackTraceObjectReg) 2552 // - the stacktrace object in register RDX (kStackTraceObjectReg)
2558 // We now setup the exception object and the trace object 2553 // We now setup the exception object and the trace object
2559 // so that the handler code has access to these objects. 2554 // so that the handler code has access to these objects.
2560 GenerateStoreVariable(node->exception_var(), 2555 GenerateStoreVariable(node->exception_var(),
2561 kExceptionObjectReg, 2556 kExceptionObjectReg,
2562 kNoRegister); 2557 kNoRegister);
2563 GenerateStoreVariable(node->stacktrace_var(), 2558 GenerateStoreVariable(node->stacktrace_var(),
2564 kStackTraceObjectReg, 2559 kStackTraceObjectReg,
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2695 const Error& error = Error::Handle( 2690 const Error& error = Error::Handle(
2696 Parser::FormatError(script, token_index, "Error", format, args)); 2691 Parser::FormatError(script, token_index, "Error", format, args));
2697 va_end(args); 2692 va_end(args);
2698 Isolate::Current()->long_jump_base()->Jump(1, error); 2693 Isolate::Current()->long_jump_base()->Jump(1, error);
2699 UNREACHABLE(); 2694 UNREACHABLE();
2700 } 2695 }
2701 2696
2702 } // namespace dart 2697 } // namespace dart
2703 2698
2704 #endif // defined TARGET_ARCH_X64 2699 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/code_generator_ia32.cc ('k') | runtime/vm/parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698