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

Side by Side Diff: runtime/vm/code_generator_x64.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 | « runtime/vm/code_generator_ia32.cc ('k') | runtime/vm/object.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 597 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 0, 608 0,
609 kStackOverflowRuntimeEntry); 609 kStackOverflowRuntimeEntry);
610 __ Bind(&no_stack_overflow); 610 __ Bind(&no_stack_overflow);
611 } 611 }
612 612
613 613
614 void CodeGenerator::GenerateReturnEpilog(ReturnNode* node) { 614 void CodeGenerator::GenerateReturnEpilog(ReturnNode* node) {
615 // Unchain the context(s) up to context level 0. 615 // Unchain the context(s) up to context level 0.
616 int context_level = state()->context_level(); 616 int context_level = state()->context_level();
617 ASSERT(context_level >= 0); 617 ASSERT(context_level >= 0);
618 while (context_level-- > 0) { 618 if (!parsed_function_.function().IsClosureFunction()) {
619 __ movq(CTX, FieldAddress(CTX, Context::parent_offset())); 619 if (context_level > 0) {
620 // CTX on entry was saved on the stack, but not linked as context parent.
621 __ popq(CTX);
622 }
623 } else {
624 while (context_level-- > 0) {
625 __ movq(CTX, FieldAddress(CTX, Context::parent_offset()));
626 }
620 } 627 }
621 #ifdef DEBUG 628 #ifdef DEBUG
622 // Check that the entry stack size matches the exit stack size. 629 // Check that the entry stack size matches the exit stack size.
623 __ movq(R10, RBP); 630 __ movq(R10, RBP);
624 __ subq(R10, RSP); 631 __ subq(R10, RSP);
625 ASSERT(locals_space_size() >= 0); 632 ASSERT(locals_space_size() >= 0);
626 __ cmpq(R10, Immediate(locals_space_size())); 633 __ cmpq(R10, Immediate(locals_space_size()));
627 Label wrong_stack; 634 Label wrong_stack;
628 __ j(NOT_EQUAL, &wrong_stack, Assembler::kNearJump); 635 __ j(NOT_EQUAL, &wrong_stack, Assembler::kNearJump);
629 #endif // DEBUG. 636 #endif // DEBUG.
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 const intptr_t num_context_variables = 806 const intptr_t num_context_variables =
800 (scope != NULL) ? scope->num_context_variables() : 0; 807 (scope != NULL) ? scope->num_context_variables() : 0;
801 if (num_context_variables > 0) { 808 if (num_context_variables > 0) {
802 // The loop local scope declares variables that are captured. 809 // The loop local scope declares variables that are captured.
803 // Allocate and chain a new context. 810 // Allocate and chain a new context.
804 __ movq(R10, Immediate(num_context_variables)); 811 __ movq(R10, Immediate(num_context_variables));
805 const ExternalLabel label("alloc_context", 812 const ExternalLabel label("alloc_context",
806 StubCode::AllocateContextEntryPoint()); 813 StubCode::AllocateContextEntryPoint());
807 GenerateCall(node_sequence->token_index(), &label, PcDescriptors::kOther); 814 GenerateCall(node_sequence->token_index(), &label, PcDescriptors::kOther);
808 815
816 // If this node_sequence is the body of the function being compiled, and if
817 // this function is not a closure, do not link the current context as the
818 // parent of the newly allocated context, as it is not accessible. Instead,
819 // save it on the stack and restore it on exit.
820 if ((node_sequence == parsed_function_.node_sequence()) &&
821 !parsed_function_.function().IsClosureFunction()) {
822 __ pushq(CTX);
823 const Immediate raw_null =
824 Immediate(reinterpret_cast<intptr_t>(Object::null()));
825 __ movq(CTX, raw_null);
826 }
827
809 // Chain the new context in RAX to its parent in CTX. 828 // Chain the new context in RAX to its parent in CTX.
810 __ StoreIntoObject(RAX, 829 __ StoreIntoObject(RAX,
811 FieldAddress(RAX, Context::parent_offset()), 830 FieldAddress(RAX, Context::parent_offset()),
812 CTX); 831 CTX);
813 // Set new context as current context. 832 // Set new context as current context.
814 __ movq(CTX, RAX); 833 __ movq(CTX, RAX);
815 state()->set_context_level(scope->context_level()); 834 state()->set_context_level(scope->context_level());
816 835
817 // If this node_sequence is the body of the function being compiled, copy 836 // If this node_sequence is the body of the function being compiled, copy
818 // the captured parameters from the frame into the context. 837 // the captured parameters from the frame into the context.
(...skipping 27 matching lines...) Expand all
846 (node_sequence == parsed_function_.node_sequence())) { 865 (node_sequence == parsed_function_.node_sequence())) {
847 GenerateArgumentTypeChecks(); 866 GenerateArgumentTypeChecks();
848 } 867 }
849 for (int i = 0; i < node_sequence->length(); i++) { 868 for (int i = 0; i < node_sequence->length(); i++) {
850 AstNode* child_node = node_sequence->NodeAt(i); 869 AstNode* child_node = node_sequence->NodeAt(i);
851 state()->set_root_node(child_node); 870 state()->set_root_node(child_node);
852 child_node->Visit(this); 871 child_node->Visit(this);
853 } 872 }
854 if (num_context_variables > 0) { 873 if (num_context_variables > 0) {
855 // Unchain the previously allocated context. 874 // Unchain the previously allocated context.
856 __ movq(CTX, FieldAddress(CTX, Context::parent_offset())); 875 if ((node_sequence == parsed_function_.node_sequence()) &&
876 !parsed_function_.function().IsClosureFunction()) {
877 __ popq(CTX);
878 } else {
879 __ movq(CTX, FieldAddress(CTX, Context::parent_offset()));
880 }
857 } 881 }
858 // If this node sequence is labeled, a break out of the sequence will have 882 // If this node sequence is labeled, a break out of the sequence will have
859 // taken care of unchaining the context. 883 // taken care of unchaining the context.
860 if (node_sequence->label() != NULL) { 884 if (node_sequence->label() != NULL) {
861 __ Bind(node_sequence->label()->break_label()); 885 __ Bind(node_sequence->label()->break_label());
886 if ((num_context_variables > 0) &&
887 (node_sequence == parsed_function_.node_sequence()) &&
888 !parsed_function_.function().IsClosureFunction()) {
889 __ popq(CTX);
890 }
862 } 891 }
863 } 892 }
864 893
865 894
866 void CodeGenerator::VisitArgumentListNode(ArgumentListNode* arguments) { 895 void CodeGenerator::VisitArgumentListNode(ArgumentListNode* arguments) {
867 for (int i = 0; i < arguments->length(); i++) { 896 for (int i = 0; i < arguments->length(); i++) {
868 AstNode* argument = arguments->NodeAt(i); 897 AstNode* argument = arguments->NodeAt(i);
869 argument->Visit(this); 898 argument->Visit(this);
870 } 899 }
871 } 900 }
(...skipping 1639 matching lines...) Expand 10 before | Expand all | Expand 10 after
2511 // and ':stacktrace_var' can never be captured variables. 2540 // and ':stacktrace_var' can never be captured variables.
2512 // Restore CTX from local variable ':saved_context'. 2541 // Restore CTX from local variable ':saved_context'.
2513 GenerateLoadVariable(CTX, node->context_var()); 2542 GenerateLoadVariable(CTX, node->context_var());
2514 2543
2515 // 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
2516 // popping arguments has not been run. 2545 // popping arguments has not been run.
2517 ASSERT(locals_space_size() >= 0); 2546 ASSERT(locals_space_size() >= 0);
2518 __ movq(RSP, RBP); 2547 __ movq(RSP, RBP);
2519 __ subq(RSP, Immediate(locals_space_size())); 2548 __ subq(RSP, Immediate(locals_space_size()));
2520 2549
2550 if ((state()->context_level() > 0) &&
2551 !parsed_function_.function().IsClosureFunction()) {
2552 // CTX was saved on entry.
2553 __ subq(RSP, Immediate(kWordSize));
2554 }
2555
2521 // The JumpToExceptionHandler trampoline code sets up 2556 // The JumpToExceptionHandler trampoline code sets up
2522 // - the exception object in RAX (kExceptionObjectReg) 2557 // - the exception object in RAX (kExceptionObjectReg)
2523 // - the stacktrace object in register RDX (kStackTraceObjectReg) 2558 // - the stacktrace object in register RDX (kStackTraceObjectReg)
2524 // We now setup the exception object and the trace object 2559 // We now setup the exception object and the trace object
2525 // so that the handler code has access to these objects. 2560 // so that the handler code has access to these objects.
2526 GenerateStoreVariable(node->exception_var(), 2561 GenerateStoreVariable(node->exception_var(),
2527 kExceptionObjectReg, 2562 kExceptionObjectReg,
2528 kNoRegister); 2563 kNoRegister);
2529 GenerateStoreVariable(node->stacktrace_var(), 2564 GenerateStoreVariable(node->stacktrace_var(),
2530 kStackTraceObjectReg, 2565 kStackTraceObjectReg,
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2661 const Error& error = Error::Handle( 2696 const Error& error = Error::Handle(
2662 Parser::FormatError(script, token_index, "Error", format, args)); 2697 Parser::FormatError(script, token_index, "Error", format, args));
2663 va_end(args); 2698 va_end(args);
2664 Isolate::Current()->long_jump_base()->Jump(1, error); 2699 Isolate::Current()->long_jump_base()->Jump(1, error);
2665 UNREACHABLE(); 2700 UNREACHABLE();
2666 } 2701 }
2667 2702
2668 } // namespace dart 2703 } // namespace dart
2669 2704
2670 #endif // defined TARGET_ARCH_X64 2705 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/code_generator_ia32.cc ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698