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

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

Powered by Google App Engine
This is Rietveld 408576698