| OLD | NEW |
| 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/code_generator.h" | 5 #include "vm/code_generator.h" |
| 6 | 6 |
| 7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
| 8 #include "vm/ast.h" | 8 #include "vm/ast.h" |
| 9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
| 10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
| (...skipping 1208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1219 result = DartEntry::InvokeNoSuchMethod(receiver, | 1219 result = DartEntry::InvokeNoSuchMethod(receiver, |
| 1220 target_name, | 1220 target_name, |
| 1221 args, | 1221 args, |
| 1222 args_descriptor); | 1222 args_descriptor); |
| 1223 } | 1223 } |
| 1224 CheckResultError(result); | 1224 CheckResultError(result); |
| 1225 arguments.SetReturn(result); | 1225 arguments.SetReturn(result); |
| 1226 } | 1226 } |
| 1227 | 1227 |
| 1228 | 1228 |
| 1229 static bool CanOptimizeFunction(const Function& function, Isolate* isolate) { |
| 1230 const intptr_t kLowInvocationCount = -100000000; |
| 1231 if (isolate->debugger()->HasBreakpoint(function)) { |
| 1232 // We cannot set breakpoints in optimized code, so do not optimize |
| 1233 // the function. |
| 1234 function.set_usage_counter(0); |
| 1235 return false; |
| 1236 } |
| 1237 if (function.deoptimization_counter() >= |
| 1238 FLAG_deoptimization_counter_threshold) { |
| 1239 if (FLAG_trace_failed_optimization_attempts) { |
| 1240 OS::PrintErr("Too Many Deoptimizations: %s\n", |
| 1241 function.ToFullyQualifiedCString()); |
| 1242 } |
| 1243 // TODO(srdjan): Investigate excessive deoptimization. |
| 1244 function.set_usage_counter(kLowInvocationCount); |
| 1245 return false; |
| 1246 } |
| 1247 if ((FLAG_optimization_filter != NULL) && |
| 1248 (strstr(function.ToFullyQualifiedCString(), |
| 1249 FLAG_optimization_filter) == NULL)) { |
| 1250 function.set_usage_counter(kLowInvocationCount); |
| 1251 return false; |
| 1252 } |
| 1253 if (!function.is_optimizable()) { |
| 1254 if (FLAG_trace_failed_optimization_attempts) { |
| 1255 OS::PrintErr("Not Optimizable: %s\n", function.ToFullyQualifiedCString()); |
| 1256 } |
| 1257 // TODO(5442338): Abort as this should not happen. |
| 1258 function.set_usage_counter(kLowInvocationCount); |
| 1259 return false; |
| 1260 } |
| 1261 return true; |
| 1262 } |
| 1263 |
| 1264 |
| 1229 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { | 1265 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { |
| 1230 ASSERT(arguments.ArgCount() == | 1266 ASSERT(arguments.ArgCount() == |
| 1231 kStackOverflowRuntimeEntry.argument_count()); | 1267 kStackOverflowRuntimeEntry.argument_count()); |
| 1232 uword stack_pos = reinterpret_cast<uword>(&arguments); | 1268 uword stack_pos = reinterpret_cast<uword>(&arguments); |
| 1233 | 1269 |
| 1234 // If an interrupt happens at the same time as a stack overflow, we | 1270 // If an interrupt happens at the same time as a stack overflow, we |
| 1235 // process the stack overflow first. | 1271 // process the stack overflow first. |
| 1236 if (stack_pos < isolate->saved_stack_limit()) { | 1272 if (stack_pos < isolate->saved_stack_limit()) { |
| 1237 // Use the preallocated stack overflow exception to avoid calling | 1273 // Use the preallocated stack overflow exception to avoid calling |
| 1238 // into dart code. | 1274 // into dart code. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1271 if (callback) { | 1307 if (callback) { |
| 1272 (*callback)(); | 1308 (*callback)(); |
| 1273 } | 1309 } |
| 1274 } | 1310 } |
| 1275 | 1311 |
| 1276 if (FLAG_use_osr && (interrupt_bits == 0)) { | 1312 if (FLAG_use_osr && (interrupt_bits == 0)) { |
| 1277 DartFrameIterator iterator; | 1313 DartFrameIterator iterator; |
| 1278 StackFrame* frame = iterator.NextFrame(); | 1314 StackFrame* frame = iterator.NextFrame(); |
| 1279 const Function& function = Function::Handle(frame->LookupDartFunction()); | 1315 const Function& function = Function::Handle(frame->LookupDartFunction()); |
| 1280 ASSERT(!function.IsNull()); | 1316 ASSERT(!function.IsNull()); |
| 1281 if (!function.is_optimizable()) return; | 1317 if (!CanOptimizeFunction(function, isolate)) return; |
| 1282 intptr_t osr_id = | 1318 intptr_t osr_id = |
| 1283 Code::Handle(function.unoptimized_code()).GetDeoptIdForOsr(frame->pc()); | 1319 Code::Handle(function.unoptimized_code()).GetDeoptIdForOsr(frame->pc()); |
| 1284 if (FLAG_trace_osr) { | 1320 if (FLAG_trace_osr) { |
| 1285 OS::Print("Attempting OSR for %s at id=%"Pd"\n", | 1321 OS::Print("Attempting OSR for %s at id=%"Pd"\n", |
| 1286 function.ToFullyQualifiedCString(), | 1322 function.ToFullyQualifiedCString(), |
| 1287 osr_id); | 1323 osr_id); |
| 1288 } | 1324 } |
| 1289 | 1325 |
| 1290 const Code& original_code = Code::Handle(function.CurrentCode()); | 1326 const Code& original_code = Code::Handle(function.CurrentCode()); |
| 1291 const Error& error = | 1327 const Error& error = |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1325 function.ToFullyQualifiedCString()); | 1361 function.ToFullyQualifiedCString()); |
| 1326 } | 1362 } |
| 1327 | 1363 |
| 1328 | 1364 |
| 1329 // This is called from function that needs to be optimized. | 1365 // This is called from function that needs to be optimized. |
| 1330 // The requesting function can be already optimized (reoptimization). | 1366 // The requesting function can be already optimized (reoptimization). |
| 1331 // Returns the Code object where to continue execution. | 1367 // Returns the Code object where to continue execution. |
| 1332 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { | 1368 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { |
| 1333 ASSERT(arguments.ArgCount() == | 1369 ASSERT(arguments.ArgCount() == |
| 1334 kOptimizeInvokedFunctionRuntimeEntry.argument_count()); | 1370 kOptimizeInvokedFunctionRuntimeEntry.argument_count()); |
| 1335 const intptr_t kLowInvocationCount = -100000000; | |
| 1336 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); | 1371 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 1337 ASSERT(!function.IsNull()); | 1372 ASSERT(!function.IsNull()); |
| 1338 if (isolate->debugger()->HasBreakpoint(function)) { | 1373 |
| 1339 // We cannot set breakpoints in optimized code, so do not optimize | 1374 if (CanOptimizeFunction(function, isolate)) { |
| 1340 // the function. | |
| 1341 function.set_usage_counter(0); | |
| 1342 arguments.SetReturn(Code::Handle(function.CurrentCode())); | |
| 1343 return; | |
| 1344 } | |
| 1345 if (function.deoptimization_counter() >= | |
| 1346 FLAG_deoptimization_counter_threshold) { | |
| 1347 if (FLAG_trace_failed_optimization_attempts) { | |
| 1348 OS::PrintErr("Too Many Deoptimizations: %s\n", | |
| 1349 function.ToFullyQualifiedCString()); | |
| 1350 } | |
| 1351 // TODO(srdjan): Investigate excessive deoptimization. | |
| 1352 function.set_usage_counter(kLowInvocationCount); | |
| 1353 arguments.SetReturn(Code::Handle(function.CurrentCode())); | |
| 1354 return; | |
| 1355 } | |
| 1356 if ((FLAG_optimization_filter != NULL) && | |
| 1357 (strstr(function.ToFullyQualifiedCString(), | |
| 1358 FLAG_optimization_filter) == NULL)) { | |
| 1359 function.set_usage_counter(kLowInvocationCount); | |
| 1360 arguments.SetReturn(Code::Handle(function.CurrentCode())); | |
| 1361 return; | |
| 1362 } | |
| 1363 if (function.is_optimizable()) { | |
| 1364 const Error& error = | 1375 const Error& error = |
| 1365 Error::Handle(Compiler::CompileOptimizedFunction(function)); | 1376 Error::Handle(Compiler::CompileOptimizedFunction(function)); |
| 1366 if (!error.IsNull()) { | 1377 if (!error.IsNull()) { |
| 1367 Exceptions::PropagateError(error); | 1378 Exceptions::PropagateError(error); |
| 1368 } | 1379 } |
| 1369 const Code& optimized_code = Code::Handle(function.CurrentCode()); | 1380 const Code& optimized_code = Code::Handle(function.CurrentCode()); |
| 1370 ASSERT(!optimized_code.IsNull()); | 1381 ASSERT(!optimized_code.IsNull()); |
| 1371 // Reset usage counter for reoptimization. | 1382 // Reset usage counter for reoptimization. |
| 1372 function.set_usage_counter(0); | 1383 function.set_usage_counter(0); |
| 1373 } else { | |
| 1374 if (FLAG_trace_failed_optimization_attempts) { | |
| 1375 OS::PrintErr("Not Optimizable: %s\n", function.ToFullyQualifiedCString()); | |
| 1376 } | |
| 1377 // TODO(5442338): Abort as this should not happen. | |
| 1378 function.set_usage_counter(kLowInvocationCount); | |
| 1379 } | 1384 } |
| 1380 arguments.SetReturn(Code::Handle(function.CurrentCode())); | 1385 arguments.SetReturn(Code::Handle(function.CurrentCode())); |
| 1381 } | 1386 } |
| 1382 | 1387 |
| 1383 | 1388 |
| 1384 // The caller must be a static call in a Dart frame, or an entry frame. | 1389 // The caller must be a static call in a Dart frame, or an entry frame. |
| 1385 // Patch static call to point to valid code's entry point. | 1390 // Patch static call to point to valid code's entry point. |
| 1386 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 0) { | 1391 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 0) { |
| 1387 ASSERT(arguments.ArgCount() == | 1392 ASSERT(arguments.ArgCount() == |
| 1388 kFixCallersTargetRuntimeEntry.argument_count()); | 1393 kFixCallersTargetRuntimeEntry.argument_count()); |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1800 // Arg1: Value that is being stored. | 1805 // Arg1: Value that is being stored. |
| 1801 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { | 1806 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { |
| 1802 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count()); | 1807 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count()); |
| 1803 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); | 1808 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); |
| 1804 const Object& value = Object::Handle(arguments.ArgAt(1)); | 1809 const Object& value = Object::Handle(arguments.ArgAt(1)); |
| 1805 | 1810 |
| 1806 field.UpdateCid(value.GetClassId()); | 1811 field.UpdateCid(value.GetClassId()); |
| 1807 } | 1812 } |
| 1808 | 1813 |
| 1809 } // namespace dart | 1814 } // namespace dart |
| OLD | NEW |