Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: runtime/vm/stub_code_arm.cc

Issue 23672011: Fix the previously ineffective assert checking the number of arguments passed to (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/runtime_entry_x64.cc ('k') | runtime/vm/stub_code_arm_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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(&not_stepping, EQ); 1467 __ b(&not_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(&not_stepping); 1473 __ Bind(&not_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
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
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(&not_stepping, EQ); 1693 __ b(&not_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(&not_stepping); 1699 __ Bind(&not_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
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
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
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
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(&not_stepping, EQ); 2149 __ b(&not_stepping, EQ);
2150 __ EnterStubFrame(); 2150 __ EnterStubFrame();
2151 __ CallRuntime(kSingleStepHandlerRuntimeEntry); 2151 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
2152 __ LeaveStubFrame(); 2152 __ LeaveStubFrame();
2153 __ Bind(&not_stepping); 2153 __ Bind(&not_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
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
OLDNEW
« no previous file with comments | « runtime/vm/runtime_entry_x64.cc ('k') | runtime/vm/stub_code_arm_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698