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

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 Created 6 years, 8 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 | « runtime/vm/stub_code.h ('k') | runtime/vm/stub_code_ia32.cc » ('j') | no next file with comments »
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/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;
805 __ b(&function_compiled, NE);
806 804
807 // Create a stub frame as we are pushing some objects on the stack before 805 // R2: code.
808 // calling into the runtime. 806 __ ldr(R2, FieldAddress(R2, Code::instructions_offset()));
809 __ EnterStubFrame(); 807 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
810 808 __ 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 809
829 __ Bind(&not_closure); 810 __ Bind(&not_closure);
830 // Call runtime to attempt to resolve and invoke a call method on a 811 // 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, 812 // non-closure object, passing the non-closure object and its arguments array,
832 // returning here. 813 // returning here.
833 // If no call method exists, throw a NoSuchMethodError. 814 // If no call method exists, throw a NoSuchMethodError.
834 // R1: non-closure object. 815 // R1: non-closure object.
835 // R4: arguments descriptor array. 816 // R4: arguments descriptor array.
836 817
837 // Create a stub frame as we are pushing some objects on the stack before 818 // 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); 1486 __ LoadFromOffset(kWord, R0, R6, target_offset);
1506 __ LoadFromOffset(kWord, R1, R6, count_offset); 1487 __ LoadFromOffset(kWord, R1, R6, count_offset);
1507 __ adds(R1, R1, ShifterOperand(Smi::RawValue(1))); 1488 __ adds(R1, R1, ShifterOperand(Smi::RawValue(1)));
1508 __ StoreToOffset(kWord, R1, R6, count_offset); 1489 __ StoreToOffset(kWord, R1, R6, count_offset);
1509 __ b(&call_target_function, VC); // No overflow. 1490 __ b(&call_target_function, VC); // No overflow.
1510 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue)); 1491 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue));
1511 __ StoreToOffset(kWord, R1, R6, count_offset); 1492 __ StoreToOffset(kWord, R1, R6, count_offset);
1512 1493
1513 __ Bind(&call_target_function); 1494 __ Bind(&call_target_function);
1514 // R0: target function. 1495 // R0: target function.
1515 __ ldr(R1, FieldAddress(R0, Function::code_offset())); 1496 __ ldr(R2, FieldAddress(R0, Function::code_offset()));
1516 if (FLAG_collect_code) { 1497 __ ldr(R2, FieldAddress(R2, Code::instructions_offset()));
1517 // If we are collecting code, the code object may be null. 1498 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
1518 Label is_compiled; 1499 __ bx(R2);
1519 __ CompareImmediate(R1, reinterpret_cast<intptr_t>(Object::null()));
1520 __ b(&is_compiled, NE);
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 }
1533 __ ldr(R0, FieldAddress(R1, Code::instructions_offset()));
1534 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag);
1535 __ bx(R0);
1536 1500
1537 // Instance in R0, return its class-id in R0 as Smi. 1501 // Instance in R0, return its class-id in R0 as Smi.
1538 __ Bind(&get_class_id_as_smi); 1502 __ Bind(&get_class_id_as_smi);
1539 1503
1540 // Test if Smi -> load Smi class for comparison. 1504 // Test if Smi -> load Smi class for comparison.
1541 __ tst(R0, ShifterOperand(kSmiTagMask)); 1505 __ tst(R0, ShifterOperand(kSmiTagMask));
1542 __ mov(R0, ShifterOperand(Smi::RawValue(kSmiCid)), EQ); 1506 __ mov(R0, ShifterOperand(Smi::RawValue(kSmiCid)), EQ);
1543 __ bx(LR, EQ); 1507 __ bx(LR, EQ);
1544 __ LoadClassId(R0, R0); 1508 __ LoadClassId(R0, R0);
1545 __ SmiTag(R0); 1509 __ SmiTag(R0);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 // Increment count for this call. 1619 // Increment count for this call.
1656 Label increment_done; 1620 Label increment_done;
1657 __ LoadFromOffset(kWord, R1, R6, count_offset); 1621 __ LoadFromOffset(kWord, R1, R6, count_offset);
1658 __ adds(R1, R1, ShifterOperand(Smi::RawValue(1))); 1622 __ adds(R1, R1, ShifterOperand(Smi::RawValue(1)));
1659 __ StoreToOffset(kWord, R1, R6, count_offset); 1623 __ StoreToOffset(kWord, R1, R6, count_offset);
1660 __ b(&increment_done, VC); // No overflow. 1624 __ b(&increment_done, VC); // No overflow.
1661 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue)); 1625 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue));
1662 __ StoreToOffset(kWord, R1, R6, count_offset); 1626 __ StoreToOffset(kWord, R1, R6, count_offset);
1663 __ Bind(&increment_done); 1627 __ Bind(&increment_done);
1664 1628
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. 1629 // Load arguments descriptor into R4.
1689 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); 1630 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
1690 __ bx(R0); 1631
1632 // Get function and call it, if possible.
1633 __ LoadFromOffset(kWord, R0, R6, target_offset);
1634 __ ldr(R2, FieldAddress(R0, Function::code_offset()));
1635
1636 // R0: function.
1637 // R2: target code.
1638 __ ldr(R2, FieldAddress(R2, Code::instructions_offset()));
1639 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
1640 __ bx(R2);
1691 } 1641 }
1692 1642
1693 1643
1694 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { 1644 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
1695 GenerateUsageCounterIncrement(assembler, R6); 1645 GenerateUsageCounterIncrement(assembler, R6);
1696 GenerateNArgsCheckInlineCacheStub( 1646 GenerateNArgsCheckInlineCacheStub(
1697 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry); 1647 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry);
1698 } 1648 }
1699 1649
1700 1650
1701 // Stub for calling the CompileFunction runtime call. 1651 // Stub for compiling a function and jumping to the compiled code.
1702 // R5: IC-Data. 1652 // R5: IC-Data (for methods).
1703 // R4: Arguments descriptor. 1653 // R4: Arguments descriptor.
1704 // R0: Function. 1654 // R0: Function.
1705 void StubCode::GenerateCompileFunctionRuntimeCallStub(Assembler* assembler) { 1655 void StubCode::GenerateLazyCompileStub(Assembler* assembler) {
1706 // Preserve arg desc. and IC data object. 1656 // Preserve arg desc. and IC data object.
1707 __ EnterStubFrame(); 1657 __ EnterStubFrame();
1708 __ PushList((1 << R4) | (1 << R5)); 1658 __ PushList((1 << R4) | (1 << R5));
1709 __ Push(R0); // Pass function. 1659 __ Push(R0); // Pass function.
1710 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); 1660 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1711 __ Pop(R0); // Restore argument. 1661 __ Pop(R0); // Restore argument.
1712 __ PopList((1 << R4) | (1 << R5)); // Restore arg desc. and IC data. 1662 __ PopList((1 << R4) | (1 << R5)); // Restore arg desc. and IC data.
1713 __ LeaveStubFrame(); 1663 __ LeaveStubFrame();
1714 __ Ret(); 1664
1665 __ ldr(R2, FieldAddress(R0, Function::code_offset()));
1666 __ ldr(R2, FieldAddress(R2, Code::instructions_offset()));
1667 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
1668 __ bx(R2);
1715 } 1669 }
1716 1670
1717 1671
1718 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { 1672 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
1719 __ Comment("BreakpointRuntime stub"); 1673 __ Comment("BreakpointRuntime stub");
1720 __ EnterStubFrame(); 1674 __ EnterStubFrame();
1721 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); 1675 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
1722 // Preserve arguments descriptor and make room for result. 1676 // Preserve arguments descriptor and make room for result.
1723 __ PushList((1 << R0) | (1 << R4) | (1 << R5)); 1677 __ PushList((1 << R0) | (1 << R4) | (1 << R5));
1724 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); 1678 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
2013 const Register right = R0; 1967 const Register right = R0;
2014 __ ldr(left, Address(SP, 1 * kWordSize)); 1968 __ ldr(left, Address(SP, 1 * kWordSize));
2015 __ ldr(right, Address(SP, 0 * kWordSize)); 1969 __ ldr(right, Address(SP, 0 * kWordSize));
2016 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 1970 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2017 __ Ret(); 1971 __ Ret();
2018 } 1972 }
2019 1973
2020 } // namespace dart 1974 } // namespace dart
2021 1975
2022 #endif // defined TARGET_ARCH_ARM 1976 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/stub_code.h ('k') | runtime/vm/stub_code_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698