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 1464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1475 // copied frame buffer. | 1475 // copied frame buffer. |
1476 static void CopyFrame(const Code& optimized_code, const StackFrame& frame) { | 1476 static void CopyFrame(const Code& optimized_code, const StackFrame& frame) { |
1477 const Function& function = Function::Handle(optimized_code.function()); | 1477 const Function& function = Function::Handle(optimized_code.function()); |
1478 // Do not copy incoming arguments if there are optional arguments (they | 1478 // Do not copy incoming arguments if there are optional arguments (they |
1479 // are copied into local space at method entry). | 1479 // are copied into local space at method entry). |
1480 const intptr_t num_args = | 1480 const intptr_t num_args = |
1481 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); | 1481 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); |
1482 // FP, PC-marker and return-address will be copied as well. | 1482 // FP, PC-marker and return-address will be copied as well. |
1483 const intptr_t frame_copy_size = | 1483 const intptr_t frame_copy_size = |
1484 // Deoptimized function's return address: caller_frame->pc(). | 1484 // Deoptimized function's return address: caller_frame->pc(). |
1485 - kPcSlotIndexFromSp | 1485 - kSavedPcSlotFromSp |
1486 + ((frame.fp() - frame.sp()) / kWordSize) | 1486 + ((frame.fp() - frame.sp()) / kWordSize) |
1487 + kLastParamSlotIndex | 1487 + 1 // For fp. |
| 1488 + kParamEndSlotFromFp |
1488 + num_args; | 1489 + num_args; |
1489 intptr_t* frame_copy = new intptr_t[frame_copy_size]; | 1490 intptr_t* frame_copy = new intptr_t[frame_copy_size]; |
1490 ASSERT(frame_copy != NULL); | 1491 ASSERT(frame_copy != NULL); |
1491 // Include the return address of optimized code. | 1492 // Include the return address of optimized code. |
1492 intptr_t* start = reinterpret_cast<intptr_t*>( | 1493 intptr_t* start = reinterpret_cast<intptr_t*>( |
1493 frame.sp() + (kPcSlotIndexFromSp * kWordSize)); | 1494 frame.sp() + (kSavedPcSlotFromSp * kWordSize)); |
1494 for (intptr_t i = 0; i < frame_copy_size; i++) { | 1495 for (intptr_t i = 0; i < frame_copy_size; i++) { |
1495 frame_copy[i] = *(start + i); | 1496 frame_copy[i] = *(start + i); |
1496 } | 1497 } |
1497 Isolate::Current()->SetDeoptFrameCopy(frame_copy, frame_copy_size); | 1498 Isolate::Current()->SetDeoptFrameCopy(frame_copy, frame_copy_size); |
1498 } | 1499 } |
1499 | 1500 |
1500 | 1501 |
1501 // Copies saved registers and caller's frame into temporary buffers. | 1502 // Copies saved registers and caller's frame into temporary buffers. |
1502 // Returns the stack size of unoptimized frame. | 1503 // Returns the stack size of unoptimized frame. |
1503 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, | 1504 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1538 function.deoptimization_counter()); | 1539 function.deoptimization_counter()); |
1539 } | 1540 } |
1540 | 1541 |
1541 // Compute the stack size of the unoptimized frame. For functions with | 1542 // Compute the stack size of the unoptimized frame. For functions with |
1542 // optional arguments the deoptimization info does not describe the | 1543 // optional arguments the deoptimization info does not describe the |
1543 // incoming arguments. | 1544 // incoming arguments. |
1544 const Function& function = Function::Handle(optimized_code.function()); | 1545 const Function& function = Function::Handle(optimized_code.function()); |
1545 const intptr_t num_args = | 1546 const intptr_t num_args = |
1546 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); | 1547 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); |
1547 intptr_t unoptimized_stack_size = | 1548 intptr_t unoptimized_stack_size = |
1548 + deopt_info.TranslationLength() - num_args | 1549 + deopt_info.TranslationLength() |
1549 - kLastParamSlotIndex; // Subtract caller FP and PC (possibly pc marker). | 1550 - num_args |
| 1551 - kParamEndSlotFromFp |
| 1552 - 1; // For fp. |
1550 return unoptimized_stack_size * kWordSize; | 1553 return unoptimized_stack_size * kWordSize; |
1551 } | 1554 } |
1552 END_LEAF_RUNTIME_ENTRY | 1555 END_LEAF_RUNTIME_ENTRY |
1553 | 1556 |
1554 | 1557 |
1555 static intptr_t DeoptimizeWithDeoptInfo(const Code& code, | 1558 static intptr_t DeoptimizeWithDeoptInfo(const Code& code, |
1556 const DeoptInfo& deopt_info, | 1559 const DeoptInfo& deopt_info, |
1557 const StackFrame& caller_frame, | 1560 const StackFrame& caller_frame, |
1558 intptr_t deopt_reason) { | 1561 intptr_t deopt_reason) { |
1559 const intptr_t len = deopt_info.TranslationLength(); | 1562 const intptr_t len = deopt_info.TranslationLength(); |
1560 GrowableArray<DeoptInstr*> deopt_instructions(len); | 1563 GrowableArray<DeoptInstr*> deopt_instructions(len); |
1561 const Array& deopt_table = Array::Handle(code.deopt_info_array()); | 1564 const Array& deopt_table = Array::Handle(code.deopt_info_array()); |
1562 ASSERT(!deopt_table.IsNull()); | 1565 ASSERT(!deopt_table.IsNull()); |
1563 deopt_info.ToInstructions(deopt_table, &deopt_instructions); | 1566 deopt_info.ToInstructions(deopt_table, &deopt_instructions); |
1564 | 1567 |
1565 intptr_t* start = reinterpret_cast<intptr_t*>( | 1568 intptr_t* start = reinterpret_cast<intptr_t*>( |
1566 caller_frame.sp() + (kPcSlotIndexFromSp * kWordSize)); | 1569 caller_frame.sp() + (kSavedPcSlotFromSp * kWordSize)); |
1567 const Function& function = Function::Handle(code.function()); | 1570 const Function& function = Function::Handle(code.function()); |
1568 const intptr_t num_args = | 1571 const intptr_t num_args = |
1569 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); | 1572 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); |
1570 const intptr_t to_frame_size = | 1573 const intptr_t to_frame_size = |
1571 - kPcSlotIndexFromSp // Deoptimized function's return address. | 1574 - kSavedPcSlotFromSp // Deoptimized function's return address. |
1572 + (caller_frame.fp() - caller_frame.sp()) / kWordSize | 1575 + (caller_frame.fp() - caller_frame.sp()) / kWordSize |
1573 + kLastParamSlotIndex | 1576 + 1 // For fp. |
| 1577 + kParamEndSlotFromFp |
1574 + num_args; | 1578 + num_args; |
1575 DeoptimizationContext deopt_context(start, | 1579 DeoptimizationContext deopt_context(start, |
1576 to_frame_size, | 1580 to_frame_size, |
1577 Array::Handle(code.object_table()), | 1581 Array::Handle(code.object_table()), |
1578 num_args, | 1582 num_args, |
1579 static_cast<DeoptReasonId>(deopt_reason)); | 1583 static_cast<DeoptReasonId>(deopt_reason)); |
1580 for (intptr_t to_index = len - 1; to_index >= 0; to_index--) { | 1584 for (intptr_t to_index = len - 1; to_index >= 0; to_index--) { |
1581 deopt_instructions[to_index]->Execute(&deopt_context, to_index); | 1585 deopt_instructions[to_index]->Execute(&deopt_context, to_index); |
1582 } | 1586 } |
1583 if (FLAG_trace_deoptimization_verbose) { | 1587 if (FLAG_trace_deoptimization_verbose) { |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1704 // Arg1: Value that is being stored. | 1708 // Arg1: Value that is being stored. |
1705 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { | 1709 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { |
1706 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count()); | 1710 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count()); |
1707 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); | 1711 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); |
1708 const Object& value = Object::Handle(arguments.ArgAt(1)); | 1712 const Object& value = Object::Handle(arguments.ArgAt(1)); |
1709 | 1713 |
1710 field.UpdateCid(Class::Handle(value.clazz()).id()); | 1714 field.UpdateCid(Class::Handle(value.clazz()).id()); |
1711 } | 1715 } |
1712 | 1716 |
1713 } // namespace dart | 1717 } // namespace dart |
OLD | NEW |