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/code_patcher.h" | 9 #include "vm/code_patcher.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 | 670 |
671 // Result of an invoke may be an unhandled exception, in which case we | 671 // Result of an invoke may be an unhandled exception, in which case we |
672 // rethrow it. | 672 // rethrow it. |
673 static void CheckResultError(const Object& result) { | 673 static void CheckResultError(const Object& result) { |
674 if (result.IsError()) { | 674 if (result.IsError()) { |
675 Exceptions::PropagateError(Error::Cast(result)); | 675 Exceptions::PropagateError(Error::Cast(result)); |
676 } | 676 } |
677 } | 677 } |
678 | 678 |
679 | 679 |
| 680 #if !defined(TARGET_ARCH_DBC) |
680 // Gets called from debug stub when code reaches a breakpoint | 681 // Gets called from debug stub when code reaches a breakpoint |
681 // set on a runtime stub call. | 682 // set on a runtime stub call. |
682 DEFINE_RUNTIME_ENTRY(BreakpointRuntimeHandler, 0) { | 683 DEFINE_RUNTIME_ENTRY(BreakpointRuntimeHandler, 0) { |
683 if (!FLAG_support_debugger) { | 684 if (!FLAG_support_debugger) { |
684 UNREACHABLE(); | 685 UNREACHABLE(); |
685 return; | 686 return; |
686 } | 687 } |
687 DartFrameIterator iterator; | 688 DartFrameIterator iterator; |
688 StackFrame* caller_frame = iterator.NextFrame(); | 689 StackFrame* caller_frame = iterator.NextFrame(); |
689 ASSERT(caller_frame != NULL); | 690 ASSERT(caller_frame != NULL); |
690 const Code& orig_stub = Code::Handle( | 691 const Code& orig_stub = Code::Handle( |
691 isolate->debugger()->GetPatchedStubAddress(caller_frame->pc())); | 692 isolate->debugger()->GetPatchedStubAddress(caller_frame->pc())); |
692 const Error& error = Error::Handle(isolate->debugger()->SignalBpReached()); | 693 const Error& error = Error::Handle(isolate->debugger()->SignalBpReached()); |
693 if (!error.IsNull()) { | 694 if (!error.IsNull()) { |
694 Exceptions::PropagateError(error); | 695 Exceptions::PropagateError(error); |
695 UNREACHABLE(); | 696 UNREACHABLE(); |
696 } | 697 } |
697 arguments.SetReturn(orig_stub); | 698 arguments.SetReturn(orig_stub); |
698 } | 699 } |
| 700 #else |
| 701 // Gets called from the simulator when the breakpoint is reached. |
| 702 DEFINE_RUNTIME_ENTRY(BreakpointRuntimeHandler, 0) { |
| 703 if (!FLAG_support_debugger) { |
| 704 UNREACHABLE(); |
| 705 return; |
| 706 } |
| 707 const Error& error = Error::Handle(isolate->debugger()->SignalBpReached()); |
| 708 if (!error.IsNull()) { |
| 709 Exceptions::PropagateError(error); |
| 710 UNREACHABLE(); |
| 711 } |
| 712 } |
| 713 #endif // !defined(TARGET_ARCH_DBC) |
699 | 714 |
700 | 715 |
701 DEFINE_RUNTIME_ENTRY(SingleStepHandler, 0) { | 716 DEFINE_RUNTIME_ENTRY(SingleStepHandler, 0) { |
702 if (!FLAG_support_debugger) { | 717 if (!FLAG_support_debugger) { |
703 UNREACHABLE(); | 718 UNREACHABLE(); |
704 return; | 719 return; |
705 } | 720 } |
706 const Error& error = | 721 const Error& error = |
707 Error::Handle(isolate->debugger()->DebuggerStepCallback()); | 722 Error::Handle(isolate->debugger()->DebuggerStepCallback()); |
708 if (!error.IsNull()) { | 723 if (!error.IsNull()) { |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1016 // Switch to megamorphic call. | 1031 // Switch to megamorphic call. |
1017 const MegamorphicCache& cache = MegamorphicCache::Handle(zone, | 1032 const MegamorphicCache& cache = MegamorphicCache::Handle(zone, |
1018 MegamorphicCacheTable::Lookup(isolate, name, descriptor)); | 1033 MegamorphicCacheTable::Lookup(isolate, name, descriptor)); |
1019 DartFrameIterator iterator; | 1034 DartFrameIterator iterator; |
1020 StackFrame* miss_function_frame = iterator.NextFrame(); | 1035 StackFrame* miss_function_frame = iterator.NextFrame(); |
1021 ASSERT(miss_function_frame->IsDartFrame()); | 1036 ASSERT(miss_function_frame->IsDartFrame()); |
1022 StackFrame* caller_frame = iterator.NextFrame(); | 1037 StackFrame* caller_frame = iterator.NextFrame(); |
1023 ASSERT(caller_frame->IsDartFrame()); | 1038 ASSERT(caller_frame->IsDartFrame()); |
1024 const Code& code = Code::Handle(zone, caller_frame->LookupDartCode()); | 1039 const Code& code = Code::Handle(zone, caller_frame->LookupDartCode()); |
1025 const Code& stub = | 1040 const Code& stub = |
| 1041 #if !defined(TARGET_ARCH_DBC) |
1026 Code::Handle(zone, StubCode::MegamorphicLookup_entry()->code()); | 1042 Code::Handle(zone, StubCode::MegamorphicLookup_entry()->code()); |
| 1043 #else |
| 1044 Code::Handle(); |
| 1045 UNREACHABLE(); |
| 1046 #endif |
1027 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), | 1047 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), |
1028 code, ic_data, cache, stub); | 1048 code, ic_data, cache, stub); |
1029 } | 1049 } |
1030 } else { | 1050 } else { |
1031 const MegamorphicCache& cache = MegamorphicCache::Cast(ic_data_or_cache); | 1051 const MegamorphicCache& cache = MegamorphicCache::Cast(ic_data_or_cache); |
1032 // Insert function found into cache and return it. | 1052 // Insert function found into cache and return it. |
1033 cache.EnsureCapacity(); | 1053 cache.EnsureCapacity(); |
1034 const Smi& class_id = Smi::Handle(zone, Smi::New(cls.id())); | 1054 const Smi& class_id = Smi::Handle(zone, Smi::New(cls.id())); |
1035 cache.Insert(class_id, target_function); | 1055 cache.Insert(class_id, target_function); |
1036 } | 1056 } |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1205 const Object& result = Object::Handle( | 1225 const Object& result = Object::Handle( |
1206 DartEntry::InvokeNoSuchMethod(receiver, | 1226 DartEntry::InvokeNoSuchMethod(receiver, |
1207 original_function_name, | 1227 original_function_name, |
1208 orig_arguments, | 1228 orig_arguments, |
1209 orig_arguments_desc)); | 1229 orig_arguments_desc)); |
1210 CheckResultError(result); | 1230 CheckResultError(result); |
1211 arguments.SetReturn(result); | 1231 arguments.SetReturn(result); |
1212 } | 1232 } |
1213 | 1233 |
1214 | 1234 |
| 1235 #if !defined(TARGET_ARCH_DBC) |
1215 static bool CanOptimizeFunction(const Function& function, Thread* thread) { | 1236 static bool CanOptimizeFunction(const Function& function, Thread* thread) { |
1216 if (FLAG_support_debugger) { | 1237 if (FLAG_support_debugger) { |
1217 Isolate* isolate = thread->isolate(); | 1238 Isolate* isolate = thread->isolate(); |
1218 if (isolate->debugger()->IsStepping() || | 1239 if (isolate->debugger()->IsStepping() || |
1219 isolate->debugger()->HasBreakpoint(function, thread->zone())) { | 1240 isolate->debugger()->HasBreakpoint(function, thread->zone())) { |
1220 // We cannot set breakpoints and single step in optimized code, | 1241 // We cannot set breakpoints and single step in optimized code, |
1221 // so do not optimize the function. | 1242 // so do not optimize the function. |
1222 function.set_usage_counter(0); | 1243 function.set_usage_counter(0); |
1223 return false; | 1244 return false; |
1224 } | 1245 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1266 // Huge methods (code size above --huge_method_cutoff_in_code_size) become | 1287 // Huge methods (code size above --huge_method_cutoff_in_code_size) become |
1267 // non-optimizable only after the code has been generated. | 1288 // non-optimizable only after the code has been generated. |
1268 if (FLAG_trace_failed_optimization_attempts) { | 1289 if (FLAG_trace_failed_optimization_attempts) { |
1269 THR_Print("Not optimizable: %s\n", function.ToFullyQualifiedCString()); | 1290 THR_Print("Not optimizable: %s\n", function.ToFullyQualifiedCString()); |
1270 } | 1291 } |
1271 function.set_usage_counter(INT_MIN); | 1292 function.set_usage_counter(INT_MIN); |
1272 return false; | 1293 return false; |
1273 } | 1294 } |
1274 return true; | 1295 return true; |
1275 } | 1296 } |
| 1297 #endif |
1276 | 1298 |
1277 | 1299 |
1278 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { | 1300 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { |
1279 #if defined(USING_SIMULATOR) | 1301 #if defined(TARGET_ARCH_DBC) |
| 1302 uword stack_pos = Simulator::Current()->sp(); |
| 1303 #elif defined(USING_SIMULATOR) |
1280 uword stack_pos = Simulator::Current()->get_register(SPREG); | 1304 uword stack_pos = Simulator::Current()->get_register(SPREG); |
1281 #else | 1305 #else |
1282 uword stack_pos = Isolate::GetCurrentStackPointer(); | 1306 uword stack_pos = Isolate::GetCurrentStackPointer(); |
1283 #endif | 1307 #endif |
1284 // Always clear the stack overflow flags. They are meant for this | 1308 // Always clear the stack overflow flags. They are meant for this |
1285 // particular stack overflow runtime call and are not meant to | 1309 // particular stack overflow runtime call and are not meant to |
1286 // persist. | 1310 // persist. |
1287 uword stack_overflow_flags = isolate->GetAndClearStackOverflowFlags(); | 1311 uword stack_overflow_flags = isolate->GetAndClearStackOverflowFlags(); |
1288 | 1312 |
1289 // If an interrupt happens at the same time as a stack overflow, we | 1313 // If an interrupt happens at the same time as a stack overflow, we |
1290 // process the stack overflow now and leave the interrupt for next | 1314 // process the stack overflow now and leave the interrupt for next |
1291 // time. | 1315 // time. |
1292 if (stack_pos < isolate->saved_stack_limit()) { | 1316 if (IsCalleeFrameOf(isolate->saved_stack_limit(), stack_pos)) { |
1293 // Use the preallocated stack overflow exception to avoid calling | 1317 // Use the preallocated stack overflow exception to avoid calling |
1294 // into dart code. | 1318 // into dart code. |
1295 const Instance& exception = | 1319 const Instance& exception = |
1296 Instance::Handle(isolate->object_store()->stack_overflow()); | 1320 Instance::Handle(isolate->object_store()->stack_overflow()); |
1297 Exceptions::Throw(thread, exception); | 1321 Exceptions::Throw(thread, exception); |
1298 UNREACHABLE(); | 1322 UNREACHABLE(); |
1299 } | 1323 } |
1300 | 1324 |
1301 // The following code is used to stress test deoptimization and | 1325 // The following code is used to stress test deoptimization and |
1302 // debugger stack tracing. | 1326 // debugger stack tracing. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1362 } | 1386 } |
1363 | 1387 |
1364 const Error& error = Error::Handle(isolate->HandleInterrupts()); | 1388 const Error& error = Error::Handle(isolate->HandleInterrupts()); |
1365 if (!error.IsNull()) { | 1389 if (!error.IsNull()) { |
1366 Exceptions::PropagateError(error); | 1390 Exceptions::PropagateError(error); |
1367 UNREACHABLE(); | 1391 UNREACHABLE(); |
1368 } | 1392 } |
1369 | 1393 |
1370 if ((stack_overflow_flags & Isolate::kOsrRequest) != 0) { | 1394 if ((stack_overflow_flags & Isolate::kOsrRequest) != 0) { |
1371 ASSERT(FLAG_use_osr); | 1395 ASSERT(FLAG_use_osr); |
| 1396 #if !defined(TARGET_ARCH_DBC) |
1372 DartFrameIterator iterator; | 1397 DartFrameIterator iterator; |
1373 StackFrame* frame = iterator.NextFrame(); | 1398 StackFrame* frame = iterator.NextFrame(); |
1374 ASSERT(frame != NULL); | 1399 ASSERT(frame != NULL); |
1375 const Code& code = Code::ZoneHandle(frame->LookupDartCode()); | 1400 const Code& code = Code::ZoneHandle(frame->LookupDartCode()); |
1376 ASSERT(!code.IsNull()); | 1401 ASSERT(!code.IsNull()); |
1377 const Function& function = Function::Handle(code.function()); | 1402 const Function& function = Function::Handle(code.function()); |
1378 ASSERT(!function.IsNull()); | 1403 ASSERT(!function.IsNull()); |
1379 // Since the code is referenced from the frame and the ZoneHandle, | 1404 // Since the code is referenced from the frame and the ZoneHandle, |
1380 // it cannot have been removed from the function. | 1405 // it cannot have been removed from the function. |
1381 ASSERT(function.HasCode()); | 1406 ASSERT(function.HasCode()); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1414 if (optimized_code.raw() != original_code.raw()) { | 1439 if (optimized_code.raw() != original_code.raw()) { |
1415 // The OSR code does not work for calling the function, so restore the | 1440 // The OSR code does not work for calling the function, so restore the |
1416 // unoptimized code. Patch the stack frame to return into the OSR | 1441 // unoptimized code. Patch the stack frame to return into the OSR |
1417 // code. | 1442 // code. |
1418 uword optimized_entry = | 1443 uword optimized_entry = |
1419 Instructions::Handle(optimized_code.instructions()).EntryPoint(); | 1444 Instructions::Handle(optimized_code.instructions()).EntryPoint(); |
1420 function.AttachCode(original_code); | 1445 function.AttachCode(original_code); |
1421 frame->set_pc(optimized_entry); | 1446 frame->set_pc(optimized_entry); |
1422 frame->set_pc_marker(optimized_code.raw()); | 1447 frame->set_pc_marker(optimized_code.raw()); |
1423 } | 1448 } |
| 1449 #endif |
1424 } | 1450 } |
1425 } | 1451 } |
1426 | 1452 |
1427 | 1453 |
1428 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) { | 1454 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) { |
1429 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(0)); | 1455 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(0)); |
1430 const Function& function = Function::CheckedHandle(arguments.ArgAt(1)); | 1456 const Function& function = Function::CheckedHandle(arguments.ArgAt(1)); |
1431 DartFrameIterator iterator; | 1457 DartFrameIterator iterator; |
1432 StackFrame* frame = iterator.NextFrame(); | 1458 StackFrame* frame = iterator.NextFrame(); |
1433 ASSERT(frame != NULL); | 1459 ASSERT(frame != NULL); |
1434 OS::PrintErr("IC call @%#" Px ": ICData: %p cnt:%" Pd " nchecks: %" Pd | 1460 OS::PrintErr("IC call @%#" Px ": ICData: %p cnt:%" Pd " nchecks: %" Pd |
1435 " %s\n", | 1461 " %s\n", |
1436 frame->pc(), | 1462 frame->pc(), |
1437 ic_data.raw(), | 1463 ic_data.raw(), |
1438 function.usage_counter(), | 1464 function.usage_counter(), |
1439 ic_data.NumberOfChecks(), | 1465 ic_data.NumberOfChecks(), |
1440 function.ToFullyQualifiedCString()); | 1466 function.ToFullyQualifiedCString()); |
1441 } | 1467 } |
1442 | 1468 |
1443 | 1469 |
1444 // This is called from function that needs to be optimized. | 1470 // This is called from function that needs to be optimized. |
1445 // The requesting function can be already optimized (reoptimization). | 1471 // The requesting function can be already optimized (reoptimization). |
1446 // Returns the Code object where to continue execution. | 1472 // Returns the Code object where to continue execution. |
1447 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { | 1473 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { |
1448 #if !defined(DART_PRECOMPILED_RUNTIME) | 1474 #if !defined(DART_PRECOMPILED_RUNTIME) && !defined(TARGET_ARCH_DBC) |
1449 const Function& function = Function::CheckedHandle(zone, | 1475 const Function& function = Function::CheckedHandle(zone, |
1450 arguments.ArgAt(0)); | 1476 arguments.ArgAt(0)); |
1451 ASSERT(!function.IsNull()); | 1477 ASSERT(!function.IsNull()); |
1452 ASSERT(function.HasCode()); | 1478 ASSERT(function.HasCode()); |
1453 | 1479 |
1454 if (CanOptimizeFunction(function, thread)) { | 1480 if (CanOptimizeFunction(function, thread)) { |
1455 if (FLAG_background_compilation) { | 1481 if (FLAG_background_compilation) { |
1456 Field& field = Field::Handle(zone, isolate->GetDeoptimizingBoxedField()); | 1482 Field& field = Field::Handle(zone, isolate->GetDeoptimizingBoxedField()); |
1457 while (!field.IsNull()) { | 1483 while (!field.IsNull()) { |
1458 if (FLAG_trace_optimization || FLAG_trace_field_guards) { | 1484 if (FLAG_trace_optimization || FLAG_trace_field_guards) { |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1892 const intptr_t elm_size = old_data.ElementSizeInBytes(); | 1918 const intptr_t elm_size = old_data.ElementSizeInBytes(); |
1893 const TypedData& new_data = | 1919 const TypedData& new_data = |
1894 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); | 1920 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); |
1895 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); | 1921 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); |
1896 typed_data_cell.SetAt(0, new_data); | 1922 typed_data_cell.SetAt(0, new_data); |
1897 arguments.SetReturn(new_data); | 1923 arguments.SetReturn(new_data); |
1898 } | 1924 } |
1899 | 1925 |
1900 | 1926 |
1901 } // namespace dart | 1927 } // namespace dart |
OLD | NEW |