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

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

Issue 1192103004: VM: New calling convention for generated code. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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
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/code_patcher.h" 9 #include "vm/code_patcher.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 if (!target_function.HasCode()) { 657 if (!target_function.HasCode()) {
658 const Error& error = 658 const Error& error =
659 Error::Handle(Compiler::CompileFunction(thread, target_function)); 659 Error::Handle(Compiler::CompileFunction(thread, target_function));
660 if (!error.IsNull()) { 660 if (!error.IsNull()) {
661 Exceptions::PropagateError(error); 661 Exceptions::PropagateError(error);
662 } 662 }
663 } 663 }
664 const Code& target_code = Code::Handle(target_function.CurrentCode()); 664 const Code& target_code = Code::Handle(target_function.CurrentCode());
665 // Before patching verify that we are not repeatedly patching to the same 665 // Before patching verify that we are not repeatedly patching to the same
666 // target. 666 // target.
667 ASSERT(target_code.EntryPoint() != 667 ASSERT(target_code.raw() !=
668 CodePatcher::GetStaticCallTargetAt(caller_frame->pc(), caller_code)); 668 CodePatcher::GetStaticCallTargetAt(caller_frame->pc(), caller_code));
669 const Instructions& instrs = 669 const Instructions& instrs =
670 Instructions::Handle(caller_code.instructions()); 670 Instructions::Handle(caller_code.instructions());
671 { 671 {
672 WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size()); 672 WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size());
673 CodePatcher::PatchStaticCallAt(caller_frame->pc(), caller_code, 673 CodePatcher::PatchStaticCallAt(caller_frame->pc(),
674 target_code.EntryPoint()); 674 caller_code,
675 target_code);
675 caller_code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code); 676 caller_code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code);
676 } 677 }
677 if (FLAG_trace_patching) { 678 if (FLAG_trace_patching) {
678 OS::PrintErr("PatchStaticCall: patching caller pc %#" Px "" 679 OS::PrintErr("PatchStaticCall: patching caller pc %#" Px ""
679 " to '%s' new entry point %#" Px " (%s)\n", 680 " to '%s' new entry point %#" Px " (%s)\n",
680 caller_frame->pc(), 681 caller_frame->pc(),
681 target_function.ToFullyQualifiedCString(), 682 target_function.ToFullyQualifiedCString(),
682 target_code.EntryPoint(), 683 target_code.EntryPoint(),
683 target_code.is_optimized() ? "optimized" : "unoptimized"); 684 target_code.is_optimized() ? "optimized" : "unoptimized");
684 } 685 }
(...skipping 10 matching lines...) Expand all
695 } 696 }
696 697
697 698
698 // Gets called from debug stub when code reaches a breakpoint 699 // Gets called from debug stub when code reaches a breakpoint
699 // set on a runtime stub call. 700 // set on a runtime stub call.
700 DEFINE_RUNTIME_ENTRY(BreakpointRuntimeHandler, 0) { 701 DEFINE_RUNTIME_ENTRY(BreakpointRuntimeHandler, 0) {
701 ASSERT(isolate->debugger() != NULL); 702 ASSERT(isolate->debugger() != NULL);
702 DartFrameIterator iterator; 703 DartFrameIterator iterator;
703 StackFrame* caller_frame = iterator.NextFrame(); 704 StackFrame* caller_frame = iterator.NextFrame();
704 ASSERT(caller_frame != NULL); 705 ASSERT(caller_frame != NULL);
705 uword orig_stub = 706 const Code& orig_stub = Code::Handle(
706 isolate->debugger()->GetPatchedStubAddress(caller_frame->pc()); 707 isolate->debugger()->GetPatchedStubAddress(caller_frame->pc()));
707 isolate->debugger()->SignalBpReached(); 708 isolate->debugger()->SignalBpReached();
708 ASSERT((orig_stub & kSmiTagMask) == kSmiTag); 709 arguments.SetReturn(orig_stub);
709 arguments.SetReturn(Smi::Handle(reinterpret_cast<RawSmi*>(orig_stub)));
710 } 710 }
711 711
712 712
713 DEFINE_RUNTIME_ENTRY(SingleStepHandler, 0) { 713 DEFINE_RUNTIME_ENTRY(SingleStepHandler, 0) {
714 ASSERT(isolate->debugger() != NULL); 714 ASSERT(isolate->debugger() != NULL);
715 isolate->debugger()->DebuggerStepCallback(); 715 isolate->debugger()->DebuggerStepCallback();
716 } 716 }
717 717
718 718
719 // An instance call of the form o.f(...) could not be resolved. Check if 719 // An instance call of the form o.f(...) could not be resolved. Check if
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after
1269 const Code& optimized_code = Code::Handle(function.CurrentCode()); 1269 const Code& optimized_code = Code::Handle(function.CurrentCode());
1270 // The current code will not be changed in the case that the compiler 1270 // The current code will not be changed in the case that the compiler
1271 // bailed out during OSR compilation. 1271 // bailed out during OSR compilation.
1272 if (optimized_code.raw() != original_code.raw()) { 1272 if (optimized_code.raw() != original_code.raw()) {
1273 // The OSR code does not work for calling the function, so restore the 1273 // The OSR code does not work for calling the function, so restore the
1274 // unoptimized code. Patch the stack frame to return into the OSR 1274 // unoptimized code. Patch the stack frame to return into the OSR
1275 // code. 1275 // code.
1276 uword optimized_entry = 1276 uword optimized_entry =
1277 Instructions::Handle(optimized_code.instructions()).EntryPoint(); 1277 Instructions::Handle(optimized_code.instructions()).EntryPoint();
1278 function.AttachCode(original_code); 1278 function.AttachCode(original_code);
1279 // TODO(vegorov) figure out if it is GC safe.
1279 frame->set_pc(optimized_entry); 1280 frame->set_pc(optimized_entry);
1281 frame->set_pc_marker(reinterpret_cast<uword>(optimized_code.raw()));
1280 } 1282 }
1281 } 1283 }
1282 } 1284 }
1283 1285
1284 1286
1285 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) { 1287 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) {
1286 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(0)); 1288 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(0));
1287 const Function& function = Function::CheckedHandle(arguments.ArgAt(1)); 1289 const Function& function = Function::CheckedHandle(arguments.ArgAt(1));
1288 DartFrameIterator iterator; 1290 DartFrameIterator iterator;
1289 StackFrame* frame = iterator.NextFrame(); 1291 StackFrame* frame = iterator.NextFrame();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 } 1357 }
1356 ASSERT(target_function.HasCode()); 1358 ASSERT(target_function.HasCode());
1357 ASSERT(target_function.raw() == target_code.function()); 1359 ASSERT(target_function.raw() == target_code.function());
1358 1360
1359 const Code& current_target_code = Code::Handle( 1361 const Code& current_target_code = Code::Handle(
1360 isolate, target_function.CurrentCode()); 1362 isolate, target_function.CurrentCode());
1361 const Instructions& instrs = Instructions::Handle( 1363 const Instructions& instrs = Instructions::Handle(
1362 isolate, caller_code.instructions()); 1364 isolate, caller_code.instructions());
1363 { 1365 {
1364 WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size()); 1366 WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size());
1365 CodePatcher::PatchStaticCallAt(frame->pc(), caller_code, 1367 CodePatcher::PatchStaticCallAt(frame->pc(),
1366 current_target_code.EntryPoint()); 1368 caller_code,
1369 current_target_code);
1367 caller_code.SetStaticCallTargetCodeAt(frame->pc(), current_target_code); 1370 caller_code.SetStaticCallTargetCodeAt(frame->pc(), current_target_code);
1368 } 1371 }
1369 if (FLAG_trace_patching) { 1372 if (FLAG_trace_patching) {
1370 OS::PrintErr("FixCallersTarget: caller %#" Px " " 1373 OS::PrintErr("FixCallersTarget: caller %#" Px " "
1371 "target '%s' %#" Px " -> %#" Px "\n", 1374 "target '%s' %#" Px " -> %#" Px "\n",
1372 frame->pc(), 1375 frame->pc(),
1373 target_function.ToFullyQualifiedCString(), 1376 target_function.ToFullyQualifiedCString(),
1374 target_code.EntryPoint(), 1377 target_code.EntryPoint(),
1375 current_target_code.EntryPoint()); 1378 current_target_code.EntryPoint());
1376 } 1379 }
(...skipping 11 matching lines...) Expand all
1388 frame = iterator.NextFrame(); 1391 frame = iterator.NextFrame();
1389 ASSERT(frame != NULL); 1392 ASSERT(frame != NULL);
1390 } 1393 }
1391 if (frame->IsEntryFrame()) { 1394 if (frame->IsEntryFrame()) {
1392 // There must be a valid Dart frame. 1395 // There must be a valid Dart frame.
1393 UNREACHABLE(); 1396 UNREACHABLE();
1394 } 1397 }
1395 ASSERT(frame->IsDartFrame()); 1398 ASSERT(frame->IsDartFrame());
1396 const Code& caller_code = Code::Handle(isolate, frame->LookupDartCode()); 1399 const Code& caller_code = Code::Handle(isolate, frame->LookupDartCode());
1397 ASSERT(!caller_code.IsNull()); 1400 ASSERT(!caller_code.IsNull());
1398 const uword target = 1401 const Code& stub = Code::Handle(
1399 CodePatcher::GetStaticCallTargetAt(frame->pc(), caller_code); 1402 CodePatcher::GetStaticCallTargetAt(frame->pc(), caller_code));
1400 const Code& stub = Code::Handle(isolate, Code::LookupCode(target));
1401 Class& alloc_class = Class::ZoneHandle(zone); 1403 Class& alloc_class = Class::ZoneHandle(zone);
1402 alloc_class ^= stub.owner(); 1404 alloc_class ^= stub.owner();
1403 Code& alloc_stub = Code::Handle(isolate, alloc_class.allocation_stub()); 1405 Code& alloc_stub = Code::Handle(isolate, alloc_class.allocation_stub());
1404 if (alloc_stub.IsNull()) { 1406 if (alloc_stub.IsNull()) {
1405 alloc_stub = isolate->stub_code()->GetAllocationStubForClass(alloc_class); 1407 alloc_stub = isolate->stub_code()->GetAllocationStubForClass(alloc_class);
1406 ASSERT(!CodePatcher::IsEntryPatched(alloc_stub)); 1408 ASSERT(!CodePatcher::IsEntryPatched(alloc_stub));
1407 } 1409 }
1408 const Instructions& instrs = 1410 const Instructions& instrs =
1409 Instructions::Handle(isolate, caller_code.instructions()); 1411 Instructions::Handle(isolate, caller_code.instructions());
1410 { 1412 {
1411 WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size()); 1413 WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size());
1412 CodePatcher::PatchStaticCallAt(frame->pc(), 1414 CodePatcher::PatchStaticCallAt(frame->pc(),
1413 caller_code, 1415 caller_code,
1414 alloc_stub.EntryPoint()); 1416 alloc_stub);
1415 caller_code.SetStubCallTargetCodeAt(frame->pc(), alloc_stub); 1417 caller_code.SetStubCallTargetCodeAt(frame->pc(), alloc_stub);
1416 } 1418 }
1417 if (FLAG_trace_patching) { 1419 if (FLAG_trace_patching) {
1418 OS::PrintErr("FixAllocationStubTarget: caller %#" Px " alloc-class %s " 1420 OS::PrintErr("FixAllocationStubTarget: caller %#" Px " alloc-class %s "
1419 " -> %#" Px "\n", 1421 " -> %#" Px "\n",
1420 frame->pc(), 1422 frame->pc(),
1421 alloc_class.ToCString(), 1423 alloc_class.ToCString(),
1422 alloc_stub.EntryPoint()); 1424 alloc_stub.EntryPoint());
1423 } 1425 }
1424 arguments.SetReturn(alloc_stub); 1426 arguments.SetReturn(alloc_stub);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1517 *reinterpret_cast<intptr_t*>(saved_registers_address); 1519 *reinterpret_cast<intptr_t*>(saved_registers_address);
1518 saved_registers_address += kWordSize; 1520 saved_registers_address += kWordSize;
1519 } 1521 }
1520 *cpu_registers = cpu_registers_copy; 1522 *cpu_registers = cpu_registers_copy;
1521 } 1523 }
1522 1524
1523 1525
1524 // Copies saved registers and caller's frame into temporary buffers. 1526 // Copies saved registers and caller's frame into temporary buffers.
1525 // Returns the stack size of unoptimized frame. 1527 // Returns the stack size of unoptimized frame.
1526 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, 1528 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
1527 1, uword saved_registers_address) { 1529 2,
1530 uword saved_registers_address,
1531 uword is_lazy_deopt) {
1528 Isolate* isolate = Isolate::Current(); 1532 Isolate* isolate = Isolate::Current();
1529 StackZone zone(isolate); 1533 StackZone zone(isolate);
1530 HANDLESCOPE(isolate); 1534 HANDLESCOPE(isolate);
1531 1535
1532 // All registers have been saved below last-fp as if they were locals. 1536 // All registers have been saved below last-fp as if they were locals.
1533 const uword last_fp = saved_registers_address 1537 const uword last_fp = saved_registers_address
1534 + (kNumberOfCpuRegisters * kWordSize) 1538 + (kNumberOfCpuRegisters * kWordSize)
1535 + (kNumberOfFpuRegisters * kFpuRegisterSize) 1539 + (kNumberOfFpuRegisters * kFpuRegisterSize)
1536 - ((kFirstLocalSlotFromFp + 1) * kWordSize); 1540 - ((kFirstLocalSlotFromFp + 1) * kWordSize);
1537 1541
1538 // Get optimized code and frame that need to be deoptimized. 1542 // Get optimized code and frame that need to be deoptimized.
1539 DartFrameIterator iterator(last_fp); 1543 DartFrameIterator iterator(last_fp);
1540 StackFrame* caller_frame = iterator.NextFrame(); 1544 StackFrame* caller_frame = iterator.NextFrame();
1541 ASSERT(caller_frame != NULL); 1545 ASSERT(caller_frame != NULL);
1542 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode()); 1546 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode());
1543 ASSERT(optimized_code.is_optimized()); 1547 ASSERT(optimized_code.is_optimized());
1544 1548
1545 // Copy the saved registers from the stack. 1549 // Copy the saved registers from the stack.
1546 fpu_register_t* fpu_registers; 1550 fpu_register_t* fpu_registers;
1547 intptr_t* cpu_registers; 1551 intptr_t* cpu_registers;
1548 CopySavedRegisters(saved_registers_address, &fpu_registers, &cpu_registers); 1552 CopySavedRegisters(saved_registers_address, &fpu_registers, &cpu_registers);
1549 1553
1550 // Create the DeoptContext. 1554 // Create the DeoptContext.
1551 DeoptContext* deopt_context = 1555 DeoptContext* deopt_context =
1552 new DeoptContext(caller_frame, optimized_code, 1556 new DeoptContext(caller_frame,
1557 optimized_code,
1553 DeoptContext::kDestIsOriginalFrame, 1558 DeoptContext::kDestIsOriginalFrame,
1554 fpu_registers, cpu_registers); 1559 fpu_registers,
1560 cpu_registers,
1561 is_lazy_deopt != 0);
1555 isolate->set_deopt_context(deopt_context); 1562 isolate->set_deopt_context(deopt_context);
1556 1563
1557 // Stack size (FP - SP) in bytes. 1564 // Stack size (FP - SP) in bytes.
1558 return deopt_context->DestStackAdjustment() * kWordSize; 1565 return deopt_context->DestStackAdjustment() * kWordSize;
1559 } 1566 }
1560 END_LEAF_RUNTIME_ENTRY 1567 END_LEAF_RUNTIME_ENTRY
1561 1568
1562 1569
1563 // The stack has been adjusted to fit all values for unoptimized frame. 1570 // The stack has been adjusted to fit all values for unoptimized frame.
1564 // Fill the unoptimized frame. 1571 // Fill the unoptimized frame.
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1684 const intptr_t elm_size = old_data.ElementSizeInBytes(); 1691 const intptr_t elm_size = old_data.ElementSizeInBytes();
1685 const TypedData& new_data = 1692 const TypedData& new_data =
1686 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); 1693 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld));
1687 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); 1694 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size);
1688 typed_data_cell.SetAt(0, new_data); 1695 typed_data_cell.SetAt(0, new_data);
1689 arguments.SetReturn(new_data); 1696 arguments.SetReturn(new_data);
1690 } 1697 }
1691 1698
1692 1699
1693 } // namespace dart 1700 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698