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

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

Issue 11833025: Fix for issue 7757 (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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 | « runtime/tests/vm/vm.status ('k') | runtime/vm/deopt_instructions.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/bigint_operations.h" 9 #include "vm/bigint_operations.h"
10 #include "vm/code_patcher.h" 10 #include "vm/code_patcher.h"
(...skipping 1420 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 #define DEOPT_REASON_ID_TO_TEXT(name) case kDeopt##name: return #name; 1431 #define DEOPT_REASON_ID_TO_TEXT(name) case kDeopt##name: return #name;
1432 DEOPT_REASONS(DEOPT_REASON_ID_TO_TEXT) 1432 DEOPT_REASONS(DEOPT_REASON_ID_TO_TEXT)
1433 #undef DEOPT_REASON_ID_TO_TEXT 1433 #undef DEOPT_REASON_ID_TO_TEXT
1434 default: 1434 default:
1435 UNREACHABLE(); 1435 UNREACHABLE();
1436 return ""; 1436 return "";
1437 } 1437 }
1438 } 1438 }
1439 1439
1440 1440
1441 static void GetDeoptInfoAtPc(const Code& code,
1442 uword pc,
1443 DeoptInfo* deopt_info,
1444 DeoptReasonId* deopt_reason) {
1445 ASSERT(code.is_optimized());
1446 const Instructions& instructions = Instructions::Handle(code.instructions());
1447 uword code_entry = instructions.EntryPoint();
1448 const Array& table = Array::Handle(code.deopt_info_array());
1449 ASSERT(!table.IsNull());
1450 // Linear search for the PC offset matching the target PC.
1451 intptr_t length = DeoptTable::GetLength(table);
1452 Smi& offset = Smi::Handle();
1453 Smi& reason = Smi::Handle();
1454 for (intptr_t i = 0; i < length; ++i) {
1455 DeoptTable::GetEntry(table, i, &offset, deopt_info, &reason);
1456 if (pc == (code_entry + offset.Value())) {
1457 *deopt_reason = static_cast<DeoptReasonId>(reason.Value());
1458 return;
1459 }
1460 }
1461 *deopt_info = DeoptInfo::null();
1462 *deopt_reason = kDeoptUnknown;
1463 }
1464
1465
1466 static void DeoptimizeAt(const Code& optimized_code, uword pc) { 1441 static void DeoptimizeAt(const Code& optimized_code, uword pc) {
1467 DeoptInfo& deopt_info = DeoptInfo::Handle(); 1442 intptr_t deopt_reason = kDeoptUnknown;
1468 DeoptReasonId deopt_reason = kDeoptUnknown; 1443 const DeoptInfo& deopt_info =
1469 GetDeoptInfoAtPc(optimized_code, pc, &deopt_info, &deopt_reason); 1444 DeoptInfo::Handle(optimized_code.GetDeoptInfoAtPc(pc, &deopt_reason));
1470 ASSERT(!deopt_info.IsNull()); 1445 ASSERT(!deopt_info.IsNull());
1471 const Function& function = Function::Handle(optimized_code.function()); 1446 const Function& function = Function::Handle(optimized_code.function());
1472 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); 1447 const Code& unoptimized_code = Code::Handle(function.unoptimized_code());
1473 ASSERT(!unoptimized_code.IsNull()); 1448 ASSERT(!unoptimized_code.IsNull());
1474 // The switch to unoptimized code may have already occured. 1449 // The switch to unoptimized code may have already occured.
1475 if (function.HasOptimizedCode()) { 1450 if (function.HasOptimizedCode()) {
1476 function.SwitchToUnoptimizedCode(); 1451 function.SwitchToUnoptimizedCode();
1477 } 1452 }
1478 // Patch call site (lazy deoptimization is quite rare, patching it twice 1453 // Patch call site (lazy deoptimization is quite rare, patching it twice
1479 // is not a performance issue). 1454 // is not a performance issue).
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 CopySavedRegisters(saved_registers_address); 1567 CopySavedRegisters(saved_registers_address);
1593 1568
1594 // Get optimized code and frame that need to be deoptimized. 1569 // Get optimized code and frame that need to be deoptimized.
1595 DartFrameIterator iterator(last_fp); 1570 DartFrameIterator iterator(last_fp);
1596 StackFrame* caller_frame = iterator.NextFrame(); 1571 StackFrame* caller_frame = iterator.NextFrame();
1597 ASSERT(caller_frame != NULL); 1572 ASSERT(caller_frame != NULL);
1598 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode()); 1573 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode());
1599 ASSERT(optimized_code.is_optimized()); 1574 ASSERT(optimized_code.is_optimized());
1600 1575
1601 1576
1602 DeoptInfo& deopt_info = DeoptInfo::Handle(); 1577 intptr_t deopt_reason = kDeoptUnknown;
1603 DeoptReasonId deopt_reason = kDeoptUnknown; 1578 const DeoptInfo& deopt_info = DeoptInfo::Handle(
1604 GetDeoptInfoAtPc(optimized_code, caller_frame->pc(), &deopt_info, 1579 optimized_code.GetDeoptInfoAtPc(caller_frame->pc(), &deopt_reason));
1605 &deopt_reason);
1606 ASSERT(!deopt_info.IsNull()); 1580 ASSERT(!deopt_info.IsNull());
1607 1581
1608 CopyFrame(optimized_code, *caller_frame); 1582 CopyFrame(optimized_code, *caller_frame);
1609 if (FLAG_trace_deoptimization) { 1583 if (FLAG_trace_deoptimization) {
1610 Function& function = Function::Handle(optimized_code.function()); 1584 Function& function = Function::Handle(optimized_code.function());
1611 OS::PrintErr("Deoptimizing (reason %d '%s') at pc %#"Px" '%s' (count %d)\n", 1585 OS::PrintErr(
1586 "Deoptimizing (reason %"Pd" '%s') at pc %#"Px" '%s' (count %d)\n",
1612 deopt_reason, 1587 deopt_reason,
1613 DeoptReasonToText(deopt_reason), 1588 DeoptReasonToText(deopt_reason),
1614 caller_frame->pc(), 1589 caller_frame->pc(),
1615 function.ToFullyQualifiedCString(), 1590 function.ToFullyQualifiedCString(),
1616 function.deoptimization_counter()); 1591 function.deoptimization_counter());
1617 } 1592 }
1618 1593
1619 // Compute the stack size of the unoptimized frame. For functions with 1594 // Compute the stack size of the unoptimized frame. For functions with
1620 // optional arguments the deoptimization info does not describe the 1595 // optional arguments the deoptimization info does not describe the
1621 // incoming arguments. 1596 // incoming arguments.
1622 const Function& function = Function::Handle(optimized_code.function()); 1597 const Function& function = Function::Handle(optimized_code.function());
1623 const intptr_t num_args = 1598 const intptr_t num_args =
1624 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); 1599 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
1625 intptr_t unoptimized_stack_size = 1600 intptr_t unoptimized_stack_size =
1626 + deopt_info.TranslationLength() - num_args 1601 + deopt_info.TranslationLength() - num_args
1627 - 2; // Subtract caller FP and PC. 1602 - 2; // Subtract caller FP and PC.
1628 return unoptimized_stack_size * kWordSize; 1603 return unoptimized_stack_size * kWordSize;
1629 } 1604 }
1630 END_LEAF_RUNTIME_ENTRY 1605 END_LEAF_RUNTIME_ENTRY
1631 1606
1632 1607
1633 1608
1634 static intptr_t DeoptimizeWithDeoptInfo(const Code& code, 1609 static intptr_t DeoptimizeWithDeoptInfo(const Code& code,
1635 const DeoptInfo& deopt_info, 1610 const DeoptInfo& deopt_info,
1636 const StackFrame& caller_frame, 1611 const StackFrame& caller_frame,
1637 DeoptReasonId deopt_reason) { 1612 intptr_t deopt_reason) {
1638 const intptr_t len = deopt_info.TranslationLength(); 1613 const intptr_t len = deopt_info.TranslationLength();
1639 GrowableArray<DeoptInstr*> deopt_instructions(len); 1614 GrowableArray<DeoptInstr*> deopt_instructions(len);
1640 const Array& deopt_table = Array::Handle(code.deopt_info_array()); 1615 const Array& deopt_table = Array::Handle(code.deopt_info_array());
1641 ASSERT(!deopt_table.IsNull()); 1616 ASSERT(!deopt_table.IsNull());
1642 deopt_info.ToInstructions(deopt_table, &deopt_instructions); 1617 deopt_info.ToInstructions(deopt_table, &deopt_instructions);
1643 1618
1644 intptr_t* start = reinterpret_cast<intptr_t*>(caller_frame.sp() - kWordSize); 1619 intptr_t* start = reinterpret_cast<intptr_t*>(caller_frame.sp() - kWordSize);
1645 const Function& function = Function::Handle(code.function()); 1620 const Function& function = Function::Handle(code.function());
1646 const intptr_t num_args = 1621 const intptr_t num_args =
1647 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); 1622 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
1648 intptr_t to_frame_size = 1623 intptr_t to_frame_size =
1649 1 // Deoptimized function's return address. 1624 1 // Deoptimized function's return address.
1650 + (caller_frame.fp() - caller_frame.sp()) / kWordSize 1625 + (caller_frame.fp() - caller_frame.sp()) / kWordSize
1651 + 3 // caller-fp, pc, pc-marker. 1626 + 3 // caller-fp, pc, pc-marker.
1652 + num_args; 1627 + num_args;
1653 DeoptimizationContext deopt_context(start, 1628 DeoptimizationContext deopt_context(start,
1654 to_frame_size, 1629 to_frame_size,
1655 Array::Handle(code.object_table()), 1630 Array::Handle(code.object_table()),
1656 num_args, 1631 num_args,
1657 deopt_reason); 1632 static_cast<DeoptReasonId>(deopt_reason));
1658 for (intptr_t to_index = len - 1; to_index >= 0; to_index--) { 1633 for (intptr_t to_index = len - 1; to_index >= 0; to_index--) {
1659 deopt_instructions[to_index]->Execute(&deopt_context, to_index); 1634 deopt_instructions[to_index]->Execute(&deopt_context, to_index);
1660 } 1635 }
1661 if (FLAG_trace_deoptimization_verbose) { 1636 if (FLAG_trace_deoptimization_verbose) {
1662 for (intptr_t i = 0; i < len; i++) { 1637 for (intptr_t i = 0; i < len; i++) {
1663 OS::PrintErr("*%"Pd". [%p] %#014"Px" [%s]\n", 1638 OS::PrintErr("*%"Pd". [%p] %#014"Px" [%s]\n",
1664 i, 1639 i,
1665 &start[i], 1640 &start[i],
1666 start[i], 1641 start[i],
1667 deopt_instructions[i]->ToCString()); 1642 deopt_instructions[i]->ToCString());
(...skipping 17 matching lines...) Expand all
1685 const Function& function = Function::Handle(optimized_code.function()); 1660 const Function& function = Function::Handle(optimized_code.function());
1686 ASSERT(!function.IsNull()); 1661 ASSERT(!function.IsNull());
1687 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); 1662 const Code& unoptimized_code = Code::Handle(function.unoptimized_code());
1688 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized()); 1663 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized());
1689 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized()); 1664 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized());
1690 1665
1691 intptr_t* frame_copy = isolate->deopt_frame_copy(); 1666 intptr_t* frame_copy = isolate->deopt_frame_copy();
1692 intptr_t* cpu_registers_copy = isolate->deopt_cpu_registers_copy(); 1667 intptr_t* cpu_registers_copy = isolate->deopt_cpu_registers_copy();
1693 double* xmm_registers_copy = isolate->deopt_xmm_registers_copy(); 1668 double* xmm_registers_copy = isolate->deopt_xmm_registers_copy();
1694 1669
1695 DeoptInfo& deopt_info = DeoptInfo::Handle(); 1670 intptr_t deopt_reason = kDeoptUnknown;
1696 DeoptReasonId deopt_reason = kDeoptUnknown; 1671 const DeoptInfo& deopt_info = DeoptInfo::Handle(
1697 GetDeoptInfoAtPc(optimized_code, caller_frame->pc(), &deopt_info, 1672 optimized_code.GetDeoptInfoAtPc(caller_frame->pc(), &deopt_reason));
1698 &deopt_reason);
1699 ASSERT(!deopt_info.IsNull()); 1673 ASSERT(!deopt_info.IsNull());
1700 1674
1701 const intptr_t caller_fp = 1675 const intptr_t caller_fp = DeoptimizeWithDeoptInfo(optimized_code,
1702 DeoptimizeWithDeoptInfo(optimized_code, deopt_info, *caller_frame, 1676 deopt_info,
1703 deopt_reason); 1677 *caller_frame,
1678 deopt_reason);
1704 1679
1705 isolate->SetDeoptFrameCopy(NULL, 0); 1680 isolate->SetDeoptFrameCopy(NULL, 0);
1706 isolate->set_deopt_cpu_registers_copy(NULL); 1681 isolate->set_deopt_cpu_registers_copy(NULL);
1707 isolate->set_deopt_xmm_registers_copy(NULL); 1682 isolate->set_deopt_xmm_registers_copy(NULL);
1708 delete[] frame_copy; 1683 delete[] frame_copy;
1709 delete[] cpu_registers_copy; 1684 delete[] cpu_registers_copy;
1710 delete[] xmm_registers_copy; 1685 delete[] xmm_registers_copy;
1711 1686
1712 return caller_fp; 1687 return caller_fp;
1713 } 1688 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1794 return; 1769 return;
1795 } 1770 }
1796 HeapTrace* heap_trace = Isolate::Current()->heap()->trace(); 1771 HeapTrace* heap_trace = Isolate::Current()->heap()->trace();
1797 heap_trace->TraceStoreIntoObject(RawObject::ToAddr(object), 1772 heap_trace->TraceStoreIntoObject(RawObject::ToAddr(object),
1798 field_addr, 1773 field_addr,
1799 RawObject::ToAddr(value)); 1774 RawObject::ToAddr(value));
1800 } 1775 }
1801 END_LEAF_RUNTIME_ENTRY 1776 END_LEAF_RUNTIME_ENTRY
1802 1777
1803 } // namespace dart 1778 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/tests/vm/vm.status ('k') | runtime/vm/deopt_instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698