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