| 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 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 | 317 |
| 318 | 318 |
| 319 // Input parameters: | 319 // Input parameters: |
| 320 // R4: arguments descriptor array. | 320 // R4: arguments descriptor array. |
| 321 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 321 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
| 322 // Create a stub frame as we are pushing some objects on the stack before | 322 // Create a stub frame as we are pushing some objects on the stack before |
| 323 // calling into the runtime. | 323 // calling into the runtime. |
| 324 __ EnterStubFrame(); | 324 __ EnterStubFrame(); |
| 325 // Setup space on stack for return value and preserve arguments descriptor. | 325 // Setup space on stack for return value and preserve arguments descriptor. |
| 326 __ Push(R4); | 326 __ Push(R4); |
| 327 __ PushObject(Object::null_object()); | 327 __ Push(ZR); |
| 328 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); | 328 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); |
| 329 // Get Code object result and restore arguments descriptor array. | 329 // Get Code object result and restore arguments descriptor array. |
| 330 __ Pop(CODE_REG); | 330 __ Pop(CODE_REG); |
| 331 __ Pop(R4); | 331 __ Pop(R4); |
| 332 // Remove the stub frame. | 332 // Remove the stub frame. |
| 333 __ LeaveStubFrame(); | 333 __ LeaveStubFrame(); |
| 334 // Jump to the dart function. | 334 // Jump to the dart function. |
| 335 __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset()); | 335 __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset()); |
| 336 __ br(R0); | 336 __ br(R0); |
| 337 } | 337 } |
| 338 | 338 |
| 339 | 339 |
| 340 // Called from a static call only when an invalid code has been entered | 340 // Called from a static call only when an invalid code has been entered |
| 341 // (invalid because its function was optimized or deoptimized). | 341 // (invalid because its function was optimized or deoptimized). |
| 342 // R4: arguments descriptor array. | 342 // R4: arguments descriptor array. |
| 343 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 343 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
| 344 // Load code pointer to this stub from the thread: | 344 // Load code pointer to this stub from the thread: |
| 345 // The one that is passed in, is not correct - it points to the code object | 345 // The one that is passed in, is not correct - it points to the code object |
| 346 // that needs to be replaced. | 346 // that needs to be replaced. |
| 347 __ ldr(CODE_REG, Address(THR, Thread::fix_callers_target_code_offset())); | 347 __ ldr(CODE_REG, Address(THR, Thread::fix_callers_target_code_offset())); |
| 348 // Create a stub frame as we are pushing some objects on the stack before | 348 // Create a stub frame as we are pushing some objects on the stack before |
| 349 // calling into the runtime. | 349 // calling into the runtime. |
| 350 __ EnterStubFrame(); | 350 __ EnterStubFrame(); |
| 351 // Setup space on stack for return value and preserve arguments descriptor. | 351 // Setup space on stack for return value and preserve arguments descriptor. |
| 352 __ Push(R4); | 352 __ Push(R4); |
| 353 __ PushObject(Object::null_object()); | 353 __ Push(ZR); |
| 354 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); | 354 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); |
| 355 // Get Code object result and restore arguments descriptor array. | 355 // Get Code object result and restore arguments descriptor array. |
| 356 __ Pop(CODE_REG); | 356 __ Pop(CODE_REG); |
| 357 __ Pop(R4); | 357 __ Pop(R4); |
| 358 // Remove the stub frame. | 358 // Remove the stub frame. |
| 359 __ LeaveStubFrame(); | 359 __ LeaveStubFrame(); |
| 360 // Jump to the dart function. | 360 // Jump to the dart function. |
| 361 __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset()); | 361 __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset()); |
| 362 __ br(R0); | 362 __ br(R0); |
| 363 } | 363 } |
| 364 | 364 |
| 365 | 365 |
| 366 // Called from object allocate instruction when the allocation stub has been | 366 // Called from object allocate instruction when the allocation stub has been |
| 367 // disabled. | 367 // disabled. |
| 368 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { | 368 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { |
| 369 // Load code pointer to this stub from the thread: | 369 // Load code pointer to this stub from the thread: |
| 370 // The one that is passed in, is not correct - it points to the code object | 370 // The one that is passed in, is not correct - it points to the code object |
| 371 // that needs to be replaced. | 371 // that needs to be replaced. |
| 372 __ ldr(CODE_REG, Address(THR, Thread::fix_allocation_stub_code_offset())); | 372 __ ldr(CODE_REG, Address(THR, Thread::fix_allocation_stub_code_offset())); |
| 373 __ EnterStubFrame(); | 373 __ EnterStubFrame(); |
| 374 // Setup space on stack for return value. | 374 // Setup space on stack for return value. |
| 375 __ PushObject(Object::null_object()); | 375 __ Push(ZR); |
| 376 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); | 376 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); |
| 377 // Get Code object result. | 377 // Get Code object result. |
| 378 __ Pop(CODE_REG); | 378 __ Pop(CODE_REG); |
| 379 // Remove the stub frame. | 379 // Remove the stub frame. |
| 380 __ LeaveStubFrame(); | 380 __ LeaveStubFrame(); |
| 381 // Jump to the dart function. | 381 // Jump to the dart function. |
| 382 __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset()); | 382 __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset()); |
| 383 __ br(R0); | 383 __ br(R0); |
| 384 } | 384 } |
| 385 | 385 |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 // When lazily generated invocation dispatchers are disabled, the | 556 // When lazily generated invocation dispatchers are disabled, the |
| 557 // miss-handler may return null. | 557 // miss-handler may return null. |
| 558 __ CompareObject(R0, Object::null_object()); | 558 __ CompareObject(R0, Object::null_object()); |
| 559 __ b(call_target_function, NE); | 559 __ b(call_target_function, NE); |
| 560 __ EnterStubFrame(); | 560 __ EnterStubFrame(); |
| 561 | 561 |
| 562 // Load the receiver. | 562 // Load the receiver. |
| 563 __ LoadFieldFromOffset(R2, R4, ArgumentsDescriptor::count_offset()); | 563 __ LoadFieldFromOffset(R2, R4, ArgumentsDescriptor::count_offset()); |
| 564 __ add(TMP, FP, Operand(R2, LSL, 2)); // R2 is Smi. | 564 __ add(TMP, FP, Operand(R2, LSL, 2)); // R2 is Smi. |
| 565 __ LoadFromOffset(R6, TMP, kParamEndSlotFromFp * kWordSize); | 565 __ LoadFromOffset(R6, TMP, kParamEndSlotFromFp * kWordSize); |
| 566 __ PushObject(Object::null_object()); | 566 __ Push(ZR); // Result slot. |
| 567 __ Push(R6); // Receiver. | 567 __ Push(R6); // Receiver. |
| 568 __ Push(R5); // ICData/MegamorphicCache. | 568 __ Push(R5); // ICData/MegamorphicCache. |
| 569 __ Push(R4); // Arguments descriptor. | 569 __ Push(R4); // Arguments descriptor. |
| 570 // R2: Smi-tagged arguments array length. | 570 // R2: Smi-tagged arguments array length. |
| 571 PushArgumentsArray(assembler); | 571 PushArgumentsArray(assembler); |
| 572 const intptr_t kNumArgs = 4; | 572 const intptr_t kNumArgs = 4; |
| 573 __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs); | 573 __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs); |
| 574 __ Drop(4); | 574 __ Drop(4); |
| 575 __ Pop(R0); // Return value. | 575 __ Pop(R0); // Return value. |
| 576 __ LeaveStubFrame(); | 576 __ LeaveStubFrame(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 587 __ LoadFromOffset(R6, TMP, kParamEndSlotFromFp * kWordSize); | 587 __ LoadFromOffset(R6, TMP, kParamEndSlotFromFp * kWordSize); |
| 588 | 588 |
| 589 // Preserve IC data and arguments descriptor. | 589 // Preserve IC data and arguments descriptor. |
| 590 __ Push(R5); | 590 __ Push(R5); |
| 591 __ Push(R4); | 591 __ Push(R4); |
| 592 | 592 |
| 593 // Push space for the return value. | 593 // Push space for the return value. |
| 594 // Push the receiver. | 594 // Push the receiver. |
| 595 // Push IC data object. | 595 // Push IC data object. |
| 596 // Push arguments descriptor array. | 596 // Push arguments descriptor array. |
| 597 __ PushObject(Object::null_object()); | 597 __ Push(ZR); |
| 598 __ Push(R6); | 598 __ Push(R6); |
| 599 __ Push(R5); | 599 __ Push(R5); |
| 600 __ Push(R4); | 600 __ Push(R4); |
| 601 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); | 601 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
| 602 // Remove arguments. | 602 // Remove arguments. |
| 603 __ Drop(3); | 603 __ Drop(3); |
| 604 __ Pop(R0); // Get result into R0 (target function). | 604 __ Pop(R0); // Get result into R0 (target function). |
| 605 | 605 |
| 606 // Restore IC data and arguments descriptor. | 606 // Restore IC data and arguments descriptor. |
| 607 __ Pop(R4); | 607 __ Pop(R4); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 749 __ ret(); | 749 __ ret(); |
| 750 | 750 |
| 751 // Unable to allocate the array using the fast inline code, just call | 751 // Unable to allocate the array using the fast inline code, just call |
| 752 // into the runtime. | 752 // into the runtime. |
| 753 __ Bind(&slow_case); | 753 __ Bind(&slow_case); |
| 754 // Create a stub frame as we are pushing some objects on the stack before | 754 // Create a stub frame as we are pushing some objects on the stack before |
| 755 // calling into the runtime. | 755 // calling into the runtime. |
| 756 __ EnterStubFrame(); | 756 __ EnterStubFrame(); |
| 757 // Setup space on stack for return value. | 757 // Setup space on stack for return value. |
| 758 // Push array length as Smi and element type. | 758 // Push array length as Smi and element type. |
| 759 __ PushObject(Object::null_object()); | 759 __ Push(ZR); |
| 760 __ Push(R2); | 760 __ Push(R2); |
| 761 __ Push(R1); | 761 __ Push(R1); |
| 762 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); | 762 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); |
| 763 // Pop arguments; result is popped in IP. | 763 // Pop arguments; result is popped in IP. |
| 764 __ Pop(R1); | 764 __ Pop(R1); |
| 765 __ Pop(R2); | 765 __ Pop(R2); |
| 766 __ Pop(R0); | 766 __ Pop(R0); |
| 767 __ LeaveStubFrame(); | 767 __ LeaveStubFrame(); |
| 768 __ ret(); | 768 __ ret(); |
| 769 } | 769 } |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1182 // R0: new object. | 1182 // R0: new object. |
| 1183 __ ret(); | 1183 __ ret(); |
| 1184 | 1184 |
| 1185 __ Bind(&slow_case); | 1185 __ Bind(&slow_case); |
| 1186 } | 1186 } |
| 1187 // If is_cls_parameterized: | 1187 // If is_cls_parameterized: |
| 1188 // R1: new object type arguments. | 1188 // R1: new object type arguments. |
| 1189 // Create a stub frame as we are pushing some objects on the stack before | 1189 // Create a stub frame as we are pushing some objects on the stack before |
| 1190 // calling into the runtime. | 1190 // calling into the runtime. |
| 1191 __ EnterStubFrame(); // Uses pool pointer to pass cls to runtime. | 1191 __ EnterStubFrame(); // Uses pool pointer to pass cls to runtime. |
| 1192 // Setup space on stack for return value. | 1192 __ Push(ZR); // Result slot. |
| 1193 __ PushObject(Object::null_object()); | |
| 1194 __ PushObject(cls); // Push class of object to be allocated. | 1193 __ PushObject(cls); // Push class of object to be allocated. |
| 1195 if (is_cls_parameterized) { | 1194 if (is_cls_parameterized) { |
| 1196 // Push type arguments. | 1195 // Push type arguments. |
| 1197 __ Push(R1); | 1196 __ Push(R1); |
| 1198 } else { | 1197 } else { |
| 1199 // Push null type arguments. | 1198 // Push null type arguments. |
| 1200 __ PushObject(Object::null_object()); | 1199 __ PushObject(Object::null_object()); |
| 1201 } | 1200 } |
| 1202 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object. | 1201 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object. |
| 1203 __ Drop(2); // Pop arguments. | 1202 __ Drop(2); // Pop arguments. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1220 __ EnterStubFrame(); | 1219 __ EnterStubFrame(); |
| 1221 | 1220 |
| 1222 // Load the receiver. | 1221 // Load the receiver. |
| 1223 __ LoadFieldFromOffset(R2, R4, ArgumentsDescriptor::count_offset()); | 1222 __ LoadFieldFromOffset(R2, R4, ArgumentsDescriptor::count_offset()); |
| 1224 __ add(TMP, FP, Operand(R2, LSL, 2)); // R2 is Smi. | 1223 __ add(TMP, FP, Operand(R2, LSL, 2)); // R2 is Smi. |
| 1225 __ LoadFromOffset(R6, TMP, kParamEndSlotFromFp * kWordSize); | 1224 __ LoadFromOffset(R6, TMP, kParamEndSlotFromFp * kWordSize); |
| 1226 | 1225 |
| 1227 // Push space for the return value. | 1226 // Push space for the return value. |
| 1228 // Push the receiver. | 1227 // Push the receiver. |
| 1229 // Push arguments descriptor array. | 1228 // Push arguments descriptor array. |
| 1230 __ PushObject(Object::null_object()); | 1229 __ Push(ZR); |
| 1231 __ Push(R6); | 1230 __ Push(R6); |
| 1232 __ Push(R4); | 1231 __ Push(R4); |
| 1233 | 1232 |
| 1234 // R2: Smi-tagged arguments array length. | 1233 // R2: Smi-tagged arguments array length. |
| 1235 PushArgumentsArray(assembler); | 1234 PushArgumentsArray(assembler); |
| 1236 | 1235 |
| 1237 const intptr_t kNumArgs = 3; | 1236 const intptr_t kNumArgs = 3; |
| 1238 __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs); | 1237 __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs); |
| 1239 // noSuchMethod on closures always throws an error, so it will never return. | 1238 // noSuchMethod on closures always throws an error, so it will never return. |
| 1240 __ brk(0); | 1239 __ brk(0); |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1475 __ add(R7, SP, Operand(R7, UXTX, 3)); // R7 is Untagged. | 1474 __ add(R7, SP, Operand(R7, UXTX, 3)); // R7 is Untagged. |
| 1476 // R7: address of receiver. | 1475 // R7: address of receiver. |
| 1477 // Create a stub frame as we are pushing some objects on the stack before | 1476 // Create a stub frame as we are pushing some objects on the stack before |
| 1478 // calling into the runtime. | 1477 // calling into the runtime. |
| 1479 __ EnterStubFrame(); | 1478 __ EnterStubFrame(); |
| 1480 // Preserve IC data object and arguments descriptor array and | 1479 // Preserve IC data object and arguments descriptor array and |
| 1481 // setup space on stack for result (target code object). | 1480 // setup space on stack for result (target code object). |
| 1482 __ Push(R4); // Preserve arguments descriptor array. | 1481 __ Push(R4); // Preserve arguments descriptor array. |
| 1483 __ Push(R5); // Preserve IC Data. | 1482 __ Push(R5); // Preserve IC Data. |
| 1484 // Setup space on stack for the result (target code object). | 1483 // Setup space on stack for the result (target code object). |
| 1485 __ PushObject(Object::null_object()); | 1484 __ Push(ZR); |
| 1486 // Push call arguments. | 1485 // Push call arguments. |
| 1487 for (intptr_t i = 0; i < num_args; i++) { | 1486 for (intptr_t i = 0; i < num_args; i++) { |
| 1488 __ LoadFromOffset(TMP, R7, -i * kWordSize); | 1487 __ LoadFromOffset(TMP, R7, -i * kWordSize); |
| 1489 __ Push(TMP); | 1488 __ Push(TMP); |
| 1490 } | 1489 } |
| 1491 // Pass IC data object. | 1490 // Pass IC data object. |
| 1492 __ Push(R5); | 1491 __ Push(R5); |
| 1493 __ CallRuntime(handle_ic_miss, num_args + 1); | 1492 __ CallRuntime(handle_ic_miss, num_args + 1); |
| 1494 // Remove the call arguments pushed earlier, including the IC data object. | 1493 // Remove the call arguments pushed earlier, including the IC data object. |
| 1495 __ Drop(num_args + 1); | 1494 __ Drop(num_args + 1); |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1706 __ LoadFieldFromOffset(CODE_REG, R0, Function::code_offset()); | 1705 __ LoadFieldFromOffset(CODE_REG, R0, Function::code_offset()); |
| 1707 __ LoadFieldFromOffset(R2, R0, Function::entry_point_offset()); | 1706 __ LoadFieldFromOffset(R2, R0, Function::entry_point_offset()); |
| 1708 __ br(R2); | 1707 __ br(R2); |
| 1709 } | 1708 } |
| 1710 | 1709 |
| 1711 | 1710 |
| 1712 // R5: Contains an ICData. | 1711 // R5: Contains an ICData. |
| 1713 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { | 1712 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { |
| 1714 __ EnterStubFrame(); | 1713 __ EnterStubFrame(); |
| 1715 __ Push(R5); | 1714 __ Push(R5); |
| 1716 __ PushObject(Object::null_object()); // Space for result. | 1715 __ Push(ZR); // Space for result. |
| 1717 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); | 1716 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); |
| 1718 __ Pop(CODE_REG); | 1717 __ Pop(CODE_REG); |
| 1719 __ Pop(R5); | 1718 __ Pop(R5); |
| 1720 __ LeaveStubFrame(); | 1719 __ LeaveStubFrame(); |
| 1721 __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset()); | 1720 __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset()); |
| 1722 __ br(R0); | 1721 __ br(R0); |
| 1723 } | 1722 } |
| 1724 | 1723 |
| 1725 | 1724 |
| 1726 void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) { | 1725 void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) { |
| 1727 __ EnterStubFrame(); | 1726 __ EnterStubFrame(); |
| 1728 __ PushObject(Object::null_object()); // Space for result. | 1727 __ Push(ZR); // Space for result. |
| 1729 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); | 1728 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); |
| 1730 __ Pop(CODE_REG); | 1729 __ Pop(CODE_REG); |
| 1731 __ LeaveStubFrame(); | 1730 __ LeaveStubFrame(); |
| 1732 __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset()); | 1731 __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset()); |
| 1733 __ br(R0); | 1732 __ br(R0); |
| 1734 } | 1733 } |
| 1735 | 1734 |
| 1736 // Called only from unoptimized code. All relevant registers have been saved. | 1735 // Called only from unoptimized code. All relevant registers have been saved. |
| 1737 void StubCode::GenerateDebugStepCheckStub( | 1736 void StubCode::GenerateDebugStepCheckStub( |
| 1738 Assembler* assembler) { | 1737 Assembler* assembler) { |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1899 } | 1898 } |
| 1900 | 1899 |
| 1901 | 1900 |
| 1902 // Calls to the runtime to optimize the given function. | 1901 // Calls to the runtime to optimize the given function. |
| 1903 // R6: function to be re-optimized. | 1902 // R6: function to be re-optimized. |
| 1904 // R4: argument descriptor (preserved). | 1903 // R4: argument descriptor (preserved). |
| 1905 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 1904 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
| 1906 __ EnterStubFrame(); | 1905 __ EnterStubFrame(); |
| 1907 __ Push(R4); | 1906 __ Push(R4); |
| 1908 // Setup space on stack for the return value. | 1907 // Setup space on stack for the return value. |
| 1909 __ PushObject(Object::null_object()); | 1908 __ Push(ZR); |
| 1910 __ Push(R6); | 1909 __ Push(R6); |
| 1911 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); | 1910 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); |
| 1912 __ Pop(R0); // Discard argument. | 1911 __ Pop(R0); // Discard argument. |
| 1913 __ Pop(CODE_REG); // Get Code object | 1912 __ Pop(CODE_REG); // Get Code object |
| 1914 __ Pop(R4); // Restore argument descriptor. | 1913 __ Pop(R4); // Restore argument descriptor. |
| 1915 __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset()); | 1914 __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset()); |
| 1916 __ LeaveStubFrame(); | 1915 __ LeaveStubFrame(); |
| 1917 __ br(R0); | 1916 __ br(R0); |
| 1918 __ brk(0); | 1917 __ brk(0); |
| 1919 } | 1918 } |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2185 | 2184 |
| 2186 // Called from switchable IC calls. | 2185 // Called from switchable IC calls. |
| 2187 // R0: receiver | 2186 // R0: receiver |
| 2188 // R5: SingleTargetCache | 2187 // R5: SingleTargetCache |
| 2189 void StubCode::GenerateUnlinkedCallStub(Assembler* assembler) { | 2188 void StubCode::GenerateUnlinkedCallStub(Assembler* assembler) { |
| 2190 __ NoMonomorphicCheckedEntry(); | 2189 __ NoMonomorphicCheckedEntry(); |
| 2191 | 2190 |
| 2192 __ EnterStubFrame(); | 2191 __ EnterStubFrame(); |
| 2193 __ Push(R0); // Preserve receiver. | 2192 __ Push(R0); // Preserve receiver. |
| 2194 | 2193 |
| 2195 __ PushObject(Object::null_object()); // Result. | 2194 __ Push(ZR); // Result slot. |
| 2196 __ Push(R0); // Arg0: Receiver | 2195 __ Push(R0); // Arg0: Receiver |
| 2197 __ Push(R5); // Arg1: UnlinkedCall | 2196 __ Push(R5); // Arg1: UnlinkedCall |
| 2198 __ CallRuntime(kUnlinkedCallRuntimeEntry, 2); | 2197 __ CallRuntime(kUnlinkedCallRuntimeEntry, 2); |
| 2199 __ Drop(2); | 2198 __ Drop(2); |
| 2200 __ Pop(R5); // result = IC | 2199 __ Pop(R5); // result = IC |
| 2201 | 2200 |
| 2202 __ Pop(R0); // Restore receiver. | 2201 __ Pop(R0); // Restore receiver. |
| 2203 __ LeaveStubFrame(); | 2202 __ LeaveStubFrame(); |
| 2204 | 2203 |
| 2205 __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); | 2204 __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); |
| 2206 __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); | 2205 __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); |
| 2207 __ br(R1); | 2206 __ br(R1); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2230 __ b(&miss, GT); | 2229 __ b(&miss, GT); |
| 2231 | 2230 |
| 2232 __ ldr(R1, FieldAddress(R5, SingleTargetCache::entry_point_offset())); | 2231 __ ldr(R1, FieldAddress(R5, SingleTargetCache::entry_point_offset())); |
| 2233 __ ldr(CODE_REG, FieldAddress(R5, SingleTargetCache::target_offset())); | 2232 __ ldr(CODE_REG, FieldAddress(R5, SingleTargetCache::target_offset())); |
| 2234 __ br(R1); | 2233 __ br(R1); |
| 2235 | 2234 |
| 2236 __ Bind(&miss); | 2235 __ Bind(&miss); |
| 2237 __ EnterStubFrame(); | 2236 __ EnterStubFrame(); |
| 2238 __ Push(R0); // Preserve receiver. | 2237 __ Push(R0); // Preserve receiver. |
| 2239 | 2238 |
| 2240 __ PushObject(Object::null_object()); // Result. | 2239 __ Push(ZR); // Result slot. |
| 2241 __ Push(R0); // Arg0: Receiver | 2240 __ Push(R0); // Arg0: Receiver |
| 2242 __ CallRuntime(kSingleTargetMissRuntimeEntry, 1); | 2241 __ CallRuntime(kSingleTargetMissRuntimeEntry, 1); |
| 2243 __ Drop(1); | 2242 __ Drop(1); |
| 2244 __ Pop(R5); // result = IC | 2243 __ Pop(R5); // result = IC |
| 2245 | 2244 |
| 2246 __ Pop(R0); // Restore receiver. | 2245 __ Pop(R0); // Restore receiver. |
| 2247 __ LeaveStubFrame(); | 2246 __ LeaveStubFrame(); |
| 2248 | 2247 |
| 2249 __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); | 2248 __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); |
| 2250 __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); | 2249 __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); |
| 2251 __ br(R1); | 2250 __ br(R1); |
| 2252 } | 2251 } |
| 2253 | 2252 |
| 2254 | 2253 |
| 2255 // Called from the monomorphic checked entry. | 2254 // Called from the monomorphic checked entry. |
| 2256 // R0: receiver | 2255 // R0: receiver |
| 2257 void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) { | 2256 void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) { |
| 2258 __ EnterStubFrame(); | 2257 __ EnterStubFrame(); |
| 2259 __ Push(R0); // Preserve receiver. | 2258 __ Push(R0); // Preserve receiver. |
| 2260 | 2259 |
| 2261 __ PushObject(Object::null_object()); // Result. | 2260 __ Push(ZR); // Result slot. |
| 2262 __ Push(R0); // Arg0: Receiver | 2261 __ Push(R0); // Arg0: Receiver |
| 2263 __ CallRuntime(kMonomorphicMissRuntimeEntry, 1); | 2262 __ CallRuntime(kMonomorphicMissRuntimeEntry, 1); |
| 2264 __ Drop(1); | 2263 __ Drop(1); |
| 2265 __ Pop(R5); // result = IC | 2264 __ Pop(R5); // result = IC |
| 2266 | 2265 |
| 2267 __ Pop(R0); // Restore receiver. | 2266 __ Pop(R0); // Restore receiver. |
| 2268 __ LeaveStubFrame(); | 2267 __ LeaveStubFrame(); |
| 2269 | 2268 |
| 2270 __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); | 2269 __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); |
| 2271 __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); | 2270 __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); |
| 2272 __ br(R1); | 2271 __ br(R1); |
| 2273 } | 2272 } |
| 2274 | 2273 |
| 2275 | 2274 |
| 2276 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { | 2275 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { |
| 2277 __ brk(0); | 2276 __ brk(0); |
| 2278 } | 2277 } |
| 2279 | 2278 |
| 2280 } // namespace dart | 2279 } // namespace dart |
| 2281 | 2280 |
| 2282 #endif // defined TARGET_ARCH_ARM64 | 2281 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |