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

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

Issue 203523011: Introduce a lazy-compile stub for functions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: rebased & added MIPS code Created 6 years, 9 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
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/globals.h" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 __ b(&not_closure, EQ); // Not a closure, but a smi. 786 __ b(&not_closure, EQ); // Not a closure, but a smi.
787 // Verify that the class of the object is a closure class by checking that 787 // Verify that the class of the object is a closure class by checking that
788 // class.signature_function() is not null. 788 // class.signature_function() is not null.
789 __ LoadClass(R0, R1, R2); 789 __ LoadClass(R0, R1, R2);
790 __ ldr(R0, FieldAddress(R0, Class::signature_function_offset())); 790 __ ldr(R0, FieldAddress(R0, Class::signature_function_offset()));
791 __ cmp(R0, ShifterOperand(R8)); // R8 is raw null. 791 __ cmp(R0, ShifterOperand(R8)); // R8 is raw null.
792 // Actual class is not a closure class. 792 // Actual class is not a closure class.
793 __ b(&not_closure, EQ); 793 __ b(&not_closure, EQ);
794 794
795 // R0 is just the signature function. Load the actual closure function. 795 // R0 is just the signature function. Load the actual closure function.
796 __ ldr(R2, FieldAddress(R1, Closure::function_offset())); 796 __ ldr(R0, FieldAddress(R1, Closure::function_offset()));
797 797
798 // Load closure context in CTX; note that CTX has already been preserved. 798 // Load closure context in CTX; note that CTX has already been preserved.
799 __ ldr(CTX, FieldAddress(R1, Closure::context_offset())); 799 __ ldr(CTX, FieldAddress(R1, Closure::context_offset()));
800 800
801 // Load closure function code in R0. 801 // R4: Arguments descriptor.
802 __ ldr(R0, FieldAddress(R2, Function::code_offset())); 802 // R0: Function.
803 __ cmp(R0, ShifterOperand(R8)); // R8 is raw null. 803 __ ldr(R2, FieldAddress(R0, Function::code_offset()));
804 Label function_compiled; 804 __ cmp(R2, ShifterOperand(R8)); // R8 is raw null.
805 __ b(&function_compiled, NE); 805 __ Branch(&StubCode::LazyCompileClosureLabel(), EQ);
806 806
807 // Create a stub frame as we are pushing some objects on the stack before 807 // R2: code.
808 // calling into the runtime. 808 __ ldr(R2, FieldAddress(R2, Code::instructions_offset()));
809 __ EnterStubFrame(); 809 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
810 810 __ bx(R2);
811 // Preserve arguments descriptor array and read-only function object argument.
812 __ PushList((1 << R2) | (1 << R4));
813 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
814 // Restore arguments descriptor array and read-only function object argument.
815 __ PopList((1 << R2) | (1 << R4));
816 // Restore R0.
817 __ ldr(R0, FieldAddress(R2, Function::code_offset()));
818
819 // Remove the stub frame as we are about to jump to the closure function.
820 __ LeaveStubFrame();
821
822 __ Bind(&function_compiled);
823 // R0: code.
824 // R4: arguments descriptor array.
825 __ ldr(R0, FieldAddress(R0, Code::instructions_offset()));
826 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag);
827 __ bx(R0);
828 811
829 __ Bind(&not_closure); 812 __ Bind(&not_closure);
830 // Call runtime to attempt to resolve and invoke a call method on a 813 // Call runtime to attempt to resolve and invoke a call method on a
831 // non-closure object, passing the non-closure object and its arguments array, 814 // non-closure object, passing the non-closure object and its arguments array,
832 // returning here. 815 // returning here.
833 // If no call method exists, throw a NoSuchMethodError. 816 // If no call method exists, throw a NoSuchMethodError.
834 // R1: non-closure object. 817 // R1: non-closure object.
835 // R4: arguments descriptor array. 818 // R4: arguments descriptor array.
836 819
837 // Create a stub frame as we are pushing some objects on the stack before 820 // Create a stub frame as we are pushing some objects on the stack before
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after
1505 __ LoadFromOffset(kWord, R0, R6, target_offset); 1488 __ LoadFromOffset(kWord, R0, R6, target_offset);
1506 __ LoadFromOffset(kWord, R1, R6, count_offset); 1489 __ LoadFromOffset(kWord, R1, R6, count_offset);
1507 __ adds(R1, R1, ShifterOperand(Smi::RawValue(1))); 1490 __ adds(R1, R1, ShifterOperand(Smi::RawValue(1)));
1508 __ StoreToOffset(kWord, R1, R6, count_offset); 1491 __ StoreToOffset(kWord, R1, R6, count_offset);
1509 __ b(&call_target_function, VC); // No overflow. 1492 __ b(&call_target_function, VC); // No overflow.
1510 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue)); 1493 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue));
1511 __ StoreToOffset(kWord, R1, R6, count_offset); 1494 __ StoreToOffset(kWord, R1, R6, count_offset);
1512 1495
1513 __ Bind(&call_target_function); 1496 __ Bind(&call_target_function);
1514 // R0: target function. 1497 // R0: target function.
1515 __ ldr(R1, FieldAddress(R0, Function::code_offset())); 1498 __ ldr(R2, FieldAddress(R0, Function::code_offset()));
1516 if (FLAG_collect_code) { 1499 if (FLAG_collect_code) {
1517 // If we are collecting code, the code object may be null. 1500 // If we are collecting code, the code object may be null.
1518 Label is_compiled; 1501 Label is_compiled;
1519 __ CompareImmediate(R1, reinterpret_cast<intptr_t>(Object::null())); 1502 __ CompareImmediate(R2, reinterpret_cast<intptr_t>(Object::null()));
1520 __ b(&is_compiled, NE); 1503 __ Branch(&StubCode::LazyCompileLabel(), EQ);
1521 __ EnterStubFrame();
1522 // Preserve arg desc. and IC data object.
1523 __ PushList((1 << R4) | (1 << R5));
1524 __ Push(R0); // Pass function.
1525 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1526 __ Pop(R0); // Discard argument.
1527 __ PopList((1 << R4) | (1 << R5)); // Restore arg desc. and IC data.
1528 __ LeaveStubFrame();
1529 // R0: target function.
1530 __ ldr(R1, FieldAddress(R0, Function::code_offset()));
1531 __ Bind(&is_compiled);
1532 } 1504 }
1533 __ ldr(R0, FieldAddress(R1, Code::instructions_offset())); 1505 __ ldr(R2, FieldAddress(R2, Code::instructions_offset()));
1534 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag); 1506 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
1535 __ bx(R0); 1507 __ bx(R2);
1536 1508
1537 // Instance in R0, return its class-id in R0 as Smi. 1509 // Instance in R0, return its class-id in R0 as Smi.
1538 __ Bind(&get_class_id_as_smi); 1510 __ Bind(&get_class_id_as_smi);
1539 1511
1540 // Test if Smi -> load Smi class for comparison. 1512 // Test if Smi -> load Smi class for comparison.
1541 __ tst(R0, ShifterOperand(kSmiTagMask)); 1513 __ tst(R0, ShifterOperand(kSmiTagMask));
1542 __ mov(R0, ShifterOperand(Smi::RawValue(kSmiCid)), EQ); 1514 __ mov(R0, ShifterOperand(Smi::RawValue(kSmiCid)), EQ);
1543 __ bx(LR, EQ); 1515 __ bx(LR, EQ);
1544 __ LoadClassId(R0, R0); 1516 __ LoadClassId(R0, R0);
1545 __ SmiTag(R0); 1517 __ SmiTag(R0);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 // Increment count for this call. 1627 // Increment count for this call.
1656 Label increment_done; 1628 Label increment_done;
1657 __ LoadFromOffset(kWord, R1, R6, count_offset); 1629 __ LoadFromOffset(kWord, R1, R6, count_offset);
1658 __ adds(R1, R1, ShifterOperand(Smi::RawValue(1))); 1630 __ adds(R1, R1, ShifterOperand(Smi::RawValue(1)));
1659 __ StoreToOffset(kWord, R1, R6, count_offset); 1631 __ StoreToOffset(kWord, R1, R6, count_offset);
1660 __ b(&increment_done, VC); // No overflow. 1632 __ b(&increment_done, VC); // No overflow.
1661 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue)); 1633 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue));
1662 __ StoreToOffset(kWord, R1, R6, count_offset); 1634 __ StoreToOffset(kWord, R1, R6, count_offset);
1663 __ Bind(&increment_done); 1635 __ Bind(&increment_done);
1664 1636
1665 Label target_is_compiled;
1666 // Get function and call it, if possible.
1667 __ LoadFromOffset(kWord, R1, R6, target_offset);
1668 __ ldr(R0, FieldAddress(R1, Function::code_offset()));
1669 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
1670 __ b(&target_is_compiled, NE);
1671 // R1: function.
1672
1673 __ EnterStubFrame();
1674 // Preserve target function and IC data object.
1675 __ PushList((1 << R1) | (1 << R5));
1676 __ Push(R1); // Pass function.
1677 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1678 __ Drop(1); // Discard argument.
1679 __ PopList((1 << R1) | (1 << R5)); // Restore function and IC data.
1680 __ LeaveStubFrame();
1681 // R0: target function.
1682 __ ldr(R0, FieldAddress(R1, Function::code_offset()));
1683
1684 __ Bind(&target_is_compiled);
1685 // R0: target code.
1686 __ ldr(R0, FieldAddress(R0, Code::instructions_offset()));
1687 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag);
1688 // Load arguments descriptor into R4. 1637 // Load arguments descriptor into R4.
1689 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); 1638 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
1690 __ bx(R0); 1639
1640 // Get function and call it, if possible.
1641 __ LoadFromOffset(kWord, R0, R6, target_offset);
1642 __ ldr(R2, FieldAddress(R0, Function::code_offset()));
1643
1644 // R0: function.
1645 // R2: target code.
1646 __ CompareImmediate(R2, reinterpret_cast<intptr_t>(Object::null()));
1647 __ Branch(&StubCode::LazyCompileLabel(), EQ);
1648
1649 __ ldr(R2, FieldAddress(R2, Code::instructions_offset()));
1650 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
1651 __ bx(R2);
1691 } 1652 }
1692 1653
1693 1654
1694 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { 1655 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
1695 GenerateUsageCounterIncrement(assembler, R6); 1656 GenerateUsageCounterIncrement(assembler, R6);
1696 GenerateNArgsCheckInlineCacheStub( 1657 GenerateNArgsCheckInlineCacheStub(
1697 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry); 1658 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry);
1698 } 1659 }
1699 1660
1700 1661
1701 // Stub for calling the CompileFunction runtime call. 1662 // Stub for compiling a function and jumping to the compiled code.
1702 // R5: IC-Data. 1663 // R5: IC-Data.
1703 // R4: Arguments descriptor. 1664 // R4: Arguments descriptor.
1704 // R0: Function. 1665 // R0: Function.
1705 void StubCode::GenerateCompileFunctionRuntimeCallStub(Assembler* assembler) { 1666 void StubCode::GenerateLazyCompileStub(Assembler* assembler) {
1706 // Preserve arg desc. and IC data object. 1667 // Preserve arg desc. and IC data object.
1707 __ EnterStubFrame(); 1668 __ EnterStubFrame();
1708 __ PushList((1 << R4) | (1 << R5)); 1669 __ PushList((1 << R4) | (1 << R5));
1709 __ Push(R0); // Pass function. 1670 __ Push(R0); // Pass function.
1710 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); 1671 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1711 __ Pop(R0); // Restore argument. 1672 __ Pop(R0); // Restore argument.
1712 __ PopList((1 << R4) | (1 << R5)); // Restore arg desc. and IC data. 1673 __ PopList((1 << R4) | (1 << R5)); // Restore arg desc. and IC data.
1713 __ LeaveStubFrame(); 1674 __ LeaveStubFrame();
1675
1676 __ ldr(R2, FieldAddress(R0, Function::code_offset()));
1677 __ ldr(R2, FieldAddress(R2, Code::instructions_offset()));
1678 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
1679 __ bx(R2);
1680 }
1681
1682
1683 // Stub for calling the CompileFunction runtime call.
1684 // R4: Arguments descriptor.
1685 // R0: Function.
1686 void StubCode::GenerateLazyCompileClosureStub(Assembler* assembler) {
1687 // Preserve arg desc. and IC data object.
1688 __ EnterStubFrame();
1689 __ Push(R4);
1690 __ Push(R0); // Pass function.
1691 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1692 __ Pop(R0); // Restore argument.
1693 __ Pop(R4); // Restore arg desc.
1694 __ LeaveStubFrame();
1695
1696 __ ldr(R2, FieldAddress(R0, Function::code_offset()));
1697 __ ldr(R2, FieldAddress(R2, Code::instructions_offset()));
1698 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
1699 __ bx(R2);
1700 }
1701
1702
1703 // Stub for calling the CompileFunction runtime call.
1704 // R0: Function.
1705 void StubCode::GenerateCompileFunctionRuntimeCallStub(Assembler* assembler) {
1706 __ EnterStubFrame();
1707 __ Push(R0); // Pass function.
1708 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1709 __ Pop(R0); // Restore argument.
1710 __ LeaveStubFrame();
1714 __ Ret(); 1711 __ Ret();
1715 } 1712 }
1716 1713
1717 1714
1718 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { 1715 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
1719 __ Comment("BreakpointRuntime stub"); 1716 __ Comment("BreakpointRuntime stub");
1720 __ EnterStubFrame(); 1717 __ EnterStubFrame();
1721 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); 1718 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
1722 // Preserve arguments descriptor and make room for result. 1719 // Preserve arguments descriptor and make room for result.
1723 __ PushList((1 << R0) | (1 << R4) | (1 << R5)); 1720 __ PushList((1 << R0) | (1 << R4) | (1 << R5));
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
2013 const Register right = R0; 2010 const Register right = R0;
2014 __ ldr(left, Address(SP, 1 * kWordSize)); 2011 __ ldr(left, Address(SP, 1 * kWordSize));
2015 __ ldr(right, Address(SP, 0 * kWordSize)); 2012 __ ldr(right, Address(SP, 0 * kWordSize));
2016 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 2013 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2017 __ Ret(); 2014 __ Ret();
2018 } 2015 }
2019 2016
2020 } // namespace dart 2017 } // namespace dart
2021 2018
2022 #endif // defined TARGET_ARCH_ARM 2019 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698