OLD | NEW |
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_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 } | 118 } |
119 END_LEAF_RUNTIME_ENTRY | 119 END_LEAF_RUNTIME_ENTRY |
120 | 120 |
121 | 121 |
122 // Input parameters: | 122 // Input parameters: |
123 // A0 : stop message (const char*). | 123 // A0 : stop message (const char*). |
124 // Must preserve all registers. | 124 // Must preserve all registers. |
125 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { | 125 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { |
126 __ EnterCallRuntimeFrame(0); | 126 __ EnterCallRuntimeFrame(0); |
127 // Call the runtime leaf function. A0 already contains the parameter. | 127 // Call the runtime leaf function. A0 already contains the parameter. |
128 __ CallRuntime(kPrintStopMessageRuntimeEntry); | 128 __ CallRuntime(kPrintStopMessageRuntimeEntry, 1); |
129 __ LeaveCallRuntimeFrame(); | 129 __ LeaveCallRuntimeFrame(); |
130 __ Ret(); | 130 __ Ret(); |
131 } | 131 } |
132 | 132 |
133 | 133 |
134 // Input parameters: | 134 // Input parameters: |
135 // RA : return address. | 135 // RA : return address. |
136 // SP : address of return value. | 136 // SP : address of return value. |
137 // T5 : address of the native function to call. | 137 // T5 : address of the native function to call. |
138 // A2 : address of first argument in argument array. | 138 // A2 : address of first argument in argument array. |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 321 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
322 __ TraceSimMsg("CallStaticFunctionStub"); | 322 __ TraceSimMsg("CallStaticFunctionStub"); |
323 __ EnterStubFrame(); | 323 __ EnterStubFrame(); |
324 // Setup space on stack for return value and preserve arguments descriptor. | 324 // Setup space on stack for return value and preserve arguments descriptor. |
325 | 325 |
326 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 326 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
327 __ sw(S4, Address(SP, 1 * kWordSize)); | 327 __ sw(S4, Address(SP, 1 * kWordSize)); |
328 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 328 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
329 __ sw(TMP, Address(SP, 0 * kWordSize)); | 329 __ sw(TMP, Address(SP, 0 * kWordSize)); |
330 | 330 |
331 __ CallRuntime(kPatchStaticCallRuntimeEntry); | 331 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); |
332 __ TraceSimMsg("CallStaticFunctionStub return"); | 332 __ TraceSimMsg("CallStaticFunctionStub return"); |
333 | 333 |
334 // Get Code object result and restore arguments descriptor array. | 334 // Get Code object result and restore arguments descriptor array. |
335 __ lw(T0, Address(SP, 0 * kWordSize)); | 335 __ lw(T0, Address(SP, 0 * kWordSize)); |
336 __ lw(S4, Address(SP, 1 * kWordSize)); | 336 __ lw(S4, Address(SP, 1 * kWordSize)); |
337 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 337 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
338 | 338 |
339 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); | 339 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); |
340 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); | 340 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); |
341 | 341 |
342 // Remove the stub frame as we are about to jump to the dart function. | 342 // Remove the stub frame as we are about to jump to the dart function. |
343 __ LeaveStubFrameAndReturn(T0); | 343 __ LeaveStubFrameAndReturn(T0); |
344 } | 344 } |
345 | 345 |
346 | 346 |
347 // Called from a static call only when an invalid code has been entered | 347 // Called from a static call only when an invalid code has been entered |
348 // (invalid because its function was optimized or deoptimized). | 348 // (invalid because its function was optimized or deoptimized). |
349 // S4: arguments descriptor array. | 349 // S4: arguments descriptor array. |
350 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 350 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
351 // Create a stub frame as we are pushing some objects on the stack before | 351 // Create a stub frame as we are pushing some objects on the stack before |
352 // calling into the runtime. | 352 // calling into the runtime. |
353 __ TraceSimMsg("FixCallersTarget"); | 353 __ TraceSimMsg("FixCallersTarget"); |
354 __ EnterStubFrame(); | 354 __ EnterStubFrame(); |
355 // Setup space on stack for return value and preserve arguments descriptor. | 355 // Setup space on stack for return value and preserve arguments descriptor. |
356 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 356 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
357 __ sw(S4, Address(SP, 1 * kWordSize)); | 357 __ sw(S4, Address(SP, 1 * kWordSize)); |
358 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 358 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
359 __ sw(TMP, Address(SP, 0 * kWordSize)); | 359 __ sw(TMP, Address(SP, 0 * kWordSize)); |
360 __ CallRuntime(kFixCallersTargetRuntimeEntry); | 360 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); |
361 // Get Code object result and restore arguments descriptor array. | 361 // Get Code object result and restore arguments descriptor array. |
362 __ lw(T0, Address(SP, 0 * kWordSize)); | 362 __ lw(T0, Address(SP, 0 * kWordSize)); |
363 __ lw(S4, Address(SP, 1 * kWordSize)); | 363 __ lw(S4, Address(SP, 1 * kWordSize)); |
364 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 364 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
365 | 365 |
366 // Jump to the dart function. | 366 // Jump to the dart function. |
367 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); | 367 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); |
368 __ AddImmediate(T0, T0, Instructions::HeaderSize() - kHeapObjectTag); | 368 __ AddImmediate(T0, T0, Instructions::HeaderSize() - kHeapObjectTag); |
369 | 369 |
370 // Remove the stub frame. | 370 // Remove the stub frame. |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 431 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
432 __ sw(TMP, Address(SP, 3 * kWordSize)); | 432 __ sw(TMP, Address(SP, 3 * kWordSize)); |
433 __ sw(T1, Address(SP, 2 * kWordSize)); | 433 __ sw(T1, Address(SP, 2 * kWordSize)); |
434 __ sw(S5, Address(SP, 1 * kWordSize)); | 434 __ sw(S5, Address(SP, 1 * kWordSize)); |
435 __ sw(S4, Address(SP, 0 * kWordSize)); | 435 __ sw(S4, Address(SP, 0 * kWordSize)); |
436 | 436 |
437 // A1: Smi-tagged arguments array length. | 437 // A1: Smi-tagged arguments array length. |
438 PushArgumentsArray(assembler); | 438 PushArgumentsArray(assembler); |
439 __ TraceSimMsg("InstanceFunctionLookupStub return"); | 439 __ TraceSimMsg("InstanceFunctionLookupStub return"); |
440 | 440 |
441 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry); | 441 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry, 4); |
442 | 442 |
443 __ lw(V0, Address(SP, 4 * kWordSize)); // Get result into V0. | 443 __ lw(V0, Address(SP, 4 * kWordSize)); // Get result into V0. |
444 __ addiu(SP, SP, Immediate(5 * kWordSize)); // Remove arguments. | 444 __ addiu(SP, SP, Immediate(5 * kWordSize)); // Remove arguments. |
445 | 445 |
446 __ LeaveStubFrameAndReturn(); | 446 __ LeaveStubFrameAndReturn(); |
447 } | 447 } |
448 | 448 |
449 | 449 |
450 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, | 450 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, |
451 intptr_t deopt_reason, | 451 intptr_t deopt_reason, |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 } | 514 } |
515 for (int i = 0; i < kNumberOfFRegisters; i++) { | 515 for (int i = 0; i < kNumberOfFRegisters; i++) { |
516 // These go below the CPU registers. | 516 // These go below the CPU registers. |
517 const int slot = 4 + kNumberOfCpuRegisters + kNumberOfFRegisters - i; | 517 const int slot = 4 + kNumberOfCpuRegisters + kNumberOfFRegisters - i; |
518 FRegister reg = static_cast<FRegister>(i); | 518 FRegister reg = static_cast<FRegister>(i); |
519 __ swc1(reg, Address(SP, kPushedRegistersSize - slot * kWordSize)); | 519 __ swc1(reg, Address(SP, kPushedRegistersSize - slot * kWordSize)); |
520 } | 520 } |
521 | 521 |
522 __ mov(A0, SP); // Pass address of saved registers block. | 522 __ mov(A0, SP); // Pass address of saved registers block. |
523 __ ReserveAlignedFrameSpace(1 * kWordSize); | 523 __ ReserveAlignedFrameSpace(1 * kWordSize); |
524 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry); | 524 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 1); |
525 // Result (V0) is stack-size (FP - SP) in bytes, incl. the return address. | 525 // Result (V0) is stack-size (FP - SP) in bytes, incl. the return address. |
526 | 526 |
527 if (preserve_result) { | 527 if (preserve_result) { |
528 // Restore result into T1 temporarily. | 528 // Restore result into T1 temporarily. |
529 __ lw(T1, Address(FP, saved_result_slot_from_fp * kWordSize)); | 529 __ lw(T1, Address(FP, saved_result_slot_from_fp * kWordSize)); |
530 } | 530 } |
531 | 531 |
532 __ addiu(SP, FP, Immediate(-kWordSize)); | 532 __ addiu(SP, FP, Immediate(-kWordSize)); |
533 __ lw(RA, Address(SP, 2 * kWordSize)); | 533 __ lw(RA, Address(SP, 2 * kWordSize)); |
534 __ lw(FP, Address(SP, 1 * kWordSize)); | 534 __ lw(FP, Address(SP, 1 * kWordSize)); |
535 __ lw(PP, Address(SP, 0 * kWordSize)); | 535 __ lw(PP, Address(SP, 0 * kWordSize)); |
536 __ subu(SP, FP, V0); | 536 __ subu(SP, FP, V0); |
537 | 537 |
538 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there | 538 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there |
539 // is no need to set the correct PC marker or load PP, since they get patched. | 539 // is no need to set the correct PC marker or load PP, since they get patched. |
540 __ addiu(SP, SP, Immediate(-4 * kWordSize)); | 540 __ addiu(SP, SP, Immediate(-4 * kWordSize)); |
541 __ sw(ZR, Address(SP, 3 * kWordSize)); | 541 __ sw(ZR, Address(SP, 3 * kWordSize)); |
542 __ sw(RA, Address(SP, 2 * kWordSize)); | 542 __ sw(RA, Address(SP, 2 * kWordSize)); |
543 __ sw(FP, Address(SP, 1 * kWordSize)); | 543 __ sw(FP, Address(SP, 1 * kWordSize)); |
544 __ sw(PP, Address(SP, 0 * kWordSize)); | 544 __ sw(PP, Address(SP, 0 * kWordSize)); |
545 __ addiu(FP, SP, Immediate(kWordSize)); | 545 __ addiu(FP, SP, Immediate(kWordSize)); |
546 | 546 |
547 __ mov(A0, FP); // Get last FP address. | 547 __ mov(A0, FP); // Get last FP address. |
548 if (preserve_result) { | 548 if (preserve_result) { |
549 __ Push(T1); // Preserve result as first local. | 549 __ Push(T1); // Preserve result as first local. |
550 } | 550 } |
551 __ ReserveAlignedFrameSpace(1 * kWordSize); | 551 __ ReserveAlignedFrameSpace(1 * kWordSize); |
552 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); // Pass last FP in A0. | 552 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1); // Pass last FP in A0. |
553 if (preserve_result) { | 553 if (preserve_result) { |
554 // Restore result into T1. | 554 // Restore result into T1. |
555 __ lw(T1, Address(FP, kFirstLocalSlotFromFp * kWordSize)); | 555 __ lw(T1, Address(FP, kFirstLocalSlotFromFp * kWordSize)); |
556 } | 556 } |
557 // Code above cannot cause GC. | 557 // Code above cannot cause GC. |
558 __ addiu(SP, FP, Immediate(-kWordSize)); | 558 __ addiu(SP, FP, Immediate(-kWordSize)); |
559 __ lw(RA, Address(SP, 2 * kWordSize)); | 559 __ lw(RA, Address(SP, 2 * kWordSize)); |
560 __ lw(FP, Address(SP, 1 * kWordSize)); | 560 __ lw(FP, Address(SP, 1 * kWordSize)); |
561 __ lw(PP, Address(SP, 0 * kWordSize)); | 561 __ lw(PP, Address(SP, 0 * kWordSize)); |
562 __ addiu(SP, SP, Immediate(4 * kWordSize)); | 562 __ addiu(SP, SP, Immediate(4 * kWordSize)); |
563 | 563 |
564 // Frame is fully rewritten at this point and it is safe to perform a GC. | 564 // Frame is fully rewritten at this point and it is safe to perform a GC. |
565 // Materialize any objects that were deferred by FillFrame because they | 565 // Materialize any objects that were deferred by FillFrame because they |
566 // require allocation. | 566 // require allocation. |
567 __ EnterStubFrame(); | 567 __ EnterStubFrame(); |
568 if (preserve_result) { | 568 if (preserve_result) { |
569 __ Push(T1); // Preserve result, it will be GC-d here. | 569 __ Push(T1); // Preserve result, it will be GC-d here. |
570 } | 570 } |
571 __ PushObject(Smi::ZoneHandle()); // Space for the result. | 571 __ PushObject(Smi::ZoneHandle()); // Space for the result. |
572 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry); | 572 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0); |
573 // Result tells stub how many bytes to remove from the expression stack | 573 // Result tells stub how many bytes to remove from the expression stack |
574 // of the bottom-most frame. They were used as materialization arguments. | 574 // of the bottom-most frame. They were used as materialization arguments. |
575 __ Pop(T1); | 575 __ Pop(T1); |
576 if (preserve_result) { | 576 if (preserve_result) { |
577 __ Pop(V0); // Restore result. | 577 __ Pop(V0); // Restore result. |
578 } | 578 } |
579 __ LeaveStubFrame(); | 579 __ LeaveStubFrame(); |
580 // Remove materialization arguments. | 580 // Remove materialization arguments. |
581 __ SmiUntag(T1); | 581 __ SmiUntag(T1); |
582 __ addu(SP, SP, T1); | 582 __ addu(SP, SP, T1); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 // Push space for the return value. | 614 // Push space for the return value. |
615 // Push the receiver. | 615 // Push the receiver. |
616 // Push IC data object. | 616 // Push IC data object. |
617 // Push arguments descriptor array. | 617 // Push arguments descriptor array. |
618 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 618 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
619 __ sw(TMP, Address(SP, 3 * kWordSize)); | 619 __ sw(TMP, Address(SP, 3 * kWordSize)); |
620 __ sw(T6, Address(SP, 2 * kWordSize)); | 620 __ sw(T6, Address(SP, 2 * kWordSize)); |
621 __ sw(S5, Address(SP, 1 * kWordSize)); | 621 __ sw(S5, Address(SP, 1 * kWordSize)); |
622 __ sw(S4, Address(SP, 0 * kWordSize)); | 622 __ sw(S4, Address(SP, 0 * kWordSize)); |
623 | 623 |
624 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry); | 624 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
625 | 625 |
626 __ lw(T0, Address(SP, 3 * kWordSize)); // Get result. | 626 __ lw(T0, Address(SP, 3 * kWordSize)); // Get result. |
627 __ lw(S4, Address(SP, 4 * kWordSize)); // Restore argument descriptor. | 627 __ lw(S4, Address(SP, 4 * kWordSize)); // Restore argument descriptor. |
628 __ lw(S5, Address(SP, 5 * kWordSize)); // Restore IC data. | 628 __ lw(S5, Address(SP, 5 * kWordSize)); // Restore IC data. |
629 __ addiu(SP, SP, Immediate(6 * kWordSize)); | 629 __ addiu(SP, SP, Immediate(6 * kWordSize)); |
630 | 630 |
631 __ LeaveStubFrame(); | 631 __ LeaveStubFrame(); |
632 | 632 |
633 Label nonnull; | 633 Label nonnull; |
634 __ BranchNotEqual(T0, reinterpret_cast<int32_t>(Object::null()), &nonnull); | 634 __ BranchNotEqual(T0, reinterpret_cast<int32_t>(Object::null()), &nonnull); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 // Create a stub frame as we are pushing some objects on the stack before | 761 // Create a stub frame as we are pushing some objects on the stack before |
762 // calling into the runtime. | 762 // calling into the runtime. |
763 __ EnterStubFrame(); | 763 __ EnterStubFrame(); |
764 // Setup space on stack for return value. | 764 // Setup space on stack for return value. |
765 // Push array length as Smi and element type. | 765 // Push array length as Smi and element type. |
766 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 766 __ addiu(SP, SP, Immediate(-3 * kWordSize)); |
767 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 767 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
768 __ sw(TMP, Address(SP, 2 * kWordSize)); | 768 __ sw(TMP, Address(SP, 2 * kWordSize)); |
769 __ sw(A1, Address(SP, 1 * kWordSize)); | 769 __ sw(A1, Address(SP, 1 * kWordSize)); |
770 __ sw(A0, Address(SP, 0 * kWordSize)); | 770 __ sw(A0, Address(SP, 0 * kWordSize)); |
771 __ CallRuntime(kAllocateArrayRuntimeEntry); | 771 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); |
772 __ TraceSimMsg("AllocateArrayStub return"); | 772 __ TraceSimMsg("AllocateArrayStub return"); |
773 // Pop arguments; result is popped in IP. | 773 // Pop arguments; result is popped in IP. |
774 __ lw(V0, Address(SP, 2 * kWordSize)); | 774 __ lw(V0, Address(SP, 2 * kWordSize)); |
775 __ lw(A1, Address(SP, 1 * kWordSize)); | 775 __ lw(A1, Address(SP, 1 * kWordSize)); |
776 __ lw(A0, Address(SP, 0 * kWordSize)); | 776 __ lw(A0, Address(SP, 0 * kWordSize)); |
777 __ addiu(SP, SP, Immediate(3 * kWordSize)); | 777 __ addiu(SP, SP, Immediate(3 * kWordSize)); |
778 | 778 |
779 __ LeaveStubFrameAndReturn(); | 779 __ LeaveStubFrameAndReturn(); |
780 } | 780 } |
781 | 781 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
831 __ bne(T0, T7, &function_compiled); | 831 __ bne(T0, T7, &function_compiled); |
832 | 832 |
833 // Create a stub frame as we are pushing some objects on the stack before | 833 // Create a stub frame as we are pushing some objects on the stack before |
834 // calling into the runtime. | 834 // calling into the runtime. |
835 __ EnterStubFrame(); | 835 __ EnterStubFrame(); |
836 | 836 |
837 // Preserve arguments descriptor array and read-only function object argument. | 837 // Preserve arguments descriptor array and read-only function object argument. |
838 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 838 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
839 __ sw(S4, Address(SP, 1 * kWordSize)); | 839 __ sw(S4, Address(SP, 1 * kWordSize)); |
840 __ sw(T2, Address(SP, 0 * kWordSize)); | 840 __ sw(T2, Address(SP, 0 * kWordSize)); |
841 __ CallRuntime(kCompileFunctionRuntimeEntry); | 841 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
842 __ TraceSimMsg("GenerateCallClosureFunctionStub return"); | 842 __ TraceSimMsg("GenerateCallClosureFunctionStub return"); |
843 // Restore arguments descriptor array and read-only function object argument. | 843 // Restore arguments descriptor array and read-only function object argument. |
844 __ lw(T2, Address(SP, 0 * kWordSize)); | 844 __ lw(T2, Address(SP, 0 * kWordSize)); |
845 __ lw(S4, Address(SP, 1 * kWordSize)); | 845 __ lw(S4, Address(SP, 1 * kWordSize)); |
846 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 846 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
847 // Restore T0. | 847 // Restore T0. |
848 __ lw(T0, FieldAddress(T2, Function::code_offset())); | 848 __ lw(T0, FieldAddress(T2, Function::code_offset())); |
849 | 849 |
850 // Remove the stub frame as we are about to jump to the closure function. | 850 // Remove the stub frame as we are about to jump to the closure function. |
851 __ LeaveStubFrame(); | 851 __ LeaveStubFrame(); |
(...skipping 29 matching lines...) Expand all Loading... |
881 | 881 |
882 // Stack: | 882 // Stack: |
883 // TOS + 0: Argument array. | 883 // TOS + 0: Argument array. |
884 // TOS + 1: Arguments descriptor array. | 884 // TOS + 1: Arguments descriptor array. |
885 // TOS + 2: Place for result from the call. | 885 // TOS + 2: Place for result from the call. |
886 // TOS + 3: Saved FP of previous frame. | 886 // TOS + 3: Saved FP of previous frame. |
887 // TOS + 4: Dart code return address. | 887 // TOS + 4: Dart code return address. |
888 // TOS + 5: PC marker (0 for stub). | 888 // TOS + 5: PC marker (0 for stub). |
889 // TOS + 6: Last argument of caller. | 889 // TOS + 6: Last argument of caller. |
890 // .... | 890 // .... |
891 __ CallRuntime(kInvokeNonClosureRuntimeEntry); | 891 __ CallRuntime(kInvokeNonClosureRuntimeEntry, 2); |
892 __ lw(V0, Address(SP, 2 * kWordSize)); // Get result into V0. | 892 __ lw(V0, Address(SP, 2 * kWordSize)); // Get result into V0. |
893 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Remove arguments. | 893 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Remove arguments. |
894 | 894 |
895 // Remove the stub frame as we are about to return. | 895 // Remove the stub frame as we are about to return. |
896 __ LeaveStubFrameAndReturn(); | 896 __ LeaveStubFrameAndReturn(); |
897 } | 897 } |
898 | 898 |
899 | 899 |
900 // Called when invoking Dart code from C++ (VM code). | 900 // Called when invoking Dart code from C++ (VM code). |
901 // Input parameters: | 901 // Input parameters: |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1122 } | 1122 } |
1123 // Create a stub frame as we are pushing some objects on the stack before | 1123 // Create a stub frame as we are pushing some objects on the stack before |
1124 // calling into the runtime. | 1124 // calling into the runtime. |
1125 __ EnterStubFrame(); | 1125 __ EnterStubFrame(); |
1126 // Setup space on stack for return value. | 1126 // Setup space on stack for return value. |
1127 __ SmiTag(T1); | 1127 __ SmiTag(T1); |
1128 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 1128 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
1129 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 1129 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
1130 __ sw(TMP, Address(SP, 1 * kWordSize)); // Store null. | 1130 __ sw(TMP, Address(SP, 1 * kWordSize)); // Store null. |
1131 __ sw(T1, Address(SP, 0 * kWordSize)); | 1131 __ sw(T1, Address(SP, 0 * kWordSize)); |
1132 __ CallRuntime(kAllocateContextRuntimeEntry); // Allocate context. | 1132 __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context. |
1133 __ lw(V0, Address(SP, 1 * kWordSize)); // Get the new context. | 1133 __ lw(V0, Address(SP, 1 * kWordSize)); // Get the new context. |
1134 __ addiu(SP, SP, Immediate(2 * kWordSize)); // Pop argument and return. | 1134 __ addiu(SP, SP, Immediate(2 * kWordSize)); // Pop argument and return. |
1135 | 1135 |
1136 // V0: new object | 1136 // V0: new object |
1137 // Restore the frame pointer. | 1137 // Restore the frame pointer. |
1138 __ LeaveStubFrameAndReturn(); | 1138 __ LeaveStubFrameAndReturn(); |
1139 } | 1139 } |
1140 | 1140 |
1141 | 1141 |
1142 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate); | 1142 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1199 __ beq(CMPRES, ZR, &L); | 1199 __ beq(CMPRES, ZR, &L); |
1200 __ delay_slot()->addiu(SP, SP, Immediate(3 * kWordSize)); | 1200 __ delay_slot()->addiu(SP, SP, Immediate(3 * kWordSize)); |
1201 __ Ret(); | 1201 __ Ret(); |
1202 | 1202 |
1203 // Handle overflow: Call the runtime leaf function. | 1203 // Handle overflow: Call the runtime leaf function. |
1204 __ Bind(&L); | 1204 __ Bind(&L); |
1205 // Setup frame, push callee-saved registers. | 1205 // Setup frame, push callee-saved registers. |
1206 | 1206 |
1207 __ EnterCallRuntimeFrame(1 * kWordSize); | 1207 __ EnterCallRuntimeFrame(1 * kWordSize); |
1208 __ lw(A0, FieldAddress(CTX, Context::isolate_offset())); | 1208 __ lw(A0, FieldAddress(CTX, Context::isolate_offset())); |
1209 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry); | 1209 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); |
1210 __ TraceSimMsg("UpdateStoreBufferStub return"); | 1210 __ TraceSimMsg("UpdateStoreBufferStub return"); |
1211 // Restore callee-saved registers, tear down frame. | 1211 // Restore callee-saved registers, tear down frame. |
1212 __ LeaveCallRuntimeFrame(); | 1212 __ LeaveCallRuntimeFrame(); |
1213 __ Ret(); | 1213 __ Ret(); |
1214 } | 1214 } |
1215 | 1215 |
1216 | 1216 |
1217 // Called for inline allocation of objects. | 1217 // Called for inline allocation of objects. |
1218 // Input parameters: | 1218 // Input parameters: |
1219 // RA : return address. | 1219 // RA : return address. |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1372 if (is_cls_parameterized) { | 1372 if (is_cls_parameterized) { |
1373 // Push type arguments of object to be allocated and of instantiator. | 1373 // Push type arguments of object to be allocated and of instantiator. |
1374 __ sw(T1, Address(SP, 1 * kWordSize)); | 1374 __ sw(T1, Address(SP, 1 * kWordSize)); |
1375 __ sw(T0, Address(SP, 0 * kWordSize)); | 1375 __ sw(T0, Address(SP, 0 * kWordSize)); |
1376 } else { | 1376 } else { |
1377 // Push null type arguments and kNoInstantiator. | 1377 // Push null type arguments and kNoInstantiator. |
1378 __ LoadImmediate(T1, Smi::RawValue(StubCode::kNoInstantiator)); | 1378 __ LoadImmediate(T1, Smi::RawValue(StubCode::kNoInstantiator)); |
1379 __ sw(T7, Address(SP, 1 * kWordSize)); | 1379 __ sw(T7, Address(SP, 1 * kWordSize)); |
1380 __ sw(T1, Address(SP, 0 * kWordSize)); | 1380 __ sw(T1, Address(SP, 0 * kWordSize)); |
1381 } | 1381 } |
1382 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object. | 1382 __ CallRuntime(kAllocateObjectRuntimeEntry, 3); // Allocate object. |
1383 __ TraceSimMsg("AllocationStubForClass return"); | 1383 __ TraceSimMsg("AllocationStubForClass return"); |
1384 // Pop result (newly allocated object). | 1384 // Pop result (newly allocated object). |
1385 __ lw(V0, Address(SP, 3 * kWordSize)); | 1385 __ lw(V0, Address(SP, 3 * kWordSize)); |
1386 __ addiu(SP, SP, Immediate(4 * kWordSize)); // Pop arguments. | 1386 __ addiu(SP, SP, Immediate(4 * kWordSize)); // Pop arguments. |
1387 // V0: new object | 1387 // V0: new object |
1388 // Restore the frame pointer and return. | 1388 // Restore the frame pointer and return. |
1389 __ LeaveStubFrameAndReturn(RA, true); | 1389 __ LeaveStubFrameAndReturn(RA, true); |
1390 } | 1390 } |
1391 | 1391 |
1392 | 1392 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1511 if (is_implicit_instance_closure) { | 1511 if (is_implicit_instance_closure) { |
1512 __ lw(T1, Address(FP, kReceiverFPOffset)); | 1512 __ lw(T1, Address(FP, kReceiverFPOffset)); |
1513 __ sw(T1, Address(SP, (num_slots - 3) * kWordSize)); // Receiver. | 1513 __ sw(T1, Address(SP, (num_slots - 3) * kWordSize)); // Receiver. |
1514 } | 1514 } |
1515 if (has_type_arguments) { | 1515 if (has_type_arguments) { |
1516 __ lw(T2, Address(FP, kTypeArgumentsFPOffset)); | 1516 __ lw(T2, Address(FP, kTypeArgumentsFPOffset)); |
1517 } | 1517 } |
1518 __ sw(T2, Address(SP, 0 * kWordSize)); | 1518 __ sw(T2, Address(SP, 0 * kWordSize)); |
1519 | 1519 |
1520 if (is_implicit_instance_closure) { | 1520 if (is_implicit_instance_closure) { |
1521 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry); | 1521 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry, 3); |
1522 __ TraceSimMsg("AllocationStubForClosure return"); | 1522 __ TraceSimMsg("AllocationStubForClosure return"); |
1523 } else { | 1523 } else { |
1524 ASSERT(func.IsNonImplicitClosureFunction()); | 1524 ASSERT(func.IsNonImplicitClosureFunction()); |
1525 __ CallRuntime(kAllocateClosureRuntimeEntry); | 1525 __ CallRuntime(kAllocateClosureRuntimeEntry, 2); |
1526 __ TraceSimMsg("AllocationStubForClosure return"); | 1526 __ TraceSimMsg("AllocationStubForClosure return"); |
1527 } | 1527 } |
1528 __ lw(V0, Address(SP, (num_slots - 1) * kWordSize)); // Pop function object. | 1528 __ lw(V0, Address(SP, (num_slots - 1) * kWordSize)); // Pop function object. |
1529 __ addiu(SP, SP, Immediate(num_slots * kWordSize)); | 1529 __ addiu(SP, SP, Immediate(num_slots * kWordSize)); |
1530 | 1530 |
1531 // V0: new object | 1531 // V0: new object |
1532 // Restore the frame pointer. | 1532 // Restore the frame pointer. |
1533 __ LeaveStubFrameAndReturn(RA, true); | 1533 __ LeaveStubFrameAndReturn(RA, true); |
1534 } | 1534 } |
1535 | 1535 |
(...skipping 22 matching lines...) Expand all Loading... |
1558 __ addiu(SP, SP, Immediate(-4 * kWordSize)); | 1558 __ addiu(SP, SP, Immediate(-4 * kWordSize)); |
1559 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 1559 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
1560 __ sw(TMP, Address(SP, 3 * kWordSize)); | 1560 __ sw(TMP, Address(SP, 3 * kWordSize)); |
1561 __ sw(T6, Address(SP, 2 * kWordSize)); | 1561 __ sw(T6, Address(SP, 2 * kWordSize)); |
1562 __ sw(S5, Address(SP, 1 * kWordSize)); | 1562 __ sw(S5, Address(SP, 1 * kWordSize)); |
1563 __ sw(S4, Address(SP, 0 * kWordSize)); | 1563 __ sw(S4, Address(SP, 0 * kWordSize)); |
1564 | 1564 |
1565 // A1: Smi-tagged arguments array length. | 1565 // A1: Smi-tagged arguments array length. |
1566 PushArgumentsArray(assembler); | 1566 PushArgumentsArray(assembler); |
1567 | 1567 |
1568 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry); | 1568 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry, 4); |
1569 | 1569 |
1570 __ lw(V0, Address(SP, 4 * kWordSize)); // Get result into V0. | 1570 __ lw(V0, Address(SP, 4 * kWordSize)); // Get result into V0. |
1571 __ LeaveStubFrameAndReturn(); | 1571 __ LeaveStubFrameAndReturn(); |
1572 } | 1572 } |
1573 | 1573 |
1574 | 1574 |
1575 // T0: function object. | 1575 // T0: function object. |
1576 // S5: inline cache data object. | 1576 // S5: inline cache data object. |
1577 // Cannot use function object from ICData as it may be the inlined | 1577 // Cannot use function object from ICData as it may be the inlined |
1578 // function and not the top-scope function. | 1578 // function and not the top-scope function. |
1579 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { | 1579 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { |
1580 __ TraceSimMsg("OptimizedUsageCounterIncrement"); | 1580 __ TraceSimMsg("OptimizedUsageCounterIncrement"); |
1581 Register ic_reg = S5; | 1581 Register ic_reg = S5; |
1582 Register func_reg = T0; | 1582 Register func_reg = T0; |
1583 if (FLAG_trace_optimized_ic_calls) { | 1583 if (FLAG_trace_optimized_ic_calls) { |
1584 __ EnterStubFrame(); | 1584 __ EnterStubFrame(); |
1585 __ addiu(SP, SP, Immediate(-4 * kWordSize)); | 1585 __ addiu(SP, SP, Immediate(-4 * kWordSize)); |
1586 __ sw(T0, Address(SP, 3 * kWordSize)); | 1586 __ sw(T0, Address(SP, 3 * kWordSize)); |
1587 __ sw(S5, Address(SP, 2 * kWordSize)); | 1587 __ sw(S5, Address(SP, 2 * kWordSize)); |
1588 __ sw(ic_reg, Address(SP, 1 * kWordSize)); // Argument. | 1588 __ sw(ic_reg, Address(SP, 1 * kWordSize)); // Argument. |
1589 __ sw(func_reg, Address(SP, 0 * kWordSize)); // Argument. | 1589 __ sw(func_reg, Address(SP, 0 * kWordSize)); // Argument. |
1590 __ CallRuntime(kTraceICCallRuntimeEntry); | 1590 __ CallRuntime(kTraceICCallRuntimeEntry, 2); |
1591 __ lw(S5, Address(SP, 2 * kWordSize)); | 1591 __ lw(S5, Address(SP, 2 * kWordSize)); |
1592 __ lw(T0, Address(SP, 3 * kWordSize)); | 1592 __ lw(T0, Address(SP, 3 * kWordSize)); |
1593 __ addiu(SP, SP, Immediate(4 * kWordSize)); // Discard argument; | 1593 __ addiu(SP, SP, Immediate(4 * kWordSize)); // Discard argument; |
1594 __ LeaveStubFrame(); | 1594 __ LeaveStubFrame(); |
1595 } | 1595 } |
1596 __ lw(T7, FieldAddress(func_reg, Function::usage_counter_offset())); | 1596 __ lw(T7, FieldAddress(func_reg, Function::usage_counter_offset())); |
1597 __ addiu(T7, T7, Immediate(1)); | 1597 __ addiu(T7, T7, Immediate(1)); |
1598 __ sw(T7, FieldAddress(func_reg, Function::usage_counter_offset())); | 1598 __ sw(T7, FieldAddress(func_reg, Function::usage_counter_offset())); |
1599 } | 1599 } |
1600 | 1600 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1643 | 1643 |
1644 // Check single stepping. | 1644 // Check single stepping. |
1645 Label not_stepping; | 1645 Label not_stepping; |
1646 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); | 1646 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); |
1647 __ lbu(T0, Address(T0, Isolate::single_step_offset())); | 1647 __ lbu(T0, Address(T0, Isolate::single_step_offset())); |
1648 __ BranchEqual(T0, 0, ¬_stepping); | 1648 __ BranchEqual(T0, 0, ¬_stepping); |
1649 // Call single step callback in debugger. | 1649 // Call single step callback in debugger. |
1650 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 1650 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
1651 __ sw(S5, Address(SP, 1 * kWordSize)); // Preserve IC data. | 1651 __ sw(S5, Address(SP, 1 * kWordSize)); // Preserve IC data. |
1652 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address. | 1652 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address. |
1653 __ CallRuntime(kSingleStepHandlerRuntimeEntry); | 1653 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
1654 __ lw(RA, Address(SP, 0 * kWordSize)); | 1654 __ lw(RA, Address(SP, 0 * kWordSize)); |
1655 __ lw(S5, Address(SP, 1 * kWordSize)); | 1655 __ lw(S5, Address(SP, 1 * kWordSize)); |
1656 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 1656 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
1657 __ Bind(¬_stepping); | 1657 __ Bind(¬_stepping); |
1658 | 1658 |
1659 // Load argument descriptor into S4. | 1659 // Load argument descriptor into S4. |
1660 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset())); | 1660 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset())); |
1661 // Preserve return address, since RA is needed for subroutine call. | 1661 // Preserve return address, since RA is needed for subroutine call. |
1662 __ mov(T2, RA); | 1662 __ mov(T2, RA); |
1663 // Loop that checks if there is an IC data match. | 1663 // Loop that checks if there is an IC data match. |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1744 __ sw(S4, Address(SP, (num_slots - 2) * kWordSize)); | 1744 __ sw(S4, Address(SP, (num_slots - 2) * kWordSize)); |
1745 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 1745 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
1746 __ sw(TMP, Address(SP, (num_slots - 3) * kWordSize)); | 1746 __ sw(TMP, Address(SP, (num_slots - 3) * kWordSize)); |
1747 // Push call arguments. | 1747 // Push call arguments. |
1748 for (intptr_t i = 0; i < num_args; i++) { | 1748 for (intptr_t i = 0; i < num_args; i++) { |
1749 __ lw(TMP1, Address(T1, -i * kWordSize)); | 1749 __ lw(TMP1, Address(T1, -i * kWordSize)); |
1750 __ sw(TMP1, Address(SP, (num_slots - i - 4) * kWordSize)); | 1750 __ sw(TMP1, Address(SP, (num_slots - i - 4) * kWordSize)); |
1751 } | 1751 } |
1752 // Pass IC data object. | 1752 // Pass IC data object. |
1753 __ sw(S5, Address(SP, (num_slots - num_args - 4) * kWordSize)); | 1753 __ sw(S5, Address(SP, (num_slots - num_args - 4) * kWordSize)); |
1754 __ CallRuntime(handle_ic_miss); | 1754 __ CallRuntime(handle_ic_miss, num_args + 1); |
1755 __ TraceSimMsg("NArgsCheckInlineCacheStub return"); | 1755 __ TraceSimMsg("NArgsCheckInlineCacheStub return"); |
1756 // Pop returned code object into T3 (null if not found). | 1756 // Pop returned code object into T3 (null if not found). |
1757 // Restore arguments descriptor array and IC data array. | 1757 // Restore arguments descriptor array and IC data array. |
1758 __ lw(T3, Address(SP, (num_slots - 3) * kWordSize)); | 1758 __ lw(T3, Address(SP, (num_slots - 3) * kWordSize)); |
1759 __ lw(S4, Address(SP, (num_slots - 2) * kWordSize)); | 1759 __ lw(S4, Address(SP, (num_slots - 2) * kWordSize)); |
1760 __ lw(S5, Address(SP, (num_slots - 1) * kWordSize)); | 1760 __ lw(S5, Address(SP, (num_slots - 1) * kWordSize)); |
1761 // Remove the call arguments pushed earlier, including the IC data object | 1761 // Remove the call arguments pushed earlier, including the IC data object |
1762 // and the arguments descriptor array. | 1762 // and the arguments descriptor array. |
1763 __ addiu(SP, SP, Immediate(num_slots * kWordSize)); | 1763 __ addiu(SP, SP, Immediate(num_slots * kWordSize)); |
1764 __ LeaveStubFrame(); | 1764 __ LeaveStubFrame(); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1897 | 1897 |
1898 // Check single stepping. | 1898 // Check single stepping. |
1899 Label not_stepping; | 1899 Label not_stepping; |
1900 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); | 1900 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); |
1901 __ lbu(T0, Address(T0, Isolate::single_step_offset())); | 1901 __ lbu(T0, Address(T0, Isolate::single_step_offset())); |
1902 __ BranchEqual(T0, 0, ¬_stepping); | 1902 __ BranchEqual(T0, 0, ¬_stepping); |
1903 // Call single step callback in debugger. | 1903 // Call single step callback in debugger. |
1904 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 1904 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
1905 __ sw(S5, Address(SP, 1 * kWordSize)); // Preserve IC data. | 1905 __ sw(S5, Address(SP, 1 * kWordSize)); // Preserve IC data. |
1906 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address. | 1906 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address. |
1907 __ CallRuntime(kSingleStepHandlerRuntimeEntry); | 1907 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
1908 __ lw(RA, Address(SP, 0 * kWordSize)); | 1908 __ lw(RA, Address(SP, 0 * kWordSize)); |
1909 __ lw(S5, Address(SP, 1 * kWordSize)); | 1909 __ lw(S5, Address(SP, 1 * kWordSize)); |
1910 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 1910 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
1911 __ Bind(¬_stepping); | 1911 __ Bind(¬_stepping); |
1912 | 1912 |
1913 | 1913 |
1914 // S5: IC data object (preserved). | 1914 // S5: IC data object (preserved). |
1915 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset())); | 1915 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset())); |
1916 // T0: ic_data_array with entries: target functions and count. | 1916 // T0: ic_data_array with entries: target functions and count. |
1917 __ AddImmediate(T0, Array::data_offset() - kHeapObjectTag); | 1917 __ AddImmediate(T0, Array::data_offset() - kHeapObjectTag); |
(...skipping 20 matching lines...) Expand all Loading... |
1938 __ LoadImmediate(CMPRES1, reinterpret_cast<intptr_t>(Object::null())); | 1938 __ LoadImmediate(CMPRES1, reinterpret_cast<intptr_t>(Object::null())); |
1939 __ bne(T4, CMPRES1, &target_is_compiled); | 1939 __ bne(T4, CMPRES1, &target_is_compiled); |
1940 | 1940 |
1941 __ EnterStubFrame(); | 1941 __ EnterStubFrame(); |
1942 // Preserve target function and IC data object. | 1942 // Preserve target function and IC data object. |
1943 // Two preserved registers, one argument (function) => 3 slots. | 1943 // Two preserved registers, one argument (function) => 3 slots. |
1944 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 1944 __ addiu(SP, SP, Immediate(-3 * kWordSize)); |
1945 __ sw(S5, Address(SP, 2 * kWordSize)); // Preserve IC data. | 1945 __ sw(S5, Address(SP, 2 * kWordSize)); // Preserve IC data. |
1946 __ sw(T3, Address(SP, 1 * kWordSize)); // Preserve function. | 1946 __ sw(T3, Address(SP, 1 * kWordSize)); // Preserve function. |
1947 __ sw(T3, Address(SP, 0 * kWordSize)); // Function argument. | 1947 __ sw(T3, Address(SP, 0 * kWordSize)); // Function argument. |
1948 __ CallRuntime(kCompileFunctionRuntimeEntry); | 1948 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
1949 __ lw(T3, Address(SP, 1 * kWordSize)); // Restore function. | 1949 __ lw(T3, Address(SP, 1 * kWordSize)); // Restore function. |
1950 __ lw(S5, Address(SP, 2 * kWordSize)); // Restore IC data. | 1950 __ lw(S5, Address(SP, 2 * kWordSize)); // Restore IC data. |
1951 __ addiu(SP, SP, Immediate(3 * kWordSize)); | 1951 __ addiu(SP, SP, Immediate(3 * kWordSize)); |
1952 // T3: target function. | 1952 // T3: target function. |
1953 __ lw(T4, FieldAddress(T3, Function::code_offset())); | 1953 __ lw(T4, FieldAddress(T3, Function::code_offset())); |
1954 __ LeaveStubFrame(); | 1954 __ LeaveStubFrame(); |
1955 | 1955 |
1956 __ Bind(&target_is_compiled); | 1956 __ Bind(&target_is_compiled); |
1957 // T4: target code. | 1957 // T4: target code. |
1958 __ lw(T3, FieldAddress(T4, Code::instructions_offset())); | 1958 __ lw(T3, FieldAddress(T4, Code::instructions_offset())); |
(...skipping 22 matching lines...) Expand all Loading... |
1981 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { | 1981 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { |
1982 __ TraceSimMsg("BreakpointStaticStub"); | 1982 __ TraceSimMsg("BreakpointStaticStub"); |
1983 // Create a stub frame as we are pushing some objects on the stack before | 1983 // Create a stub frame as we are pushing some objects on the stack before |
1984 // calling into the runtime. | 1984 // calling into the runtime. |
1985 __ EnterStubFrame(); | 1985 __ EnterStubFrame(); |
1986 // Preserve arguments descriptor and make room for result. | 1986 // Preserve arguments descriptor and make room for result. |
1987 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 1987 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
1988 __ sw(S5, Address(SP, 1 * kWordSize)); | 1988 __ sw(S5, Address(SP, 1 * kWordSize)); |
1989 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 1989 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
1990 __ sw(TMP, Address(SP, 0 * kWordSize)); | 1990 __ sw(TMP, Address(SP, 0 * kWordSize)); |
1991 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); | 1991 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry, 0); |
1992 // Pop code object result and restore arguments descriptor. | 1992 // Pop code object result and restore arguments descriptor. |
1993 __ lw(T0, Address(SP, 0 * kWordSize)); | 1993 __ lw(T0, Address(SP, 0 * kWordSize)); |
1994 __ lw(S5, Address(SP, 1 * kWordSize)); | 1994 __ lw(S5, Address(SP, 1 * kWordSize)); |
1995 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 1995 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
1996 __ LeaveStubFrame(); | 1996 __ LeaveStubFrame(); |
1997 | 1997 |
1998 // Now call the static function. The breakpoint handler function | 1998 // Now call the static function. The breakpoint handler function |
1999 // ensures that the call target is compiled. | 1999 // ensures that the call target is compiled. |
2000 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); | 2000 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); |
2001 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); | 2001 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); |
2002 // Load arguments descriptor into S4. | 2002 // Load arguments descriptor into S4. |
2003 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset())); | 2003 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset())); |
2004 __ jr(T0); | 2004 __ jr(T0); |
2005 } | 2005 } |
2006 | 2006 |
2007 | 2007 |
2008 // V0: return value. | 2008 // V0: return value. |
2009 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { | 2009 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { |
2010 __ TraceSimMsg("BreakpoingReturnStub"); | 2010 __ TraceSimMsg("BreakpoingReturnStub"); |
2011 // Create a stub frame as we are pushing some objects on the stack before | 2011 // Create a stub frame as we are pushing some objects on the stack before |
2012 // calling into the runtime. | 2012 // calling into the runtime. |
2013 __ EnterStubFrame(); | 2013 __ EnterStubFrame(); |
2014 __ Push(V0); | 2014 __ Push(V0); |
2015 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry); | 2015 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry, 0); |
2016 __ Pop(V0); | 2016 __ Pop(V0); |
2017 __ LeaveStubFrame(); | 2017 __ LeaveStubFrame(); |
2018 | 2018 |
2019 // Instead of returning to the patched Dart function, emulate the | 2019 // Instead of returning to the patched Dart function, emulate the |
2020 // smashed return code pattern and return to the function's caller. | 2020 // smashed return code pattern and return to the function's caller. |
2021 __ LeaveDartFrameAndReturn(); | 2021 __ LeaveDartFrameAndReturn(); |
2022 } | 2022 } |
2023 | 2023 |
2024 | 2024 |
2025 // RA: return address (Dart code). | 2025 // RA: return address (Dart code). |
2026 // S5: Inline cache data array. | 2026 // S5: Inline cache data array. |
2027 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { | 2027 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { |
2028 // Create a stub frame as we are pushing some objects on the stack before | 2028 // Create a stub frame as we are pushing some objects on the stack before |
2029 // calling into the runtime. | 2029 // calling into the runtime. |
2030 __ TraceSimMsg("BreakpointDynamicStub"); | 2030 __ TraceSimMsg("BreakpointDynamicStub"); |
2031 __ EnterStubFrame(); | 2031 __ EnterStubFrame(); |
2032 __ Push(S5); | 2032 __ Push(S5); |
2033 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); | 2033 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry, 0); |
2034 __ Pop(S5); | 2034 __ Pop(S5); |
2035 __ LeaveStubFrame(); | 2035 __ LeaveStubFrame(); |
2036 | 2036 |
2037 // Find out which dispatch stub to call. | 2037 // Find out which dispatch stub to call. |
2038 __ lw(T1, FieldAddress(S5, ICData::num_args_tested_offset())); | 2038 __ lw(T1, FieldAddress(S5, ICData::num_args_tested_offset())); |
2039 | 2039 |
2040 Label one_arg, two_args, three_args; | 2040 Label one_arg, two_args, three_args; |
2041 __ BranchEqual(T1, 1, &one_arg); | 2041 __ BranchEqual(T1, 1, &one_arg); |
2042 __ BranchEqual(T1, 2, &two_args); | 2042 __ BranchEqual(T1, 2, &two_args); |
2043 __ BranchEqual(T1, 3, &three_args); | 2043 __ BranchEqual(T1, 3, &three_args); |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2278 __ delay_slot()->SmiTag(T2); | 2278 __ delay_slot()->SmiTag(T2); |
2279 | 2279 |
2280 __ Bind(&update_ic_data); | 2280 __ Bind(&update_ic_data); |
2281 // T0: ICData | 2281 // T0: ICData |
2282 __ addiu(SP, SP, Immediate(-4 * kWordSize)); | 2282 __ addiu(SP, SP, Immediate(-4 * kWordSize)); |
2283 __ sw(A1, Address(SP, 3 * kWordSize)); | 2283 __ sw(A1, Address(SP, 3 * kWordSize)); |
2284 __ sw(A0, Address(SP, 2 * kWordSize)); | 2284 __ sw(A0, Address(SP, 2 * kWordSize)); |
2285 __ LoadObject(TMP1, Symbols::EqualOperator()); // Target's name. | 2285 __ LoadObject(TMP1, Symbols::EqualOperator()); // Target's name. |
2286 __ sw(TMP1, Address(SP, 1 * kWordSize)); | 2286 __ sw(TMP1, Address(SP, 1 * kWordSize)); |
2287 __ sw(T0, Address(SP, 0 * kWordSize)); // ICData. | 2287 __ sw(T0, Address(SP, 0 * kWordSize)); // ICData. |
2288 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry); | 2288 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry, 4); |
2289 __ lw(A0, Address(SP, 2 * kWordSize)); | 2289 __ lw(A0, Address(SP, 2 * kWordSize)); |
2290 __ lw(A1, Address(SP, 3 * kWordSize)); | 2290 __ lw(A1, Address(SP, 3 * kWordSize)); |
2291 __ b(&compute_result); | 2291 __ b(&compute_result); |
2292 __ delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize)); | 2292 __ delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize)); |
2293 } | 2293 } |
2294 | 2294 |
2295 | 2295 |
2296 // Calls to the runtime to optimize the given function. | 2296 // Calls to the runtime to optimize the given function. |
2297 // T0: function to be reoptimized. | 2297 // T0: function to be reoptimized. |
2298 // S4: argument descriptor (preserved). | 2298 // S4: argument descriptor (preserved). |
2299 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 2299 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
2300 __ TraceSimMsg("OptimizeFunctionStub"); | 2300 __ TraceSimMsg("OptimizeFunctionStub"); |
2301 __ EnterStubFrame(); | 2301 __ EnterStubFrame(); |
2302 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 2302 __ addiu(SP, SP, Immediate(-3 * kWordSize)); |
2303 __ sw(S4, Address(SP, 2 * kWordSize)); | 2303 __ sw(S4, Address(SP, 2 * kWordSize)); |
2304 // Setup space on stack for return value. | 2304 // Setup space on stack for return value. |
2305 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 2305 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
2306 __ sw(TMP, Address(SP, 1 * kWordSize)); | 2306 __ sw(TMP, Address(SP, 1 * kWordSize)); |
2307 __ sw(T0, Address(SP, 0 * kWordSize)); | 2307 __ sw(T0, Address(SP, 0 * kWordSize)); |
2308 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); | 2308 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); |
2309 __ TraceSimMsg("OptimizeFunctionStub return"); | 2309 __ TraceSimMsg("OptimizeFunctionStub return"); |
2310 __ lw(T0, Address(SP, 1 * kWordSize)); // Get Code object | 2310 __ lw(T0, Address(SP, 1 * kWordSize)); // Get Code object |
2311 __ lw(S4, Address(SP, 2 * kWordSize)); // Restore argument descriptor. | 2311 __ lw(S4, Address(SP, 2 * kWordSize)); // Restore argument descriptor. |
2312 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Discard argument. | 2312 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Discard argument. |
2313 | 2313 |
2314 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); | 2314 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); |
2315 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); | 2315 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); |
2316 __ LeaveStubFrameAndReturn(T0); | 2316 __ LeaveStubFrameAndReturn(T0); |
2317 __ break_(0); | 2317 __ break_(0); |
2318 } | 2318 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2385 __ LoadClassId(temp2, right); | 2385 __ LoadClassId(temp2, right); |
2386 __ subu(CMPRES, temp1, temp2); | 2386 __ subu(CMPRES, temp1, temp2); |
2387 __ bne(CMPRES, ZR, &done); | 2387 __ bne(CMPRES, ZR, &done); |
2388 | 2388 |
2389 __ EnterStubFrame(); | 2389 __ EnterStubFrame(); |
2390 __ ReserveAlignedFrameSpace(2 * kWordSize); | 2390 __ ReserveAlignedFrameSpace(2 * kWordSize); |
2391 __ sw(left, Address(SP, 1 * kWordSize)); | 2391 __ sw(left, Address(SP, 1 * kWordSize)); |
2392 __ sw(right, Address(SP, 0 * kWordSize)); | 2392 __ sw(right, Address(SP, 0 * kWordSize)); |
2393 __ mov(A0, left); | 2393 __ mov(A0, left); |
2394 __ mov(A1, right); | 2394 __ mov(A1, right); |
2395 __ CallRuntime(kBigintCompareRuntimeEntry); | 2395 __ CallRuntime(kBigintCompareRuntimeEntry, 2); |
2396 __ TraceSimMsg("IdenticalWithNumberCheckStub return"); | 2396 __ TraceSimMsg("IdenticalWithNumberCheckStub return"); |
2397 // Result in V0, 0 means equal. | 2397 // Result in V0, 0 means equal. |
2398 __ LeaveStubFrame(); | 2398 __ LeaveStubFrame(); |
2399 __ b(&done); | 2399 __ b(&done); |
2400 __ delay_slot()->mov(CMPRES, V0); | 2400 __ delay_slot()->mov(CMPRES, V0); |
2401 | 2401 |
2402 __ Bind(&reference_compare); | 2402 __ Bind(&reference_compare); |
2403 __ subu(CMPRES, left, right); | 2403 __ subu(CMPRES, left, right); |
2404 __ Bind(&done); | 2404 __ Bind(&done); |
2405 // A branch or test after this comparison will check CMPRES1 == CMPRES2. | 2405 // A branch or test after this comparison will check CMPRES1 == CMPRES2. |
2406 __ mov(CMPRES2, ZR); | 2406 __ mov(CMPRES2, ZR); |
2407 } | 2407 } |
2408 | 2408 |
2409 | 2409 |
2410 // Called only from unoptimized code. All relevant registers have been saved. | 2410 // Called only from unoptimized code. All relevant registers have been saved. |
2411 // RA: return address. | 2411 // RA: return address. |
2412 // SP + 4: left operand. | 2412 // SP + 4: left operand. |
2413 // SP + 0: right operand. | 2413 // SP + 0: right operand. |
2414 // Returns: CMPRES is zero if equal, non-zero otherwise. | 2414 // Returns: CMPRES is zero if equal, non-zero otherwise. |
2415 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( | 2415 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( |
2416 Assembler* assembler) { | 2416 Assembler* assembler) { |
2417 // Check single stepping. | 2417 // Check single stepping. |
2418 Label not_stepping; | 2418 Label not_stepping; |
2419 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); | 2419 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); |
2420 __ lbu(T0, Address(T0, Isolate::single_step_offset())); | 2420 __ lbu(T0, Address(T0, Isolate::single_step_offset())); |
2421 __ BranchEqual(T0, 0, ¬_stepping); | 2421 __ BranchEqual(T0, 0, ¬_stepping); |
2422 // Call single step callback in debugger. | 2422 // Call single step callback in debugger. |
2423 __ addiu(SP, SP, Immediate(-1 * kWordSize)); | 2423 __ addiu(SP, SP, Immediate(-1 * kWordSize)); |
2424 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address. | 2424 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address. |
2425 __ CallRuntime(kSingleStepHandlerRuntimeEntry); | 2425 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
2426 __ lw(RA, Address(SP, 0 * kWordSize)); | 2426 __ lw(RA, Address(SP, 0 * kWordSize)); |
2427 __ addiu(SP, SP, Immediate(1 * kWordSize)); | 2427 __ addiu(SP, SP, Immediate(1 * kWordSize)); |
2428 __ Bind(¬_stepping); | 2428 __ Bind(¬_stepping); |
2429 | 2429 |
2430 const Register temp1 = T2; | 2430 const Register temp1 = T2; |
2431 const Register temp2 = T3; | 2431 const Register temp2 = T3; |
2432 const Register left = T1; | 2432 const Register left = T1; |
2433 const Register right = T0; | 2433 const Register right = T0; |
2434 // Preserve left, right. | 2434 // Preserve left, right. |
2435 __ lw(left, Address(SP, 1 * kWordSize)); | 2435 __ lw(left, Address(SP, 1 * kWordSize)); |
(...skipping 27 matching lines...) Expand all Loading... |
2463 __ lw(left, Address(SP, 1 * kWordSize)); | 2463 __ lw(left, Address(SP, 1 * kWordSize)); |
2464 __ lw(temp2, Address(SP, 2 * kWordSize)); | 2464 __ lw(temp2, Address(SP, 2 * kWordSize)); |
2465 __ lw(temp1, Address(SP, 3 * kWordSize)); | 2465 __ lw(temp1, Address(SP, 3 * kWordSize)); |
2466 __ Ret(); | 2466 __ Ret(); |
2467 __ delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize)); | 2467 __ delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize)); |
2468 } | 2468 } |
2469 | 2469 |
2470 } // namespace dart | 2470 } // namespace dart |
2471 | 2471 |
2472 #endif // defined TARGET_ARCH_MIPS | 2472 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |