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" |
11 #include "vm/ast_printer.h" | 11 #include "vm/ast_printer.h" |
12 #include "vm/dart_entry.h" | 12 #include "vm/dart_entry.h" |
13 #include "vm/il_printer.h" | 13 #include "vm/il_printer.h" |
14 #include "vm/locations.h" | 14 #include "vm/locations.h" |
15 #include "vm/object_store.h" | 15 #include "vm/object_store.h" |
16 #include "vm/parser.h" | 16 #include "vm/parser.h" |
17 #include "vm/stub_code.h" | 17 #include "vm/stub_code.h" |
18 #include "vm/symbols.h" | 18 #include "vm/symbols.h" |
19 | 19 |
20 namespace dart { | 20 namespace dart { |
21 | 21 |
| 22 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization."); |
| 23 DECLARE_FLAG(int, optimization_counter_threshold); |
22 DECLARE_FLAG(bool, print_ast); | 24 DECLARE_FLAG(bool, print_ast); |
23 DECLARE_FLAG(bool, print_scopes); | 25 DECLARE_FLAG(bool, print_scopes); |
24 DECLARE_FLAG(bool, use_sse41); | 26 DECLARE_FLAG(bool, use_sse41); |
25 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization."); | |
26 | 27 |
27 | 28 |
28 bool FlowGraphCompiler::SupportsUnboxedMints() { | 29 bool FlowGraphCompiler::SupportsUnboxedMints() { |
29 return false; | 30 return false; |
30 } | 31 } |
31 | 32 |
32 | 33 |
33 void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler, | 34 void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler, |
34 intptr_t stub_ix) { | 35 intptr_t stub_ix) { |
35 // Calls do not need stubs, they share a deoptimization trampoline. | 36 // Calls do not need stubs, they share a deoptimization trampoline. |
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 __ movq(RAX, Address(RSP, 2 * kWordSize)); // Receiver. | 859 __ movq(RAX, Address(RSP, 2 * kWordSize)); // Receiver. |
859 __ movq(RBX, Address(RSP, 1 * kWordSize)); // Value. | 860 __ movq(RBX, Address(RSP, 1 * kWordSize)); // Value. |
860 __ StoreIntoObject(RAX, FieldAddress(RAX, offset), RBX); | 861 __ StoreIntoObject(RAX, FieldAddress(RAX, offset), RBX); |
861 const Immediate raw_null = | 862 const Immediate raw_null = |
862 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 863 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
863 __ movq(RAX, raw_null); | 864 __ movq(RAX, raw_null); |
864 __ ret(); | 865 __ ret(); |
865 } | 866 } |
866 | 867 |
867 | 868 |
| 869 void FlowGraphCompiler::EmitFrameEntry() { |
| 870 const Function& function = parsed_function().function(); |
| 871 if (CanOptimizeFunction() && function.is_optimizable()) { |
| 872 const bool can_optimize = !is_optimizing() || may_reoptimize(); |
| 873 const Register function_reg = RDI; |
| 874 if (can_optimize) { |
| 875 __ LoadObject(function_reg, function); |
| 876 } |
| 877 // Patch point is after the eventually inlined function object. |
| 878 AddCurrentDescriptor(PcDescriptors::kEntryPatch, |
| 879 Isolate::kNoDeoptId, |
| 880 0); // No token position. |
| 881 if (can_optimize) { |
| 882 // Reoptimization of optimized function is triggered by counting in |
| 883 // IC stubs, but not at the entry of the function. |
| 884 if (!is_optimizing()) { |
| 885 __ incq(FieldAddress(function_reg, Function::usage_counter_offset())); |
| 886 } |
| 887 __ cmpq(FieldAddress(function_reg, Function::usage_counter_offset()), |
| 888 Immediate(FLAG_optimization_counter_threshold)); |
| 889 ASSERT(function_reg == RDI); |
| 890 __ j(GREATER_EQUAL, &StubCode::OptimizeFunctionLabel()); |
| 891 } |
| 892 } else { |
| 893 AddCurrentDescriptor(PcDescriptors::kEntryPatch, |
| 894 Isolate::kNoDeoptId, |
| 895 0); // No token position. |
| 896 } |
| 897 __ Comment("Enter frame"); |
| 898 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize)); |
| 899 } |
| 900 |
| 901 |
868 void FlowGraphCompiler::CompileGraph() { | 902 void FlowGraphCompiler::CompileGraph() { |
869 InitCompiler(); | 903 InitCompiler(); |
870 if (TryIntrinsify()) { | 904 if (TryIntrinsify()) { |
871 // Although this intrinsified code will never be patched, it must satisfy | 905 // Although this intrinsified code will never be patched, it must satisfy |
872 // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum | 906 // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum |
873 // code size, and nop(2) increases the minimum code size appropriately. | 907 // code size, and nop(2) increases the minimum code size appropriately. |
874 __ nop(2); | 908 __ nop(2); |
875 __ int3(); | 909 __ int3(); |
876 __ jmp(&StubCode::FixCallersTargetLabel()); | 910 __ jmp(&StubCode::FixCallersTargetLabel()); |
877 return; | 911 return; |
878 } | 912 } |
879 // Specialized version of entry code from CodeGenerator::GenerateEntryCode. | 913 |
| 914 EmitFrameEntry(); |
| 915 |
880 const Function& function = parsed_function().function(); | 916 const Function& function = parsed_function().function(); |
881 | 917 |
882 const int num_fixed_params = function.num_fixed_parameters(); | 918 const int num_fixed_params = function.num_fixed_parameters(); |
883 const int num_copied_params = parsed_function().num_copied_params(); | 919 const int num_copied_params = parsed_function().num_copied_params(); |
884 const int num_locals = parsed_function().num_stack_locals(); | 920 const int num_locals = parsed_function().num_stack_locals(); |
885 __ Comment("Enter frame"); | |
886 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize)); | |
887 | 921 |
888 // For optimized code, keep a bitmap of the frame in order to build | 922 // For optimized code, keep a bitmap of the frame in order to build |
889 // stackmaps for GC safepoints in the prologue. | 923 // stackmaps for GC safepoints in the prologue. |
890 LocationSummary* prologue_locs = NULL; | 924 LocationSummary* prologue_locs = NULL; |
891 if (is_optimizing()) { | 925 if (is_optimizing()) { |
892 // Spill slots are allocated but not initialized. | 926 // Spill slots are allocated but not initialized. |
893 prologue_locs = new LocationSummary(0, 0, LocationSummary::kCall); | 927 prologue_locs = new LocationSummary(0, 0, LocationSummary::kCall); |
894 prologue_locs->stack_bitmap()->SetLength(StackSize()); | 928 prologue_locs->stack_bitmap()->SetLength(StackSize()); |
895 } | 929 } |
896 | 930 |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1065 const Array& arguments_descriptor, | 1099 const Array& arguments_descriptor, |
1066 intptr_t argument_count, | 1100 intptr_t argument_count, |
1067 intptr_t deopt_id, | 1101 intptr_t deopt_id, |
1068 intptr_t token_pos, | 1102 intptr_t token_pos, |
1069 LocationSummary* locs) { | 1103 LocationSummary* locs) { |
1070 // Each ICData propagated from unoptimized to optimized code contains the | 1104 // Each ICData propagated from unoptimized to optimized code contains the |
1071 // function that corresponds to the Dart function of that IC call. Due | 1105 // function that corresponds to the Dart function of that IC call. Due |
1072 // to inlining in optimized code, that function may not correspond to the | 1106 // to inlining in optimized code, that function may not correspond to the |
1073 // top-level function (parsed_function().function()) which could be | 1107 // top-level function (parsed_function().function()) which could be |
1074 // reoptimized and which counter needs to be incremented. | 1108 // reoptimized and which counter needs to be incremented. |
1075 // Pass the function explicitly. | 1109 // Pass the function explicitly, it is used in IC stub. |
1076 __ LoadObject(RDI, parsed_function().function()); | 1110 __ LoadObject(RDI, parsed_function().function()); |
1077 __ LoadObject(RBX, ic_data); | 1111 __ LoadObject(RBX, ic_data); |
1078 __ LoadObject(R10, arguments_descriptor); | 1112 __ LoadObject(R10, arguments_descriptor); |
1079 GenerateDartCall(deopt_id, | 1113 GenerateDartCall(deopt_id, |
1080 token_pos, | 1114 token_pos, |
1081 target_label, | 1115 target_label, |
1082 PcDescriptors::kIcCall, | 1116 PcDescriptors::kIcCall, |
1083 locs); | 1117 locs); |
1084 __ Drop(argument_count); | 1118 __ Drop(argument_count); |
1085 } | 1119 } |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1465 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1499 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
1466 __ Exchange(mem1, mem2); | 1500 __ Exchange(mem1, mem2); |
1467 } | 1501 } |
1468 | 1502 |
1469 | 1503 |
1470 #undef __ | 1504 #undef __ |
1471 | 1505 |
1472 } // namespace dart | 1506 } // namespace dart |
1473 | 1507 |
1474 #endif // defined TARGET_ARCH_X64 | 1508 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |