| 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" |
| (...skipping 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1543 deopt_id, | 1543 deopt_id, |
| 1544 Function::Handle(optimized_code.function()).ToFullyQualifiedCString()); | 1544 Function::Handle(optimized_code.function()).ToFullyQualifiedCString()); |
| 1545 } | 1545 } |
| 1546 | 1546 |
| 1547 // Compute the stack size of unoptimized frame | 1547 // Compute the stack size of unoptimized frame |
| 1548 const Array& deopt_info_array = | 1548 const Array& deopt_info_array = |
| 1549 Array::Handle(optimized_code.deopt_info_array()); | 1549 Array::Handle(optimized_code.deopt_info_array()); |
| 1550 ASSERT(!deopt_info_array.IsNull()); | 1550 ASSERT(!deopt_info_array.IsNull()); |
| 1551 DeoptInfo& deopt_info = DeoptInfo::Handle(); | 1551 DeoptInfo& deopt_info = DeoptInfo::Handle(); |
| 1552 deopt_info ^= deopt_info_array.At(deopt_index); | 1552 deopt_info ^= deopt_info_array.At(deopt_index); |
| 1553 if (deopt_info.IsNull()) { | 1553 ASSERT(!deopt_info.IsNull()); |
| 1554 // TODO(srdjan): Deprecate. | 1554 // For functions with optional argument deoptimization info does not |
| 1555 // Include the space for return address. | 1555 // describe incoming arguments. |
| 1556 intptr_t stack_size_in_bytes = caller_frame->fp() - caller_frame->sp(); | 1556 const Function& function = Function::Handle(optimized_code.function()); |
| 1557 return stack_size_in_bytes + kWordSize; | 1557 const intptr_t num_args = (function.num_optional_parameters() > 0) ? |
| 1558 } else { | 1558 0 : function.num_fixed_parameters(); |
| 1559 // For functions with optional argument deoptimization info does not | 1559 intptr_t unoptimized_stack_size = |
| 1560 // describe incoming arguments. | 1560 + deopt_info.Length() - num_args |
| 1561 const Function& function = Function::Handle(optimized_code.function()); | 1561 - 2; // Subtract caller FP and PC. |
| 1562 const intptr_t num_args = (function.num_optional_parameters() > 0) ? | 1562 return unoptimized_stack_size * kWordSize; |
| 1563 0 : function.num_fixed_parameters(); | |
| 1564 intptr_t unoptimized_stack_size = | |
| 1565 + deopt_info.Length() - num_args | |
| 1566 - 2; // Subtract caller FP and PC. | |
| 1567 return unoptimized_stack_size * kWordSize; | |
| 1568 } | |
| 1569 } | 1563 } |
| 1570 END_LEAF_RUNTIME_ENTRY | 1564 END_LEAF_RUNTIME_ENTRY |
| 1571 | 1565 |
| 1572 | 1566 |
| 1573 | 1567 |
| 1574 static void DeoptimizeWithDeoptInfo(const Code& code, | 1568 static void DeoptimizeWithDeoptInfo(const Code& code, |
| 1575 const DeoptInfo& deopt_info, | 1569 const DeoptInfo& deopt_info, |
| 1576 const StackFrame& caller_frame) { | 1570 const StackFrame& caller_frame) { |
| 1577 const intptr_t len = deopt_info.Length(); | 1571 const intptr_t len = deopt_info.Length(); |
| 1578 GrowableArray<DeoptInstr*> deopt_instructions(len); | 1572 GrowableArray<DeoptInstr*> deopt_instructions(len); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1638 if (FLAG_trace_deopt) { | 1632 if (FLAG_trace_deopt) { |
| 1639 OS::Print(" -> continue at 0x%x\n", continue_at_pc); | 1633 OS::Print(" -> continue at 0x%x\n", continue_at_pc); |
| 1640 // TODO(srdjan): If we could allow GC, we could print the line where | 1634 // TODO(srdjan): If we could allow GC, we could print the line where |
| 1641 // deoptimization occured. | 1635 // deoptimization occured. |
| 1642 } | 1636 } |
| 1643 const Array& deopt_info_array = | 1637 const Array& deopt_info_array = |
| 1644 Array::Handle(optimized_code.deopt_info_array()); | 1638 Array::Handle(optimized_code.deopt_info_array()); |
| 1645 ASSERT(!deopt_info_array.IsNull()); | 1639 ASSERT(!deopt_info_array.IsNull()); |
| 1646 DeoptInfo& deopt_info = DeoptInfo::Handle(); | 1640 DeoptInfo& deopt_info = DeoptInfo::Handle(); |
| 1647 deopt_info ^= deopt_info_array.At(deopt_index); | 1641 deopt_info ^= deopt_info_array.At(deopt_index); |
| 1648 if (deopt_info.IsNull()) { | 1642 ASSERT(!deopt_info.IsNull()); |
| 1649 // TODO(srdjan): Deprecate. | 1643 DeoptimizeWithDeoptInfo(optimized_code, deopt_info, *caller_frame); |
| 1650 const intptr_t deopt_frame_copy_size = isolate->deopt_frame_copy_size(); | |
| 1651 const intptr_t pc_marker_index = | |
| 1652 ((caller_frame->fp() - caller_frame->sp()) / kWordSize); | |
| 1653 // Patch the return PC and saved PC marker in frame to point to the | |
| 1654 // unoptimized version. | |
| 1655 frame_copy[0] = continue_at_pc; | |
| 1656 frame_copy[pc_marker_index] = | |
| 1657 unoptimized_code.EntryPoint() + | |
| 1658 AssemblerMacros::kOffsetOfSavedPCfromEntrypoint; | |
| 1659 intptr_t* start = | |
| 1660 reinterpret_cast<intptr_t*>(caller_frame->sp() - kWordSize); | |
| 1661 for (intptr_t i = 0; i < deopt_frame_copy_size; i++) { | |
| 1662 if (FLAG_trace_deopt) { | |
| 1663 OS::Print("%d. 0x%x\n", i, frame_copy[i]); | |
| 1664 } | |
| 1665 *(start + i) = frame_copy[i]; | |
| 1666 } | |
| 1667 } else { | |
| 1668 DeoptimizeWithDeoptInfo(optimized_code, deopt_info, *caller_frame); | |
| 1669 } | |
| 1670 | 1644 |
| 1671 isolate->SetDeoptFrameCopy(NULL, 0); | 1645 isolate->SetDeoptFrameCopy(NULL, 0); |
| 1672 isolate->set_deopt_cpu_registers_copy(NULL); | 1646 isolate->set_deopt_cpu_registers_copy(NULL); |
| 1673 isolate->set_deopt_xmm_registers_copy(NULL); | 1647 isolate->set_deopt_xmm_registers_copy(NULL); |
| 1674 delete[] frame_copy; | 1648 delete[] frame_copy; |
| 1675 delete[] cpu_registers_copy; | 1649 delete[] cpu_registers_copy; |
| 1676 delete[] xmm_registers_copy; | 1650 delete[] xmm_registers_copy; |
| 1677 | 1651 |
| 1678 // Clear invocation counter so that the function gets optimized after | 1652 // Clear invocation counter so that the function gets optimized after |
| 1679 // classes have been collected. | 1653 // classes have been collected. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1702 current->slot(), | 1676 current->slot(), |
| 1703 current->value()); | 1677 current->value()); |
| 1704 } | 1678 } |
| 1705 | 1679 |
| 1706 delete current; | 1680 delete current; |
| 1707 } | 1681 } |
| 1708 } | 1682 } |
| 1709 | 1683 |
| 1710 | 1684 |
| 1711 } // namespace dart | 1685 } // namespace dart |
| OLD | NEW |