| 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 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 749 __ cmpq(RSP, Address(TMP, 0)); | 749 __ cmpq(RSP, Address(TMP, 0)); |
| 750 Label no_stack_overflow; | 750 Label no_stack_overflow; |
| 751 __ j(ABOVE, &no_stack_overflow); | 751 __ j(ABOVE, &no_stack_overflow); |
| 752 GenerateCallRuntime(AstNode::kNoId, | 752 GenerateCallRuntime(AstNode::kNoId, |
| 753 function.token_index(), | 753 function.token_index(), |
| 754 kStackOverflowRuntimeEntry); | 754 kStackOverflowRuntimeEntry); |
| 755 __ Bind(&no_stack_overflow); | 755 __ Bind(&no_stack_overflow); |
| 756 } | 756 } |
| 757 | 757 |
| 758 | 758 |
| 759 void CodeGenerator::GenerateReturnEpilog() { | 759 void CodeGenerator::GenerateReturnEpilog(ReturnNode* node) { |
| 760 // Unchain the context(s) up to context level 0. | 760 // Unchain the context(s) up to context level 0. |
| 761 int context_level = state()->context_level(); | 761 int context_level = state()->context_level(); |
| 762 ASSERT(context_level >= 0); | 762 ASSERT(context_level >= 0); |
| 763 while (context_level-- > 0) { | 763 while (context_level-- > 0) { |
| 764 __ movq(CTX, FieldAddress(CTX, Context::parent_offset())); | 764 __ movq(CTX, FieldAddress(CTX, Context::parent_offset())); |
| 765 } | 765 } |
| 766 #ifdef DEBUG | 766 #ifdef DEBUG |
| 767 // Check that the entry stack size matches the exit stack size. | 767 // Check that the entry stack size matches the exit stack size. |
| 768 __ movq(R10, RBP); | 768 __ movq(R10, RBP); |
| 769 __ subq(R10, RSP); | 769 __ subq(R10, RSP); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 780 __ LoadObject(RBX, function); | 780 __ LoadObject(RBX, function); |
| 781 __ pushq(RBX); | 781 __ pushq(RBX); |
| 782 GenerateCallRuntime(AstNode::kNoId, | 782 GenerateCallRuntime(AstNode::kNoId, |
| 783 0, | 783 0, |
| 784 kTraceFunctionExitRuntimeEntry); | 784 kTraceFunctionExitRuntimeEntry); |
| 785 __ popq(RAX); // Remove argument. | 785 __ popq(RAX); // Remove argument. |
| 786 __ popq(RAX); // Restore result. | 786 __ popq(RAX); // Restore result. |
| 787 } | 787 } |
| 788 __ LeaveFrame(); | 788 __ LeaveFrame(); |
| 789 __ ret(); | 789 __ ret(); |
| 790 // TODO(hausner): insert generation of of PcDescriptor::kReturn, |
| 791 // analogous to 32bit version. |
| 790 | 792 |
| 791 #ifdef DEBUG | 793 #ifdef DEBUG |
| 792 __ Bind(&wrong_stack); | 794 __ Bind(&wrong_stack); |
| 793 __ Stop("Exit stack size does not match the entry stack size."); | 795 __ Stop("Exit stack size does not match the entry stack size."); |
| 794 #endif // DEBUG. | 796 #endif // DEBUG. |
| 795 } | 797 } |
| 796 | 798 |
| 797 | 799 |
| 798 void CodeGenerator::VisitReturnNode(ReturnNode* node) { | 800 void CodeGenerator::VisitReturnNode(ReturnNode* node) { |
| 799 ASSERT(!IsResultNeeded(node)); | 801 ASSERT(!IsResultNeeded(node)); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 829 // Implicit getters do not need a type check at return. | 831 // Implicit getters do not need a type check at return. |
| 830 if ((kind != RawFunction::kImplicitGetter) && | 832 if ((kind != RawFunction::kImplicitGetter) && |
| 831 (kind != RawFunction::kConstImplicitGetter)) { | 833 (kind != RawFunction::kConstImplicitGetter)) { |
| 832 GenerateAssertAssignable( | 834 GenerateAssertAssignable( |
| 833 node->id(), | 835 node->id(), |
| 834 node->value()->token_index(), | 836 node->value()->token_index(), |
| 835 AbstractType::ZoneHandle(parsed_function().function().result_type()), | 837 AbstractType::ZoneHandle(parsed_function().function().result_type()), |
| 836 String::ZoneHandle(String::NewSymbol("function result"))); | 838 String::ZoneHandle(String::NewSymbol("function result"))); |
| 837 } | 839 } |
| 838 } | 840 } |
| 839 GenerateReturnEpilog(); | 841 GenerateReturnEpilog(node); |
| 840 } | 842 } |
| 841 | 843 |
| 842 | 844 |
| 843 void CodeGenerator::VisitLiteralNode(LiteralNode* node) { | 845 void CodeGenerator::VisitLiteralNode(LiteralNode* node) { |
| 844 if (!IsResultNeeded(node)) return; | 846 if (!IsResultNeeded(node)) return; |
| 845 __ PushObject(node->literal()); | 847 __ PushObject(node->literal()); |
| 846 } | 848 } |
| 847 | 849 |
| 848 | 850 |
| 849 void CodeGenerator::VisitTypeNode(TypeNode* node) { | 851 void CodeGenerator::VisitTypeNode(TypeNode* node) { |
| (...skipping 1939 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2789 const Error& error = Error::Handle( | 2791 const Error& error = Error::Handle( |
| 2790 Parser::FormatError(script, token_index, "Error", format, args)); | 2792 Parser::FormatError(script, token_index, "Error", format, args)); |
| 2791 va_end(args); | 2793 va_end(args); |
| 2792 Isolate::Current()->long_jump_base()->Jump(1, error); | 2794 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2793 UNREACHABLE(); | 2795 UNREACHABLE(); |
| 2794 } | 2796 } |
| 2795 | 2797 |
| 2796 } // namespace dart | 2798 } // namespace dart |
| 2797 | 2799 |
| 2798 #endif // defined TARGET_ARCH_X64 | 2800 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |