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

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

Issue 24834002: Refactor some deoptimization code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 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/deferred_objects.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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.h" 7 #include "vm/assembler.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 1476 matching lines...) Expand 10 before | Expand all | Expand 10 after
1487 const intptr_t owner_cid = Class::Handle(Function::Handle( 1487 const intptr_t owner_cid = Class::Handle(Function::Handle(
1488 optimized_code.function()).Owner()).id(); 1488 optimized_code.function()).Owner()).id();
1489 if (ContainsCid(classes, owner_cid)) { 1489 if (ContainsCid(classes, owner_cid)) {
1490 DeoptimizeAt(optimized_code, frame->pc()); 1490 DeoptimizeAt(optimized_code, frame->pc());
1491 } 1491 }
1492 } 1492 }
1493 } 1493 }
1494 } 1494 }
1495 1495
1496 1496
1497 // Copy saved registers into the isolate buffer. 1497 static void CopySavedRegisters(uword saved_registers_address,
1498 static void CopySavedRegisters(uword saved_registers_address) { 1498 fpu_register_t** fpu_registers,
1499 intptr_t** cpu_registers) {
1499 ASSERT(sizeof(fpu_register_t) == kFpuRegisterSize); 1500 ASSERT(sizeof(fpu_register_t) == kFpuRegisterSize);
1500 fpu_register_t* fpu_registers_copy = 1501 fpu_register_t* fpu_registers_copy =
1501 new fpu_register_t[kNumberOfFpuRegisters]; 1502 new fpu_register_t[kNumberOfFpuRegisters];
1502 ASSERT(fpu_registers_copy != NULL); 1503 ASSERT(fpu_registers_copy != NULL);
1503 for (intptr_t i = 0; i < kNumberOfFpuRegisters; i++) { 1504 for (intptr_t i = 0; i < kNumberOfFpuRegisters; i++) {
1504 fpu_registers_copy[i] = 1505 fpu_registers_copy[i] =
1505 *reinterpret_cast<fpu_register_t*>(saved_registers_address); 1506 *reinterpret_cast<fpu_register_t*>(saved_registers_address);
1506 saved_registers_address += kFpuRegisterSize; 1507 saved_registers_address += kFpuRegisterSize;
1507 } 1508 }
1508 Isolate::Current()->set_deopt_fpu_registers_copy(fpu_registers_copy); 1509 *fpu_registers = fpu_registers_copy;
1509 1510
1510 ASSERT(sizeof(intptr_t) == kWordSize); 1511 ASSERT(sizeof(intptr_t) == kWordSize);
1511 intptr_t* cpu_registers_copy = new intptr_t[kNumberOfCpuRegisters]; 1512 intptr_t* cpu_registers_copy = new intptr_t[kNumberOfCpuRegisters];
1512 ASSERT(cpu_registers_copy != NULL); 1513 ASSERT(cpu_registers_copy != NULL);
1513 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { 1514 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
1514 cpu_registers_copy[i] = 1515 cpu_registers_copy[i] =
1515 *reinterpret_cast<intptr_t*>(saved_registers_address); 1516 *reinterpret_cast<intptr_t*>(saved_registers_address);
1516 saved_registers_address += kWordSize; 1517 saved_registers_address += kWordSize;
1517 } 1518 }
1518 Isolate::Current()->set_deopt_cpu_registers_copy(cpu_registers_copy); 1519 *cpu_registers = cpu_registers_copy;
1519 } 1520 }
1520 1521
1521 1522
1522 // Copy optimized frame into the isolate buffer. 1523 // Copy optimized frame into the DeoptContext..
1523 // The first incoming argument is stored at the last entry in the 1524 // The first incoming argument is stored at the last entry in the
1524 // copied frame buffer. 1525 // copied frame buffer.
1525 static void CopyFrame(const Code& optimized_code, const StackFrame& frame) { 1526 static void CopyFrame(DeoptContext* deopt_context,
1527 const Code& optimized_code,
1528 const StackFrame& frame) {
1526 const Function& function = Function::Handle(optimized_code.function()); 1529 const Function& function = Function::Handle(optimized_code.function());
1527 // Do not copy incoming arguments if there are optional arguments (they 1530 // Do not copy incoming arguments if there are optional arguments (they
1528 // are copied into local space at method entry). 1531 // are copied into local space at method entry).
1529 const intptr_t num_args = 1532 const intptr_t num_args =
1530 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); 1533 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
1531 // The fixed size section of the (fake) Dart frame called via a stub by the 1534 // The fixed size section of the (fake) Dart frame called via a stub by the
1532 // optimized function contains FP, PP (ARM and MIPS only), PC-marker and 1535 // optimized function contains FP, PP (ARM and MIPS only), PC-marker and
1533 // return-address. This section is copied as well, so that its contained 1536 // return-address. This section is copied as well, so that its contained
1534 // values can be updated before returning to the deoptimized function. 1537 // values can be updated before returning to the deoptimized function.
1535 const intptr_t frame_copy_size = 1538 const intptr_t frame_copy_size =
1536 + kDartFrameFixedSize // For saved values below sp. 1539 + kDartFrameFixedSize // For saved values below sp.
1537 + ((frame.fp() - frame.sp()) / kWordSize) // For frame size incl. sp. 1540 + ((frame.fp() - frame.sp()) / kWordSize) // For frame size incl. sp.
1538 + 1 // For fp. 1541 + 1 // For fp.
1539 + kParamEndSlotFromFp // For saved values above fp. 1542 + kParamEndSlotFromFp // For saved values above fp.
1540 + num_args; // For arguments. 1543 + num_args; // For arguments.
1541 intptr_t* frame_copy = new intptr_t[frame_copy_size]; 1544 intptr_t* frame_copy = new intptr_t[frame_copy_size];
1542 ASSERT(frame_copy != NULL); 1545 ASSERT(frame_copy != NULL);
1543 intptr_t* start = reinterpret_cast<intptr_t*>( 1546 intptr_t* start = reinterpret_cast<intptr_t*>(
1544 frame.sp() - (kDartFrameFixedSize * kWordSize)); 1547 frame.sp() - (kDartFrameFixedSize * kWordSize));
1545 for (intptr_t i = 0; i < frame_copy_size; i++) { 1548 for (intptr_t i = 0; i < frame_copy_size; i++) {
1546 frame_copy[i] = *(start + i); 1549 frame_copy[i] = *(start + i);
1547 } 1550 }
1548 Isolate::Current()->SetDeoptFrameCopy(frame_copy, frame_copy_size); 1551 deopt_context->SetFromFrame(frame_copy, frame_copy_size);
1549 } 1552 }
1550 1553
1551 1554
1552 // Copies saved registers and caller's frame into temporary buffers. 1555 // Copies saved registers and caller's frame into temporary buffers.
1553 // Returns the stack size of unoptimized frame. 1556 // Returns the stack size of unoptimized frame.
1554 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, 1557 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
1555 1, uword saved_registers_address) { 1558 1, uword saved_registers_address) {
1556 Isolate* isolate = Isolate::Current(); 1559 Isolate* isolate = Isolate::Current();
1557 StackZone zone(isolate); 1560 StackZone zone(isolate);
1558 HANDLESCOPE(isolate); 1561 HANDLESCOPE(isolate);
1559 1562
1560 // All registers have been saved below last-fp as if they were locals. 1563 // All registers have been saved below last-fp as if they were locals.
1561 const uword last_fp = saved_registers_address 1564 const uword last_fp = saved_registers_address
1562 + (kNumberOfCpuRegisters * kWordSize) 1565 + (kNumberOfCpuRegisters * kWordSize)
1563 + (kNumberOfFpuRegisters * kFpuRegisterSize) 1566 + (kNumberOfFpuRegisters * kFpuRegisterSize)
1564 - ((kFirstLocalSlotFromFp + 1) * kWordSize); 1567 - ((kFirstLocalSlotFromFp + 1) * kWordSize);
1565 CopySavedRegisters(saved_registers_address); 1568 fpu_register_t* fpu_registers;
1569 intptr_t* cpu_registers;
1570 CopySavedRegisters(saved_registers_address, &fpu_registers, &cpu_registers);
1566 1571
1567 // Get optimized code and frame that need to be deoptimized. 1572 // Get optimized code and frame that needs to be deoptimized.
1568 DartFrameIterator iterator(last_fp); 1573 DartFrameIterator iterator(last_fp);
1569 StackFrame* caller_frame = iterator.NextFrame(); 1574 StackFrame* caller_frame = iterator.NextFrame();
1570 ASSERT(caller_frame != NULL); 1575 ASSERT(caller_frame != NULL);
1571 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode()); 1576 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode());
1572 ASSERT(optimized_code.is_optimized()); 1577 ASSERT(optimized_code.is_optimized());
1573 1578
1574 intptr_t deopt_reason = kDeoptUnknown; 1579 intptr_t deopt_reason = kDeoptUnknown;
1575 const DeoptInfo& deopt_info = DeoptInfo::Handle( 1580 const DeoptInfo& deopt_info = DeoptInfo::Handle(
1576 optimized_code.GetDeoptInfoAtPc(caller_frame->pc(), &deopt_reason)); 1581 optimized_code.GetDeoptInfoAtPc(caller_frame->pc(), &deopt_reason));
1577 ASSERT(!deopt_info.IsNull()); 1582 ASSERT(!deopt_info.IsNull());
1578 1583
1579 CopyFrame(optimized_code, *caller_frame); 1584 // Create the DeoptContext for this deoptimization. Store in isolate.
1585 const Function& function = Function::Handle(optimized_code.function());
1586 const intptr_t num_args =
1587 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
1588 DeoptContext* deopt_context = new DeoptContext(
1589 Array::Handle(optimized_code.object_table()),
1590 num_args,
1591 static_cast<DeoptReasonId>(deopt_reason));
1592 isolate->set_deopt_context(deopt_context);
1593
1594 // TODO(turnidge): Why can't I move CopySavedRegisters here?
turnidge 2013/09/26 21:17:28 Srdjan, any idea on this one? When I move CopySav
srdjan 2013/09/27 17:04:54 I do not understand why. CC-d Kevin and Florian th
1595 deopt_context->SetSavedRegisters(fpu_registers, cpu_registers);
1596 CopyFrame(deopt_context, optimized_code, *caller_frame);
1597
1580 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) { 1598 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
1581 Function& function = Function::Handle(optimized_code.function());
1582 OS::PrintErr( 1599 OS::PrintErr(
1583 "Deoptimizing (reason %" Pd " '%s') at pc %#" Px " '%s' (count %d)\n", 1600 "Deoptimizing (reason %" Pd " '%s') at pc %#" Px " '%s' (count %d)\n",
1584 deopt_reason, 1601 deopt_reason,
1585 DeoptReasonToText(deopt_reason), 1602 DeoptReasonToText(deopt_reason),
1586 caller_frame->pc(), 1603 caller_frame->pc(),
1587 function.ToFullyQualifiedCString(), 1604 function.ToFullyQualifiedCString(),
1588 function.deoptimization_counter()); 1605 function.deoptimization_counter());
1589 } 1606 }
1590 1607
1591 // Compute the stack size of the unoptimized frame. For functions with 1608 // Compute the stack size of the unoptimized frame. For functions with
1592 // optional arguments the deoptimization info does not describe the 1609 // optional arguments the deoptimization info does not describe the
1593 // incoming arguments. 1610 // incoming arguments.
1594 const Function& function = Function::Handle(optimized_code.function());
1595 const intptr_t num_args =
1596 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
1597 const intptr_t unoptimized_stack_size = 1611 const intptr_t unoptimized_stack_size =
1598 + deopt_info.FrameSize() 1612 + deopt_info.FrameSize()
1599 - kDartFrameFixedSize 1613 - kDartFrameFixedSize
1600 - num_args 1614 - num_args
1601 - kParamEndSlotFromFp 1615 - kParamEndSlotFromFp
1602 - 1; // For fp. 1616 - 1; // For fp.
1603 return unoptimized_stack_size * kWordSize; // Stack size (FP - SP) in bytes. 1617 return unoptimized_stack_size * kWordSize; // Stack size (FP - SP) in bytes.
1604 } 1618 }
1605 END_LEAF_RUNTIME_ENTRY 1619 END_LEAF_RUNTIME_ENTRY
1606 1620
1607 1621
1608 static void DeoptimizeWithDeoptInfo(const Code& code, 1622 static void DeoptimizeWithDeoptInfo(DeoptContext* deopt_context,
1623 const Code& code,
1609 const DeoptInfo& deopt_info, 1624 const DeoptInfo& deopt_info,
1610 const StackFrame& caller_frame, 1625 const StackFrame& caller_frame) {
1611 intptr_t deopt_reason) {
1612 const intptr_t len = deopt_info.TranslationLength(); 1626 const intptr_t len = deopt_info.TranslationLength();
1613 GrowableArray<DeoptInstr*> deopt_instructions(len); 1627 GrowableArray<DeoptInstr*> deopt_instructions(len);
1614 const Array& deopt_table = Array::Handle(code.deopt_info_array()); 1628 const Array& deopt_table = Array::Handle(code.deopt_info_array());
1615 ASSERT(!deopt_table.IsNull()); 1629 ASSERT(!deopt_table.IsNull());
1616 deopt_info.ToInstructions(deopt_table, &deopt_instructions); 1630 deopt_info.ToInstructions(deopt_table, &deopt_instructions);
1617 1631
1618 intptr_t* start = reinterpret_cast<intptr_t*>( 1632 intptr_t* start = reinterpret_cast<intptr_t*>(
1619 caller_frame.sp() - (kDartFrameFixedSize * kWordSize)); 1633 caller_frame.sp() - (kDartFrameFixedSize * kWordSize));
1620 const Function& function = Function::Handle(code.function()); 1634 const Function& function = Function::Handle(code.function());
1621 const intptr_t num_args = 1635 const intptr_t num_args =
1622 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); 1636 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
1623 const intptr_t to_frame_size = 1637 const intptr_t to_frame_size =
1624 + kDartFrameFixedSize // For saved values below sp. 1638 + kDartFrameFixedSize // For saved values below sp.
1625 + (caller_frame.fp() - caller_frame.sp()) / kWordSize 1639 + (caller_frame.fp() - caller_frame.sp()) / kWordSize
1626 + 1 // For fp. 1640 + 1 // For fp.
1627 + kParamEndSlotFromFp 1641 + kParamEndSlotFromFp
1628 + num_args; 1642 + num_args;
1629 DeoptimizationContext deopt_context(start, 1643
1630 to_frame_size, 1644 deopt_context->SetToFrame(start, to_frame_size);
1631 Array::Handle(code.object_table()), 1645
1632 num_args,
1633 static_cast<DeoptReasonId>(deopt_reason));
1634 const intptr_t frame_size = deopt_info.FrameSize(); 1646 const intptr_t frame_size = deopt_info.FrameSize();
1635 1647
1636 // All kMaterializeObject instructions are emitted before the instructions 1648 // All kMaterializeObject instructions are emitted before the instructions
1637 // that describe stack frames. Skip them and defer materialization of 1649 // that describe stack frames. Skip them and defer materialization of
1638 // objects until the frame is fully reconstructed and it is safe to perform 1650 // objects until the frame is fully reconstructed and it is safe to perform
1639 // GC. 1651 // GC.
1640 // Arguments (class of the instance to allocate and field-value pairs) are 1652 // Arguments (class of the instance to allocate and field-value pairs) are
1641 // described as part of the expression stack for the bottom-most deoptimized 1653 // described as part of the expression stack for the bottom-most deoptimized
1642 // frame. They will be used during materialization and removed from the stack 1654 // frame. They will be used during materialization and removed from the stack
1643 // right before control switches to the unoptimized code. 1655 // right before control switches to the unoptimized code.
1644 const intptr_t num_materializations = len - frame_size; 1656 const intptr_t num_materializations = len - frame_size;
1645 Isolate::Current()->PrepareForDeferredMaterialization(num_materializations); 1657 deopt_context->PrepareForDeferredMaterialization(num_materializations);
1646 for (intptr_t from_index = 0, to_index = kDartFrameFixedSize; 1658 for (intptr_t from_index = 0, to_index = kDartFrameFixedSize;
1647 from_index < num_materializations; 1659 from_index < num_materializations;
1648 from_index++) { 1660 from_index++) {
1649 const intptr_t field_count = 1661 const intptr_t field_count =
1650 DeoptInstr::GetFieldCount(deopt_instructions[from_index]); 1662 DeoptInstr::GetFieldCount(deopt_instructions[from_index]);
1651 intptr_t* args = deopt_context.GetToFrameAddressAt(to_index); 1663 intptr_t* args = deopt_context->GetToFrameAddressAt(to_index);
1652 DeferredObject* obj = new DeferredObject(field_count, args); 1664 DeferredObject* obj = new DeferredObject(field_count, args);
1653 Isolate::Current()->SetDeferredObjectAt(from_index, obj); 1665 deopt_context->SetDeferredObjectAt(from_index, obj);
1654 to_index += obj->ArgumentCount(); 1666 to_index += obj->ArgumentCount();
1655 } 1667 }
1656 1668
1657 // Populate stack frames. 1669 // Populate stack frames.
1658 for (intptr_t to_index = frame_size - 1, from_index = len - 1; 1670 for (intptr_t to_index = frame_size - 1, from_index = len - 1;
1659 to_index >= 0; 1671 to_index >= 0;
1660 to_index--, from_index--) { 1672 to_index--, from_index--) {
1661 intptr_t* to_addr = deopt_context.GetToFrameAddressAt(to_index); 1673 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index);
1662 deopt_instructions[from_index]->Execute(&deopt_context, to_addr); 1674 deopt_instructions[from_index]->Execute(deopt_context, to_addr);
1663 } 1675 }
1664 1676
1665 if (FLAG_trace_deoptimization_verbose) { 1677 if (FLAG_trace_deoptimization_verbose) {
1666 for (intptr_t i = 0; i < frame_size; i++) { 1678 for (intptr_t i = 0; i < frame_size; i++) {
1667 OS::PrintErr("*%" Pd ". [%" Px "] %#014" Px " [%s]\n", 1679 OS::PrintErr("*%" Pd ". [%" Px "] %#014" Px " [%s]\n",
1668 i, 1680 i,
1669 reinterpret_cast<uword>(&start[i]), 1681 reinterpret_cast<uword>(&start[i]),
1670 start[i], 1682 start[i],
1671 deopt_instructions[i + (len - frame_size)]->ToCString()); 1683 deopt_instructions[i + (len - frame_size)]->ToCString());
1672 } 1684 }
(...skipping 11 matching lines...) Expand all
1684 DartFrameIterator iterator(last_fp); 1696 DartFrameIterator iterator(last_fp);
1685 StackFrame* caller_frame = iterator.NextFrame(); 1697 StackFrame* caller_frame = iterator.NextFrame();
1686 ASSERT(caller_frame != NULL); 1698 ASSERT(caller_frame != NULL);
1687 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode()); 1699 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode());
1688 const Function& function = Function::Handle(optimized_code.function()); 1700 const Function& function = Function::Handle(optimized_code.function());
1689 ASSERT(!function.IsNull()); 1701 ASSERT(!function.IsNull());
1690 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); 1702 const Code& unoptimized_code = Code::Handle(function.unoptimized_code());
1691 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized()); 1703 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized());
1692 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized()); 1704 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized());
1693 1705
1694 intptr_t* frame_copy = isolate->deopt_frame_copy();
1695 intptr_t* cpu_registers_copy = isolate->deopt_cpu_registers_copy();
1696 fpu_register_t* fpu_registers_copy = isolate->deopt_fpu_registers_copy();
1697
1698 intptr_t deopt_reason = kDeoptUnknown; 1706 intptr_t deopt_reason = kDeoptUnknown;
1699 const DeoptInfo& deopt_info = DeoptInfo::Handle( 1707 const DeoptInfo& deopt_info = DeoptInfo::Handle(
1700 optimized_code.GetDeoptInfoAtPc(caller_frame->pc(), &deopt_reason)); 1708 optimized_code.GetDeoptInfoAtPc(caller_frame->pc(), &deopt_reason));
1701 ASSERT(!deopt_info.IsNull()); 1709 ASSERT(!deopt_info.IsNull());
1702 1710
1703 DeoptimizeWithDeoptInfo(optimized_code, 1711 DeoptContext* deopt_context = isolate->deopt_context();
1712 DeoptimizeWithDeoptInfo(deopt_context,
1713 optimized_code,
1704 deopt_info, 1714 deopt_info,
1705 *caller_frame, 1715 *caller_frame);
1706 deopt_reason);
1707
1708 isolate->SetDeoptFrameCopy(NULL, 0);
1709 isolate->set_deopt_cpu_registers_copy(NULL);
1710 isolate->set_deopt_fpu_registers_copy(NULL);
1711 delete[] frame_copy;
1712 delete[] cpu_registers_copy;
1713 delete[] fpu_registers_copy;
1714 } 1716 }
1715 END_LEAF_RUNTIME_ENTRY 1717 END_LEAF_RUNTIME_ENTRY
1716 1718
1717 1719
1718 // This is the last step in the deoptimization, GC can occur. 1720 // This is the last step in the deoptimization, GC can occur.
1719 // Returns number of bytes to remove from the expression stack of the 1721 // Returns number of bytes to remove from the expression stack of the
1720 // bottom-most deoptimized frame. Those arguments were artificially injected 1722 // bottom-most deoptimized frame. Those arguments were artificially injected
1721 // under return address to keep them discoverable by GC that can occur during 1723 // under return address to keep them discoverable by GC that can occur during
1722 // materialization phase. 1724 // materialization phase.
1723 DEFINE_RUNTIME_ENTRY(DeoptimizeMaterialize, 0) { 1725 DEFINE_RUNTIME_ENTRY(DeoptimizeMaterialize, 0) {
1724 // First materialize all unboxed "primitive" values (doubles, mints, simd) 1726 DeoptContext* deopt_context = isolate->deopt_context();
1725 // then materialize objects. The order is important: objects might be
1726 // referencing boxes allocated on the first step. At the same time
1727 // objects can't be referencing other deferred objects because storing
1728 // an object into a field is always conservatively treated as escaping by
1729 // allocation sinking and load forwarding.
1730 isolate->MaterializeDeferredBoxes();
1731 isolate->MaterializeDeferredObjects();
1732 1727
1733 // Compute total number of artificial arguments used during deoptimization. 1728 intptr_t deopt_arg_count = deopt_context->MaterializeDeferredObjects();
1734 intptr_t deopt_arguments = 0; 1729
1735 for (intptr_t i = 0; i < isolate->DeferredObjectsCount(); i++) { 1730 // Delete temporary copies of frame and registers.
1736 deopt_arguments += isolate->GetDeferredObject(i)->ArgumentCount(); 1731 isolate->set_deopt_context(NULL);
1737 } 1732 delete[] deopt_context->from_frame(); // Allocated in CopyFrame.
1738 Isolate::Current()->DeleteDeferredObjects(); 1733 delete[] deopt_context->fpu_registers(); // Allocated in CopySavedRegisters.
1734 delete[] deopt_context->cpu_registers(); // Allocated in CopySavedRegisters.
1735 delete deopt_context;
1739 1736
1740 // Return value tells deoptimization stub to remove the given number of bytes 1737 // Return value tells deoptimization stub to remove the given number of bytes
1741 // from the stack. 1738 // from the stack.
1742 arguments.SetReturn(Smi::Handle(Smi::New(deopt_arguments * kWordSize))); 1739 arguments.SetReturn(Smi::Handle(Smi::New(deopt_arg_count * kWordSize)));
1743 1740
1744 // Since this is the only step where GC can occur during deoptimization, 1741 // Since this is the only step where GC can occur during deoptimization,
1745 // use it to report the source line where deoptimization occured. 1742 // use it to report the source line where deoptimization occured.
1746 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) { 1743 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
1747 DartFrameIterator iterator; 1744 DartFrameIterator iterator;
1748 StackFrame* top_frame = iterator.NextFrame(); 1745 StackFrame* top_frame = iterator.NextFrame();
1749 ASSERT(top_frame != NULL); 1746 ASSERT(top_frame != NULL);
1750 const Code& code = Code::Handle(top_frame->LookupDartCode()); 1747 const Code& code = Code::Handle(top_frame->LookupDartCode());
1751 const Function& top_function = Function::Handle(code.function()); 1748 const Function& top_function = Function::Handle(code.function());
1752 const Script& script = Script::Handle(top_function.script()); 1749 const Script& script = Script::Handle(top_function.script());
1753 const intptr_t token_pos = code.GetTokenIndexOfPC(top_frame->pc()); 1750 const intptr_t token_pos = code.GetTokenIndexOfPC(top_frame->pc());
1754 intptr_t line, column; 1751 intptr_t line, column;
1755 script.GetTokenLocation(token_pos, &line, &column); 1752 script.GetTokenLocation(token_pos, &line, &column);
1756 String& line_string = String::Handle(script.GetLine(line)); 1753 String& line_string = String::Handle(script.GetLine(line));
1757 OS::PrintErr(" Function: %s\n", top_function.ToFullyQualifiedCString()); 1754 OS::PrintErr(" Function: %s\n", top_function.ToFullyQualifiedCString());
1758 OS::PrintErr(" Line %" Pd ": '%s'\n", line, line_string.ToCString()); 1755 OS::PrintErr(" Line %" Pd ": '%s'\n", line, line_string.ToCString());
1759 OS::PrintErr(" Deopt args: %" Pd "\n", deopt_arguments); 1756 OS::PrintErr(" Deopt args: %" Pd "\n", deopt_arg_count);
1760 } 1757 }
1761 } 1758 }
1762 1759
1763 1760
1764 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, 1761 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t,
1765 BigintCompare, 1762 BigintCompare,
1766 2, 1763 2,
1767 RawBigint* left, 1764 RawBigint* left,
1768 RawBigint* right) { 1765 RawBigint* right) {
1769 Isolate* isolate = Isolate::Current(); 1766 Isolate* isolate = Isolate::Current();
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1828 field.UpdateCid(cid); 1825 field.UpdateCid(cid);
1829 intptr_t list_length = Field::kNoFixedLength; 1826 intptr_t list_length = Field::kNoFixedLength;
1830 if ((field.guarded_cid() != kDynamicCid) && 1827 if ((field.guarded_cid() != kDynamicCid) &&
1831 field.is_final() && RawObject::IsBuiltinListClassId(cid)) { 1828 field.is_final() && RawObject::IsBuiltinListClassId(cid)) {
1832 list_length = GetListLength(value); 1829 list_length = GetListLength(value);
1833 } 1830 }
1834 field.UpdateLength(list_length); 1831 field.UpdateLength(list_length);
1835 } 1832 }
1836 1833
1837 } // namespace dart 1834 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/deferred_objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698