| 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/code_generator.h" | 5 #include "vm/code_generator.h" |
| 6 | 6 |
| 7 #include "vm/assembler_macros.h" | 7 #include "vm/assembler_macros.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" |
| 11 #include "vm/dart_api_impl.h" | 11 #include "vm/dart_api_impl.h" |
| 12 #include "vm/dart_entry.h" | 12 #include "vm/dart_entry.h" |
| 13 #include "vm/debugger.h" | 13 #include "vm/debugger.h" |
| 14 #include "vm/deopt_instructions.h" | 14 #include "vm/deopt_instructions.h" |
| 15 #include "vm/exceptions.h" | 15 #include "vm/exceptions.h" |
| 16 #include "vm/intermediate_language.h" | 16 #include "vm/intermediate_language.h" |
| 17 #include "vm/object_store.h" | 17 #include "vm/object_store.h" |
| 18 #include "vm/message.h" | 18 #include "vm/message.h" |
| 19 #include "vm/message_handler.h" | 19 #include "vm/message_handler.h" |
| 20 #include "vm/parser.h" | 20 #include "vm/parser.h" |
| 21 #include "vm/resolver.h" | 21 #include "vm/resolver.h" |
| 22 #include "vm/runtime_entry.h" | 22 #include "vm/runtime_entry.h" |
| 23 #include "vm/stack_frame.h" | 23 #include "vm/stack_frame.h" |
| 24 #include "vm/symbols.h" | 24 #include "vm/symbols.h" |
| 25 #include "vm/verifier.h" | 25 #include "vm/verifier.h" |
| 26 | 26 |
| 27 namespace dart { | 27 namespace dart { |
| 28 | 28 |
| 29 DEFINE_FLAG(bool, deoptimize_alot, false, |
| 30 "Deoptimizes all live frames when we are about to return to Dart code from" |
| 31 " native entries."); |
| 29 DEFINE_FLAG(bool, inline_cache, true, "Enable inline caches"); | 32 DEFINE_FLAG(bool, inline_cache, true, "Enable inline caches"); |
| 30 DEFINE_FLAG(bool, trace_deopt, false, "Trace deoptimization"); | 33 DEFINE_FLAG(bool, trace_deopt, false, "Trace deoptimization"); |
| 31 DEFINE_FLAG(bool, trace_ic, false, "Trace IC handling"); | 34 DEFINE_FLAG(bool, trace_ic, false, "Trace IC handling"); |
| 32 DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code."); | 35 DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code."); |
| 33 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls"); | 36 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls"); |
| 34 DEFINE_FLAG(int, optimization_counter_threshold, 2000, | 37 DEFINE_FLAG(int, optimization_counter_threshold, 2000, |
| 35 "Function's usage-counter value before it is optimized, -1 means never"); | 38 "Function's usage-counter value before it is optimized, -1 means never"); |
| 36 DECLARE_FLAG(bool, enable_type_checks); | 39 DECLARE_FLAG(bool, enable_type_checks); |
| 37 DECLARE_FLAG(bool, trace_type_checks); | 40 DECLARE_FLAG(bool, trace_type_checks); |
| 38 DECLARE_FLAG(bool, report_usage_count); | 41 DECLARE_FLAG(bool, report_usage_count); |
| (...skipping 1330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1369 return ""; | 1372 return ""; |
| 1370 } | 1373 } |
| 1371 } | 1374 } |
| 1372 | 1375 |
| 1373 | 1376 |
| 1374 static void GetDeoptIxDescrAtPc(const Code& code, | 1377 static void GetDeoptIxDescrAtPc(const Code& code, |
| 1375 uword pc, | 1378 uword pc, |
| 1376 intptr_t* deopt_id, | 1379 intptr_t* deopt_id, |
| 1377 intptr_t* deopt_reason, | 1380 intptr_t* deopt_reason, |
| 1378 intptr_t* deopt_index) { | 1381 intptr_t* deopt_index) { |
| 1382 ASSERT(code.is_optimized()); |
| 1379 const PcDescriptors& descriptors = | 1383 const PcDescriptors& descriptors = |
| 1380 PcDescriptors::Handle(code.pc_descriptors()); | 1384 PcDescriptors::Handle(code.pc_descriptors()); |
| 1381 ASSERT(!descriptors.IsNull()); | 1385 ASSERT(!descriptors.IsNull()); |
| 1382 // Locate deopt id at deoptimization point inside optimized code. | 1386 // Locate deopt id at deoptimization point inside optimized code. |
| 1383 for (int i = 0; i < descriptors.Length(); i++) { | 1387 for (int i = 0; i < descriptors.Length(); i++) { |
| 1384 if ((static_cast<uword>(descriptors.PC(i)) == pc) && | 1388 if ((static_cast<uword>(descriptors.PC(i)) == pc) && |
| 1385 (descriptors.DescriptorKind(i) == PcDescriptors::kDeoptIndex)) { | 1389 (descriptors.DescriptorKind(i) == PcDescriptors::kDeoptIndex)) { |
| 1386 *deopt_id = descriptors.DeoptId(i); | 1390 *deopt_id = descriptors.DeoptId(i); |
| 1387 *deopt_reason = descriptors.DeoptReason(i); | 1391 *deopt_reason = descriptors.DeoptReason(i); |
| 1388 *deopt_index = descriptors.DeoptIndex(i); | 1392 *deopt_index = descriptors.DeoptIndex(i); |
| 1389 return; | 1393 return; |
| 1390 } | 1394 } |
| 1391 } | 1395 } |
| 1392 *deopt_id = Isolate::kNoDeoptId; | 1396 *deopt_id = Isolate::kNoDeoptId; |
| 1393 *deopt_reason = kDeoptUnknown; | 1397 *deopt_reason = kDeoptUnknown; |
| 1394 *deopt_index = -1; | 1398 *deopt_index = -1; |
| 1395 } | 1399 } |
| 1396 | 1400 |
| 1397 | 1401 |
| 1402 // Currently checks only that all optimized frames have kDeoptIndex |
| 1403 // and unoptimized code has the kDeoptAfter. |
| 1404 void DeoptimizeAll() { |
| 1405 DartFrameIterator iterator; |
| 1406 StackFrame* frame = iterator.NextFrame(); |
| 1407 Code& optimized_code = Code::Handle(); |
| 1408 Function& function = Function::Handle(); |
| 1409 Code& unoptimized_code = Code::Handle(); |
| 1410 while (frame != NULL) { |
| 1411 optimized_code = frame->LookupDartCode(); |
| 1412 if (optimized_code.is_optimized()) { |
| 1413 intptr_t deopt_id, deopt_reason, deopt_index; |
| 1414 GetDeoptIxDescrAtPc(optimized_code, frame->pc(), |
| 1415 &deopt_id, &deopt_reason, &deopt_index); |
| 1416 ASSERT(deopt_id != Isolate::kNoDeoptId); |
| 1417 function = optimized_code.function(); |
| 1418 unoptimized_code = function.unoptimized_code(); |
| 1419 ASSERT(!unoptimized_code.IsNull()); |
| 1420 uword continue_at_pc = |
| 1421 unoptimized_code.GetDeoptAfterPcAtDeoptId(deopt_id); |
| 1422 ASSERT(continue_at_pc != 0); |
| 1423 } |
| 1424 frame = iterator.NextFrame(); |
| 1425 } |
| 1426 } |
| 1427 |
| 1398 | 1428 |
| 1399 // Copy saved registers into the isolate buffer. | 1429 // Copy saved registers into the isolate buffer. |
| 1400 static void CopySavedRegisters(intptr_t* saved_registers_address) { | 1430 static void CopySavedRegisters(intptr_t* saved_registers_address) { |
| 1401 intptr_t* registers_copy = new intptr_t[kNumberOfCpuRegisters]; | 1431 intptr_t* registers_copy = new intptr_t[kNumberOfCpuRegisters]; |
| 1402 ASSERT(registers_copy != NULL); | 1432 ASSERT(registers_copy != NULL); |
| 1403 ASSERT(saved_registers_address != NULL); | 1433 ASSERT(saved_registers_address != NULL); |
| 1404 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { | 1434 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { |
| 1405 registers_copy[i] = *saved_registers_address; | 1435 registers_copy[i] = *saved_registers_address; |
| 1406 saved_registers_address++; | 1436 saved_registers_address++; |
| 1407 } | 1437 } |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1556 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized()); | 1586 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized()); |
| 1557 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized()); | 1587 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized()); |
| 1558 | 1588 |
| 1559 intptr_t* frame_copy = isolate->deopt_frame_copy(); | 1589 intptr_t* frame_copy = isolate->deopt_frame_copy(); |
| 1560 intptr_t* registers_copy = isolate->deopt_registers_copy(); | 1590 intptr_t* registers_copy = isolate->deopt_registers_copy(); |
| 1561 | 1591 |
| 1562 intptr_t deopt_id, deopt_reason, deopt_index; | 1592 intptr_t deopt_id, deopt_reason, deopt_index; |
| 1563 GetDeoptIxDescrAtPc(optimized_code, caller_frame->pc(), | 1593 GetDeoptIxDescrAtPc(optimized_code, caller_frame->pc(), |
| 1564 &deopt_id, &deopt_reason, &deopt_index); | 1594 &deopt_id, &deopt_reason, &deopt_index); |
| 1565 ASSERT(deopt_id != Isolate::kNoDeoptId); | 1595 ASSERT(deopt_id != Isolate::kNoDeoptId); |
| 1566 uword continue_at_pc = unoptimized_code.GetDeoptPcAtDeoptId(deopt_id); | 1596 uword continue_at_pc = unoptimized_code.GetDeoptBeforePcAtDeoptId(deopt_id); |
| 1567 if (FLAG_trace_deopt) { | 1597 if (FLAG_trace_deopt) { |
| 1568 OS::Print(" -> continue at 0x%x\n", continue_at_pc); | 1598 OS::Print(" -> continue at 0x%x\n", continue_at_pc); |
| 1569 // TODO(srdjan): If we could allow GC, we could print the line where | 1599 // TODO(srdjan): If we could allow GC, we could print the line where |
| 1570 // deoptimization occured. | 1600 // deoptimization occured. |
| 1571 } | 1601 } |
| 1572 const Array& deopt_info_array = | 1602 const Array& deopt_info_array = |
| 1573 Array::Handle(optimized_code.deopt_info_array()); | 1603 Array::Handle(optimized_code.deopt_info_array()); |
| 1574 ASSERT(!deopt_info_array.IsNull()); | 1604 ASSERT(!deopt_info_array.IsNull()); |
| 1575 DeoptInfo& deopt_info = DeoptInfo::Handle(); | 1605 DeoptInfo& deopt_info = DeoptInfo::Handle(); |
| 1576 deopt_info ^= deopt_info_array.At(deopt_index); | 1606 deopt_info ^= deopt_info_array.At(deopt_index); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1607 function.set_usage_counter(0); | 1637 function.set_usage_counter(0); |
| 1608 function.set_deoptimization_counter(function.deoptimization_counter() + 1); | 1638 function.set_deoptimization_counter(function.deoptimization_counter() + 1); |
| 1609 | 1639 |
| 1610 if (function.HasOptimizedCode()) { | 1640 if (function.HasOptimizedCode()) { |
| 1611 function.SwitchToUnoptimizedCode(); | 1641 function.SwitchToUnoptimizedCode(); |
| 1612 } | 1642 } |
| 1613 } | 1643 } |
| 1614 END_LEAF_RUNTIME_ENTRY | 1644 END_LEAF_RUNTIME_ENTRY |
| 1615 | 1645 |
| 1616 } // namespace dart | 1646 } // namespace dart |
| OLD | NEW |