| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |