OLD | NEW |
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/code_patcher.h" | 9 #include "vm/code_patcher.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 1379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1390 } | 1390 } |
1391 } | 1391 } |
1392 *deopt_id = Isolate::kNoDeoptId; | 1392 *deopt_id = Isolate::kNoDeoptId; |
1393 *deopt_reason = kDeoptUnknown; | 1393 *deopt_reason = kDeoptUnknown; |
1394 *deopt_index = -1; | 1394 *deopt_index = -1; |
1395 } | 1395 } |
1396 | 1396 |
1397 | 1397 |
1398 | 1398 |
1399 // Copy saved registers into the isolate buffer. | 1399 // Copy saved registers into the isolate buffer. |
1400 static void CopySavedRegisters(intptr_t* saved_registers_address) { | 1400 static void CopySavedRegisters(uword saved_registers_address) { |
1401 intptr_t* registers_copy = new intptr_t[kNumberOfCpuRegisters]; | 1401 double* xmm_registers_copy = new double[kNumberOfXmmRegisters]; |
1402 ASSERT(registers_copy != NULL); | 1402 ASSERT(xmm_registers_copy != NULL); |
1403 ASSERT(saved_registers_address != NULL); | 1403 for (intptr_t i = 0; i < kNumberOfXmmRegisters; i++) { |
| 1404 xmm_registers_copy[i] = *reinterpret_cast<double*>(saved_registers_address); |
| 1405 saved_registers_address += kDoubleSize; |
| 1406 } |
| 1407 Isolate::Current()->set_deopt_xmm_registers_copy(xmm_registers_copy); |
| 1408 |
| 1409 intptr_t* cpu_registers_copy = new intptr_t[kNumberOfCpuRegisters]; |
| 1410 ASSERT(cpu_registers_copy != NULL); |
1404 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { | 1411 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { |
1405 registers_copy[i] = *saved_registers_address; | 1412 cpu_registers_copy[i] = |
1406 saved_registers_address++; | 1413 *reinterpret_cast<intptr_t*>(saved_registers_address); |
| 1414 saved_registers_address += kWordSize; |
1407 } | 1415 } |
1408 Isolate::Current()->set_deopt_registers_copy(registers_copy); | 1416 Isolate::Current()->set_deopt_cpu_registers_copy(cpu_registers_copy); |
1409 } | 1417 } |
1410 | 1418 |
1411 | 1419 |
1412 // Copy optimized frame into the isolate buffer. | 1420 // Copy optimized frame into the isolate buffer. |
1413 // The first incoming argument is stored at the last entry in the | 1421 // The first incoming argument is stored at the last entry in the |
1414 // copied frame buffer. | 1422 // copied frame buffer. |
1415 static void CopyFrame(const Code& optimized_code, const StackFrame& frame) { | 1423 static void CopyFrame(const Code& optimized_code, const StackFrame& frame) { |
1416 const Function& function = Function::Handle(optimized_code.function()); | 1424 const Function& function = Function::Handle(optimized_code.function()); |
1417 // Do not copy incoming arguments if there are optional arguments (they | 1425 // Do not copy incoming arguments if there are optional arguments (they |
1418 // are copied into local space at method entry). | 1426 // are copied into local space at method entry). |
(...skipping 13 matching lines...) Expand all Loading... |
1432 for (intptr_t i = 0; i < frame_copy_size; i++) { | 1440 for (intptr_t i = 0; i < frame_copy_size; i++) { |
1433 frame_copy[i] = *(start + i); | 1441 frame_copy[i] = *(start + i); |
1434 } | 1442 } |
1435 Isolate::Current()->SetDeoptFrameCopy(frame_copy, frame_copy_size); | 1443 Isolate::Current()->SetDeoptFrameCopy(frame_copy, frame_copy_size); |
1436 } | 1444 } |
1437 | 1445 |
1438 | 1446 |
1439 // Copies saved registers and caller's frame into temporary buffers. | 1447 // Copies saved registers and caller's frame into temporary buffers. |
1440 // Returns the stack size of unoptimzied frame. | 1448 // Returns the stack size of unoptimzied frame. |
1441 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, | 1449 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, |
1442 intptr_t* saved_registers_address) { | 1450 uword saved_registers_address) { |
1443 Isolate* isolate = Isolate::Current(); | 1451 Isolate* isolate = Isolate::Current(); |
1444 Zone zone(isolate); | 1452 Zone zone(isolate); |
1445 HANDLESCOPE(isolate); | 1453 HANDLESCOPE(isolate); |
1446 | 1454 |
1447 // All registers have been saved below last-fp. | 1455 // All registers have been saved below last-fp. |
1448 const uword last_fp = | 1456 const uword last_fp = saved_registers_address + |
1449 reinterpret_cast<uword>(saved_registers_address + kNumberOfCpuRegisters); | 1457 kNumberOfCpuRegisters * kWordSize + kNumberOfXmmRegisters * kDoubleSize; |
1450 CopySavedRegisters(saved_registers_address); | 1458 CopySavedRegisters(saved_registers_address); |
1451 | 1459 |
1452 // Get optimized code and frame that need to be deoptimized. | 1460 // Get optimized code and frame that need to be deoptimized. |
1453 DartFrameIterator iterator(last_fp); | 1461 DartFrameIterator iterator(last_fp); |
1454 StackFrame* caller_frame = iterator.NextFrame(); | 1462 StackFrame* caller_frame = iterator.NextFrame(); |
1455 ASSERT(caller_frame != NULL); | 1463 ASSERT(caller_frame != NULL); |
1456 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode()); | 1464 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode()); |
1457 ASSERT(optimized_code.is_optimized()); | 1465 ASSERT(optimized_code.is_optimized()); |
1458 | 1466 |
1459 intptr_t deopt_id, deopt_reason, deopt_index; | 1467 intptr_t deopt_id, deopt_reason, deopt_index; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1550 StackFrame* caller_frame = iterator.NextFrame(); | 1558 StackFrame* caller_frame = iterator.NextFrame(); |
1551 ASSERT(caller_frame != NULL); | 1559 ASSERT(caller_frame != NULL); |
1552 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode()); | 1560 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode()); |
1553 const Function& function = Function::Handle(optimized_code.function()); | 1561 const Function& function = Function::Handle(optimized_code.function()); |
1554 ASSERT(!function.IsNull()); | 1562 ASSERT(!function.IsNull()); |
1555 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); | 1563 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); |
1556 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized()); | 1564 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized()); |
1557 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized()); | 1565 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized()); |
1558 | 1566 |
1559 intptr_t* frame_copy = isolate->deopt_frame_copy(); | 1567 intptr_t* frame_copy = isolate->deopt_frame_copy(); |
1560 intptr_t* registers_copy = isolate->deopt_registers_copy(); | 1568 intptr_t* cpu_registers_copy = isolate->deopt_cpu_registers_copy(); |
| 1569 double* xmm_registers_copy = isolate->deopt_xmm_registers_copy(); |
1561 | 1570 |
1562 intptr_t deopt_id, deopt_reason, deopt_index; | 1571 intptr_t deopt_id, deopt_reason, deopt_index; |
1563 GetDeoptIxDescrAtPc(optimized_code, caller_frame->pc(), | 1572 GetDeoptIxDescrAtPc(optimized_code, caller_frame->pc(), |
1564 &deopt_id, &deopt_reason, &deopt_index); | 1573 &deopt_id, &deopt_reason, &deopt_index); |
1565 ASSERT(deopt_id != Isolate::kNoDeoptId); | 1574 ASSERT(deopt_id != Isolate::kNoDeoptId); |
1566 uword continue_at_pc = unoptimized_code.GetDeoptPcAtDeoptId(deopt_id); | 1575 uword continue_at_pc = unoptimized_code.GetDeoptPcAtDeoptId(deopt_id); |
1567 if (FLAG_trace_deopt) { | 1576 if (FLAG_trace_deopt) { |
1568 OS::Print(" -> continue at 0x%x\n", continue_at_pc); | 1577 OS::Print(" -> continue at 0x%x\n", continue_at_pc); |
1569 // TODO(srdjan): If we could allow GC, we could print the line where | 1578 // TODO(srdjan): If we could allow GC, we could print the line where |
1570 // deoptimization occured. | 1579 // deoptimization occured. |
(...skipping 20 matching lines...) Expand all Loading... |
1591 if (FLAG_trace_deopt) { | 1600 if (FLAG_trace_deopt) { |
1592 OS::Print("%d. 0x%x\n", i, frame_copy[i]); | 1601 OS::Print("%d. 0x%x\n", i, frame_copy[i]); |
1593 } | 1602 } |
1594 *(start + i) = frame_copy[i]; | 1603 *(start + i) = frame_copy[i]; |
1595 } | 1604 } |
1596 } else { | 1605 } else { |
1597 DeoptimizeWithDeoptInfo(optimized_code, deopt_info, *caller_frame); | 1606 DeoptimizeWithDeoptInfo(optimized_code, deopt_info, *caller_frame); |
1598 } | 1607 } |
1599 | 1608 |
1600 isolate->SetDeoptFrameCopy(NULL, 0); | 1609 isolate->SetDeoptFrameCopy(NULL, 0); |
1601 isolate->set_deopt_registers_copy(NULL); | 1610 isolate->set_deopt_cpu_registers_copy(NULL); |
| 1611 isolate->set_deopt_xmm_registers_copy(NULL); |
1602 delete[] frame_copy; | 1612 delete[] frame_copy; |
1603 delete[] registers_copy; | 1613 delete[] cpu_registers_copy; |
| 1614 delete[] xmm_registers_copy; |
1604 | 1615 |
1605 // Clear invocation counter so that the function gets optimized after | 1616 // Clear invocation counter so that the function gets optimized after |
1606 // classes have been collected. | 1617 // classes have been collected. |
1607 function.set_usage_counter(0); | 1618 function.set_usage_counter(0); |
1608 function.set_deoptimization_counter(function.deoptimization_counter() + 1); | 1619 function.set_deoptimization_counter(function.deoptimization_counter() + 1); |
1609 | 1620 |
1610 if (function.HasOptimizedCode()) { | 1621 if (function.HasOptimizedCode()) { |
1611 function.SwitchToUnoptimizedCode(); | 1622 function.SwitchToUnoptimizedCode(); |
1612 } | 1623 } |
1613 } | 1624 } |
1614 END_LEAF_RUNTIME_ENTRY | 1625 END_LEAF_RUNTIME_ENTRY |
1615 | 1626 |
| 1627 |
| 1628 DEFINE_RUNTIME_ENTRY(DeoptimizeMaterializeDoubles, 0) { |
| 1629 DeferredDouble* deferred_double = Isolate::Current()->DetachDeferredDoubles(); |
| 1630 |
| 1631 while (deferred_double != NULL) { |
| 1632 DeferredDouble* current = deferred_double; |
| 1633 deferred_double = deferred_double->next(); |
| 1634 |
| 1635 RawDouble** slot = current->slot(); |
| 1636 *slot = Double::New(current->value()); |
| 1637 |
| 1638 if (FLAG_trace_deopt) { |
| 1639 OS::Print("materialing double at 0x%" PRIxPTR ": %g\n", |
| 1640 current->slot(), |
| 1641 current->value()); |
| 1642 } |
| 1643 |
| 1644 delete current; |
| 1645 } |
| 1646 } |
| 1647 |
| 1648 |
1616 } // namespace dart | 1649 } // namespace dart |
OLD | NEW |