Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Side by Side Diff: runtime/vm/code_generator.cc

Issue 14812005: Cleanup deoptimization code to make it architecture independent (in progress). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/code_patcher_arm.cc » ('j') | runtime/vm/code_patcher_arm.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1463 matching lines...) Expand 10 before | Expand all | Expand 10 after
1474 // The first incoming argument is stored at the last entry in the 1474 // The first incoming argument is stored at the last entry in the
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 1 // Deoptimized function's return address: caller_frame->pc(). 1484 // Deoptimized function's return address: caller_frame->pc().
1485 - kPcSlotIndexFromSp
1485 + ((frame.fp() - frame.sp()) / kWordSize) 1486 + ((frame.fp() - frame.sp()) / kWordSize)
1486 + 1 // PC marker. 1487 + kLastParamSlotIndex
1487 + 1 // Caller return address.
1488 + num_args; 1488 + num_args;
1489 intptr_t* frame_copy = new intptr_t[frame_copy_size]; 1489 intptr_t* frame_copy = new intptr_t[frame_copy_size];
1490 ASSERT(frame_copy != NULL); 1490 ASSERT(frame_copy != NULL);
1491 // Include the return address of optimized code. 1491 // Include the return address of optimized code.
1492 intptr_t* start = reinterpret_cast<intptr_t*>(frame.sp() - kWordSize); 1492 intptr_t* start = reinterpret_cast<intptr_t*>(
1493 frame.sp() + (kPcSlotIndexFromSp * kWordSize));
1493 for (intptr_t i = 0; i < frame_copy_size; i++) { 1494 for (intptr_t i = 0; i < frame_copy_size; i++) {
1494 frame_copy[i] = *(start + i); 1495 frame_copy[i] = *(start + i);
1495 } 1496 }
1496 Isolate::Current()->SetDeoptFrameCopy(frame_copy, frame_copy_size); 1497 Isolate::Current()->SetDeoptFrameCopy(frame_copy, frame_copy_size);
1497 } 1498 }
1498 1499
1499 1500
1500 // Copies saved registers and caller's frame into temporary buffers. 1501 // Copies saved registers and caller's frame into temporary buffers.
1501 // Returns the stack size of unoptimized frame. 1502 // Returns the stack size of unoptimized frame.
1502 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, 1503 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
1503 uword saved_registers_address) { 1504 uword saved_registers_address) {
1504 Isolate* isolate = Isolate::Current(); 1505 Isolate* isolate = Isolate::Current();
1505 StackZone zone(isolate); 1506 StackZone zone(isolate);
1506 HANDLESCOPE(isolate); 1507 HANDLESCOPE(isolate);
1507 1508
1508 // All registers have been saved below last-fp. 1509 // All registers have been saved below last-fp.
1510 // Note that the deopt stub is not allowed to save any other values (pc
1511 // marker, pool pointer, alignment, etc...) below last-fp.
1509 const uword last_fp = saved_registers_address + 1512 const uword last_fp = saved_registers_address +
1510 kNumberOfCpuRegisters * kWordSize + 1513 kNumberOfCpuRegisters * kWordSize +
1511 kNumberOfFpuRegisters * kFpuRegisterSize; 1514 kNumberOfFpuRegisters * kFpuRegisterSize;
1512 CopySavedRegisters(saved_registers_address); 1515 CopySavedRegisters(saved_registers_address);
1513 1516
1514 // Get optimized code and frame that need to be deoptimized. 1517 // Get optimized code and frame that need to be deoptimized.
1515 DartFrameIterator iterator(last_fp); 1518 DartFrameIterator iterator(last_fp);
1516 StackFrame* caller_frame = iterator.NextFrame(); 1519 StackFrame* caller_frame = iterator.NextFrame();
1517 ASSERT(caller_frame != NULL); 1520 ASSERT(caller_frame != NULL);
1518 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode()); 1521 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode());
1519 ASSERT(optimized_code.is_optimized()); 1522 ASSERT(optimized_code.is_optimized());
1520 1523
1521
1522 intptr_t deopt_reason = kDeoptUnknown; 1524 intptr_t deopt_reason = kDeoptUnknown;
1523 const DeoptInfo& deopt_info = DeoptInfo::Handle( 1525 const DeoptInfo& deopt_info = DeoptInfo::Handle(
1524 optimized_code.GetDeoptInfoAtPc(caller_frame->pc(), &deopt_reason)); 1526 optimized_code.GetDeoptInfoAtPc(caller_frame->pc(), &deopt_reason));
1525 ASSERT(!deopt_info.IsNull()); 1527 ASSERT(!deopt_info.IsNull());
1526 1528
1527 CopyFrame(optimized_code, *caller_frame); 1529 CopyFrame(optimized_code, *caller_frame);
1528 if (FLAG_trace_deoptimization) { 1530 if (FLAG_trace_deoptimization) {
1529 Function& function = Function::Handle(optimized_code.function()); 1531 Function& function = Function::Handle(optimized_code.function());
1530 OS::PrintErr( 1532 OS::PrintErr(
1531 "Deoptimizing (reason %"Pd" '%s') at pc %#"Px" '%s' (count %d)\n", 1533 "Deoptimizing (reason %"Pd" '%s') at pc %#"Px" '%s' (count %d)\n",
1532 deopt_reason, 1534 deopt_reason,
1533 DeoptReasonToText(deopt_reason), 1535 DeoptReasonToText(deopt_reason),
1534 caller_frame->pc(), 1536 caller_frame->pc(),
1535 function.ToFullyQualifiedCString(), 1537 function.ToFullyQualifiedCString(),
1536 function.deoptimization_counter()); 1538 function.deoptimization_counter());
1537 } 1539 }
1538 1540
1539 // Compute the stack size of the unoptimized frame. For functions with 1541 // Compute the stack size of the unoptimized frame. For functions with
1540 // optional arguments the deoptimization info does not describe the 1542 // optional arguments the deoptimization info does not describe the
1541 // incoming arguments. 1543 // incoming arguments.
1542 const Function& function = Function::Handle(optimized_code.function()); 1544 const Function& function = Function::Handle(optimized_code.function());
1543 const intptr_t num_args = 1545 const intptr_t num_args =
1544 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); 1546 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
1545 intptr_t unoptimized_stack_size = 1547 intptr_t unoptimized_stack_size =
1546 + deopt_info.TranslationLength() - num_args 1548 + deopt_info.TranslationLength() - num_args
1547 - 2; // Subtract caller FP and PC. 1549 - kLastParamSlotIndex; // Subtract caller FP and PC (possibly pc marker).
1548 return unoptimized_stack_size * kWordSize; 1550 return unoptimized_stack_size * kWordSize;
1549 } 1551 }
1550 END_LEAF_RUNTIME_ENTRY 1552 END_LEAF_RUNTIME_ENTRY
1551 1553
1552 1554
1553
1554 static intptr_t DeoptimizeWithDeoptInfo(const Code& code, 1555 static intptr_t DeoptimizeWithDeoptInfo(const Code& code,
1555 const DeoptInfo& deopt_info, 1556 const DeoptInfo& deopt_info,
1556 const StackFrame& caller_frame, 1557 const StackFrame& caller_frame,
1557 intptr_t deopt_reason) { 1558 intptr_t deopt_reason) {
1558 const intptr_t len = deopt_info.TranslationLength(); 1559 const intptr_t len = deopt_info.TranslationLength();
1559 GrowableArray<DeoptInstr*> deopt_instructions(len); 1560 GrowableArray<DeoptInstr*> deopt_instructions(len);
1560 const Array& deopt_table = Array::Handle(code.deopt_info_array()); 1561 const Array& deopt_table = Array::Handle(code.deopt_info_array());
1561 ASSERT(!deopt_table.IsNull()); 1562 ASSERT(!deopt_table.IsNull());
1562 deopt_info.ToInstructions(deopt_table, &deopt_instructions); 1563 deopt_info.ToInstructions(deopt_table, &deopt_instructions);
1563 1564
1564 intptr_t* start = reinterpret_cast<intptr_t*>(caller_frame.sp() - kWordSize); 1565 intptr_t* start = reinterpret_cast<intptr_t*>(
1566 caller_frame.sp() + (kPcSlotIndexFromSp * kWordSize));
1565 const Function& function = Function::Handle(code.function()); 1567 const Function& function = Function::Handle(code.function());
1566 const intptr_t num_args = 1568 const intptr_t num_args =
1567 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); 1569 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
1568 intptr_t to_frame_size = 1570 const intptr_t to_frame_size =
1569 1 // Deoptimized function's return address. 1571 - kPcSlotIndexFromSp // Deoptimized function's return address.
1570 + (caller_frame.fp() - caller_frame.sp()) / kWordSize 1572 + (caller_frame.fp() - caller_frame.sp()) / kWordSize
1571 + 3 // caller-fp, pc, pc-marker. 1573 + kLastParamSlotIndex
regis 2013/05/03 00:48:58 I think 3 was wrong for IA32 and X64, but it had n
srdjan 2013/05/03 17:16:18 Thanks for fixing it.
1572 + num_args; 1574 + num_args;
1573 DeoptimizationContext deopt_context(start, 1575 DeoptimizationContext deopt_context(start,
1574 to_frame_size, 1576 to_frame_size,
1575 Array::Handle(code.object_table()), 1577 Array::Handle(code.object_table()),
1576 num_args, 1578 num_args,
1577 static_cast<DeoptReasonId>(deopt_reason)); 1579 static_cast<DeoptReasonId>(deopt_reason));
1578 for (intptr_t to_index = len - 1; to_index >= 0; to_index--) { 1580 for (intptr_t to_index = len - 1; to_index >= 0; to_index--) {
1579 deopt_instructions[to_index]->Execute(&deopt_context, to_index); 1581 deopt_instructions[to_index]->Execute(&deopt_context, to_index);
1580 } 1582 }
1581 if (FLAG_trace_deoptimization_verbose) { 1583 if (FLAG_trace_deoptimization_verbose) {
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1702 // Arg1: Value that is being stored. 1704 // Arg1: Value that is being stored.
1703 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { 1705 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) {
1704 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count()); 1706 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count());
1705 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); 1707 const Field& field = Field::CheckedHandle(arguments.ArgAt(0));
1706 const Object& value = Object::Handle(arguments.ArgAt(1)); 1708 const Object& value = Object::Handle(arguments.ArgAt(1));
1707 1709
1708 field.UpdateCid(Class::Handle(value.clazz()).id()); 1710 field.UpdateCid(Class::Handle(value.clazz()).id());
1709 } 1711 }
1710 1712
1711 } // namespace dart 1713 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/code_patcher_arm.cc » ('j') | runtime/vm/code_patcher_arm.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698