Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(604)

Side by Side Diff: runtime/vm/flow_graph_compiler_x64.cc

Issue 17233003: Reapply "Initial implementation of on-stack replacement (OSR)." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.cc ('k') | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/deopt_instructions.h" 13 #include "vm/deopt_instructions.h"
14 #include "vm/il_printer.h" 14 #include "vm/il_printer.h"
15 #include "vm/locations.h" 15 #include "vm/locations.h"
16 #include "vm/object_store.h" 16 #include "vm/object_store.h"
17 #include "vm/parser.h" 17 #include "vm/parser.h"
18 #include "vm/stack_frame.h" 18 #include "vm/stack_frame.h"
19 #include "vm/stub_code.h" 19 #include "vm/stub_code.h"
20 #include "vm/symbols.h" 20 #include "vm/symbols.h"
21 21
22 namespace dart { 22 namespace dart {
23 23
24 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization."); 24 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
25 DECLARE_FLAG(int, optimization_counter_threshold); 25 DECLARE_FLAG(int, optimization_counter_threshold);
26 DECLARE_FLAG(int, reoptimization_counter_threshold);
26 DECLARE_FLAG(bool, print_ast); 27 DECLARE_FLAG(bool, print_ast);
27 DECLARE_FLAG(bool, print_scopes); 28 DECLARE_FLAG(bool, print_scopes);
28 DECLARE_FLAG(bool, enable_type_checks); 29 DECLARE_FLAG(bool, enable_type_checks);
29 DECLARE_FLAG(bool, eliminate_type_checks); 30 DECLARE_FLAG(bool, eliminate_type_checks);
30 31
31 32
32 FlowGraphCompiler::~FlowGraphCompiler() { 33 FlowGraphCompiler::~FlowGraphCompiler() {
33 // BlockInfos are zone-allocated, so their destructors are not called. 34 // BlockInfos are zone-allocated, so their destructors are not called.
34 // Verify the labels explicitly here. 35 // Verify the labels explicitly here.
35 for (int i = 0; i < block_info_.length(); ++i) { 36 for (int i = 0; i < block_info_.length(); ++i) {
(...skipping 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 __ StoreIntoObject(RAX, FieldAddress(RAX, offset), RBX); 1065 __ StoreIntoObject(RAX, FieldAddress(RAX, offset), RBX);
1065 const Immediate& raw_null = 1066 const Immediate& raw_null =
1066 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1067 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1067 __ movq(RAX, raw_null); 1068 __ movq(RAX, raw_null);
1068 __ ret(); 1069 __ ret();
1069 } 1070 }
1070 1071
1071 1072
1072 void FlowGraphCompiler::EmitFrameEntry() { 1073 void FlowGraphCompiler::EmitFrameEntry() {
1073 const Function& function = parsed_function().function(); 1074 const Function& function = parsed_function().function();
1074 if (CanOptimizeFunction() && function.is_optimizable()) { 1075 if (CanOptimizeFunction() &&
1075 const bool can_optimize = !is_optimizing() || may_reoptimize(); 1076 function.is_optimizable() &&
1077 (!is_optimizing() || may_reoptimize())) {
1076 const Register function_reg = RDI; 1078 const Register function_reg = RDI;
1077 if (can_optimize) { 1079 __ LoadObject(function_reg, function);
1078 __ LoadObject(function_reg, function);
1079 }
1080 // Patch point is after the eventually inlined function object. 1080 // Patch point is after the eventually inlined function object.
1081 AddCurrentDescriptor(PcDescriptors::kEntryPatch, 1081 AddCurrentDescriptor(PcDescriptors::kEntryPatch,
1082 Isolate::kNoDeoptId, 1082 Isolate::kNoDeoptId,
1083 0); // No token position. 1083 0); // No token position.
1084 if (can_optimize) { 1084 if (is_optimizing()) {
1085 // Reoptimization of optimized function is triggered by counting in 1085 // Reoptimization of an optimized function is triggered by counting in
1086 // IC stubs, but not at the entry of the function. 1086 // IC stubs, but not at the entry of the function.
1087 if (!is_optimizing()) {
1088 __ incq(FieldAddress(function_reg, Function::usage_counter_offset()));
1089 }
1090 __ cmpq(FieldAddress(function_reg, Function::usage_counter_offset()), 1087 __ cmpq(FieldAddress(function_reg, Function::usage_counter_offset()),
1091 Immediate(FLAG_optimization_counter_threshold)); 1088 Immediate(FLAG_reoptimization_counter_threshold));
1092 ASSERT(function_reg == RDI); 1089 } else {
1093 __ j(GREATER_EQUAL, &StubCode::OptimizeFunctionLabel()); 1090 __ incq(FieldAddress(function_reg, Function::usage_counter_offset()));
1091 __ cmpq(FieldAddress(function_reg, Function::usage_counter_offset()),
1092 Immediate(FLAG_optimization_counter_threshold));
1094 } 1093 }
1095 } else { 1094 ASSERT(function_reg == RDI);
1095 __ j(GREATER_EQUAL, &StubCode::OptimizeFunctionLabel());
1096 } else if (!flow_graph().IsCompiledForOsr()) {
1096 AddCurrentDescriptor(PcDescriptors::kEntryPatch, 1097 AddCurrentDescriptor(PcDescriptors::kEntryPatch,
1097 Isolate::kNoDeoptId, 1098 Isolate::kNoDeoptId,
1098 0); // No token position. 1099 0); // No token position.
1099 } 1100 }
1100 __ Comment("Enter frame"); 1101 __ Comment("Enter frame");
1101 __ EnterDartFrame(StackSize() * kWordSize); 1102 if (flow_graph().IsCompiledForOsr()) {
1103 intptr_t extra_slots = StackSize()
1104 - flow_graph().num_stack_locals()
1105 - flow_graph().num_copied_params();
1106 ASSERT(extra_slots >= 0);
1107 __ EnterOsrFrame(extra_slots * kWordSize);
1108 } else {
1109 ASSERT(StackSize() >= 0);
1110 __ EnterDartFrame(StackSize() * kWordSize);
1111 }
1102 } 1112 }
1103 1113
1104 1114
1105 void FlowGraphCompiler::CompileGraph() { 1115 void FlowGraphCompiler::CompileGraph() {
1106 InitCompiler(); 1116 InitCompiler();
1107 if (TryIntrinsify()) { 1117 if (TryIntrinsify()) {
1108 // Although this intrinsified code will never be patched, it must satisfy 1118 // Although this intrinsified code will never be patched, it must satisfy
1109 // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum 1119 // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum
1110 // code size, and nop(2) increases the minimum code size appropriately. 1120 // code size, and nop(2) increases the minimum code size appropriately.
1111 __ nop(2); 1121 __ nop(2);
(...skipping 12 matching lines...) Expand all
1124 1134
1125 // We check the number of passed arguments when we have to copy them due to 1135 // We check the number of passed arguments when we have to copy them due to
1126 // the presence of optional parameters. 1136 // the presence of optional parameters.
1127 // No such checking code is generated if only fixed parameters are declared, 1137 // No such checking code is generated if only fixed parameters are declared,
1128 // unless we are in debug mode or unless we are compiling a closure. 1138 // unless we are in debug mode or unless we are compiling a closure.
1129 LocalVariable* saved_args_desc_var = 1139 LocalVariable* saved_args_desc_var =
1130 parsed_function().GetSavedArgumentsDescriptorVar(); 1140 parsed_function().GetSavedArgumentsDescriptorVar();
1131 if (num_copied_params == 0) { 1141 if (num_copied_params == 0) {
1132 #ifdef DEBUG 1142 #ifdef DEBUG
1133 ASSERT(!parsed_function().function().HasOptionalParameters()); 1143 ASSERT(!parsed_function().function().HasOptionalParameters());
1134 const bool check_arguments = true; 1144 const bool check_arguments = !flow_graph().IsCompiledForOsr();
1135 #else 1145 #else
1136 const bool check_arguments = function.IsClosureFunction(); 1146 const bool check_arguments =
1147 function.IsClosureFunction() && !flow_graph().IsCompiledForOsr();
1137 #endif 1148 #endif
1138 if (check_arguments) { 1149 if (check_arguments) {
1139 __ Comment("Check argument count"); 1150 __ Comment("Check argument count");
1140 // Check that exactly num_fixed arguments are passed in. 1151 // Check that exactly num_fixed arguments are passed in.
1141 Label correct_num_arguments, wrong_num_arguments; 1152 Label correct_num_arguments, wrong_num_arguments;
1142 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 1153 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
1143 __ cmpq(RAX, Immediate(Smi::RawValue(num_fixed_params))); 1154 __ cmpq(RAX, Immediate(Smi::RawValue(num_fixed_params)));
1144 __ j(NOT_EQUAL, &wrong_num_arguments, Assembler::kNearJump); 1155 __ j(NOT_EQUAL, &wrong_num_arguments, Assembler::kNearJump);
1145 __ cmpq(RAX, 1156 __ cmpq(RAX,
1146 FieldAddress(R10, 1157 FieldAddress(R10,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 __ LeaveFrame(); 1195 __ LeaveFrame();
1185 __ ret(); 1196 __ ret();
1186 } else { 1197 } else {
1187 __ Stop("Wrong number of arguments"); 1198 __ Stop("Wrong number of arguments");
1188 } 1199 }
1189 __ Bind(&correct_num_arguments); 1200 __ Bind(&correct_num_arguments);
1190 } 1201 }
1191 // The arguments descriptor is never saved in the absence of optional 1202 // The arguments descriptor is never saved in the absence of optional
1192 // parameters, since any argument definition test would always yield true. 1203 // parameters, since any argument definition test would always yield true.
1193 ASSERT(saved_args_desc_var == NULL); 1204 ASSERT(saved_args_desc_var == NULL);
1194 } else { 1205 } else if (!flow_graph().IsCompiledForOsr()) {
1195 if (saved_args_desc_var != NULL) { 1206 if (saved_args_desc_var != NULL) {
1196 __ Comment("Save arguments descriptor"); 1207 __ Comment("Save arguments descriptor");
1197 const Register kArgumentsDescriptorReg = R10; 1208 const Register kArgumentsDescriptorReg = R10;
1198 // The saved_args_desc_var is allocated one slot before the first local. 1209 // The saved_args_desc_var is allocated one slot before the first local.
1199 const intptr_t slot = parsed_function().first_stack_local_index() + 1; 1210 const intptr_t slot = parsed_function().first_stack_local_index() + 1;
1200 // If the saved_args_desc_var is captured, it is first moved to the stack 1211 // If the saved_args_desc_var is captured, it is first moved to the stack
1201 // and later to the context, once the context is allocated. 1212 // and later to the context, once the context is allocated.
1202 ASSERT(saved_args_desc_var->is_captured() || 1213 ASSERT(saved_args_desc_var->is_captured() ||
1203 (saved_args_desc_var->index() == slot)); 1214 (saved_args_desc_var->index() == slot));
1204 __ movq(Address(RBP, slot * kWordSize), kArgumentsDescriptorReg); 1215 __ movq(Address(RBP, slot * kWordSize), kArgumentsDescriptorReg);
(...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after
1893 __ movups(reg, Address(RSP, 0)); 1904 __ movups(reg, Address(RSP, 0));
1894 __ addq(RSP, Immediate(kFpuRegisterSize)); 1905 __ addq(RSP, Immediate(kFpuRegisterSize));
1895 } 1906 }
1896 1907
1897 1908
1898 #undef __ 1909 #undef __
1899 1910
1900 } // namespace dart 1911 } // namespace dart
1901 1912
1902 #endif // defined TARGET_ARCH_X64 1913 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.cc ('k') | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698