Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(426)

Side by Side Diff: runtime/vm/code_generator.cc

Issue 10952002: Reapply "Deoptimization support in inlined code." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/compiler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1464 matching lines...) Expand 10 before | Expand all | Expand 10 after
1475 while (frame != NULL) { 1475 while (frame != NULL) {
1476 optimized_code = frame->LookupDartCode(); 1476 optimized_code = frame->LookupDartCode();
1477 if (optimized_code.is_optimized()) { 1477 if (optimized_code.is_optimized()) {
1478 intptr_t deopt_id, deopt_reason, deopt_index; 1478 intptr_t deopt_id, deopt_reason, deopt_index;
1479 GetDeoptIxDescrAtPc(optimized_code, frame->pc(), 1479 GetDeoptIxDescrAtPc(optimized_code, frame->pc(),
1480 &deopt_id, &deopt_reason, &deopt_index); 1480 &deopt_id, &deopt_reason, &deopt_index);
1481 ASSERT(deopt_id != Isolate::kNoDeoptId); 1481 ASSERT(deopt_id != Isolate::kNoDeoptId);
1482 function = optimized_code.function(); 1482 function = optimized_code.function();
1483 unoptimized_code = function.unoptimized_code(); 1483 unoptimized_code = function.unoptimized_code();
1484 ASSERT(!unoptimized_code.IsNull()); 1484 ASSERT(!unoptimized_code.IsNull());
1485 uword continue_at_pc =
1486 unoptimized_code.GetDeoptAfterPcAtDeoptId(deopt_id);
1487 ASSERT(continue_at_pc != 0);
1488 // The switch to unoptimized code may have already occured. 1485 // The switch to unoptimized code may have already occured.
1489 if (function.HasOptimizedCode()) { 1486 if (function.HasOptimizedCode()) {
1490 function.SwitchToUnoptimizedCode(); 1487 function.SwitchToUnoptimizedCode();
1491 } 1488 }
1492 // Patch call site (lazy deoptimization is quite rare, patching it twice 1489 // Patch call site (lazy deoptimization is quite rare, patching it twice
1493 // is not a performance issue). 1490 // is not a performance issue).
1494 uword lazy_deopt_jump = optimized_code.GetLazyDeoptPc(); 1491 uword lazy_deopt_jump = optimized_code.GetLazyDeoptPc();
1495 ASSERT(lazy_deopt_jump != 0); 1492 ASSERT(lazy_deopt_jump != 0);
1496 CodePatcher::InsertCallAt(frame->pc(), lazy_deopt_jump); 1493 CodePatcher::InsertCallAt(frame->pc(), lazy_deopt_jump);
1497 // Mark code as dead (do not GC its embedded objects). 1494 // Mark code as dead (do not GC its embedded objects).
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); 1599 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
1603 intptr_t unoptimized_stack_size = 1600 intptr_t unoptimized_stack_size =
1604 + deopt_info.Length() - num_args 1601 + deopt_info.Length() - num_args
1605 - 2; // Subtract caller FP and PC. 1602 - 2; // Subtract caller FP and PC.
1606 return unoptimized_stack_size * kWordSize; 1603 return unoptimized_stack_size * kWordSize;
1607 } 1604 }
1608 END_LEAF_RUNTIME_ENTRY 1605 END_LEAF_RUNTIME_ENTRY
1609 1606
1610 1607
1611 1608
1612 static void DeoptimizeWithDeoptInfo(const Code& code, 1609 static intptr_t DeoptimizeWithDeoptInfo(const Code& code,
1613 const DeoptInfo& deopt_info, 1610 const DeoptInfo& deopt_info,
1614 const StackFrame& caller_frame) { 1611 const StackFrame& caller_frame) {
1615 const intptr_t len = deopt_info.Length(); 1612 const intptr_t len = deopt_info.Length();
1616 GrowableArray<DeoptInstr*> deopt_instructions(len); 1613 GrowableArray<DeoptInstr*> deopt_instructions(len);
1617 for (intptr_t i = 0; i < len; i++) { 1614 for (intptr_t i = 0; i < len; i++) {
1618 deopt_instructions.Add(DeoptInstr::Create(deopt_info.Instruction(i), 1615 deopt_instructions.Add(DeoptInstr::Create(deopt_info.Instruction(i),
1619 deopt_info.FromIndex(i))); 1616 deopt_info.FromIndex(i)));
1620 } 1617 }
1621 1618
1622 intptr_t* start = reinterpret_cast<intptr_t*>(caller_frame.sp() - kWordSize); 1619 intptr_t* start = reinterpret_cast<intptr_t*>(caller_frame.sp() - kWordSize);
1623 const Function& function = Function::Handle(code.function()); 1620 const Function& function = Function::Handle(code.function());
1624 const intptr_t num_args = 1621 const intptr_t num_args =
(...skipping 12 matching lines...) Expand all
1637 } 1634 }
1638 if (FLAG_trace_deopt) { 1635 if (FLAG_trace_deopt) {
1639 for (intptr_t i = 0; i < len; i++) { 1636 for (intptr_t i = 0; i < len; i++) {
1640 OS::Print("*%"Pd". [%p] %#014"Px" [%s]\n", 1637 OS::Print("*%"Pd". [%p] %#014"Px" [%s]\n",
1641 i, 1638 i,
1642 &start[i], 1639 &start[i],
1643 start[i], 1640 start[i],
1644 deopt_instructions[i]->ToCString()); 1641 deopt_instructions[i]->ToCString());
1645 } 1642 }
1646 } 1643 }
1644 return deopt_context.GetCallerFp();
1647 } 1645 }
1648 1646
1649 1647
1650 // The stack has been adjusted to fit all values for unoptimized frame. 1648 // The stack has been adjusted to fit all values for unoptimized frame.
1651 // Fill the unoptimized frame. 1649 // Fill the unoptimized frame.
1652 DEFINE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp) { 1650 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeFillFrame, uword last_fp) {
1653 Isolate* isolate = Isolate::Current(); 1651 Isolate* isolate = Isolate::Current();
1654 Zone zone(isolate); 1652 Zone zone(isolate);
1655 HANDLESCOPE(isolate); 1653 HANDLESCOPE(isolate);
1656 1654
1657 DartFrameIterator iterator(last_fp); 1655 DartFrameIterator iterator(last_fp);
1658 StackFrame* caller_frame = iterator.NextFrame(); 1656 StackFrame* caller_frame = iterator.NextFrame();
1659 ASSERT(caller_frame != NULL); 1657 ASSERT(caller_frame != NULL);
1660 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode()); 1658 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode());
1661 const Function& function = Function::Handle(optimized_code.function()); 1659 const Function& function = Function::Handle(optimized_code.function());
1662 ASSERT(!function.IsNull()); 1660 ASSERT(!function.IsNull());
1663 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); 1661 const Code& unoptimized_code = Code::Handle(function.unoptimized_code());
1664 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized()); 1662 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized());
1665 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized()); 1663 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized());
1666 1664
1667 intptr_t* frame_copy = isolate->deopt_frame_copy(); 1665 intptr_t* frame_copy = isolate->deopt_frame_copy();
1668 intptr_t* cpu_registers_copy = isolate->deopt_cpu_registers_copy(); 1666 intptr_t* cpu_registers_copy = isolate->deopt_cpu_registers_copy();
1669 double* xmm_registers_copy = isolate->deopt_xmm_registers_copy(); 1667 double* xmm_registers_copy = isolate->deopt_xmm_registers_copy();
1670 1668
1671 intptr_t deopt_id, deopt_reason, deopt_index; 1669 intptr_t deopt_id, deopt_reason, deopt_index;
1672 GetDeoptIxDescrAtPc(optimized_code, caller_frame->pc(), 1670 GetDeoptIxDescrAtPc(optimized_code, caller_frame->pc(),
1673 &deopt_id, &deopt_reason, &deopt_index); 1671 &deopt_id, &deopt_reason, &deopt_index);
1674 ASSERT(deopt_id != Isolate::kNoDeoptId); 1672 ASSERT(deopt_id != Isolate::kNoDeoptId);
1675 uword continue_at_pc = 0;
1676 if (deopt_reason == kDeoptAtCall) {
1677 continue_at_pc = unoptimized_code.GetDeoptAfterPcAtDeoptId(deopt_id);
1678 } else {
1679 continue_at_pc = unoptimized_code.GetDeoptBeforePcAtDeoptId(deopt_id);
1680 }
1681 ASSERT(continue_at_pc != 0);
1682 if (FLAG_trace_deopt) {
1683 OS::Print(" -> continue at %#"Px"\n", continue_at_pc);
1684 // TODO(srdjan): If we could allow GC, we could print the line where
1685 // deoptimization occured.
1686 }
1687 const Array& deopt_info_array = 1673 const Array& deopt_info_array =
1688 Array::Handle(optimized_code.deopt_info_array()); 1674 Array::Handle(optimized_code.deopt_info_array());
1689 ASSERT(!deopt_info_array.IsNull()); 1675 ASSERT(!deopt_info_array.IsNull());
1690 DeoptInfo& deopt_info = DeoptInfo::Handle(); 1676 DeoptInfo& deopt_info = DeoptInfo::Handle();
1691 deopt_info ^= deopt_info_array.At(deopt_index); 1677 deopt_info ^= deopt_info_array.At(deopt_index);
1692 ASSERT(!deopt_info.IsNull()); 1678 ASSERT(!deopt_info.IsNull());
1693 DeoptimizeWithDeoptInfo(optimized_code, deopt_info, *caller_frame); 1679 const intptr_t caller_fp =
1680 DeoptimizeWithDeoptInfo(optimized_code, deopt_info, *caller_frame);
1694 1681
1695 isolate->SetDeoptFrameCopy(NULL, 0); 1682 isolate->SetDeoptFrameCopy(NULL, 0);
1696 isolate->set_deopt_cpu_registers_copy(NULL); 1683 isolate->set_deopt_cpu_registers_copy(NULL);
1697 isolate->set_deopt_xmm_registers_copy(NULL); 1684 isolate->set_deopt_xmm_registers_copy(NULL);
1698 delete[] frame_copy; 1685 delete[] frame_copy;
1699 delete[] cpu_registers_copy; 1686 delete[] cpu_registers_copy;
1700 delete[] xmm_registers_copy; 1687 delete[] xmm_registers_copy;
1701 1688
1702 // Clear invocation counter so that the function gets optimized after 1689 // Clear invocation counter so that the function gets optimized after
1703 // classes have been collected. 1690 // classes have been collected.
1704 function.set_usage_counter(0); 1691 function.set_usage_counter(0);
1705 function.set_deoptimization_counter(function.deoptimization_counter() + 1); 1692 function.set_deoptimization_counter(function.deoptimization_counter() + 1);
1706 1693
1707 if (function.HasOptimizedCode()) { 1694 if (function.HasOptimizedCode()) {
1708 function.SwitchToUnoptimizedCode(); 1695 function.SwitchToUnoptimizedCode();
1709 } 1696 }
1697 return caller_fp;
1710 } 1698 }
1711 END_LEAF_RUNTIME_ENTRY 1699 END_LEAF_RUNTIME_ENTRY
1712 1700
1713 1701
1714 DEFINE_RUNTIME_ENTRY(DeoptimizeMaterializeDoubles, 0) { 1702 DEFINE_RUNTIME_ENTRY(DeoptimizeMaterializeDoubles, 0) {
1715 DeferredDouble* deferred_double = Isolate::Current()->DetachDeferredDoubles(); 1703 DeferredDouble* deferred_double = Isolate::Current()->DetachDeferredDoubles();
1716 1704
1717 while (deferred_double != NULL) { 1705 while (deferred_double != NULL) {
1718 DeferredDouble* current = deferred_double; 1706 DeferredDouble* current = deferred_double;
1719 deferred_double = deferred_double->next(); 1707 deferred_double = deferred_double->next();
1720 1708
1721 RawDouble** slot = current->slot(); 1709 RawDouble** slot = current->slot();
1722 *slot = Double::New(current->value()); 1710 *slot = Double::New(current->value());
1723 1711
1724 if (FLAG_trace_deopt) { 1712 if (FLAG_trace_deopt) {
1725 OS::Print("materialing double at %p: %g\n", 1713 OS::Print("materialing double at %p: %g\n",
1726 current->slot(), 1714 current->slot(),
1727 current->value()); 1715 current->value());
1728 } 1716 }
1729 1717
1730 delete current; 1718 delete current;
1731 } 1719 }
1732 } 1720 }
1733 1721
1734 1722
1735 } // namespace dart 1723 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698