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

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

Issue 1421253004: Use the iOS ABI when running SIMARM on Mac or targeting iOS. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month 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
« runtime/vm/simulator_arm.cc ('K') | « runtime/vm/stack_frame_arm.h ('k') | no next file » | 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/cpu.h" 10 #include "vm/cpu.h"
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 __ add(R9, R9, Operand(R3, LSL, 1)); // R3 is a Smi. 630 __ add(R9, R9, Operand(R3, LSL, 1)); // R3 is a Smi.
631 ASSERT(kSmiTagShift == 1); 631 ASSERT(kSmiTagShift == 1);
632 __ bic(R9, R9, Operand(kObjectAlignment - 1)); 632 __ bic(R9, R9, Operand(kObjectAlignment - 1));
633 633
634 // R9: Allocation size. 634 // R9: Allocation size.
635 Heap::Space space = Heap::SpaceForAllocation(cid); 635 Heap::Space space = Heap::SpaceForAllocation(cid);
636 __ LoadIsolate(R8); 636 __ LoadIsolate(R8);
637 __ ldr(R8, Address(R8, Isolate::heap_offset())); 637 __ ldr(R8, Address(R8, Isolate::heap_offset()));
638 // Potential new object start. 638 // Potential new object start.
639 __ ldr(R0, Address(R8, Heap::TopOffset(space))); 639 __ ldr(R0, Address(R8, Heap::TopOffset(space)));
640 __ adds(R7, R0, Operand(R9)); // Potential next object start. 640 __ adds(R711, R0, Operand(R9)); // Potential next object start.
641 __ b(&slow_case, CS); // Branch if unsigned overflow. 641 __ b(&slow_case, CS); // Branch if unsigned overflow.
642 642
643 // Check if the allocation fits into the remaining space. 643 // Check if the allocation fits into the remaining space.
644 // R0: potential new object start. 644 // R0: potential new object start.
645 // R7: potential next object start. 645 // R711: potential next object start.
646 // R9: allocation size. 646 // R9: allocation size.
647 __ ldr(R3, Address(R8, Heap::EndOffset(space))); 647 __ ldr(R3, Address(R8, Heap::EndOffset(space)));
648 __ cmp(R7, Operand(R3)); 648 __ cmp(R711, Operand(R3));
649 __ b(&slow_case, CS); 649 __ b(&slow_case, CS);
650 650
651 // Successfully allocated the object(s), now update top to point to 651 // Successfully allocated the object(s), now update top to point to
652 // next object start and initialize the object. 652 // next object start and initialize the object.
653 __ LoadAllocationStatsAddress(R3, cid, /* inline_isolate = */ false); 653 __ LoadAllocationStatsAddress(R3, cid, /* inline_isolate = */ false);
654 __ str(R7, Address(R8, Heap::TopOffset(space))); 654 __ str(R711, Address(R8, Heap::TopOffset(space)));
655 __ add(R0, R0, Operand(kHeapObjectTag)); 655 __ add(R0, R0, Operand(kHeapObjectTag));
656 656
657 // Initialize the tags. 657 // Initialize the tags.
658 // R0: new object start as a tagged pointer. 658 // R0: new object start as a tagged pointer.
659 // R3: allocation stats address. 659 // R3: allocation stats address.
660 // R7: new object end address. 660 // R711: new object end address.
661 // R9: allocation size. 661 // R9: allocation size.
662 { 662 {
663 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; 663 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
664 664
665 __ CompareImmediate(R9, RawObject::SizeTag::kMaxSizeTag); 665 __ CompareImmediate(R9, RawObject::SizeTag::kMaxSizeTag);
666 __ mov(R8, Operand(R9, LSL, shift), LS); 666 __ mov(R8, Operand(R9, LSL, shift), LS);
667 __ mov(R8, Operand(0), HI); 667 __ mov(R8, Operand(0), HI);
668 668
669 // Get the class index and insert it into the tags. 669 // Get the class index and insert it into the tags.
670 // R8: size and bit tags. 670 // R8: size and bit tags.
671 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid)); 671 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid));
672 __ orr(R8, R8, Operand(TMP)); 672 __ orr(R8, R8, Operand(TMP));
673 __ str(R8, FieldAddress(R0, Array::tags_offset())); // Store tags. 673 __ str(R8, FieldAddress(R0, Array::tags_offset())); // Store tags.
674 } 674 }
675 675
676 // R0: new object start as a tagged pointer. 676 // R0: new object start as a tagged pointer.
677 // R7: new object end address. 677 // R711: new object end address.
678 // Store the type argument field. 678 // Store the type argument field.
679 __ InitializeFieldNoBarrier(R0, 679 __ InitializeFieldNoBarrier(R0,
680 FieldAddress(R0, Array::type_arguments_offset()), 680 FieldAddress(R0, Array::type_arguments_offset()),
681 R1); 681 R1);
682 682
683 // Set the length field. 683 // Set the length field.
684 __ InitializeFieldNoBarrier(R0, 684 __ InitializeFieldNoBarrier(R0,
685 FieldAddress(R0, Array::length_offset()), 685 FieldAddress(R0, Array::length_offset()),
686 R2); 686 R2);
687 687
688 // Initialize all array elements to raw_null. 688 // Initialize all array elements to raw_null.
689 // R0: new object start as a tagged pointer. 689 // R0: new object start as a tagged pointer.
690 // R3: allocation stats address. 690 // R3: allocation stats address.
691 // R8, R9: null 691 // R8, R9: null
692 // R4: iterator which initially points to the start of the variable 692 // R4: iterator which initially points to the start of the variable
693 // data area to be initialized. 693 // data area to be initialized.
694 // R7: new object end address. 694 // R711: new object end address.
695 // R9: allocation size. 695 // R9: allocation size.
696 __ IncrementAllocationStatsWithSize(R3, R9, space); 696 __ IncrementAllocationStatsWithSize(R3, R9, space);
697 697
698 __ LoadObject(R8, Object::null_object()); 698 __ LoadObject(R8, Object::null_object());
699 __ mov(R9, Operand(R8)); 699 __ mov(R9, Operand(R8));
700 __ AddImmediate(R4, R0, sizeof(RawArray) - kHeapObjectTag); 700 __ AddImmediate(R4, R0, sizeof(RawArray) - kHeapObjectTag);
701 __ InitializeFieldsNoBarrier(R0, R4, R7, R8, R9); 701 __ InitializeFieldsNoBarrier(R0, R4, R711, R8, R9);
702 __ Ret(); // Returns the newly allocated object in R0. 702 __ Ret(); // Returns the newly allocated object in R0.
703 // Unable to allocate the array using the fast inline code, just call 703 // Unable to allocate the array using the fast inline code, just call
704 // into the runtime. 704 // into the runtime.
705 __ Bind(&slow_case); 705 __ Bind(&slow_case);
706 706
707 // Create a stub frame as we are pushing some objects on the stack before 707 // Create a stub frame as we are pushing some objects on the stack before
708 // calling into the runtime. 708 // calling into the runtime.
709 __ EnterStubFrame(); 709 __ EnterStubFrame();
710 __ LoadObject(IP, Object::null_object()); 710 __ LoadObject(IP, Object::null_object());
711 // Setup space on stack for return value. 711 // Setup space on stack for return value.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 // Save top resource and top exit frame info. Use R4-6 as temporary registers. 763 // Save top resource and top exit frame info. Use R4-6 as temporary registers.
764 // StackFrameIterator reads the top exit frame info saved in this frame. 764 // StackFrameIterator reads the top exit frame info saved in this frame.
765 __ LoadFromOffset(kWord, R9, THR, Thread::top_exit_frame_info_offset()); 765 __ LoadFromOffset(kWord, R9, THR, Thread::top_exit_frame_info_offset());
766 __ LoadFromOffset(kWord, R4, THR, Thread::top_resource_offset()); 766 __ LoadFromOffset(kWord, R4, THR, Thread::top_resource_offset());
767 __ LoadImmediate(R8, 0); 767 __ LoadImmediate(R8, 0);
768 __ StoreToOffset(kWord, R8, THR, Thread::top_resource_offset()); 768 __ StoreToOffset(kWord, R8, THR, Thread::top_resource_offset());
769 __ StoreToOffset(kWord, R8, THR, Thread::top_exit_frame_info_offset()); 769 __ StoreToOffset(kWord, R8, THR, Thread::top_exit_frame_info_offset());
770 770
771 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. 771 // kExitLinkSlotFromEntryFp must be kept in sync with the code below.
772 __ Push(R4); 772 __ Push(R4);
773 #if defined(TARGET_OS_MAC)
774 ASSERT(kExitLinkSlotFromEntryFp == -26);
775 #else
773 ASSERT(kExitLinkSlotFromEntryFp == -27); 776 ASSERT(kExitLinkSlotFromEntryFp == -27);
777 #endif
774 __ Push(R9); 778 __ Push(R9);
775 779
776 // Load arguments descriptor array into R4, which is passed to Dart code. 780 // Load arguments descriptor array into R4, which is passed to Dart code.
777 __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle)); 781 __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle));
778 782
779 // Load number of arguments into R9. 783 // Load number of arguments into R9.
780 __ ldr(R9, FieldAddress(R4, ArgumentsDescriptor::count_offset())); 784 __ ldr(R9, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
781 __ SmiUntag(R9); 785 __ SmiUntag(R9);
782 786
783 // Compute address of 'arguments array' data area into R2. 787 // Compute address of 'arguments array' data area into R2.
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 R8); 929 R8);
926 930
927 // Initialize the context variables. 931 // Initialize the context variables.
928 // R0: new object. 932 // R0: new object.
929 // R1: number of context variables. 933 // R1: number of context variables.
930 // R2: object size. 934 // R2: object size.
931 // R3: next object start. 935 // R3: next object start.
932 // R8, R9: raw null. 936 // R8, R9: raw null.
933 // R4: allocation stats address. 937 // R4: allocation stats address.
934 Label loop; 938 Label loop;
935 __ AddImmediate(R7, R0, Context::variable_offset(0) - kHeapObjectTag); 939 __ AddImmediate(R711, R0, Context::variable_offset(0) - kHeapObjectTag);
936 __ InitializeFieldsNoBarrier(R0, R7, R3, R8, R9); 940 __ InitializeFieldsNoBarrier(R0, R711, R3, R8, R9);
937 __ IncrementAllocationStatsWithSize(R4, R2, space); 941 __ IncrementAllocationStatsWithSize(R4, R2, space);
938 942
939 // Done allocating and initializing the context. 943 // Done allocating and initializing the context.
940 // R0: new object. 944 // R0: new object.
941 __ Ret(); 945 __ Ret();
942 946
943 __ Bind(&slow_case); 947 __ Bind(&slow_case);
944 } 948 }
945 // Create a stub frame as we are pushing some objects on the stack before 949 // Create a stub frame as we are pushing some objects on the stack before
946 // calling into the runtime. 950 // calling into the runtime.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 } 1036 }
1033 1037
1034 1038
1035 // Called for inline allocation of objects. 1039 // Called for inline allocation of objects.
1036 // Input parameters: 1040 // Input parameters:
1037 // LR : return address. 1041 // LR : return address.
1038 // SP + 0 : type arguments object (only if class is parameterized). 1042 // SP + 0 : type arguments object (only if class is parameterized).
1039 void StubCode::GenerateAllocationStubForClass(Assembler* assembler, 1043 void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
1040 const Class& cls) { 1044 const Class& cls) {
1041 // Must load pool pointer before being able to patch. 1045 // Must load pool pointer before being able to patch.
1042 Register new_pp = R7; 1046 Register new_pp = R711;
1043 __ LoadPoolPointer(new_pp); 1047 __ LoadPoolPointer(new_pp);
1044 // The generated code is different if the class is parameterized. 1048 // The generated code is different if the class is parameterized.
1045 const bool is_cls_parameterized = cls.NumTypeArguments() > 0; 1049 const bool is_cls_parameterized = cls.NumTypeArguments() > 0;
1046 ASSERT(!is_cls_parameterized || 1050 ASSERT(!is_cls_parameterized ||
1047 (cls.type_arguments_field_offset() != Class::kNoTypeArguments)); 1051 (cls.type_arguments_field_offset() != Class::kNoTypeArguments));
1048 // kInlineInstanceSize is a constant used as a threshold for determining 1052 // kInlineInstanceSize is a constant used as a threshold for determining
1049 // when the object initialization should be done as a loop or as 1053 // when the object initialization should be done as a loop or as
1050 // straight line code. 1054 // straight line code.
1051 const int kInlineInstanceSize = 12; 1055 const int kInlineInstanceSize = 12;
1052 const intptr_t instance_size = cls.instance_size(); 1056 const intptr_t instance_size = cls.instance_size();
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 if (FLAG_trace_optimized_ic_calls) { 1214 if (FLAG_trace_optimized_ic_calls) {
1211 __ EnterStubFrame(); 1215 __ EnterStubFrame();
1212 __ PushList((1 << R9) | (1 << R8)); // Preserve. 1216 __ PushList((1 << R9) | (1 << R8)); // Preserve.
1213 __ Push(ic_reg); // Argument. 1217 __ Push(ic_reg); // Argument.
1214 __ Push(func_reg); // Argument. 1218 __ Push(func_reg); // Argument.
1215 __ CallRuntime(kTraceICCallRuntimeEntry, 2); 1219 __ CallRuntime(kTraceICCallRuntimeEntry, 2);
1216 __ Drop(2); // Discard argument; 1220 __ Drop(2); // Discard argument;
1217 __ PopList((1 << R9) | (1 << R8)); // Restore. 1221 __ PopList((1 << R9) | (1 << R8)); // Restore.
1218 __ LeaveStubFrame(); 1222 __ LeaveStubFrame();
1219 } 1223 }
1220 __ ldr(R7, FieldAddress(func_reg, Function::usage_counter_offset())); 1224 __ ldr(R711, FieldAddress(func_reg, Function::usage_counter_offset()));
1221 __ add(R7, R7, Operand(1)); 1225 __ add(R711, R711, Operand(1));
1222 __ str(R7, FieldAddress(func_reg, Function::usage_counter_offset())); 1226 __ str(R711, FieldAddress(func_reg, Function::usage_counter_offset()));
1223 } 1227 }
1224 1228
1225 1229
1226 // Loads function into 'temp_reg'. 1230 // Loads function into 'temp_reg'.
1227 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, 1231 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
1228 Register temp_reg) { 1232 Register temp_reg) {
1229 if (FLAG_optimization_counter_threshold >= 0) { 1233 if (FLAG_optimization_counter_threshold >= 0) {
1230 Register ic_reg = R9; 1234 Register ic_reg = R9;
1231 Register func_reg = temp_reg; 1235 Register func_reg = temp_reg;
1232 ASSERT(temp_reg == R8); 1236 ASSERT(temp_reg == R8);
1233 __ Comment("Increment function counter"); 1237 __ Comment("Increment function counter");
1234 __ ldr(func_reg, FieldAddress(ic_reg, ICData::owner_offset())); 1238 __ ldr(func_reg, FieldAddress(ic_reg, ICData::owner_offset()));
1235 __ ldr(R7, FieldAddress(func_reg, Function::usage_counter_offset())); 1239 __ ldr(R711, FieldAddress(func_reg, Function::usage_counter_offset()));
1236 __ add(R7, R7, Operand(1)); 1240 __ add(R711, R711, Operand(1));
1237 __ str(R7, FieldAddress(func_reg, Function::usage_counter_offset())); 1241 __ str(R711, FieldAddress(func_reg, Function::usage_counter_offset()));
1238 } 1242 }
1239 } 1243 }
1240 1244
1241 1245
1242 // Note: R9 must be preserved. 1246 // Note: R9 must be preserved.
1243 // Attempt a quick Smi operation for known operations ('kind'). The ICData 1247 // Attempt a quick Smi operation for known operations ('kind'). The ICData
1244 // must have been primed with a Smi/Smi check that will be used for counting 1248 // must have been primed with a Smi/Smi check that will be used for counting
1245 // the invocations. 1249 // the invocations.
1246 static void EmitFastSmiOp(Assembler* assembler, 1250 static void EmitFastSmiOp(Assembler* assembler,
1247 Token::Kind kind, 1251 Token::Kind kind,
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1369 // Loop that checks if there is an IC data match. 1373 // Loop that checks if there is an IC data match.
1370 Label loop, update, test, found; 1374 Label loop, update, test, found;
1371 // R9: IC data object (preserved). 1375 // R9: IC data object (preserved).
1372 __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset())); 1376 __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset()));
1373 // R8: ic_data_array with check entries: classes and target functions. 1377 // R8: ic_data_array with check entries: classes and target functions.
1374 __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag); 1378 __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag);
1375 // R8: points directly to the first ic data array element. 1379 // R8: points directly to the first ic data array element.
1376 1380
1377 // Get the receiver's class ID (first read number of arguments from 1381 // Get the receiver's class ID (first read number of arguments from
1378 // arguments descriptor array and then access the receiver from the stack). 1382 // arguments descriptor array and then access the receiver from the stack).
1379 __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset())); 1383 __ ldr(R711, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
1380 __ sub(R7, R7, Operand(Smi::RawValue(1))); 1384 __ sub(R711, R711, Operand(Smi::RawValue(1)));
1381 __ ldr(R0, Address(SP, R7, LSL, 1)); // R7 (argument_count - 1) is smi. 1385 __ ldr(R0, Address(SP, R711, LSL, 1)); // R711 (argument_count - 1) is smi.
1382 __ LoadTaggedClassIdMayBeSmi(R0, R0); 1386 __ LoadTaggedClassIdMayBeSmi(R0, R0);
1383 // R7: argument_count - 1 (smi). 1387 // R711: argument_count - 1 (smi).
1384 // R0: receiver's class ID (smi). 1388 // R0: receiver's class ID (smi).
1385 __ ldr(R1, Address(R8, 0)); // First class id (smi) to check. 1389 __ ldr(R1, Address(R8, 0)); // First class id (smi) to check.
1386 __ b(&test); 1390 __ b(&test);
1387 1391
1388 __ Comment("ICData loop"); 1392 __ Comment("ICData loop");
1389 __ Bind(&loop); 1393 __ Bind(&loop);
1390 for (int i = 0; i < num_args; i++) { 1394 for (int i = 0; i < num_args; i++) {
1391 if (i > 0) { 1395 if (i > 0) {
1392 // If not the first, load the next argument's class ID. 1396 // If not the first, load the next argument's class ID.
1393 __ AddImmediate(R0, R7, Smi::RawValue(-i)); 1397 __ AddImmediate(R0, R711, Smi::RawValue(-i));
1394 __ ldr(R0, Address(SP, R0, LSL, 1)); 1398 __ ldr(R0, Address(SP, R0, LSL, 1));
1395 __ LoadTaggedClassIdMayBeSmi(R0, R0); 1399 __ LoadTaggedClassIdMayBeSmi(R0, R0);
1396 // R0: next argument class ID (smi). 1400 // R0: next argument class ID (smi).
1397 __ LoadFromOffset(kWord, R1, R8, i * kWordSize); 1401 __ LoadFromOffset(kWord, R1, R8, i * kWordSize);
1398 // R1: next class ID to check (smi). 1402 // R1: next class ID to check (smi).
1399 } 1403 }
1400 __ cmp(R0, Operand(R1)); // Class id match? 1404 __ cmp(R0, Operand(R1)); // Class id match?
1401 if (i < (num_args - 1)) { 1405 if (i < (num_args - 1)) {
1402 __ b(&update, NE); // Continue. 1406 __ b(&update, NE); // Continue.
1403 } else { 1407 } else {
1404 // Last check, all checks before matched. 1408 // Last check, all checks before matched.
1405 __ b(&found, EQ); // Break. 1409 __ b(&found, EQ); // Break.
1406 } 1410 }
1407 } 1411 }
1408 __ Bind(&update); 1412 __ Bind(&update);
1409 // Reload receiver class ID. It has not been destroyed when num_args == 1. 1413 // Reload receiver class ID. It has not been destroyed when num_args == 1.
1410 if (num_args > 1) { 1414 if (num_args > 1) {
1411 __ ldr(R0, Address(SP, R7, LSL, 1)); 1415 __ ldr(R0, Address(SP, R711, LSL, 1));
1412 __ LoadTaggedClassIdMayBeSmi(R0, R0); 1416 __ LoadTaggedClassIdMayBeSmi(R0, R0);
1413 } 1417 }
1414 1418
1415 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; 1419 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize;
1416 __ AddImmediate(R8, entry_size); // Next entry. 1420 __ AddImmediate(R8, entry_size); // Next entry.
1417 __ ldr(R1, Address(R8, 0)); // Next class ID. 1421 __ ldr(R1, Address(R8, 0)); // Next class ID.
1418 1422
1419 __ Bind(&test); 1423 __ Bind(&test);
1420 __ CompareImmediate(R1, Smi::RawValue(kIllegalCid)); // Done? 1424 __ CompareImmediate(R1, Smi::RawValue(kIllegalCid)); // Done?
1421 __ b(&loop, NE); 1425 __ b(&loop, NE);
1422 1426
1423 __ Comment("IC miss"); 1427 __ Comment("IC miss");
1424 // Compute address of arguments. 1428 // Compute address of arguments.
1425 // R7: argument_count - 1 (smi). 1429 // R711: argument_count - 1 (smi).
1426 __ add(R7, SP, Operand(R7, LSL, 1)); // R7 is Smi. 1430 __ add(R711, SP, Operand(R711, LSL, 1)); // R711 is Smi.
1427 // R7: address of receiver. 1431 // R711: address of receiver.
1428 // Create a stub frame as we are pushing some objects on the stack before 1432 // Create a stub frame as we are pushing some objects on the stack before
1429 // calling into the runtime. 1433 // calling into the runtime.
1430 __ EnterStubFrame(); 1434 __ EnterStubFrame();
1431 __ LoadObject(R0, Object::null_object()); 1435 __ LoadObject(R0, Object::null_object());
1432 // Preserve IC data object and arguments descriptor array and 1436 // Preserve IC data object and arguments descriptor array and
1433 // setup space on stack for result (target code object). 1437 // setup space on stack for result (target code object).
1434 __ PushList((1 << R0) | (1 << R4) | (1 << R9)); 1438 __ PushList((1 << R0) | (1 << R4) | (1 << R9));
1435 // Push call arguments. 1439 // Push call arguments.
1436 for (intptr_t i = 0; i < num_args; i++) { 1440 for (intptr_t i = 0; i < num_args; i++) {
1437 __ LoadFromOffset(kWord, IP, R7, -i * kWordSize); 1441 __ LoadFromOffset(kWord, IP, R711, -i * kWordSize);
1438 __ Push(IP); 1442 __ Push(IP);
1439 } 1443 }
1440 // Pass IC data object. 1444 // Pass IC data object.
1441 __ Push(R9); 1445 __ Push(R9);
1442 __ CallRuntime(handle_ic_miss, num_args + 1); 1446 __ CallRuntime(handle_ic_miss, num_args + 1);
1443 // Remove the call arguments pushed earlier, including the IC data object. 1447 // Remove the call arguments pushed earlier, including the IC data object.
1444 __ Drop(num_args + 1); 1448 __ Drop(num_args + 1);
1445 // Pop returned function object into R0. 1449 // Pop returned function object into R0.
1446 // Restore arguments descriptor array and IC data array. 1450 // Restore arguments descriptor array and IC data array.
1447 __ PopList((1 << R0) | (1 << R4) | (1 << R9)); 1451 __ PopList((1 << R0) | (1 << R4) | (1 << R9));
(...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after
2087 // Result: 2091 // Result:
2088 // R1: entry point. 2092 // R1: entry point.
2089 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { 2093 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
2090 EmitMegamorphicLookup(assembler, R0, R1, R1); 2094 EmitMegamorphicLookup(assembler, R0, R1, R1);
2091 __ Ret(); 2095 __ Ret();
2092 } 2096 }
2093 2097
2094 } // namespace dart 2098 } // namespace dart
2095 2099
2096 #endif // defined TARGET_ARCH_ARM 2100 #endif // defined TARGET_ARCH_ARM
OLDNEW
« runtime/vm/simulator_arm.cc ('K') | « runtime/vm/stack_frame_arm.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698