Chromium Code Reviews| 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 1619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1630 if (pc == (code_entry + offset.Value())) { | 1630 if (pc == (code_entry + offset.Value())) { |
| 1631 *deopt_reason = static_cast<DeoptReasonId>(reason.Value()); | 1631 *deopt_reason = static_cast<DeoptReasonId>(reason.Value()); |
| 1632 return; | 1632 return; |
| 1633 } | 1633 } |
| 1634 } | 1634 } |
| 1635 *deopt_info = DeoptInfo::null(); | 1635 *deopt_info = DeoptInfo::null(); |
| 1636 *deopt_reason = kDeoptUnknown; | 1636 *deopt_reason = kDeoptUnknown; |
| 1637 } | 1637 } |
| 1638 | 1638 |
| 1639 | 1639 |
| 1640 static void DeoptimizeAt(const Code& optimized_code, uword pc) { | |
| 1641 DeoptInfo& deopt_info = DeoptInfo::Handle(); | |
| 1642 DeoptReasonId deopt_reason = kDeoptUnknown; | |
| 1643 GetDeoptInfoAtPc(optimized_code, pc, &deopt_info, &deopt_reason); | |
| 1644 ASSERT(!deopt_info.IsNull()); | |
| 1645 const Function& function = Function::Handle(optimized_code.function()); | |
| 1646 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); | |
| 1647 ASSERT(!unoptimized_code.IsNull()); | |
| 1648 // The switch to unoptimized code may have already occured. | |
| 1649 if (function.HasOptimizedCode()) { | |
| 1650 function.SwitchToUnoptimizedCode(); | |
| 1651 } | |
| 1652 // Patch call site (lazy deoptimization is quite rare, patching it twice | |
| 1653 // is not a performance issue). | |
| 1654 uword lazy_deopt_jump = optimized_code.GetLazyDeoptPc(); | |
| 1655 ASSERT(lazy_deopt_jump != 0); | |
| 1656 CodePatcher::InsertCallAt(pc, lazy_deopt_jump); | |
| 1657 // Mark code as dead (do not GC its embedded objects). | |
| 1658 optimized_code.set_is_alive(false); | |
| 1659 } | |
| 1660 | |
| 1661 | |
| 1640 // Currently checks only that all optimized frames have kDeoptIndex | 1662 // Currently checks only that all optimized frames have kDeoptIndex |
| 1641 // and unoptimized code has the kDeoptAfter. | 1663 // and unoptimized code has the kDeoptAfter. |
| 1642 void DeoptimizeAll() { | 1664 void DeoptimizeAll() { |
| 1643 DartFrameIterator iterator; | 1665 DartFrameIterator iterator; |
| 1644 StackFrame* frame = iterator.NextFrame(); | 1666 StackFrame* frame = iterator.NextFrame(); |
| 1645 Code& optimized_code = Code::Handle(); | 1667 Code& optimized_code = Code::Handle(); |
| 1646 Function& function = Function::Handle(); | |
| 1647 Code& unoptimized_code = Code::Handle(); | |
| 1648 while (frame != NULL) { | 1668 while (frame != NULL) { |
| 1649 optimized_code = frame->LookupDartCode(); | 1669 optimized_code = frame->LookupDartCode(); |
| 1650 if (optimized_code.is_optimized()) { | 1670 if (optimized_code.is_optimized()) { |
| 1651 DeoptInfo& deopt_info = DeoptInfo::Handle(); | 1671 DeoptimizeAt(optimized_code, frame->pc()); |
| 1652 DeoptReasonId deopt_reason = kDeoptUnknown; | |
| 1653 GetDeoptInfoAtPc(optimized_code, frame->pc(), &deopt_info, &deopt_reason); | |
| 1654 ASSERT(!deopt_info.IsNull()); | |
| 1655 function = optimized_code.function(); | |
| 1656 unoptimized_code = function.unoptimized_code(); | |
| 1657 ASSERT(!unoptimized_code.IsNull()); | |
| 1658 // The switch to unoptimized code may have already occured. | |
| 1659 if (function.HasOptimizedCode()) { | |
| 1660 function.SwitchToUnoptimizedCode(); | |
| 1661 } | |
| 1662 // Patch call site (lazy deoptimization is quite rare, patching it twice | |
| 1663 // is not a performance issue). | |
| 1664 uword lazy_deopt_jump = optimized_code.GetLazyDeoptPc(); | |
| 1665 ASSERT(lazy_deopt_jump != 0); | |
| 1666 CodePatcher::InsertCallAt(frame->pc(), lazy_deopt_jump); | |
| 1667 // Mark code as dead (do not GC its embedded objects). | |
| 1668 optimized_code.set_is_alive(false); | |
| 1669 } | 1672 } |
| 1670 frame = iterator.NextFrame(); | 1673 frame = iterator.NextFrame(); |
| 1671 } | 1674 } |
| 1672 } | 1675 } |
| 1673 | 1676 |
| 1674 | 1677 |
| 1678 // Returns true if the given array of cids contains the given cid. | |
| 1679 static bool ContainsCid(const GrowableArray<intptr_t>& cids, intptr_t cid) { | |
| 1680 for (intptr_t i = 0; i < cids.length(); i++) { | |
| 1681 if (cids[i] == cid) { | |
| 1682 return true; | |
| 1683 } | |
| 1684 } | |
| 1685 return false; | |
| 1686 } | |
| 1687 | |
| 1688 | |
| 1689 // Deoptimize optimized code on stack if its class is in the 'classes' array. | |
| 1690 void DeoptimizeIfOwner(const GrowableArray<intptr_t>& classes) { | |
|
Florian Schneider
2012/11/15 00:46:06
It seems that DeoptimizeIfOwner is not used yet. I
srdjan
2012/11/15 01:04:44
Oops, forgot to refer to it from RemoveOptimizedCo
| |
| 1691 DartFrameIterator iterator; | |
| 1692 StackFrame* frame = iterator.NextFrame(); | |
| 1693 Code& optimized_code = Code::Handle(); | |
| 1694 while (frame != NULL) { | |
| 1695 optimized_code = frame->LookupDartCode(); | |
| 1696 if (optimized_code.is_optimized()) { | |
| 1697 const intptr_t owner_cid = Class::Handle(Function::Handle( | |
| 1698 optimized_code.function()).Owner()).id(); | |
| 1699 if (ContainsCid(classes, owner_cid)) { | |
| 1700 DeoptimizeAt(optimized_code, frame->pc()); | |
| 1701 } | |
| 1702 } | |
| 1703 } | |
| 1704 } | |
| 1705 | |
| 1706 | |
| 1675 // Copy saved registers into the isolate buffer. | 1707 // Copy saved registers into the isolate buffer. |
| 1676 static void CopySavedRegisters(uword saved_registers_address) { | 1708 static void CopySavedRegisters(uword saved_registers_address) { |
| 1677 double* xmm_registers_copy = new double[kNumberOfXmmRegisters]; | 1709 double* xmm_registers_copy = new double[kNumberOfXmmRegisters]; |
| 1678 ASSERT(xmm_registers_copy != NULL); | 1710 ASSERT(xmm_registers_copy != NULL); |
| 1679 for (intptr_t i = 0; i < kNumberOfXmmRegisters; i++) { | 1711 for (intptr_t i = 0; i < kNumberOfXmmRegisters; i++) { |
| 1680 xmm_registers_copy[i] = *reinterpret_cast<double*>(saved_registers_address); | 1712 xmm_registers_copy[i] = *reinterpret_cast<double*>(saved_registers_address); |
| 1681 saved_registers_address += kDoubleSize; | 1713 saved_registers_address += kDoubleSize; |
| 1682 } | 1714 } |
| 1683 Isolate::Current()->set_deopt_xmm_registers_copy(xmm_registers_copy); | 1715 Isolate::Current()->set_deopt_xmm_registers_copy(xmm_registers_copy); |
| 1684 | 1716 |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1907 intptr_t line, column; | 1939 intptr_t line, column; |
| 1908 script.GetTokenLocation(token_pos, &line, &column); | 1940 script.GetTokenLocation(token_pos, &line, &column); |
| 1909 String& line_string = String::Handle(script.GetLine(line)); | 1941 String& line_string = String::Handle(script.GetLine(line)); |
| 1910 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); | 1942 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); |
| 1911 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); | 1943 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); |
| 1912 } | 1944 } |
| 1913 } | 1945 } |
| 1914 | 1946 |
| 1915 | 1947 |
| 1916 } // namespace dart | 1948 } // namespace dart |
| OLD | NEW |