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

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

Issue 14935005: Implement a variation of scalar replacement for non-escaping allocations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address comments Created 7 years, 7 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/vm/code_generator.h ('k') | runtime/vm/compiler.cc » ('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 1527 matching lines...) Expand 10 before | Expand all | Expand 10 after
1538 function.deoptimization_counter()); 1538 function.deoptimization_counter());
1539 } 1539 }
1540 1540
1541 // Compute the stack size of the unoptimized frame. For functions with 1541 // Compute the stack size of the unoptimized frame. For functions with
1542 // optional arguments the deoptimization info does not describe the 1542 // optional arguments the deoptimization info does not describe the
1543 // incoming arguments. 1543 // incoming arguments.
1544 const Function& function = Function::Handle(optimized_code.function()); 1544 const Function& function = Function::Handle(optimized_code.function());
1545 const intptr_t num_args = 1545 const intptr_t num_args =
1546 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); 1546 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
1547 intptr_t unoptimized_stack_size = 1547 intptr_t unoptimized_stack_size =
1548 + deopt_info.TranslationLength() - num_args 1548 + deopt_info.FrameSize() - num_args
1549 - kLastParamSlotIndex; // Subtract caller FP and PC (possibly pc marker). 1549 - kLastParamSlotIndex; // Subtract caller FP and PC (possibly pc marker).
1550 return unoptimized_stack_size * kWordSize; 1550 return unoptimized_stack_size * kWordSize;
1551 } 1551 }
1552 END_LEAF_RUNTIME_ENTRY 1552 END_LEAF_RUNTIME_ENTRY
1553 1553
1554 1554
1555 static intptr_t DeoptimizeWithDeoptInfo(const Code& code, 1555 static intptr_t DeoptimizeWithDeoptInfo(const Code& code,
1556 const DeoptInfo& deopt_info, 1556 const DeoptInfo& deopt_info,
1557 const StackFrame& caller_frame, 1557 const StackFrame& caller_frame,
1558 intptr_t deopt_reason) { 1558 intptr_t deopt_reason) {
(...skipping 11 matching lines...) Expand all
1570 const intptr_t to_frame_size = 1570 const intptr_t to_frame_size =
1571 - kPcSlotIndexFromSp // Deoptimized function's return address. 1571 - kPcSlotIndexFromSp // Deoptimized function's return address.
1572 + (caller_frame.fp() - caller_frame.sp()) / kWordSize 1572 + (caller_frame.fp() - caller_frame.sp()) / kWordSize
1573 + kLastParamSlotIndex 1573 + kLastParamSlotIndex
1574 + num_args; 1574 + num_args;
1575 DeoptimizationContext deopt_context(start, 1575 DeoptimizationContext deopt_context(start,
1576 to_frame_size, 1576 to_frame_size,
1577 Array::Handle(code.object_table()), 1577 Array::Handle(code.object_table()),
1578 num_args, 1578 num_args,
1579 static_cast<DeoptReasonId>(deopt_reason)); 1579 static_cast<DeoptReasonId>(deopt_reason));
1580 for (intptr_t to_index = len - 1; to_index >= 0; to_index--) { 1580 const intptr_t frame_size = deopt_info.FrameSize();
1581 deopt_instructions[to_index]->Execute(&deopt_context, to_index); 1581
1582 // All kMaterializeObject instructions are emitted before the instructions
1583 // that describe stack frames. Skip them and defer materialization of
1584 // objects until the frame is fully reconstructed and it is safe to perform
1585 // GC.
1586 // Arguments (class of the instance to allocate and field-value pairs) are
1587 // described as part of the expression stack for the bottom-most deoptimized
1588 // frame. They will be used during materialization and removed from the stack
1589 // right before control switches to the unoptimized code.
1590 const intptr_t num_materializations = len - frame_size;
1591 Isolate::Current()->PrepareForDeferredMaterialization(num_materializations);
1592 for (intptr_t from_index = 0, to_index = 1;
1593 from_index < num_materializations;
1594 from_index++) {
1595 const intptr_t field_count =
1596 DeoptInstr::GetFieldCount(deopt_instructions[from_index]);
1597 intptr_t* args = deopt_context.GetToFrameAddressAt(to_index);
1598 DeferredObject* obj = new DeferredObject(field_count, args);
1599 Isolate::Current()->SetDeferredObjectAt(from_index, obj);
1600 to_index += obj->ArgumentCount();
1582 } 1601 }
1602
1603 // Populate stack frames.
1604 for (intptr_t to_index = frame_size - 1, from_index = len - 1;
1605 to_index >= 0;
1606 to_index--, from_index--) {
1607 intptr_t* to_addr = deopt_context.GetToFrameAddressAt(to_index);
1608 deopt_instructions[from_index]->Execute(&deopt_context, to_addr);
1609 }
1610
1583 if (FLAG_trace_deoptimization_verbose) { 1611 if (FLAG_trace_deoptimization_verbose) {
1584 for (intptr_t i = 0; i < len; i++) { 1612 for (intptr_t i = 0; i < frame_size; i++) {
1585 OS::PrintErr("*%"Pd". [%p] %#014"Px" [%s]\n", 1613 OS::PrintErr("*%"Pd". [%"Px"] %#014"Px" [%s]\n",
1586 i, 1614 i,
1587 &start[i], 1615 reinterpret_cast<uword>(&start[i]),
1588 start[i], 1616 start[i],
1589 deopt_instructions[i]->ToCString()); 1617 deopt_instructions[i + (len - frame_size)]->ToCString());
1590 } 1618 }
1591 } 1619 }
1592 return deopt_context.GetCallerFp(); 1620 return deopt_context.GetCallerFp();
1593 } 1621 }
1594 1622
1595 1623
1596 // The stack has been adjusted to fit all values for unoptimized frame. 1624 // The stack has been adjusted to fit all values for unoptimized frame.
1597 // Fill the unoptimized frame. 1625 // Fill the unoptimized frame.
1598 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeFillFrame, uword last_fp) { 1626 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeFillFrame, uword last_fp) {
1599 Isolate* isolate = Isolate::Current(); 1627 Isolate* isolate = Isolate::Current();
(...skipping 30 matching lines...) Expand all
1630 delete[] frame_copy; 1658 delete[] frame_copy;
1631 delete[] cpu_registers_copy; 1659 delete[] cpu_registers_copy;
1632 delete[] fpu_registers_copy; 1660 delete[] fpu_registers_copy;
1633 1661
1634 return caller_fp; 1662 return caller_fp;
1635 } 1663 }
1636 END_LEAF_RUNTIME_ENTRY 1664 END_LEAF_RUNTIME_ENTRY
1637 1665
1638 1666
1639 // This is the last step in the deoptimization, GC can occur. 1667 // This is the last step in the deoptimization, GC can occur.
1640 DEFINE_RUNTIME_ENTRY(DeoptimizeMaterializeDoubles, 0) { 1668 // Returns number of bytes to remove from the expression stack of the
1641 DeferredObject* deferred_object = Isolate::Current()->DetachDeferredObjects(); 1669 // bottom-most deoptimized frame. Those arguments were artificially injected
1670 // under return address to keep them discoverable by GC that can occur during
1671 // materialization phase.
1672 DEFINE_RUNTIME_ENTRY(DeoptimizeMaterialize, 0) {
1673 // First materialize all unboxed "primitive" values (doubles, mints, simd)
1674 // then materialize objects. The order is important: objects might be
1675 // referencing boxes allocated on the first step. At the same time
1676 // objects can't be referencing other deferred objects because storing
1677 // an object into a field is always conservatively treated as escaping by
1678 // allocation sinking and load forwarding.
1679 isolate->MaterializeDeferredBoxes();
1680 isolate->MaterializeDeferredObjects();
1642 1681
1643 while (deferred_object != NULL) { 1682 // Compute total number of artificial arguments used during deoptimization.
1644 DeferredObject* current = deferred_object; 1683 intptr_t deopt_arguments = 0;
1645 deferred_object = deferred_object->next(); 1684 for (intptr_t i = 0; i < isolate->DeferredObjectsCount(); i++) {
1685 deopt_arguments += isolate->GetDeferredObject(i)->ArgumentCount();
1686 }
1687 Isolate::Current()->DeleteDeferredObjects();
1646 1688
1647 current->Materialize(); 1689 // Return value tells deoptimization stub to remove the given number of bytes
1648 1690 // from the stack.
1649 delete current; 1691 arguments.SetReturn(Smi::Handle(Smi::New(deopt_arguments * kWordSize)));
1650 }
1651 1692
1652 // Since this is the only step where GC can occur during deoptimization, 1693 // Since this is the only step where GC can occur during deoptimization,
1653 // use it to report the source line where deoptimization occured. 1694 // use it to report the source line where deoptimization occured.
1654 if (FLAG_trace_deoptimization) { 1695 if (FLAG_trace_deoptimization) {
1655 DartFrameIterator iterator; 1696 DartFrameIterator iterator;
1656 StackFrame* top_frame = iterator.NextFrame(); 1697 StackFrame* top_frame = iterator.NextFrame();
1657 ASSERT(top_frame != NULL); 1698 ASSERT(top_frame != NULL);
1658 const Code& code = Code::Handle(top_frame->LookupDartCode()); 1699 const Code& code = Code::Handle(top_frame->LookupDartCode());
1659 const Function& top_function = Function::Handle(code.function()); 1700 const Function& top_function = Function::Handle(code.function());
1660 const Script& script = Script::Handle(top_function.script()); 1701 const Script& script = Script::Handle(top_function.script());
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1704 // Arg1: Value that is being stored. 1745 // Arg1: Value that is being stored.
1705 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { 1746 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) {
1706 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count()); 1747 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count());
1707 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); 1748 const Field& field = Field::CheckedHandle(arguments.ArgAt(0));
1708 const Object& value = Object::Handle(arguments.ArgAt(1)); 1749 const Object& value = Object::Handle(arguments.ArgAt(1));
1709 1750
1710 field.UpdateCid(Class::Handle(value.clazz()).id()); 1751 field.UpdateCid(Class::Handle(value.clazz()).id());
1711 } 1752 }
1712 1753
1713 } // namespace dart 1754 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/code_generator.h ('k') | runtime/vm/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698