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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
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 DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic."); |
| 24 DECLARE_FLAG(int, optimization_counter_threshold); |
22 DECLARE_FLAG(bool, print_ast); | 25 DECLARE_FLAG(bool, print_ast); |
23 DECLARE_FLAG(bool, print_scopes); | 26 DECLARE_FLAG(bool, print_scopes); |
24 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization."); | |
25 DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic."); | |
26 | 27 |
27 | 28 |
28 bool FlowGraphCompiler::SupportsUnboxedMints() { | 29 bool FlowGraphCompiler::SupportsUnboxedMints() { |
29 // Support unboxed mints when SSE 4.1 is available. | 30 // Support unboxed mints when SSE 4.1 is available. |
30 return FLAG_unbox_mints && CPUFeatures::sse4_1_supported(); | 31 return FLAG_unbox_mints && CPUFeatures::sse4_1_supported(); |
31 } | 32 } |
32 | 33 |
33 | 34 |
34 void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler, | 35 void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler, |
35 intptr_t stub_ix) { | 36 intptr_t stub_ix) { |
(...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
856 __ movl(EAX, Address(ESP, 2 * kWordSize)); // Receiver. | 857 __ movl(EAX, Address(ESP, 2 * kWordSize)); // Receiver. |
857 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Value. | 858 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Value. |
858 __ StoreIntoObject(EAX, FieldAddress(EAX, offset), EBX); | 859 __ StoreIntoObject(EAX, FieldAddress(EAX, offset), EBX); |
859 const Immediate raw_null = | 860 const Immediate raw_null = |
860 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 861 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
861 __ movl(EAX, raw_null); | 862 __ movl(EAX, raw_null); |
862 __ ret(); | 863 __ ret(); |
863 } | 864 } |
864 | 865 |
865 | 866 |
| 867 void FlowGraphCompiler::EmitFrameEntry() { |
| 868 const Function& function = parsed_function().function(); |
| 869 if (CanOptimizeFunction() && function.is_optimizable()) { |
| 870 const bool can_optimize = !is_optimizing() || may_reoptimize(); |
| 871 const Register function_reg = EDI; |
| 872 if (can_optimize) { |
| 873 __ LoadObject(function_reg, function); |
| 874 } |
| 875 // Patch point is after the eventually inlined function object. |
| 876 AddCurrentDescriptor(PcDescriptors::kEntryPatch, |
| 877 Isolate::kNoDeoptId, |
| 878 0); // No token position. |
| 879 if (can_optimize) { |
| 880 // Reoptimization of optimized function is triggered by counting in |
| 881 // IC stubs, but not at the entry of the function. |
| 882 if (!is_optimizing()) { |
| 883 __ incl(FieldAddress(function_reg, Function::usage_counter_offset())); |
| 884 } |
| 885 __ cmpl(FieldAddress(function_reg, Function::usage_counter_offset()), |
| 886 Immediate(FLAG_optimization_counter_threshold)); |
| 887 ASSERT(function_reg == EDI); |
| 888 __ j(GREATER_EQUAL, &StubCode::OptimizeFunctionLabel()); |
| 889 } |
| 890 } else { |
| 891 AddCurrentDescriptor(PcDescriptors::kEntryPatch, |
| 892 Isolate::kNoDeoptId, |
| 893 0); // No token position. |
| 894 } |
| 895 __ Comment("Enter frame"); |
| 896 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize)); |
| 897 } |
| 898 |
| 899 |
866 void FlowGraphCompiler::CompileGraph() { | 900 void FlowGraphCompiler::CompileGraph() { |
867 InitCompiler(); | 901 InitCompiler(); |
868 if (TryIntrinsify()) { | 902 if (TryIntrinsify()) { |
869 // Although this intrinsified code will never be patched, it must satisfy | 903 // Although this intrinsified code will never be patched, it must satisfy |
870 // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum | 904 // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum |
871 // code size. | 905 // code size. |
872 __ int3(); | 906 __ int3(); |
873 __ jmp(&StubCode::FixCallersTargetLabel()); | 907 __ jmp(&StubCode::FixCallersTargetLabel()); |
874 return; | 908 return; |
875 } | 909 } |
876 // Specialized version of entry code from CodeGenerator::GenerateEntryCode. | 910 |
| 911 EmitFrameEntry(); |
| 912 |
877 const Function& function = parsed_function().function(); | 913 const Function& function = parsed_function().function(); |
878 | 914 |
879 const int num_fixed_params = function.num_fixed_parameters(); | 915 const int num_fixed_params = function.num_fixed_parameters(); |
880 const int num_copied_params = parsed_function().num_copied_params(); | 916 const int num_copied_params = parsed_function().num_copied_params(); |
881 const int num_locals = parsed_function().num_stack_locals(); | 917 const int num_locals = parsed_function().num_stack_locals(); |
882 __ Comment("Enter frame"); | |
883 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize)); | |
884 | 918 |
885 // For optimized code, keep a bitmap of the frame in order to build | 919 // For optimized code, keep a bitmap of the frame in order to build |
886 // stackmaps for GC safepoints in the prologue. | 920 // stackmaps for GC safepoints in the prologue. |
887 LocationSummary* prologue_locs = NULL; | 921 LocationSummary* prologue_locs = NULL; |
888 if (is_optimizing()) { | 922 if (is_optimizing()) { |
889 // Spill slots are allocated but not initialized. | 923 // Spill slots are allocated but not initialized. |
890 prologue_locs = new LocationSummary(0, 0, LocationSummary::kCall); | 924 prologue_locs = new LocationSummary(0, 0, LocationSummary::kCall); |
891 prologue_locs->stack_bitmap()->SetLength(StackSize()); | 925 prologue_locs->stack_bitmap()->SetLength(StackSize()); |
892 } | 926 } |
893 | 927 |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1061 const Array& arguments_descriptor, | 1095 const Array& arguments_descriptor, |
1062 intptr_t argument_count, | 1096 intptr_t argument_count, |
1063 intptr_t deopt_id, | 1097 intptr_t deopt_id, |
1064 intptr_t token_pos, | 1098 intptr_t token_pos, |
1065 LocationSummary* locs) { | 1099 LocationSummary* locs) { |
1066 // Each ICData propagated from unoptimized to optimized code contains the | 1100 // Each ICData propagated from unoptimized to optimized code contains the |
1067 // function that corresponds to the Dart function of that IC call. Due | 1101 // function that corresponds to the Dart function of that IC call. Due |
1068 // to inlining in optimized code, that function may not correspond to the | 1102 // to inlining in optimized code, that function may not correspond to the |
1069 // top-level function (parsed_function().function()) which could be | 1103 // top-level function (parsed_function().function()) which could be |
1070 // reoptimized and which counter needs to be incremented. | 1104 // reoptimized and which counter needs to be incremented. |
1071 // Pass the function explicitly. | 1105 // Pass the function explicitly, it is used in IC stub. |
1072 __ LoadObject(EDI, parsed_function().function()); | 1106 __ LoadObject(EDI, parsed_function().function()); |
1073 __ LoadObject(ECX, ic_data); | 1107 __ LoadObject(ECX, ic_data); |
1074 __ LoadObject(EDX, arguments_descriptor); | 1108 __ LoadObject(EDX, arguments_descriptor); |
1075 GenerateDartCall(deopt_id, | 1109 GenerateDartCall(deopt_id, |
1076 token_pos, | 1110 token_pos, |
1077 target_label, | 1111 target_label, |
1078 PcDescriptors::kIcCall, | 1112 PcDescriptors::kIcCall, |
1079 locs); | 1113 locs); |
1080 __ Drop(argument_count); | 1114 __ Drop(argument_count); |
1081 } | 1115 } |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1487 __ popl(ECX); | 1521 __ popl(ECX); |
1488 __ popl(EAX); | 1522 __ popl(EAX); |
1489 } | 1523 } |
1490 | 1524 |
1491 | 1525 |
1492 #undef __ | 1526 #undef __ |
1493 | 1527 |
1494 } // namespace dart | 1528 } // namespace dart |
1495 | 1529 |
1496 #endif // defined TARGET_ARCH_IA32 | 1530 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |