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 |