| 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 |