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_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 } | 106 } |
107 END_LEAF_RUNTIME_ENTRY | 107 END_LEAF_RUNTIME_ENTRY |
108 | 108 |
109 | 109 |
110 // Input parameters: | 110 // Input parameters: |
111 // R0 : stop message (const char*). | 111 // R0 : stop message (const char*). |
112 // Must preserve all registers. | 112 // Must preserve all registers. |
113 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { | 113 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { |
114 __ EnterCallRuntimeFrame(0); | 114 __ EnterCallRuntimeFrame(0); |
115 // Call the runtime leaf function. R0 already contains the parameter. | 115 // Call the runtime leaf function. R0 already contains the parameter. |
116 __ CallRuntime(kPrintStopMessageRuntimeEntry); | 116 __ CallRuntime(kPrintStopMessageRuntimeEntry, 1); |
117 __ LeaveCallRuntimeFrame(); | 117 __ LeaveCallRuntimeFrame(); |
118 __ Ret(); | 118 __ Ret(); |
119 } | 119 } |
120 | 120 |
121 | 121 |
122 // Input parameters: | 122 // Input parameters: |
123 // LR : return address. | 123 // LR : return address. |
124 // SP : address of return value. | 124 // SP : address of return value. |
125 // R5 : address of the native function to call. | 125 // R5 : address of the native function to call. |
126 // R2 : address of first argument in argument array. | 126 // R2 : address of first argument in argument array. |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 | 284 |
285 // Input parameters: | 285 // Input parameters: |
286 // R4: arguments descriptor array. | 286 // R4: arguments descriptor array. |
287 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 287 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
288 // Create a stub frame as we are pushing some objects on the stack before | 288 // Create a stub frame as we are pushing some objects on the stack before |
289 // calling into the runtime. | 289 // calling into the runtime. |
290 __ EnterStubFrame(); | 290 __ EnterStubFrame(); |
291 // Setup space on stack for return value and preserve arguments descriptor. | 291 // Setup space on stack for return value and preserve arguments descriptor. |
292 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 292 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
293 __ PushList((1 << R0) | (1 << R4)); | 293 __ PushList((1 << R0) | (1 << R4)); |
294 __ CallRuntime(kPatchStaticCallRuntimeEntry); | 294 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); |
295 // Get Code object result and restore arguments descriptor array. | 295 // Get Code object result and restore arguments descriptor array. |
296 __ PopList((1 << R0) | (1 << R4)); | 296 __ PopList((1 << R0) | (1 << R4)); |
297 // Remove the stub frame. | 297 // Remove the stub frame. |
298 __ LeaveStubFrame(); | 298 __ LeaveStubFrame(); |
299 // Jump to the dart function. | 299 // Jump to the dart function. |
300 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); | 300 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); |
301 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); | 301 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); |
302 __ bx(R0); | 302 __ bx(R0); |
303 } | 303 } |
304 | 304 |
305 | 305 |
306 // Called from a static call only when an invalid code has been entered | 306 // Called from a static call only when an invalid code has been entered |
307 // (invalid because its function was optimized or deoptimized). | 307 // (invalid because its function was optimized or deoptimized). |
308 // R4: arguments descriptor array. | 308 // R4: arguments descriptor array. |
309 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 309 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
310 // Create a stub frame as we are pushing some objects on the stack before | 310 // Create a stub frame as we are pushing some objects on the stack before |
311 // calling into the runtime. | 311 // calling into the runtime. |
312 __ EnterStubFrame(); | 312 __ EnterStubFrame(); |
313 // Setup space on stack for return value and preserve arguments descriptor. | 313 // Setup space on stack for return value and preserve arguments descriptor. |
314 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 314 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
315 __ PushList((1 << R0) | (1 << R4)); | 315 __ PushList((1 << R0) | (1 << R4)); |
316 __ CallRuntime(kFixCallersTargetRuntimeEntry); | 316 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); |
317 // Get Code object result and restore arguments descriptor array. | 317 // Get Code object result and restore arguments descriptor array. |
318 __ PopList((1 << R0) | (1 << R4)); | 318 __ PopList((1 << R0) | (1 << R4)); |
319 // Remove the stub frame. | 319 // Remove the stub frame. |
320 __ LeaveStubFrame(); | 320 __ LeaveStubFrame(); |
321 // Jump to the dart function. | 321 // Jump to the dart function. |
322 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); | 322 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); |
323 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); | 323 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); |
324 __ bx(R0); | 324 __ bx(R0); |
325 } | 325 } |
326 | 326 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 // Push space for the return value. | 370 // Push space for the return value. |
371 // Push the receiver. | 371 // Push the receiver. |
372 // Push IC data object. | 372 // Push IC data object. |
373 // Push arguments descriptor array. | 373 // Push arguments descriptor array. |
374 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 374 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); |
375 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); | 375 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); |
376 | 376 |
377 // R2: Smi-tagged arguments array length. | 377 // R2: Smi-tagged arguments array length. |
378 PushArgumentsArray(assembler); | 378 PushArgumentsArray(assembler); |
379 | 379 |
380 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry); | 380 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry, 4); |
381 | 381 |
382 // Remove arguments. | 382 // Remove arguments. |
383 __ Drop(4); | 383 __ Drop(4); |
384 __ Pop(R0); // Get result into R0. | 384 __ Pop(R0); // Get result into R0. |
385 __ LeaveStubFrame(); | 385 __ LeaveStubFrame(); |
386 __ Ret(); | 386 __ Ret(); |
387 } | 387 } |
388 | 388 |
389 | 389 |
390 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, | 390 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 ASSERT(kFpuRegisterSize == 4 * kWordSize); | 440 ASSERT(kFpuRegisterSize == 4 * kWordSize); |
441 if (kNumberOfDRegisters > 16) { | 441 if (kNumberOfDRegisters > 16) { |
442 __ vstmd(DB_W, SP, D16, kNumberOfDRegisters - 16); | 442 __ vstmd(DB_W, SP, D16, kNumberOfDRegisters - 16); |
443 __ vstmd(DB_W, SP, D0, 16); | 443 __ vstmd(DB_W, SP, D0, 16); |
444 } else { | 444 } else { |
445 __ vstmd(DB_W, SP, D0, kNumberOfDRegisters); | 445 __ vstmd(DB_W, SP, D0, kNumberOfDRegisters); |
446 } | 446 } |
447 | 447 |
448 __ mov(R0, ShifterOperand(SP)); // Pass address of saved registers block. | 448 __ mov(R0, ShifterOperand(SP)); // Pass address of saved registers block. |
449 __ ReserveAlignedFrameSpace(0); | 449 __ ReserveAlignedFrameSpace(0); |
450 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry); | 450 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 1); |
451 // Result (R0) is stack-size (FP - SP) in bytes. | 451 // Result (R0) is stack-size (FP - SP) in bytes. |
452 | 452 |
453 if (preserve_result) { | 453 if (preserve_result) { |
454 // Restore result into R1 temporarily. | 454 // Restore result into R1 temporarily. |
455 __ ldr(R1, Address(FP, saved_result_slot_from_fp * kWordSize)); | 455 __ ldr(R1, Address(FP, saved_result_slot_from_fp * kWordSize)); |
456 } | 456 } |
457 | 457 |
458 __ LeaveDartFrame(); | 458 __ LeaveDartFrame(); |
459 __ sub(SP, FP, ShifterOperand(R0)); | 459 __ sub(SP, FP, ShifterOperand(R0)); |
460 | 460 |
461 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there | 461 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there |
462 // is no need to set the correct PC marker or load PP, since they get patched. | 462 // is no need to set the correct PC marker or load PP, since they get patched. |
463 __ mov(IP, ShifterOperand(LR)); | 463 __ mov(IP, ShifterOperand(LR)); |
464 __ mov(LR, ShifterOperand(0)); | 464 __ mov(LR, ShifterOperand(0)); |
465 __ EnterFrame((1 << PP) | (1 << FP) | (1 << IP) | (1 << LR), 0); | 465 __ EnterFrame((1 << PP) | (1 << FP) | (1 << IP) | (1 << LR), 0); |
466 __ mov(R0, ShifterOperand(FP)); // Get last FP address. | 466 __ mov(R0, ShifterOperand(FP)); // Get last FP address. |
467 if (preserve_result) { | 467 if (preserve_result) { |
468 __ Push(R1); // Preserve result as first local. | 468 __ Push(R1); // Preserve result as first local. |
469 } | 469 } |
470 __ ReserveAlignedFrameSpace(0); | 470 __ ReserveAlignedFrameSpace(0); |
471 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); // Pass last FP in R0. | 471 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1); // Pass last FP in R0. |
472 if (preserve_result) { | 472 if (preserve_result) { |
473 // Restore result into R1. | 473 // Restore result into R1. |
474 __ ldr(R1, Address(FP, kFirstLocalSlotFromFp * kWordSize)); | 474 __ ldr(R1, Address(FP, kFirstLocalSlotFromFp * kWordSize)); |
475 } | 475 } |
476 // Code above cannot cause GC. | 476 // Code above cannot cause GC. |
477 __ LeaveDartFrame(); | 477 __ LeaveDartFrame(); |
478 | 478 |
479 // Frame is fully rewritten at this point and it is safe to perform a GC. | 479 // Frame is fully rewritten at this point and it is safe to perform a GC. |
480 // Materialize any objects that were deferred by FillFrame because they | 480 // Materialize any objects that were deferred by FillFrame because they |
481 // require allocation. | 481 // require allocation. |
482 __ EnterStubFrame(); | 482 __ EnterStubFrame(); |
483 if (preserve_result) { | 483 if (preserve_result) { |
484 __ Push(R1); // Preserve result, it will be GC-d here. | 484 __ Push(R1); // Preserve result, it will be GC-d here. |
485 } | 485 } |
486 __ PushObject(Smi::ZoneHandle()); // Space for the result. | 486 __ PushObject(Smi::ZoneHandle()); // Space for the result. |
487 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry); | 487 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0); |
488 // Result tells stub how many bytes to remove from the expression stack | 488 // Result tells stub how many bytes to remove from the expression stack |
489 // of the bottom-most frame. They were used as materialization arguments. | 489 // of the bottom-most frame. They were used as materialization arguments. |
490 __ Pop(R1); | 490 __ Pop(R1); |
491 if (preserve_result) { | 491 if (preserve_result) { |
492 __ Pop(R0); // Restore result. | 492 __ Pop(R0); // Restore result. |
493 } | 493 } |
494 __ LeaveStubFrame(); | 494 __ LeaveStubFrame(); |
495 // Remove materialization arguments. | 495 // Remove materialization arguments. |
496 __ add(SP, SP, ShifterOperand(R1, ASR, kSmiTagSize)); | 496 __ add(SP, SP, ShifterOperand(R1, ASR, kSmiTagSize)); |
497 __ Ret(); | 497 __ Ret(); |
(...skipping 23 matching lines...) Expand all Loading... |
521 | 521 |
522 // Preserve IC data and arguments descriptor. | 522 // Preserve IC data and arguments descriptor. |
523 __ PushList((1 << R4) | (1 << R5)); | 523 __ PushList((1 << R4) | (1 << R5)); |
524 | 524 |
525 // Push space for the return value. | 525 // Push space for the return value. |
526 // Push the receiver. | 526 // Push the receiver. |
527 // Push IC data object. | 527 // Push IC data object. |
528 // Push arguments descriptor array. | 528 // Push arguments descriptor array. |
529 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 529 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); |
530 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); | 530 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); |
531 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry); | 531 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
532 // Remove arguments. | 532 // Remove arguments. |
533 __ Drop(3); | 533 __ Drop(3); |
534 __ Pop(R0); // Get result into R0. | 534 __ Pop(R0); // Get result into R0. |
535 | 535 |
536 // Restore IC data and arguments descriptor. | 536 // Restore IC data and arguments descriptor. |
537 __ PopList((1 << R4) | (1 << R5)); | 537 __ PopList((1 << R4) | (1 << R5)); |
538 | 538 |
539 __ LeaveStubFrame(); | 539 __ LeaveStubFrame(); |
540 | 540 |
541 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 541 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 // Unable to allocate the array using the fast inline code, just call | 660 // Unable to allocate the array using the fast inline code, just call |
661 // into the runtime. | 661 // into the runtime. |
662 __ Bind(&slow_case); | 662 __ Bind(&slow_case); |
663 // Create a stub frame as we are pushing some objects on the stack before | 663 // Create a stub frame as we are pushing some objects on the stack before |
664 // calling into the runtime. | 664 // calling into the runtime. |
665 __ EnterStubFrame(); | 665 __ EnterStubFrame(); |
666 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 666 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); |
667 // Setup space on stack for return value. | 667 // Setup space on stack for return value. |
668 // Push array length as Smi and element type. | 668 // Push array length as Smi and element type. |
669 __ PushList((1 << R1) | (1 << R2) | (1 << IP)); | 669 __ PushList((1 << R1) | (1 << R2) | (1 << IP)); |
670 __ CallRuntime(kAllocateArrayRuntimeEntry); | 670 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); |
671 // Pop arguments; result is popped in IP. | 671 // Pop arguments; result is popped in IP. |
672 __ PopList((1 << R1) | (1 << R2) | (1 << IP)); // R2 is restored. | 672 __ PopList((1 << R1) | (1 << R2) | (1 << IP)); // R2 is restored. |
673 __ mov(R0, ShifterOperand(IP)); | 673 __ mov(R0, ShifterOperand(IP)); |
674 __ LeaveStubFrame(); | 674 __ LeaveStubFrame(); |
675 __ Ret(); | 675 __ Ret(); |
676 } | 676 } |
677 | 677 |
678 | 678 |
679 // Input parameters: | 679 // Input parameters: |
680 // LR: return address. | 680 // LR: return address. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 __ cmp(R0, ShifterOperand(R8)); // R8 is raw null. | 717 __ cmp(R0, ShifterOperand(R8)); // R8 is raw null. |
718 Label function_compiled; | 718 Label function_compiled; |
719 __ b(&function_compiled, NE); | 719 __ b(&function_compiled, NE); |
720 | 720 |
721 // Create a stub frame as we are pushing some objects on the stack before | 721 // Create a stub frame as we are pushing some objects on the stack before |
722 // calling into the runtime. | 722 // calling into the runtime. |
723 __ EnterStubFrame(); | 723 __ EnterStubFrame(); |
724 | 724 |
725 // Preserve arguments descriptor array and read-only function object argument. | 725 // Preserve arguments descriptor array and read-only function object argument. |
726 __ PushList((1 << R2) | (1 << R4)); | 726 __ PushList((1 << R2) | (1 << R4)); |
727 __ CallRuntime(kCompileFunctionRuntimeEntry); | 727 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
728 // Restore arguments descriptor array and read-only function object argument. | 728 // Restore arguments descriptor array and read-only function object argument. |
729 __ PopList((1 << R2) | (1 << R4)); | 729 __ PopList((1 << R2) | (1 << R4)); |
730 // Restore R0. | 730 // Restore R0. |
731 __ ldr(R0, FieldAddress(R2, Function::code_offset())); | 731 __ ldr(R0, FieldAddress(R2, Function::code_offset())); |
732 | 732 |
733 // Remove the stub frame as we are about to jump to the closure function. | 733 // Remove the stub frame as we are about to jump to the closure function. |
734 __ LeaveStubFrame(); | 734 __ LeaveStubFrame(); |
735 | 735 |
736 __ Bind(&function_compiled); | 736 __ Bind(&function_compiled); |
737 // R0: code. | 737 // R0: code. |
(...skipping 14 matching lines...) Expand all Loading... |
752 // calling into the runtime. | 752 // calling into the runtime. |
753 __ EnterStubFrame(); | 753 __ EnterStubFrame(); |
754 | 754 |
755 // Setup space on stack for result from error reporting. | 755 // Setup space on stack for result from error reporting. |
756 __ PushList((1 << R4) | (1 << R8)); // Arguments descriptor and raw null. | 756 __ PushList((1 << R4) | (1 << R8)); // Arguments descriptor and raw null. |
757 | 757 |
758 // Load smi-tagged arguments array length, including the non-closure. | 758 // Load smi-tagged arguments array length, including the non-closure. |
759 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset())); | 759 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset())); |
760 PushArgumentsArray(assembler); | 760 PushArgumentsArray(assembler); |
761 | 761 |
762 __ CallRuntime(kInvokeNonClosureRuntimeEntry); | 762 __ CallRuntime(kInvokeNonClosureRuntimeEntry, 2); |
763 // Remove arguments. | 763 // Remove arguments. |
764 __ Drop(2); | 764 __ Drop(2); |
765 __ Pop(R0); // Get result into R0. | 765 __ Pop(R0); // Get result into R0. |
766 | 766 |
767 // Remove the stub frame as we are about to return. | 767 // Remove the stub frame as we are about to return. |
768 __ LeaveStubFrame(); | 768 __ LeaveStubFrame(); |
769 __ Ret(); | 769 __ Ret(); |
770 } | 770 } |
771 | 771 |
772 | 772 |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
975 | 975 |
976 __ Bind(&slow_case); | 976 __ Bind(&slow_case); |
977 } | 977 } |
978 // Create a stub frame as we are pushing some objects on the stack before | 978 // Create a stub frame as we are pushing some objects on the stack before |
979 // calling into the runtime. | 979 // calling into the runtime. |
980 __ EnterStubFrame(); | 980 __ EnterStubFrame(); |
981 // Setup space on stack for return value. | 981 // Setup space on stack for return value. |
982 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null())); | 982 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null())); |
983 __ SmiTag(R1); | 983 __ SmiTag(R1); |
984 __ PushList((1 << R1) | (1 << R2)); | 984 __ PushList((1 << R1) | (1 << R2)); |
985 __ CallRuntime(kAllocateContextRuntimeEntry); // Allocate context. | 985 __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context. |
986 __ Drop(1); // Pop number of context variables argument. | 986 __ Drop(1); // Pop number of context variables argument. |
987 __ Pop(R0); // Pop the new context object. | 987 __ Pop(R0); // Pop the new context object. |
988 // R0: new object | 988 // R0: new object |
989 // Restore the frame pointer. | 989 // Restore the frame pointer. |
990 __ LeaveStubFrame(); | 990 __ LeaveStubFrame(); |
991 __ Ret(); | 991 __ Ret(); |
992 } | 992 } |
993 | 993 |
994 | 994 |
995 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate); | 995 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1040 __ PopList((1 << R1) | (1 << R2) | (1 << R3)); | 1040 __ PopList((1 << R1) | (1 << R2) | (1 << R3)); |
1041 __ b(&L, EQ); | 1041 __ b(&L, EQ); |
1042 __ Ret(); | 1042 __ Ret(); |
1043 | 1043 |
1044 // Handle overflow: Call the runtime leaf function. | 1044 // Handle overflow: Call the runtime leaf function. |
1045 __ Bind(&L); | 1045 __ Bind(&L); |
1046 // Setup frame, push callee-saved registers. | 1046 // Setup frame, push callee-saved registers. |
1047 | 1047 |
1048 __ EnterCallRuntimeFrame(0 * kWordSize); | 1048 __ EnterCallRuntimeFrame(0 * kWordSize); |
1049 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); | 1049 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); |
1050 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry); | 1050 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); |
1051 // Restore callee-saved registers, tear down frame. | 1051 // Restore callee-saved registers, tear down frame. |
1052 __ LeaveCallRuntimeFrame(); | 1052 __ LeaveCallRuntimeFrame(); |
1053 __ Ret(); | 1053 __ Ret(); |
1054 } | 1054 } |
1055 | 1055 |
1056 | 1056 |
1057 // Called for inline allocation of objects. | 1057 // Called for inline allocation of objects. |
1058 // Input parameters: | 1058 // Input parameters: |
1059 // LR : return address. | 1059 // LR : return address. |
1060 // SP + 4 : type arguments object (only if class is parameterized). | 1060 // SP + 4 : type arguments object (only if class is parameterized). |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1205 __ Push(R2); // Setup space on stack for return value. | 1205 __ Push(R2); // Setup space on stack for return value. |
1206 __ PushObject(cls); // Push class of object to be allocated. | 1206 __ PushObject(cls); // Push class of object to be allocated. |
1207 if (is_cls_parameterized) { | 1207 if (is_cls_parameterized) { |
1208 // Push type arguments of object to be allocated and of instantiator. | 1208 // Push type arguments of object to be allocated and of instantiator. |
1209 __ PushList((1 << R0) | (1 << R1)); | 1209 __ PushList((1 << R0) | (1 << R1)); |
1210 } else { | 1210 } else { |
1211 // Push null type arguments and kNoInstantiator. | 1211 // Push null type arguments and kNoInstantiator. |
1212 __ LoadImmediate(R1, Smi::RawValue(StubCode::kNoInstantiator)); | 1212 __ LoadImmediate(R1, Smi::RawValue(StubCode::kNoInstantiator)); |
1213 __ PushList((1 << R1) | (1 << R2)); | 1213 __ PushList((1 << R1) | (1 << R2)); |
1214 } | 1214 } |
1215 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object. | 1215 __ CallRuntime(kAllocateObjectRuntimeEntry, 3); // Allocate object. |
1216 __ Drop(3); // Pop arguments. | 1216 __ Drop(3); // Pop arguments. |
1217 __ Pop(R0); // Pop result (newly allocated object). | 1217 __ Pop(R0); // Pop result (newly allocated object). |
1218 // R0: new object | 1218 // R0: new object |
1219 // Restore the frame pointer. | 1219 // Restore the frame pointer. |
1220 __ LeaveStubFrame(true); | 1220 __ LeaveStubFrame(true); |
1221 __ Ret(); | 1221 __ Ret(); |
1222 } | 1222 } |
1223 | 1223 |
1224 | 1224 |
1225 // Called for inline allocation of closures. | 1225 // Called for inline allocation of closures. |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1338 __ ldr(R1, Address(FP, kReceiverFPOffset)); | 1338 __ ldr(R1, Address(FP, kReceiverFPOffset)); |
1339 __ Push(R1); // Receiver. | 1339 __ Push(R1); // Receiver. |
1340 } | 1340 } |
1341 // R0: raw null. | 1341 // R0: raw null. |
1342 if (has_type_arguments) { | 1342 if (has_type_arguments) { |
1343 __ ldr(R0, Address(FP, kTypeArgumentsFPOffset)); | 1343 __ ldr(R0, Address(FP, kTypeArgumentsFPOffset)); |
1344 } | 1344 } |
1345 __ Push(R0); // Push type arguments of closure to be allocated or null. | 1345 __ Push(R0); // Push type arguments of closure to be allocated or null. |
1346 | 1346 |
1347 if (is_implicit_instance_closure) { | 1347 if (is_implicit_instance_closure) { |
1348 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry); | 1348 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry, 3); |
1349 __ Drop(2); // Pop arguments (type arguments of object and receiver). | 1349 __ Drop(2); // Pop arguments (type arguments of object and receiver). |
1350 } else { | 1350 } else { |
1351 ASSERT(func.IsNonImplicitClosureFunction()); | 1351 ASSERT(func.IsNonImplicitClosureFunction()); |
1352 __ CallRuntime(kAllocateClosureRuntimeEntry); | 1352 __ CallRuntime(kAllocateClosureRuntimeEntry, 2); |
1353 __ Drop(1); // Pop argument (type arguments of object). | 1353 __ Drop(1); // Pop argument (type arguments of object). |
1354 } | 1354 } |
1355 __ Drop(1); // Pop function object. | 1355 __ Drop(1); // Pop function object. |
1356 __ Pop(R0); | 1356 __ Pop(R0); |
1357 // R0: new object | 1357 // R0: new object |
1358 // Restore the frame pointer. | 1358 // Restore the frame pointer. |
1359 __ LeaveStubFrame(true); | 1359 __ LeaveStubFrame(true); |
1360 __ Ret(); | 1360 __ Ret(); |
1361 } | 1361 } |
1362 | 1362 |
(...skipping 17 matching lines...) Expand all Loading... |
1380 // Push space for the return value. | 1380 // Push space for the return value. |
1381 // Push the receiver. | 1381 // Push the receiver. |
1382 // Push IC data object. | 1382 // Push IC data object. |
1383 // Push arguments descriptor array. | 1383 // Push arguments descriptor array. |
1384 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 1384 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); |
1385 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); | 1385 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); |
1386 | 1386 |
1387 // R2: Smi-tagged arguments array length. | 1387 // R2: Smi-tagged arguments array length. |
1388 PushArgumentsArray(assembler); | 1388 PushArgumentsArray(assembler); |
1389 | 1389 |
1390 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry); | 1390 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry, 4); |
1391 // Remove arguments. | 1391 // Remove arguments. |
1392 __ Drop(4); | 1392 __ Drop(4); |
1393 __ Pop(R0); // Get result into R0. | 1393 __ Pop(R0); // Get result into R0. |
1394 __ LeaveStubFrame(); | 1394 __ LeaveStubFrame(); |
1395 __ Ret(); | 1395 __ Ret(); |
1396 } | 1396 } |
1397 | 1397 |
1398 | 1398 |
1399 // R6: function object. | 1399 // R6: function object. |
1400 // R5: inline cache data object. | 1400 // R5: inline cache data object. |
1401 // Cannot use function object from ICData as it may be the inlined | 1401 // Cannot use function object from ICData as it may be the inlined |
1402 // function and not the top-scope function. | 1402 // function and not the top-scope function. |
1403 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { | 1403 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { |
1404 Register ic_reg = R5; | 1404 Register ic_reg = R5; |
1405 Register func_reg = R6; | 1405 Register func_reg = R6; |
1406 if (FLAG_trace_optimized_ic_calls) { | 1406 if (FLAG_trace_optimized_ic_calls) { |
1407 __ EnterStubFrame(); | 1407 __ EnterStubFrame(); |
1408 __ PushList((1 << R5) | (1 << R6)); // Preserve. | 1408 __ PushList((1 << R5) | (1 << R6)); // Preserve. |
1409 __ Push(ic_reg); // Argument. | 1409 __ Push(ic_reg); // Argument. |
1410 __ Push(func_reg); // Argument. | 1410 __ Push(func_reg); // Argument. |
1411 __ CallRuntime(kTraceICCallRuntimeEntry); | 1411 __ CallRuntime(kTraceICCallRuntimeEntry, 2); |
1412 __ Drop(2); // Discard argument; | 1412 __ Drop(2); // Discard argument; |
1413 __ PopList((1 << R5) | (1 << R6)); // Restore. | 1413 __ PopList((1 << R5) | (1 << R6)); // Restore. |
1414 __ LeaveStubFrame(); | 1414 __ LeaveStubFrame(); |
1415 } | 1415 } |
1416 __ ldr(R7, FieldAddress(func_reg, Function::usage_counter_offset())); | 1416 __ ldr(R7, FieldAddress(func_reg, Function::usage_counter_offset())); |
1417 __ add(R7, R7, ShifterOperand(1)); | 1417 __ add(R7, R7, ShifterOperand(1)); |
1418 __ str(R7, FieldAddress(func_reg, Function::usage_counter_offset())); | 1418 __ str(R7, FieldAddress(func_reg, Function::usage_counter_offset())); |
1419 } | 1419 } |
1420 | 1420 |
1421 | 1421 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1460 #endif // DEBUG | 1460 #endif // DEBUG |
1461 | 1461 |
1462 // Check single stepping. | 1462 // Check single stepping. |
1463 Label not_stepping; | 1463 Label not_stepping; |
1464 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); | 1464 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); |
1465 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); | 1465 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); |
1466 __ CompareImmediate(R6, 0); | 1466 __ CompareImmediate(R6, 0); |
1467 __ b(¬_stepping, EQ); | 1467 __ b(¬_stepping, EQ); |
1468 __ EnterStubFrame(); | 1468 __ EnterStubFrame(); |
1469 __ Push(R5); // Preserve IC data. | 1469 __ Push(R5); // Preserve IC data. |
1470 __ CallRuntime(kSingleStepHandlerRuntimeEntry); | 1470 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
1471 __ Pop(R5); | 1471 __ Pop(R5); |
1472 __ LeaveStubFrame(); | 1472 __ LeaveStubFrame(); |
1473 __ Bind(¬_stepping); | 1473 __ Bind(¬_stepping); |
1474 | 1474 |
1475 // Load arguments descriptor into R4. | 1475 // Load arguments descriptor into R4. |
1476 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); | 1476 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); |
1477 // Preserve return address, since LR is needed for subroutine call. | 1477 // Preserve return address, since LR is needed for subroutine call. |
1478 __ mov(R8, ShifterOperand(LR)); | 1478 __ mov(R8, ShifterOperand(LR)); |
1479 // Loop that checks if there is an IC data match. | 1479 // Loop that checks if there is an IC data match. |
1480 Label loop, update, test, found, get_class_id_as_smi; | 1480 Label loop, update, test, found, get_class_id_as_smi; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1545 // Preserve IC data object and arguments descriptor array and | 1545 // Preserve IC data object and arguments descriptor array and |
1546 // setup space on stack for result (target code object). | 1546 // setup space on stack for result (target code object). |
1547 __ PushList((1 << R0) | (1 << R4) | (1 << R5)); | 1547 __ PushList((1 << R0) | (1 << R4) | (1 << R5)); |
1548 // Push call arguments. | 1548 // Push call arguments. |
1549 for (intptr_t i = 0; i < num_args; i++) { | 1549 for (intptr_t i = 0; i < num_args; i++) { |
1550 __ LoadFromOffset(kWord, IP, R7, -i * kWordSize); | 1550 __ LoadFromOffset(kWord, IP, R7, -i * kWordSize); |
1551 __ Push(IP); | 1551 __ Push(IP); |
1552 } | 1552 } |
1553 // Pass IC data object. | 1553 // Pass IC data object. |
1554 __ Push(R5); | 1554 __ Push(R5); |
1555 __ CallRuntime(handle_ic_miss); | 1555 __ CallRuntime(handle_ic_miss, num_args + 1); |
1556 // Remove the call arguments pushed earlier, including the IC data object. | 1556 // Remove the call arguments pushed earlier, including the IC data object. |
1557 __ Drop(num_args + 1); | 1557 __ Drop(num_args + 1); |
1558 // Pop returned code object into R0 (null if not found). | 1558 // Pop returned code object into R0 (null if not found). |
1559 // Restore arguments descriptor array and IC data array. | 1559 // Restore arguments descriptor array and IC data array. |
1560 __ PopList((1 << R0) | (1 << R4) | (1 << R5)); | 1560 __ PopList((1 << R0) | (1 << R4) | (1 << R5)); |
1561 __ LeaveStubFrame(); | 1561 __ LeaveStubFrame(); |
1562 Label call_target_function; | 1562 Label call_target_function; |
1563 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 1563 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
1564 __ b(&call_target_function, NE); | 1564 __ b(&call_target_function, NE); |
1565 // NoSuchMethod or closure. | 1565 // NoSuchMethod or closure. |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1686 #endif // DEBUG | 1686 #endif // DEBUG |
1687 | 1687 |
1688 // Check single stepping. | 1688 // Check single stepping. |
1689 Label not_stepping; | 1689 Label not_stepping; |
1690 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); | 1690 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); |
1691 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); | 1691 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); |
1692 __ CompareImmediate(R6, 0); | 1692 __ CompareImmediate(R6, 0); |
1693 __ b(¬_stepping, EQ); | 1693 __ b(¬_stepping, EQ); |
1694 __ EnterStubFrame(); | 1694 __ EnterStubFrame(); |
1695 __ Push(R5); // Preserve IC data. | 1695 __ Push(R5); // Preserve IC data. |
1696 __ CallRuntime(kSingleStepHandlerRuntimeEntry); | 1696 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
1697 __ Pop(R5); | 1697 __ Pop(R5); |
1698 __ LeaveStubFrame(); | 1698 __ LeaveStubFrame(); |
1699 __ Bind(¬_stepping); | 1699 __ Bind(¬_stepping); |
1700 | 1700 |
1701 // R5: IC data object (preserved). | 1701 // R5: IC data object (preserved). |
1702 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset())); | 1702 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset())); |
1703 // R6: ic_data_array with entries: target functions and count. | 1703 // R6: ic_data_array with entries: target functions and count. |
1704 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); | 1704 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); |
1705 // R6: points directly to the first ic data array element. | 1705 // R6: points directly to the first ic data array element. |
1706 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; | 1706 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; |
(...skipping 14 matching lines...) Expand all Loading... |
1721 __ LoadFromOffset(kWord, R1, R6, target_offset); | 1721 __ LoadFromOffset(kWord, R1, R6, target_offset); |
1722 __ ldr(R0, FieldAddress(R1, Function::code_offset())); | 1722 __ ldr(R0, FieldAddress(R1, Function::code_offset())); |
1723 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 1723 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
1724 __ b(&target_is_compiled, NE); | 1724 __ b(&target_is_compiled, NE); |
1725 // R1: function. | 1725 // R1: function. |
1726 | 1726 |
1727 __ EnterStubFrame(); | 1727 __ EnterStubFrame(); |
1728 // Preserve target function and IC data object. | 1728 // Preserve target function and IC data object. |
1729 __ PushList((1 << R1) | (1 << R5)); | 1729 __ PushList((1 << R1) | (1 << R5)); |
1730 __ Push(R1); // Pass function. | 1730 __ Push(R1); // Pass function. |
1731 __ CallRuntime(kCompileFunctionRuntimeEntry); | 1731 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
1732 __ Drop(1); // Discard argument. | 1732 __ Drop(1); // Discard argument. |
1733 __ PopList((1 << R1) | (1 << R5)); // Restore function and IC data. | 1733 __ PopList((1 << R1) | (1 << R5)); // Restore function and IC data. |
1734 __ LeaveStubFrame(); | 1734 __ LeaveStubFrame(); |
1735 // R0: target function. | 1735 // R0: target function. |
1736 __ ldr(R0, FieldAddress(R1, Function::code_offset())); | 1736 __ ldr(R0, FieldAddress(R1, Function::code_offset())); |
1737 | 1737 |
1738 __ Bind(&target_is_compiled); | 1738 __ Bind(&target_is_compiled); |
1739 // R0: target code. | 1739 // R0: target code. |
1740 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); | 1740 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); |
1741 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag); | 1741 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag); |
(...skipping 17 matching lines...) Expand all Loading... |
1759 | 1759 |
1760 // LR: return address (Dart code). | 1760 // LR: return address (Dart code). |
1761 // R5: IC data (unoptimized static call). | 1761 // R5: IC data (unoptimized static call). |
1762 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { | 1762 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { |
1763 // Create a stub frame as we are pushing some objects on the stack before | 1763 // Create a stub frame as we are pushing some objects on the stack before |
1764 // calling into the runtime. | 1764 // calling into the runtime. |
1765 __ EnterStubFrame(); | 1765 __ EnterStubFrame(); |
1766 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 1766 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
1767 // Preserve arguments descriptor and make room for result. | 1767 // Preserve arguments descriptor and make room for result. |
1768 __ PushList((1 << R0) | (1 << R5)); | 1768 __ PushList((1 << R0) | (1 << R5)); |
1769 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); | 1769 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry, 0); |
1770 // Pop code object result and restore arguments descriptor. | 1770 // Pop code object result and restore arguments descriptor. |
1771 __ PopList((1 << R0) | (1 << R5)); | 1771 __ PopList((1 << R0) | (1 << R5)); |
1772 __ LeaveStubFrame(); | 1772 __ LeaveStubFrame(); |
1773 | 1773 |
1774 // Now call the static function. The breakpoint handler function | 1774 // Now call the static function. The breakpoint handler function |
1775 // ensures that the call target is compiled. | 1775 // ensures that the call target is compiled. |
1776 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); | 1776 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); |
1777 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag); | 1777 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag); |
1778 // Load arguments descriptor into R4. | 1778 // Load arguments descriptor into R4. |
1779 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); | 1779 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); |
1780 __ bx(R0); | 1780 __ bx(R0); |
1781 } | 1781 } |
1782 | 1782 |
1783 | 1783 |
1784 // R0: return value. | 1784 // R0: return value. |
1785 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { | 1785 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { |
1786 // Create a stub frame as we are pushing some objects on the stack before | 1786 // Create a stub frame as we are pushing some objects on the stack before |
1787 // calling into the runtime. | 1787 // calling into the runtime. |
1788 __ EnterStubFrame(); | 1788 __ EnterStubFrame(); |
1789 __ Push(R0); | 1789 __ Push(R0); |
1790 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry); | 1790 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry, 0); |
1791 __ Pop(R0); | 1791 __ Pop(R0); |
1792 __ LeaveStubFrame(); | 1792 __ LeaveStubFrame(); |
1793 | 1793 |
1794 // Instead of returning to the patched Dart function, emulate the | 1794 // Instead of returning to the patched Dart function, emulate the |
1795 // smashed return code pattern and return to the function's caller. | 1795 // smashed return code pattern and return to the function's caller. |
1796 __ LeaveDartFrame(); | 1796 __ LeaveDartFrame(); |
1797 __ Ret(); | 1797 __ Ret(); |
1798 } | 1798 } |
1799 | 1799 |
1800 | 1800 |
1801 // LR: return address (Dart code). | 1801 // LR: return address (Dart code). |
1802 // R5: inline cache data array. | 1802 // R5: inline cache data array. |
1803 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { | 1803 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { |
1804 // Create a stub frame as we are pushing some objects on the stack before | 1804 // Create a stub frame as we are pushing some objects on the stack before |
1805 // calling into the runtime. | 1805 // calling into the runtime. |
1806 __ EnterStubFrame(); | 1806 __ EnterStubFrame(); |
1807 __ Push(R5); | 1807 __ Push(R5); |
1808 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); | 1808 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry, 0); |
1809 __ Pop(R5); | 1809 __ Pop(R5); |
1810 __ LeaveStubFrame(); | 1810 __ LeaveStubFrame(); |
1811 | 1811 |
1812 // Find out which dispatch stub to call. | 1812 // Find out which dispatch stub to call. |
1813 __ ldr(IP, FieldAddress(R5, ICData::num_args_tested_offset())); | 1813 __ ldr(IP, FieldAddress(R5, ICData::num_args_tested_offset())); |
1814 __ cmp(IP, ShifterOperand(1)); | 1814 __ cmp(IP, ShifterOperand(1)); |
1815 __ Branch(&StubCode::OneArgCheckInlineCacheLabel(), EQ); | 1815 __ Branch(&StubCode::OneArgCheckInlineCacheLabel(), EQ); |
1816 __ cmp(IP, ShifterOperand(2)); | 1816 __ cmp(IP, ShifterOperand(2)); |
1817 __ Branch(&StubCode::TwoArgsCheckInlineCacheLabel(), EQ); | 1817 __ Branch(&StubCode::TwoArgsCheckInlineCacheLabel(), EQ); |
1818 __ cmp(IP, ShifterOperand(3)); | 1818 __ cmp(IP, ShifterOperand(3)); |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2025 __ bx(LR, EQ); | 2025 __ bx(LR, EQ); |
2026 __ LoadClassId(R2, R2); | 2026 __ LoadClassId(R2, R2); |
2027 __ SmiTag(R2); | 2027 __ SmiTag(R2); |
2028 __ bx(LR); | 2028 __ bx(LR); |
2029 | 2029 |
2030 __ Bind(&update_ic_data); | 2030 __ Bind(&update_ic_data); |
2031 // R5: ICData | 2031 // R5: ICData |
2032 __ PushList((1 << R0) | (1 << R1)); | 2032 __ PushList((1 << R0) | (1 << R1)); |
2033 __ PushObject(Symbols::EqualOperator()); // Target's name. | 2033 __ PushObject(Symbols::EqualOperator()); // Target's name. |
2034 __ Push(R5); // ICData | 2034 __ Push(R5); // ICData |
2035 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry); // Clobbers R4, R5. | 2035 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry, 4); // Clobbers R4, R5. |
2036 __ Drop(2); | 2036 __ Drop(2); |
2037 __ PopList((1 << R0) | (1 << R1)); | 2037 __ PopList((1 << R0) | (1 << R1)); |
2038 __ b(&compute_result); | 2038 __ b(&compute_result); |
2039 } | 2039 } |
2040 | 2040 |
2041 | 2041 |
2042 // Calls to the runtime to optimize the given function. | 2042 // Calls to the runtime to optimize the given function. |
2043 // R6: function to be reoptimized. | 2043 // R6: function to be reoptimized. |
2044 // R4: argument descriptor (preserved). | 2044 // R4: argument descriptor (preserved). |
2045 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 2045 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
2046 __ EnterStubFrame(); | 2046 __ EnterStubFrame(); |
2047 __ Push(R4); | 2047 __ Push(R4); |
2048 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 2048 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); |
2049 __ Push(IP); // Setup space on stack for return value. | 2049 __ Push(IP); // Setup space on stack for return value. |
2050 __ Push(R6); | 2050 __ Push(R6); |
2051 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); | 2051 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); |
2052 __ Pop(R0); // Discard argument. | 2052 __ Pop(R0); // Discard argument. |
2053 __ Pop(R0); // Get Code object | 2053 __ Pop(R0); // Get Code object |
2054 __ Pop(R4); // Restore argument descriptor. | 2054 __ Pop(R4); // Restore argument descriptor. |
2055 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); | 2055 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); |
2056 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag); | 2056 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag); |
2057 __ LeaveStubFrame(); | 2057 __ LeaveStubFrame(); |
2058 __ bx(R0); | 2058 __ bx(R0); |
2059 __ bkpt(0); | 2059 __ bkpt(0); |
2060 } | 2060 } |
2061 | 2061 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2115 __ b(&done); | 2115 __ b(&done); |
2116 | 2116 |
2117 __ Bind(&check_bigint); | 2117 __ Bind(&check_bigint); |
2118 __ CompareClassId(left, kBigintCid, temp); | 2118 __ CompareClassId(left, kBigintCid, temp); |
2119 __ b(&reference_compare, NE); | 2119 __ b(&reference_compare, NE); |
2120 __ CompareClassId(right, kBigintCid, temp); | 2120 __ CompareClassId(right, kBigintCid, temp); |
2121 __ b(&done, NE); | 2121 __ b(&done, NE); |
2122 __ EnterStubFrame(0); | 2122 __ EnterStubFrame(0); |
2123 __ ReserveAlignedFrameSpace(2 * kWordSize); | 2123 __ ReserveAlignedFrameSpace(2 * kWordSize); |
2124 __ stm(IA, SP, (1 << R0) | (1 << R1)); | 2124 __ stm(IA, SP, (1 << R0) | (1 << R1)); |
2125 __ CallRuntime(kBigintCompareRuntimeEntry); | 2125 __ CallRuntime(kBigintCompareRuntimeEntry, 2); |
2126 // Result in R0, 0 means equal. | 2126 // Result in R0, 0 means equal. |
2127 __ LeaveStubFrame(); | 2127 __ LeaveStubFrame(); |
2128 __ cmp(R0, ShifterOperand(0)); | 2128 __ cmp(R0, ShifterOperand(0)); |
2129 __ b(&done); | 2129 __ b(&done); |
2130 | 2130 |
2131 __ Bind(&reference_compare); | 2131 __ Bind(&reference_compare); |
2132 __ cmp(left, ShifterOperand(right)); | 2132 __ cmp(left, ShifterOperand(right)); |
2133 __ Bind(&done); | 2133 __ Bind(&done); |
2134 } | 2134 } |
2135 | 2135 |
2136 | 2136 |
2137 // Called only from unoptimized code. All relevant registers have been saved. | 2137 // Called only from unoptimized code. All relevant registers have been saved. |
2138 // LR: return address. | 2138 // LR: return address. |
2139 // SP + 4: left operand. | 2139 // SP + 4: left operand. |
2140 // SP + 0: right operand. | 2140 // SP + 0: right operand. |
2141 // Return Zero condition flag set if equal. | 2141 // Return Zero condition flag set if equal. |
2142 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( | 2142 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( |
2143 Assembler* assembler) { | 2143 Assembler* assembler) { |
2144 // Check single stepping. | 2144 // Check single stepping. |
2145 Label not_stepping; | 2145 Label not_stepping; |
2146 __ ldr(R1, FieldAddress(CTX, Context::isolate_offset())); | 2146 __ ldr(R1, FieldAddress(CTX, Context::isolate_offset())); |
2147 __ ldrb(R1, Address(R1, Isolate::single_step_offset())); | 2147 __ ldrb(R1, Address(R1, Isolate::single_step_offset())); |
2148 __ CompareImmediate(R1, 0); | 2148 __ CompareImmediate(R1, 0); |
2149 __ b(¬_stepping, EQ); | 2149 __ b(¬_stepping, EQ); |
2150 __ EnterStubFrame(); | 2150 __ EnterStubFrame(); |
2151 __ CallRuntime(kSingleStepHandlerRuntimeEntry); | 2151 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
2152 __ LeaveStubFrame(); | 2152 __ LeaveStubFrame(); |
2153 __ Bind(¬_stepping); | 2153 __ Bind(¬_stepping); |
2154 | 2154 |
2155 const Register temp = R2; | 2155 const Register temp = R2; |
2156 const Register left = R1; | 2156 const Register left = R1; |
2157 const Register right = R0; | 2157 const Register right = R0; |
2158 __ ldr(left, Address(SP, 1 * kWordSize)); | 2158 __ ldr(left, Address(SP, 1 * kWordSize)); |
2159 __ ldr(right, Address(SP, 0 * kWordSize)); | 2159 __ ldr(right, Address(SP, 0 * kWordSize)); |
2160 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2160 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
2161 __ Ret(); | 2161 __ Ret(); |
(...skipping 16 matching lines...) Expand all Loading... |
2178 __ ldr(left, Address(SP, 4 * kWordSize)); | 2178 __ ldr(left, Address(SP, 4 * kWordSize)); |
2179 __ ldr(right, Address(SP, 3 * kWordSize)); | 2179 __ ldr(right, Address(SP, 3 * kWordSize)); |
2180 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2180 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
2181 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); | 2181 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); |
2182 __ Ret(); | 2182 __ Ret(); |
2183 } | 2183 } |
2184 | 2184 |
2185 } // namespace dart | 2185 } // namespace dart |
2186 | 2186 |
2187 #endif // defined TARGET_ARCH_ARM | 2187 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |