| 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/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 // Calls do not need stubs, they share a deoptimization trampoline. | 36 // Calls do not need stubs, they share a deoptimization trampoline. |
| 37 ASSERT(reason() != kDeoptAtCall); | 37 ASSERT(reason() != kDeoptAtCall); |
| 38 Assembler* assem = compiler->assembler(); | 38 Assembler* assem = compiler->assembler(); |
| 39 #define __ assem-> | 39 #define __ assem-> |
| 40 __ Comment("Deopt stub for id %"Pd"", deopt_id()); | 40 __ Comment("Deopt stub for id %"Pd"", deopt_id()); |
| 41 __ Bind(entry_label()); | 41 __ Bind(entry_label()); |
| 42 if (FLAG_trap_on_deoptimization) __ int3(); | 42 if (FLAG_trap_on_deoptimization) __ int3(); |
| 43 | 43 |
| 44 ASSERT(deoptimization_env() != NULL); | 44 ASSERT(deoptimization_env() != NULL); |
| 45 | 45 |
| 46 if (compiler->IsLeaf()) { | |
| 47 __ Comment("Leaf method, lazy PC marker setup"); | |
| 48 // TODO(srdjan): Can we use TMP instead of RAX? We must guarantee that | |
| 49 // TMP is never part of deoptimization environment. | |
| 50 __ pushq(RAX); // Preserve RAX. | |
| 51 Label L; | |
| 52 __ call(&L); | |
| 53 const intptr_t offset = assem->CodeSize(); | |
| 54 __ Bind(&L); | |
| 55 __ popq(RAX); | |
| 56 __ subq(RAX, | |
| 57 Immediate(offset - AssemblerMacros::kOffsetOfSavedPCfromEntrypoint)); | |
| 58 __ movq(Address(RBP, -kWordSize), RAX); | |
| 59 __ popq(RAX); // Restore RAX. | |
| 60 } | |
| 61 __ call(&StubCode::DeoptimizeLabel()); | 46 __ call(&StubCode::DeoptimizeLabel()); |
| 62 set_pc_offset(assem->CodeSize()); | 47 set_pc_offset(assem->CodeSize()); |
| 63 __ int3(); | 48 __ int3(); |
| 64 #undef __ | 49 #undef __ |
| 65 } | 50 } |
| 66 | 51 |
| 67 | 52 |
| 68 #define __ assembler()-> | 53 #define __ assembler()-> |
| 69 | 54 |
| 70 | 55 |
| (...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 824 // dropped the spill slots. | 809 // dropped the spill slots. |
| 825 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder(); | 810 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder(); |
| 826 if (function.IsClosureFunction()) { | 811 if (function.IsClosureFunction()) { |
| 827 // We do not use GenerateCallRuntime because of the non-standard (empty) | 812 // We do not use GenerateCallRuntime because of the non-standard (empty) |
| 828 // stackmap used here. | 813 // stackmap used here. |
| 829 __ CallRuntime(kClosureArgumentMismatchRuntimeEntry); | 814 __ CallRuntime(kClosureArgumentMismatchRuntimeEntry); |
| 830 AddCurrentDescriptor(PcDescriptors::kOther, | 815 AddCurrentDescriptor(PcDescriptors::kOther, |
| 831 Isolate::kNoDeoptId, | 816 Isolate::kNoDeoptId, |
| 832 0); // No token position. | 817 0); // No token position. |
| 833 } else { | 818 } else { |
| 834 ASSERT(!IsLeaf()); | |
| 835 // Invoke noSuchMethod function. | 819 // Invoke noSuchMethod function. |
| 836 const int kNumArgsChecked = 1; | 820 const int kNumArgsChecked = 1; |
| 837 ICData& ic_data = ICData::ZoneHandle(); | 821 ICData& ic_data = ICData::ZoneHandle(); |
| 838 ic_data = ICData::New(function, | 822 ic_data = ICData::New(function, |
| 839 String::Handle(function.name()), | 823 String::Handle(function.name()), |
| 840 Isolate::kNoDeoptId, | 824 Isolate::kNoDeoptId, |
| 841 kNumArgsChecked); | 825 kNumArgsChecked); |
| 842 __ LoadObject(RBX, ic_data); | 826 __ LoadObject(RBX, ic_data); |
| 843 // RBP - 8 : PC marker, allows easy identification of RawInstruction obj. | 827 // RBP - 8 : PC marker, allows easy identification of RawInstruction obj. |
| 844 // RBP : points to previous frame pointer. | 828 // RBP : points to previous frame pointer. |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 __ jmp(&StubCode::FixCallersTargetLabel()); | 917 __ jmp(&StubCode::FixCallersTargetLabel()); |
| 934 return; | 918 return; |
| 935 } | 919 } |
| 936 // Specialized version of entry code from CodeGenerator::GenerateEntryCode. | 920 // Specialized version of entry code from CodeGenerator::GenerateEntryCode. |
| 937 const Function& function = parsed_function().function(); | 921 const Function& function = parsed_function().function(); |
| 938 | 922 |
| 939 const int num_fixed_params = function.num_fixed_parameters(); | 923 const int num_fixed_params = function.num_fixed_parameters(); |
| 940 const int num_copied_params = parsed_function().num_copied_params(); | 924 const int num_copied_params = parsed_function().num_copied_params(); |
| 941 const int num_locals = parsed_function().num_stack_locals(); | 925 const int num_locals = parsed_function().num_stack_locals(); |
| 942 __ Comment("Enter frame"); | 926 __ Comment("Enter frame"); |
| 943 if (IsLeaf()) { | 927 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize)); |
| 944 AssemblerMacros::EnterDartLeafFrame(assembler(), (StackSize() * kWordSize)); | |
| 945 } else { | |
| 946 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize)); | |
| 947 } | |
| 948 | 928 |
| 949 // For optimized code, keep a bitmap of the frame in order to build | 929 // For optimized code, keep a bitmap of the frame in order to build |
| 950 // stackmaps for GC safepoints in the prologue. | 930 // stackmaps for GC safepoints in the prologue. |
| 951 LocationSummary* prologue_locs = NULL; | 931 LocationSummary* prologue_locs = NULL; |
| 952 if (is_optimizing()) { | 932 if (is_optimizing()) { |
| 953 // Spill slots are allocated but not initialized. | 933 // Spill slots are allocated but not initialized. |
| 954 prologue_locs = new LocationSummary(0, 0, LocationSummary::kCall); | 934 prologue_locs = new LocationSummary(0, 0, LocationSummary::kCall); |
| 955 prologue_locs->stack_bitmap()->SetLength(StackSize()); | 935 prologue_locs->stack_bitmap()->SetLength(StackSize()); |
| 956 } | 936 } |
| 957 | 937 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1042 Isolate::kNoDeoptId, | 1022 Isolate::kNoDeoptId, |
| 1043 0); // No token position. | 1023 0); // No token position. |
| 1044 __ jmp(&StubCode::DeoptimizeLazyLabel()); | 1024 __ jmp(&StubCode::DeoptimizeLazyLabel()); |
| 1045 } | 1025 } |
| 1046 | 1026 |
| 1047 | 1027 |
| 1048 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, | 1028 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, |
| 1049 const ExternalLabel* label, | 1029 const ExternalLabel* label, |
| 1050 PcDescriptors::Kind kind, | 1030 PcDescriptors::Kind kind, |
| 1051 LocationSummary* locs) { | 1031 LocationSummary* locs) { |
| 1052 ASSERT(!IsLeaf()); | |
| 1053 __ call(label); | 1032 __ call(label); |
| 1054 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos); | 1033 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos); |
| 1055 RecordSafepoint(locs); | 1034 RecordSafepoint(locs); |
| 1056 } | 1035 } |
| 1057 | 1036 |
| 1058 | 1037 |
| 1059 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id, | 1038 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id, |
| 1060 intptr_t token_pos, | 1039 intptr_t token_pos, |
| 1061 const ExternalLabel* label, | 1040 const ExternalLabel* label, |
| 1062 PcDescriptors::Kind kind, | 1041 PcDescriptors::Kind kind, |
| 1063 LocationSummary* locs) { | 1042 LocationSummary* locs) { |
| 1064 ASSERT(!IsLeaf()); | |
| 1065 __ call(label); | 1043 __ call(label); |
| 1066 AddCurrentDescriptor(kind, deopt_id, token_pos); | 1044 AddCurrentDescriptor(kind, deopt_id, token_pos); |
| 1067 RecordSafepoint(locs); | 1045 RecordSafepoint(locs); |
| 1068 // Marks either the continuation point in unoptimized code or the | 1046 // Marks either the continuation point in unoptimized code or the |
| 1069 // deoptimization point in optimized code, after call. | 1047 // deoptimization point in optimized code, after call. |
| 1070 if (is_optimizing()) { | 1048 if (is_optimizing()) { |
| 1071 AddDeoptIndexAtCall(deopt_id, token_pos); | 1049 AddDeoptIndexAtCall(deopt_id, token_pos); |
| 1072 } else { | 1050 } else { |
| 1073 // Add deoptimization continuation point after the call and before the | 1051 // Add deoptimization continuation point after the call and before the |
| 1074 // arguments are removed. | 1052 // arguments are removed. |
| 1075 AddCurrentDescriptor(PcDescriptors::kDeoptAfter, | 1053 AddCurrentDescriptor(PcDescriptors::kDeoptAfter, |
| 1076 deopt_id, | 1054 deopt_id, |
| 1077 token_pos); | 1055 token_pos); |
| 1078 } | 1056 } |
| 1079 } | 1057 } |
| 1080 | 1058 |
| 1081 | 1059 |
| 1082 void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos, | 1060 void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos, |
| 1083 const RuntimeEntry& entry, | 1061 const RuntimeEntry& entry, |
| 1084 LocationSummary* locs) { | 1062 LocationSummary* locs) { |
| 1085 ASSERT(!IsLeaf()); | |
| 1086 __ CallRuntime(entry); | 1063 __ CallRuntime(entry); |
| 1087 AddCurrentDescriptor(PcDescriptors::kOther, Isolate::kNoDeoptId, token_pos); | 1064 AddCurrentDescriptor(PcDescriptors::kOther, Isolate::kNoDeoptId, token_pos); |
| 1088 RecordSafepoint(locs); | 1065 RecordSafepoint(locs); |
| 1089 } | 1066 } |
| 1090 | 1067 |
| 1091 | 1068 |
| 1092 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, | 1069 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, |
| 1093 const ICData& ic_data, | 1070 const ICData& ic_data, |
| 1094 const Array& arguments_descriptor, | 1071 const Array& arguments_descriptor, |
| 1095 intptr_t argument_count, | 1072 intptr_t argument_count, |
| 1096 intptr_t deopt_id, | 1073 intptr_t deopt_id, |
| 1097 intptr_t token_pos, | 1074 intptr_t token_pos, |
| 1098 LocationSummary* locs) { | 1075 LocationSummary* locs) { |
| 1099 ASSERT(!IsLeaf()); | |
| 1100 __ LoadObject(RBX, ic_data); | 1076 __ LoadObject(RBX, ic_data); |
| 1101 __ LoadObject(R10, arguments_descriptor); | 1077 __ LoadObject(R10, arguments_descriptor); |
| 1102 GenerateDartCall(deopt_id, | 1078 GenerateDartCall(deopt_id, |
| 1103 token_pos, | 1079 token_pos, |
| 1104 target_label, | 1080 target_label, |
| 1105 PcDescriptors::kIcCall, | 1081 PcDescriptors::kIcCall, |
| 1106 locs); | 1082 locs); |
| 1107 __ Drop(argument_count); | 1083 __ Drop(argument_count); |
| 1108 } | 1084 } |
| 1109 | 1085 |
| 1110 | 1086 |
| 1111 void FlowGraphCompiler::EmitStaticCall(const Function& function, | 1087 void FlowGraphCompiler::EmitStaticCall(const Function& function, |
| 1112 const Array& arguments_descriptor, | 1088 const Array& arguments_descriptor, |
| 1113 intptr_t argument_count, | 1089 intptr_t argument_count, |
| 1114 intptr_t deopt_id, | 1090 intptr_t deopt_id, |
| 1115 intptr_t token_pos, | 1091 intptr_t token_pos, |
| 1116 LocationSummary* locs) { | 1092 LocationSummary* locs) { |
| 1117 ASSERT(!IsLeaf()); | |
| 1118 __ LoadObject(RBX, function); | 1093 __ LoadObject(RBX, function); |
| 1119 __ LoadObject(R10, arguments_descriptor); | 1094 __ LoadObject(R10, arguments_descriptor); |
| 1120 if (function.HasCode()) { | 1095 if (function.HasCode()) { |
| 1121 const Code& code = Code::Handle(function.CurrentCode()); | 1096 const Code& code = Code::Handle(function.CurrentCode()); |
| 1122 ExternalLabel target_label(function.ToFullyQualifiedCString(), | 1097 ExternalLabel target_label(function.ToFullyQualifiedCString(), |
| 1123 code.EntryPoint()); | 1098 code.EntryPoint()); |
| 1124 GenerateDartCall(deopt_id, | 1099 GenerateDartCall(deopt_id, |
| 1125 token_pos, | 1100 token_pos, |
| 1126 &target_label, | 1101 &target_label, |
| 1127 PcDescriptors::kFuncCall, | 1102 PcDescriptors::kFuncCall, |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1363 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1338 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
| 1364 __ Exchange(mem1, mem2); | 1339 __ Exchange(mem1, mem2); |
| 1365 } | 1340 } |
| 1366 | 1341 |
| 1367 | 1342 |
| 1368 #undef __ | 1343 #undef __ |
| 1369 | 1344 |
| 1370 } // namespace dart | 1345 } // namespace dart |
| 1371 | 1346 |
| 1372 #endif // defined TARGET_ARCH_X64 | 1347 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |