OLD | NEW |
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 1432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1443 if (ContainsCid(classes, owner_cid)) { | 1443 if (ContainsCid(classes, owner_cid)) { |
1444 DeoptimizeAt(optimized_code, frame->pc()); | 1444 DeoptimizeAt(optimized_code, frame->pc()); |
1445 } | 1445 } |
1446 } | 1446 } |
1447 } | 1447 } |
1448 } | 1448 } |
1449 | 1449 |
1450 | 1450 |
1451 // Copy saved registers into the isolate buffer. | 1451 // Copy saved registers into the isolate buffer. |
1452 static void CopySavedRegisters(uword saved_registers_address) { | 1452 static void CopySavedRegisters(uword saved_registers_address) { |
1453 double* fpu_registers_copy = new double[kNumberOfFpuRegisters]; | 1453 fpu_register_t* fpu_registers_copy = |
| 1454 new fpu_register_t[kNumberOfFpuRegisters]; |
1454 ASSERT(fpu_registers_copy != NULL); | 1455 ASSERT(fpu_registers_copy != NULL); |
1455 for (intptr_t i = 0; i < kNumberOfFpuRegisters; i++) { | 1456 for (intptr_t i = 0; i < kNumberOfFpuRegisters; i++) { |
1456 fpu_registers_copy[i] = *reinterpret_cast<double*>(saved_registers_address); | 1457 fpu_registers_copy[i] = |
1457 saved_registers_address += kDoubleSize; | 1458 *reinterpret_cast<fpu_register_t*>(saved_registers_address); |
| 1459 saved_registers_address += kFpuRegisterSize; |
1458 } | 1460 } |
1459 Isolate::Current()->set_deopt_fpu_registers_copy(fpu_registers_copy); | 1461 Isolate::Current()->set_deopt_fpu_registers_copy(fpu_registers_copy); |
1460 | 1462 |
1461 intptr_t* cpu_registers_copy = new intptr_t[kNumberOfCpuRegisters]; | 1463 intptr_t* cpu_registers_copy = new intptr_t[kNumberOfCpuRegisters]; |
1462 ASSERT(cpu_registers_copy != NULL); | 1464 ASSERT(cpu_registers_copy != NULL); |
1463 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { | 1465 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { |
1464 cpu_registers_copy[i] = | 1466 cpu_registers_copy[i] = |
1465 *reinterpret_cast<intptr_t*>(saved_registers_address); | 1467 *reinterpret_cast<intptr_t*>(saved_registers_address); |
1466 saved_registers_address += kWordSize; | 1468 saved_registers_address += kWordSize; |
1467 } | 1469 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1499 // Copies saved registers and caller's frame into temporary buffers. | 1501 // Copies saved registers and caller's frame into temporary buffers. |
1500 // Returns the stack size of unoptimized frame. | 1502 // Returns the stack size of unoptimized frame. |
1501 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, | 1503 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, |
1502 uword saved_registers_address) { | 1504 uword saved_registers_address) { |
1503 Isolate* isolate = Isolate::Current(); | 1505 Isolate* isolate = Isolate::Current(); |
1504 StackZone zone(isolate); | 1506 StackZone zone(isolate); |
1505 HANDLESCOPE(isolate); | 1507 HANDLESCOPE(isolate); |
1506 | 1508 |
1507 // All registers have been saved below last-fp. | 1509 // All registers have been saved below last-fp. |
1508 const uword last_fp = saved_registers_address + | 1510 const uword last_fp = saved_registers_address + |
1509 kNumberOfCpuRegisters * kWordSize + kNumberOfFpuRegisters * kDoubleSize; | 1511 kNumberOfCpuRegisters * kWordSize + |
| 1512 kNumberOfFpuRegisters * kFpuRegisterSize; |
1510 CopySavedRegisters(saved_registers_address); | 1513 CopySavedRegisters(saved_registers_address); |
1511 | 1514 |
1512 // Get optimized code and frame that need to be deoptimized. | 1515 // Get optimized code and frame that need to be deoptimized. |
1513 DartFrameIterator iterator(last_fp); | 1516 DartFrameIterator iterator(last_fp); |
1514 StackFrame* caller_frame = iterator.NextFrame(); | 1517 StackFrame* caller_frame = iterator.NextFrame(); |
1515 ASSERT(caller_frame != NULL); | 1518 ASSERT(caller_frame != NULL); |
1516 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode()); | 1519 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode()); |
1517 ASSERT(optimized_code.is_optimized()); | 1520 ASSERT(optimized_code.is_optimized()); |
1518 | 1521 |
1519 | 1522 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1601 ASSERT(caller_frame != NULL); | 1604 ASSERT(caller_frame != NULL); |
1602 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode()); | 1605 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode()); |
1603 const Function& function = Function::Handle(optimized_code.function()); | 1606 const Function& function = Function::Handle(optimized_code.function()); |
1604 ASSERT(!function.IsNull()); | 1607 ASSERT(!function.IsNull()); |
1605 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); | 1608 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); |
1606 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized()); | 1609 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized()); |
1607 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized()); | 1610 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized()); |
1608 | 1611 |
1609 intptr_t* frame_copy = isolate->deopt_frame_copy(); | 1612 intptr_t* frame_copy = isolate->deopt_frame_copy(); |
1610 intptr_t* cpu_registers_copy = isolate->deopt_cpu_registers_copy(); | 1613 intptr_t* cpu_registers_copy = isolate->deopt_cpu_registers_copy(); |
1611 double* fpu_registers_copy = isolate->deopt_fpu_registers_copy(); | 1614 fpu_register_t* fpu_registers_copy = isolate->deopt_fpu_registers_copy(); |
1612 | 1615 |
1613 intptr_t deopt_reason = kDeoptUnknown; | 1616 intptr_t deopt_reason = kDeoptUnknown; |
1614 const DeoptInfo& deopt_info = DeoptInfo::Handle( | 1617 const DeoptInfo& deopt_info = DeoptInfo::Handle( |
1615 optimized_code.GetDeoptInfoAtPc(caller_frame->pc(), &deopt_reason)); | 1618 optimized_code.GetDeoptInfoAtPc(caller_frame->pc(), &deopt_reason)); |
1616 ASSERT(!deopt_info.IsNull()); | 1619 ASSERT(!deopt_info.IsNull()); |
1617 | 1620 |
1618 const intptr_t caller_fp = DeoptimizeWithDeoptInfo(optimized_code, | 1621 const intptr_t caller_fp = DeoptimizeWithDeoptInfo(optimized_code, |
1619 deopt_info, | 1622 deopt_info, |
1620 *caller_frame, | 1623 *caller_frame, |
1621 deopt_reason); | 1624 deopt_reason); |
1622 | 1625 |
1623 isolate->SetDeoptFrameCopy(NULL, 0); | 1626 isolate->SetDeoptFrameCopy(NULL, 0); |
1624 isolate->set_deopt_cpu_registers_copy(NULL); | 1627 isolate->set_deopt_cpu_registers_copy(NULL); |
1625 isolate->set_deopt_fpu_registers_copy(NULL); | 1628 isolate->set_deopt_fpu_registers_copy(NULL); |
1626 delete[] frame_copy; | 1629 delete[] frame_copy; |
1627 delete[] cpu_registers_copy; | 1630 delete[] cpu_registers_copy; |
1628 delete[] fpu_registers_copy; | 1631 delete[] fpu_registers_copy; |
1629 | 1632 |
1630 return caller_fp; | 1633 return caller_fp; |
1631 } | 1634 } |
1632 END_LEAF_RUNTIME_ENTRY | 1635 END_LEAF_RUNTIME_ENTRY |
1633 | 1636 |
1634 | 1637 |
1635 // This is the last step in the deoptimization, GC can occur. | 1638 // This is the last step in the deoptimization, GC can occur. |
1636 DEFINE_RUNTIME_ENTRY(DeoptimizeMaterializeDoubles, 0) { | 1639 DEFINE_RUNTIME_ENTRY(DeoptimizeMaterializeDoubles, 0) { |
1637 DeferredDouble* deferred_double = Isolate::Current()->DetachDeferredDoubles(); | 1640 DeferredObject* deferred_object = Isolate::Current()->DetachDeferredObjects(); |
1638 | 1641 |
1639 while (deferred_double != NULL) { | 1642 while (deferred_object != NULL) { |
1640 DeferredDouble* current = deferred_double; | 1643 DeferredObject* current = deferred_object; |
1641 deferred_double = deferred_double->next(); | 1644 deferred_object = deferred_object->next(); |
1642 | 1645 |
1643 RawDouble** slot = current->slot(); | 1646 current->Materialize(); |
1644 *slot = Double::New(current->value()); | |
1645 | |
1646 if (FLAG_trace_deoptimization_verbose) { | |
1647 OS::PrintErr("materializing double at %"Px": %g\n", | |
1648 reinterpret_cast<uword>(current->slot()), | |
1649 current->value()); | |
1650 } | |
1651 | 1647 |
1652 delete current; | 1648 delete current; |
1653 } | 1649 } |
1654 | 1650 |
1655 DeferredMint* deferred_mint = Isolate::Current()->DetachDeferredMints(); | |
1656 | |
1657 while (deferred_mint != NULL) { | |
1658 DeferredMint* current = deferred_mint; | |
1659 deferred_mint = deferred_mint->next(); | |
1660 | |
1661 RawMint** slot = current->slot(); | |
1662 ASSERT(!Smi::IsValid64(current->value())); | |
1663 *slot = Mint::New(current->value()); | |
1664 | |
1665 if (FLAG_trace_deoptimization_verbose) { | |
1666 OS::PrintErr("materializing mint at %"Px": %"Pd64"\n", | |
1667 reinterpret_cast<uword>(current->slot()), | |
1668 current->value()); | |
1669 } | |
1670 | |
1671 delete current; | |
1672 } | |
1673 // Since this is the only step where GC can occur during deoptimization, | 1651 // Since this is the only step where GC can occur during deoptimization, |
1674 // use it to report the source line where deoptimization occured. | 1652 // use it to report the source line where deoptimization occured. |
1675 if (FLAG_trace_deoptimization) { | 1653 if (FLAG_trace_deoptimization) { |
1676 DartFrameIterator iterator; | 1654 DartFrameIterator iterator; |
1677 StackFrame* top_frame = iterator.NextFrame(); | 1655 StackFrame* top_frame = iterator.NextFrame(); |
1678 ASSERT(top_frame != NULL); | 1656 ASSERT(top_frame != NULL); |
1679 const Code& code = Code::Handle(top_frame->LookupDartCode()); | 1657 const Code& code = Code::Handle(top_frame->LookupDartCode()); |
1680 const Function& top_function = Function::Handle(code.function()); | 1658 const Function& top_function = Function::Handle(code.function()); |
1681 const Script& script = Script::Handle(top_function.script()); | 1659 const Script& script = Script::Handle(top_function.script()); |
1682 const intptr_t token_pos = code.GetTokenIndexOfPC(top_frame->pc()); | 1660 const intptr_t token_pos = code.GetTokenIndexOfPC(top_frame->pc()); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1741 // Arg1: Value that is being stored. | 1719 // Arg1: Value that is being stored. |
1742 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { | 1720 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { |
1743 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count()); | 1721 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count()); |
1744 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); | 1722 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); |
1745 const Object& value = Object::Handle(arguments.ArgAt(1)); | 1723 const Object& value = Object::Handle(arguments.ArgAt(1)); |
1746 | 1724 |
1747 field.UpdateCid(Class::Handle(value.clazz()).id()); | 1725 field.UpdateCid(Class::Handle(value.clazz()).id()); |
1748 } | 1726 } |
1749 | 1727 |
1750 } // namespace dart | 1728 } // namespace dart |
OLD | NEW |