| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
| 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 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 // Setup space on stack for return value and preserve arguments descriptor. | 337 // Setup space on stack for return value and preserve arguments descriptor. |
| 338 __ Push(R4); | 338 __ Push(R4); |
| 339 __ PushObject(Object::null_object()); | 339 __ PushObject(Object::null_object()); |
| 340 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); | 340 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); |
| 341 // Get Code object result and restore arguments descriptor array. | 341 // Get Code object result and restore arguments descriptor array. |
| 342 __ Pop(R0); | 342 __ Pop(R0); |
| 343 __ Pop(R4); | 343 __ Pop(R4); |
| 344 // Remove the stub frame. | 344 // Remove the stub frame. |
| 345 __ LeaveStubFrame(); | 345 __ LeaveStubFrame(); |
| 346 // Jump to the dart function. | 346 // Jump to the dart function. |
| 347 __ LoadFieldFromOffset(R0, R0, Code::instructions_offset()); | 347 __ LoadFieldFromOffset(R0, R0, Code::entry_point_offset()); |
| 348 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); | |
| 349 __ br(R0); | 348 __ br(R0); |
| 350 } | 349 } |
| 351 | 350 |
| 352 | 351 |
| 353 // Called from a static call only when an invalid code has been entered | 352 // Called from a static call only when an invalid code has been entered |
| 354 // (invalid because its function was optimized or deoptimized). | 353 // (invalid because its function was optimized or deoptimized). |
| 355 // R4: arguments descriptor array. | 354 // R4: arguments descriptor array. |
| 356 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 355 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
| 357 // Create a stub frame as we are pushing some objects on the stack before | 356 // Create a stub frame as we are pushing some objects on the stack before |
| 358 // calling into the runtime. | 357 // calling into the runtime. |
| 359 __ EnterStubFrame(); | 358 __ EnterStubFrame(); |
| 360 // Setup space on stack for return value and preserve arguments descriptor. | 359 // Setup space on stack for return value and preserve arguments descriptor. |
| 361 __ Push(R4); | 360 __ Push(R4); |
| 362 __ PushObject(Object::null_object()); | 361 __ PushObject(Object::null_object()); |
| 363 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); | 362 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); |
| 364 // Get Code object result and restore arguments descriptor array. | 363 // Get Code object result and restore arguments descriptor array. |
| 365 __ Pop(R0); | 364 __ Pop(R0); |
| 366 __ Pop(R4); | 365 __ Pop(R4); |
| 367 // Remove the stub frame. | 366 // Remove the stub frame. |
| 368 __ LeaveStubFrame(); | 367 __ LeaveStubFrame(); |
| 369 // Jump to the dart function. | 368 // Jump to the dart function. |
| 370 __ LoadFieldFromOffset(R0, R0, Code::instructions_offset()); | 369 __ LoadFieldFromOffset(R0, R0, Code::entry_point_offset()); |
| 371 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); | |
| 372 __ br(R0); | 370 __ br(R0); |
| 373 } | 371 } |
| 374 | 372 |
| 375 | 373 |
| 376 // Called from object allocate instruction when the allocation stub has been | 374 // Called from object allocate instruction when the allocation stub has been |
| 377 // disabled. | 375 // disabled. |
| 378 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { | 376 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { |
| 379 __ EnterStubFrame(); | 377 __ EnterStubFrame(); |
| 380 // Setup space on stack for return value. | 378 // Setup space on stack for return value. |
| 381 __ PushObject(Object::null_object()); | 379 __ PushObject(Object::null_object()); |
| 382 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); | 380 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); |
| 383 // Get Code object result. | 381 // Get Code object result. |
| 384 __ Pop(R0); | 382 __ Pop(R0); |
| 385 // Remove the stub frame. | 383 // Remove the stub frame. |
| 386 __ LeaveStubFrame(); | 384 __ LeaveStubFrame(); |
| 387 // Jump to the dart function. | 385 // Jump to the dart function. |
| 388 __ LoadFieldFromOffset(R0, R0, Code::instructions_offset()); | 386 __ LoadFieldFromOffset(R0, R0, Code::entry_point_offset()); |
| 389 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); | |
| 390 __ br(R0); | 387 __ br(R0); |
| 391 } | 388 } |
| 392 | 389 |
| 393 | 390 |
| 394 // Input parameters: | 391 // Input parameters: |
| 395 // R2: smi-tagged argument count, may be zero. | 392 // R2: smi-tagged argument count, may be zero. |
| 396 // FP[kParamEndSlotFromFp + 1]: last argument. | 393 // FP[kParamEndSlotFromFp + 1]: last argument. |
| 397 static void PushArgumentsArray(Assembler* assembler) { | 394 static void PushArgumentsArray(Assembler* assembler) { |
| 398 // Allocate array to store arguments of caller. | 395 // Allocate array to store arguments of caller. |
| 399 __ LoadObject(R1, Object::null_object()); | 396 __ LoadObject(R1, Object::null_object()); |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 | 598 |
| 602 __ LeaveStubFrame(); | 599 __ LeaveStubFrame(); |
| 603 | 600 |
| 604 if (!FLAG_lazy_dispatchers) { | 601 if (!FLAG_lazy_dispatchers) { |
| 605 Label call_target_function; | 602 Label call_target_function; |
| 606 GenerateDispatcherCode(assembler, &call_target_function); | 603 GenerateDispatcherCode(assembler, &call_target_function); |
| 607 __ Bind(&call_target_function); | 604 __ Bind(&call_target_function); |
| 608 } | 605 } |
| 609 | 606 |
| 610 // Tail-call to target function. | 607 // Tail-call to target function. |
| 611 __ LoadFieldFromOffset(R2, R0, Function::instructions_offset()); | 608 __ LoadFieldFromOffset(R2, R0, Function::entry_point_offset()); |
| 612 __ AddImmediate(R2, R2, Instructions::HeaderSize() - kHeapObjectTag); | |
| 613 __ br(R2); | 609 __ br(R2); |
| 614 } | 610 } |
| 615 | 611 |
| 616 | 612 |
| 617 // Called for inline allocation of arrays. | 613 // Called for inline allocation of arrays. |
| 618 // Input parameters: | 614 // Input parameters: |
| 619 // LR: return address. | 615 // LR: return address. |
| 620 // R2: array length as Smi. | 616 // R2: array length as Smi. |
| 621 // R1: array element type (either NULL or an instantiated type). | 617 // R1: array element type (either NULL or an instantiated type). |
| 622 // NOTE: R2 cannot be clobbered here as the caller relies on it being saved. | 618 // NOTE: R2 cannot be clobbered here as the caller relies on it being saved. |
| (...skipping 911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1534 __ LoadFromOffset(R1, R6, count_offset); | 1530 __ LoadFromOffset(R1, R6, count_offset); |
| 1535 __ adds(R1, R1, Operand(Smi::RawValue(1))); | 1531 __ adds(R1, R1, Operand(Smi::RawValue(1))); |
| 1536 __ LoadImmediate(R2, Smi::RawValue(Smi::kMaxValue)); | 1532 __ LoadImmediate(R2, Smi::RawValue(Smi::kMaxValue)); |
| 1537 __ csel(R1, R2, R1, VS); // Overflow. | 1533 __ csel(R1, R2, R1, VS); // Overflow. |
| 1538 __ StoreToOffset(R1, R6, count_offset); | 1534 __ StoreToOffset(R1, R6, count_offset); |
| 1539 } | 1535 } |
| 1540 | 1536 |
| 1541 __ Comment("Call target"); | 1537 __ Comment("Call target"); |
| 1542 __ Bind(&call_target_function); | 1538 __ Bind(&call_target_function); |
| 1543 // R0: target function. | 1539 // R0: target function. |
| 1544 __ LoadFieldFromOffset(R2, R0, Function::instructions_offset()); | 1540 __ LoadFieldFromOffset(R2, R0, Function::entry_point_offset()); |
| 1545 __ AddImmediate( | |
| 1546 R2, R2, Instructions::HeaderSize() - kHeapObjectTag); | |
| 1547 if (range_collection_mode == kCollectRanges) { | 1541 if (range_collection_mode == kCollectRanges) { |
| 1548 __ ldr(R1, Address(SP, 0 * kWordSize)); | 1542 __ ldr(R1, Address(SP, 0 * kWordSize)); |
| 1549 if (num_args == 2) { | 1543 if (num_args == 2) { |
| 1550 __ ldr(R3, Address(SP, 1 * kWordSize)); | 1544 __ ldr(R3, Address(SP, 1 * kWordSize)); |
| 1551 } | 1545 } |
| 1552 __ EnterStubFrame(); | 1546 __ EnterStubFrame(); |
| 1553 __ Push(R5); | 1547 __ Push(R5); |
| 1554 if (num_args == 2) { | 1548 if (num_args == 2) { |
| 1555 __ Push(R3); | 1549 __ Push(R3); |
| 1556 } | 1550 } |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1710 __ LoadImmediate(R2, Smi::RawValue(Smi::kMaxValue)); | 1704 __ LoadImmediate(R2, Smi::RawValue(Smi::kMaxValue)); |
| 1711 __ csel(R1, R2, R1, VS); // Overflow. | 1705 __ csel(R1, R2, R1, VS); // Overflow. |
| 1712 __ StoreToOffset(R1, R6, count_offset); | 1706 __ StoreToOffset(R1, R6, count_offset); |
| 1713 } | 1707 } |
| 1714 | 1708 |
| 1715 // Load arguments descriptor into R4. | 1709 // Load arguments descriptor into R4. |
| 1716 __ LoadFieldFromOffset(R4, R5, ICData::arguments_descriptor_offset()); | 1710 __ LoadFieldFromOffset(R4, R5, ICData::arguments_descriptor_offset()); |
| 1717 | 1711 |
| 1718 // Get function and call it, if possible. | 1712 // Get function and call it, if possible. |
| 1719 __ LoadFromOffset(R0, R6, target_offset); | 1713 __ LoadFromOffset(R0, R6, target_offset); |
| 1720 __ LoadFieldFromOffset(R2, R0, Function::instructions_offset()); | 1714 __ LoadFieldFromOffset(R2, R0, Function::entry_point_offset()); |
| 1721 | |
| 1722 // R0: function. | |
| 1723 // R2: target instructons. | |
| 1724 __ AddImmediate( | |
| 1725 R2, R2, Instructions::HeaderSize() - kHeapObjectTag); | |
| 1726 __ br(R2); | 1715 __ br(R2); |
| 1727 | 1716 |
| 1728 if (FLAG_support_debugger) { | 1717 if (FLAG_support_debugger) { |
| 1729 __ Bind(&stepping); | 1718 __ Bind(&stepping); |
| 1730 __ EnterStubFrame(); | 1719 __ EnterStubFrame(); |
| 1731 __ Push(R5); // Preserve IC data. | 1720 __ Push(R5); // Preserve IC data. |
| 1732 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1721 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 1733 __ Pop(R5); | 1722 __ Pop(R5); |
| 1734 __ LeaveStubFrame(); | 1723 __ LeaveStubFrame(); |
| 1735 __ b(&done_stepping); | 1724 __ b(&done_stepping); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1762 __ EnterStubFrame(); | 1751 __ EnterStubFrame(); |
| 1763 __ Push(R5); // Save IC Data. | 1752 __ Push(R5); // Save IC Data. |
| 1764 __ Push(R4); // Save arg. desc. | 1753 __ Push(R4); // Save arg. desc. |
| 1765 __ Push(R0); // Pass function. | 1754 __ Push(R0); // Pass function. |
| 1766 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); | 1755 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
| 1767 __ Pop(R0); // Restore argument. | 1756 __ Pop(R0); // Restore argument. |
| 1768 __ Pop(R4); // Restore arg desc. | 1757 __ Pop(R4); // Restore arg desc. |
| 1769 __ Pop(R5); // Restore IC Data. | 1758 __ Pop(R5); // Restore IC Data. |
| 1770 __ LeaveStubFrame(); | 1759 __ LeaveStubFrame(); |
| 1771 | 1760 |
| 1772 __ LoadFieldFromOffset(R2, R0, Function::instructions_offset()); | 1761 __ LoadFieldFromOffset(R2, R0, Function::entry_point_offset()); |
| 1773 __ AddImmediate( | |
| 1774 R2, R2, Instructions::HeaderSize() - kHeapObjectTag); | |
| 1775 __ br(R2); | 1762 __ br(R2); |
| 1776 } | 1763 } |
| 1777 | 1764 |
| 1778 | 1765 |
| 1779 // R5: Contains an ICData. | 1766 // R5: Contains an ICData. |
| 1780 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { | 1767 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { |
| 1781 __ EnterStubFrame(); | 1768 __ EnterStubFrame(); |
| 1782 __ Push(R5); | 1769 __ Push(R5); |
| 1783 __ PushObject(Object::null_object()); // Space for result. | 1770 __ PushObject(Object::null_object()); // Space for result. |
| 1784 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); | 1771 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1967 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 1954 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
| 1968 __ EnterStubFrame(); | 1955 __ EnterStubFrame(); |
| 1969 __ Push(R4); | 1956 __ Push(R4); |
| 1970 // Setup space on stack for the return value. | 1957 // Setup space on stack for the return value. |
| 1971 __ PushObject(Object::null_object()); | 1958 __ PushObject(Object::null_object()); |
| 1972 __ Push(R6); | 1959 __ Push(R6); |
| 1973 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); | 1960 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); |
| 1974 __ Pop(R0); // Discard argument. | 1961 __ Pop(R0); // Discard argument. |
| 1975 __ Pop(R0); // Get Code object | 1962 __ Pop(R0); // Get Code object |
| 1976 __ Pop(R4); // Restore argument descriptor. | 1963 __ Pop(R4); // Restore argument descriptor. |
| 1977 __ LoadFieldFromOffset(R0, R0, Code::instructions_offset()); | 1964 __ LoadFieldFromOffset(R0, R0, Code::entry_point_offset()); |
| 1978 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); | |
| 1979 __ LeaveStubFrame(); | 1965 __ LeaveStubFrame(); |
| 1980 __ br(R0); | 1966 __ br(R0); |
| 1981 __ brk(0); | 1967 __ brk(0); |
| 1982 } | 1968 } |
| 1983 | 1969 |
| 1984 | 1970 |
| 1985 // Does identical check (object references are equal or not equal) with special | 1971 // Does identical check (object references are equal or not equal) with special |
| 1986 // checks for boxed numbers. | 1972 // checks for boxed numbers. |
| 1987 // Left and right are pushed on stack. | 1973 // Left and right are pushed on stack. |
| 1988 // Return Zero condition flag set if equal. | 1974 // Return Zero condition flag set if equal. |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2119 __ CompareRegisters(R4, R0); | 2105 __ CompareRegisters(R4, R0); |
| 2120 __ b(&update, NE); | 2106 __ b(&update, NE); |
| 2121 | 2107 |
| 2122 __ Bind(&call_target_function); | 2108 __ Bind(&call_target_function); |
| 2123 // Call the target found in the cache. For a class id match, this is a | 2109 // Call the target found in the cache. For a class id match, this is a |
| 2124 // proper target for the given name and arguments descriptor. If the | 2110 // proper target for the given name and arguments descriptor. If the |
| 2125 // illegal class id was found, the target is a cache miss handler that can | 2111 // illegal class id was found, the target is a cache miss handler that can |
| 2126 // be invoked as a normal Dart function. | 2112 // be invoked as a normal Dart function. |
| 2127 __ add(TMP, R2, Operand(R3, LSL, 3)); | 2113 __ add(TMP, R2, Operand(R3, LSL, 3)); |
| 2128 __ LoadFieldFromOffset(R0, TMP, base + kWordSize); | 2114 __ LoadFieldFromOffset(R0, TMP, base + kWordSize); |
| 2129 __ LoadFieldFromOffset(R1, R0, Function::instructions_offset()); | 2115 __ LoadFieldFromOffset(R1, R0, Function::entry_point_offset()); |
| 2130 // TODO(srdjan): Evaluate performance impact of moving the instruction below | |
| 2131 // to the call site, instead of having it here. | |
| 2132 __ AddImmediate(target, R1, Instructions::HeaderSize() - kHeapObjectTag); | |
| 2133 } | 2116 } |
| 2134 | 2117 |
| 2135 | 2118 |
| 2136 // Called from megamorphic calls. | 2119 // Called from megamorphic calls. |
| 2137 // R0: receiver. | 2120 // R0: receiver. |
| 2138 // R1: lookup cache. | 2121 // R1: lookup cache. |
| 2139 // Result: | 2122 // Result: |
| 2140 // R1: entry point. | 2123 // R1: entry point. |
| 2141 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2124 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
| 2142 EmitMegamorphicLookup(assembler, R0, R1, R1); | 2125 EmitMegamorphicLookup(assembler, R0, R1, R1); |
| 2143 __ ret(); | 2126 __ ret(); |
| 2144 } | 2127 } |
| 2145 | 2128 |
| 2146 } // namespace dart | 2129 } // namespace dart |
| 2147 | 2130 |
| 2148 #endif // defined TARGET_ARCH_ARM64 | 2131 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |