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

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

Issue 19256021: Merges ARM load/store type enums into one enum. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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/intrinsifier_arm.cc ('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/compiler.h" 10 #include "vm/compiler.h"
(...skipping 29 matching lines...) Expand all
40 const intptr_t argv_offset = NativeArguments::argv_offset(); 40 const intptr_t argv_offset = NativeArguments::argv_offset();
41 const intptr_t retval_offset = NativeArguments::retval_offset(); 41 const intptr_t retval_offset = NativeArguments::retval_offset();
42 42
43 __ EnterFrame((1 << FP) | (1 << LR), 0); 43 __ EnterFrame((1 << FP) | (1 << LR), 0);
44 44
45 // Load current Isolate pointer from Context structure into R0. 45 // Load current Isolate pointer from Context structure into R0.
46 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); 46 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset()));
47 47
48 // Save exit frame information to enable stack walking as we are about 48 // Save exit frame information to enable stack walking as we are about
49 // to transition to Dart VM C++ code. 49 // to transition to Dart VM C++ code.
50 __ StoreToOffset(kStoreWord, SP, R0, Isolate::top_exit_frame_info_offset()); 50 __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset());
51 51
52 // Save current Context pointer into Isolate structure. 52 // Save current Context pointer into Isolate structure.
53 __ StoreToOffset(kStoreWord, CTX, R0, Isolate::top_context_offset()); 53 __ StoreToOffset(kWord, CTX, R0, Isolate::top_context_offset());
54 54
55 // Cache Isolate pointer into CTX while executing runtime code. 55 // Cache Isolate pointer into CTX while executing runtime code.
56 __ mov(CTX, ShifterOperand(R0)); 56 __ mov(CTX, ShifterOperand(R0));
57 57
58 // Reserve space for arguments and align frame before entering C++ world. 58 // Reserve space for arguments and align frame before entering C++ world.
59 // NativeArguments are passed in registers. 59 // NativeArguments are passed in registers.
60 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); 60 ASSERT(sizeof(NativeArguments) == 4 * kWordSize);
61 __ ReserveAlignedFrameSpace(0); 61 __ ReserveAlignedFrameSpace(0);
62 62
63 // Pass NativeArguments structure by value and call runtime. 63 // Pass NativeArguments structure by value and call runtime.
(...skipping 12 matching lines...) Expand all
76 __ AddImmediate(R2, kWordSize); // Set argv in NativeArguments. 76 __ AddImmediate(R2, kWordSize); // Set argv in NativeArguments.
77 77
78 ASSERT(retval_offset == 3 * kWordSize); 78 ASSERT(retval_offset == 3 * kWordSize);
79 __ add(R3, R2, ShifterOperand(kWordSize)); // Retval is next to 1st argument. 79 __ add(R3, R2, ShifterOperand(kWordSize)); // Retval is next to 1st argument.
80 80
81 // Call runtime or redirection via simulator. 81 // Call runtime or redirection via simulator.
82 __ blx(R5); 82 __ blx(R5);
83 83
84 // Reset exit frame information in Isolate structure. 84 // Reset exit frame information in Isolate structure.
85 __ LoadImmediate(R2, 0); 85 __ LoadImmediate(R2, 0);
86 __ StoreToOffset(kStoreWord, R2, CTX, Isolate::top_exit_frame_info_offset()); 86 __ StoreToOffset(kWord, R2, CTX, Isolate::top_exit_frame_info_offset());
87 87
88 // Load Context pointer from Isolate structure into R2. 88 // Load Context pointer from Isolate structure into R2.
89 __ LoadFromOffset(kLoadWord, R2, CTX, Isolate::top_context_offset()); 89 __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset());
90 90
91 // Reset Context pointer in Isolate structure. 91 // Reset Context pointer in Isolate structure.
92 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); 92 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null()));
93 __ StoreToOffset(kStoreWord, R3, CTX, Isolate::top_context_offset()); 93 __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset());
94 94
95 // Cache Context pointer into CTX while executing Dart code. 95 // Cache Context pointer into CTX while executing Dart code.
96 __ mov(CTX, ShifterOperand(R2)); 96 __ mov(CTX, ShifterOperand(R2));
97 97
98 __ LeaveFrame((1 << FP) | (1 << LR)); 98 __ LeaveFrame((1 << FP) | (1 << LR));
99 __ Ret(); 99 __ Ret();
100 } 100 }
101 101
102 102
103 // Print the stop message. 103 // Print the stop message.
(...skipping 27 matching lines...) Expand all
131 const intptr_t argv_offset = NativeArguments::argv_offset(); 131 const intptr_t argv_offset = NativeArguments::argv_offset();
132 const intptr_t retval_offset = NativeArguments::retval_offset(); 132 const intptr_t retval_offset = NativeArguments::retval_offset();
133 133
134 __ EnterFrame((1 << FP) | (1 << LR), 0); 134 __ EnterFrame((1 << FP) | (1 << LR), 0);
135 135
136 // Load current Isolate pointer from Context structure into R0. 136 // Load current Isolate pointer from Context structure into R0.
137 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); 137 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset()));
138 138
139 // Save exit frame information to enable stack walking as we are about 139 // Save exit frame information to enable stack walking as we are about
140 // to transition to native code. 140 // to transition to native code.
141 __ StoreToOffset(kStoreWord, SP, R0, Isolate::top_exit_frame_info_offset()); 141 __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset());
142 142
143 // Save current Context pointer into Isolate structure. 143 // Save current Context pointer into Isolate structure.
144 __ StoreToOffset(kStoreWord, CTX, R0, Isolate::top_context_offset()); 144 __ StoreToOffset(kWord, CTX, R0, Isolate::top_context_offset());
145 145
146 // Cache Isolate pointer into CTX while executing native code. 146 // Cache Isolate pointer into CTX while executing native code.
147 __ mov(CTX, ShifterOperand(R0)); 147 __ mov(CTX, ShifterOperand(R0));
148 148
149 // Reserve space for the native arguments structure passed on the stack (the 149 // Reserve space for the native arguments structure passed on the stack (the
150 // outgoing pointer parameter to the native arguments structure is passed in 150 // outgoing pointer parameter to the native arguments structure is passed in
151 // R0) and align frame before entering the C++ world. 151 // R0) and align frame before entering the C++ world.
152 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); 152 __ ReserveAlignedFrameSpace(sizeof(NativeArguments));
153 153
154 // Initialize NativeArguments structure and call native function. 154 // Initialize NativeArguments structure and call native function.
(...skipping 17 matching lines...) Expand all
172 // It would require changing Dart API for native functions. 172 // It would require changing Dart API for native functions.
173 // For now, space is reserved on the stack and we pass a pointer to it. 173 // For now, space is reserved on the stack and we pass a pointer to it.
174 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); 174 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3));
175 __ mov(R0, ShifterOperand(SP)); // Pass the pointer to the NativeArguments. 175 __ mov(R0, ShifterOperand(SP)); // Pass the pointer to the NativeArguments.
176 176
177 // Call native function or redirection via simulator. 177 // Call native function or redirection via simulator.
178 __ blx(R5); 178 __ blx(R5);
179 179
180 // Reset exit frame information in Isolate structure. 180 // Reset exit frame information in Isolate structure.
181 __ LoadImmediate(R2, 0); 181 __ LoadImmediate(R2, 0);
182 __ StoreToOffset(kStoreWord, R2, CTX, Isolate::top_exit_frame_info_offset()); 182 __ StoreToOffset(kWord, R2, CTX, Isolate::top_exit_frame_info_offset());
183 183
184 // Load Context pointer from Isolate structure into R2. 184 // Load Context pointer from Isolate structure into R2.
185 __ LoadFromOffset(kLoadWord, R2, CTX, Isolate::top_context_offset()); 185 __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset());
186 186
187 // Reset Context pointer in Isolate structure. 187 // Reset Context pointer in Isolate structure.
188 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); 188 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null()));
189 __ StoreToOffset(kStoreWord, R3, CTX, Isolate::top_context_offset()); 189 __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset());
190 190
191 // Cache Context pointer into CTX while executing Dart code. 191 // Cache Context pointer into CTX while executing Dart code.
192 __ mov(CTX, ShifterOperand(R2)); 192 __ mov(CTX, ShifterOperand(R2));
193 193
194 __ LeaveFrame((1 << FP) | (1 << LR)); 194 __ LeaveFrame((1 << FP) | (1 << LR));
195 __ Ret(); 195 __ Ret();
196 } 196 }
197 197
198 198
199 // Input parameters: 199 // Input parameters:
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 // and is computed as: 468 // and is computed as:
469 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). 469 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
470 // Assert that length is a Smi. 470 // Assert that length is a Smi.
471 __ tst(R2, ShifterOperand(kSmiTagMask)); 471 __ tst(R2, ShifterOperand(kSmiTagMask));
472 if (FLAG_use_slow_path) { 472 if (FLAG_use_slow_path) {
473 __ b(&slow_case); 473 __ b(&slow_case);
474 } else { 474 } else {
475 __ b(&slow_case, NE); 475 __ b(&slow_case, NE);
476 } 476 }
477 __ ldr(R8, FieldAddress(CTX, Context::isolate_offset())); 477 __ ldr(R8, FieldAddress(CTX, Context::isolate_offset()));
478 __ LoadFromOffset(kLoadWord, R8, R8, Isolate::heap_offset()); 478 __ LoadFromOffset(kWord, R8, R8, Isolate::heap_offset());
479 __ LoadFromOffset(kLoadWord, R8, R8, Heap::new_space_offset()); 479 __ LoadFromOffset(kWord, R8, R8, Heap::new_space_offset());
480 480
481 // Calculate and align allocation size. 481 // Calculate and align allocation size.
482 // Load new object start and calculate next object start. 482 // Load new object start and calculate next object start.
483 // R1: array element type. 483 // R1: array element type.
484 // R2: array length as Smi. 484 // R2: array length as Smi.
485 // R8: points to new space object. 485 // R8: points to new space object.
486 __ LoadFromOffset(kLoadWord, R0, R8, Scavenger::top_offset()); 486 __ LoadFromOffset(kWord, R0, R8, Scavenger::top_offset());
487 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; 487 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1;
488 __ LoadImmediate(R3, fixed_size); 488 __ LoadImmediate(R3, fixed_size);
489 __ add(R3, R3, ShifterOperand(R2, LSL, 1)); // R2 is Smi. 489 __ add(R3, R3, ShifterOperand(R2, LSL, 1)); // R2 is Smi.
490 ASSERT(kSmiTagShift == 1); 490 ASSERT(kSmiTagShift == 1);
491 __ bic(R3, R3, ShifterOperand(kObjectAlignment - 1)); 491 __ bic(R3, R3, ShifterOperand(kObjectAlignment - 1));
492 __ add(R7, R3, ShifterOperand(R0)); 492 __ add(R7, R3, ShifterOperand(R0));
493 493
494 // Check if the allocation fits into the remaining space. 494 // Check if the allocation fits into the remaining space.
495 // R0: potential new object start. 495 // R0: potential new object start.
496 // R1: array element type. 496 // R1: array element type.
497 // R2: array length as Smi. 497 // R2: array length as Smi.
498 // R3: array size. 498 // R3: array size.
499 // R7: potential next object start. 499 // R7: potential next object start.
500 // R8: points to new space object. 500 // R8: points to new space object.
501 __ LoadFromOffset(kLoadWord, IP, R8, Scavenger::end_offset()); 501 __ LoadFromOffset(kWord, IP, R8, Scavenger::end_offset());
502 __ cmp(R7, ShifterOperand(IP)); 502 __ cmp(R7, ShifterOperand(IP));
503 __ b(&slow_case, CS); // Branch if unsigned higher or equal. 503 __ b(&slow_case, CS); // Branch if unsigned higher or equal.
504 504
505 // Successfully allocated the object(s), now update top to point to 505 // Successfully allocated the object(s), now update top to point to
506 // next object start and initialize the object. 506 // next object start and initialize the object.
507 // R0: potential new object start. 507 // R0: potential new object start.
508 // R7: potential next object start. 508 // R7: potential next object start.
509 // R8: Points to new space object. 509 // R8: Points to new space object.
510 __ StoreToOffset(kStoreWord, R7, R8, Scavenger::top_offset()); 510 __ StoreToOffset(kWord, R7, R8, Scavenger::top_offset());
511 __ add(R0, R0, ShifterOperand(kHeapObjectTag)); 511 __ add(R0, R0, ShifterOperand(kHeapObjectTag));
512 512
513 // R0: new object start as a tagged pointer. 513 // R0: new object start as a tagged pointer.
514 // R1: array element type. 514 // R1: array element type.
515 // R2: array length as Smi. 515 // R2: array length as Smi.
516 // R3: array size. 516 // R3: array size.
517 // R7: new object end address. 517 // R7: new object end address.
518 518
519 // Store the type argument field. 519 // Store the type argument field.
520 __ StoreIntoObjectNoBarrier( 520 __ StoreIntoObjectNoBarrier(
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 // compiled or runtime stub code. 702 // compiled or runtime stub code.
703 703
704 // Cache the new Context pointer into CTX while executing Dart code. 704 // Cache the new Context pointer into CTX while executing Dart code.
705 __ ldr(CTX, Address(R3, VMHandles::kOffsetOfRawPtrInHandle)); 705 __ ldr(CTX, Address(R3, VMHandles::kOffsetOfRawPtrInHandle));
706 706
707 // Load Isolate pointer from Context structure into temporary register R8. 707 // Load Isolate pointer from Context structure into temporary register R8.
708 __ ldr(R8, FieldAddress(CTX, Context::isolate_offset())); 708 __ ldr(R8, FieldAddress(CTX, Context::isolate_offset()));
709 709
710 // Save the top exit frame info. Use R5 as a temporary register. 710 // Save the top exit frame info. Use R5 as a temporary register.
711 // StackFrameIterator reads the top exit frame info saved in this frame. 711 // StackFrameIterator reads the top exit frame info saved in this frame.
712 __ LoadFromOffset(kLoadWord, R5, R8, Isolate::top_exit_frame_info_offset()); 712 __ LoadFromOffset(kWord, R5, R8, Isolate::top_exit_frame_info_offset());
713 __ LoadImmediate(R6, 0); 713 __ LoadImmediate(R6, 0);
714 __ StoreToOffset(kStoreWord, R6, R8, Isolate::top_exit_frame_info_offset()); 714 __ StoreToOffset(kWord, R6, R8, Isolate::top_exit_frame_info_offset());
715 715
716 // Save the old Context pointer. Use R4 as a temporary register. 716 // Save the old Context pointer. Use R4 as a temporary register.
717 // Note that VisitObjectPointers will find this saved Context pointer during 717 // Note that VisitObjectPointers will find this saved Context pointer during
718 // GC marking, since it traverses any information between SP and 718 // GC marking, since it traverses any information between SP and
719 // FP - kExitLinkSlotFromEntryFp. 719 // FP - kExitLinkSlotFromEntryFp.
720 // EntryFrame::SavedContext reads the context saved in this frame. 720 // EntryFrame::SavedContext reads the context saved in this frame.
721 __ LoadFromOffset(kLoadWord, R4, R8, Isolate::top_context_offset()); 721 __ LoadFromOffset(kWord, R4, R8, Isolate::top_context_offset());
722 722
723 // The constants kSavedContextSlotFromEntryFp and 723 // The constants kSavedContextSlotFromEntryFp and
724 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. 724 // kExitLinkSlotFromEntryFp must be kept in sync with the code below.
725 ASSERT(kExitLinkSlotFromEntryFp == -9); 725 ASSERT(kExitLinkSlotFromEntryFp == -9);
726 ASSERT(kSavedContextSlotFromEntryFp == -10); 726 ASSERT(kSavedContextSlotFromEntryFp == -10);
727 __ PushList((1 << R4) | (1 << R5)); 727 __ PushList((1 << R4) | (1 << R5));
728 728
729 // The stack pointer is restored after the call to this location. 729 // The stack pointer is restored after the call to this location.
730 const intptr_t kSavedContextSlotFromEntryFp = -10 * kWordSize; 730 const intptr_t kSavedContextSlotFromEntryFp = -10 * kWordSize;
731 731
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp); 766 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp);
767 767
768 // Load Isolate pointer from Context structure into CTX. Drop Context. 768 // Load Isolate pointer from Context structure into CTX. Drop Context.
769 __ ldr(CTX, FieldAddress(CTX, Context::isolate_offset())); 769 __ ldr(CTX, FieldAddress(CTX, Context::isolate_offset()));
770 770
771 // Restore the saved Context pointer into the Isolate structure. 771 // Restore the saved Context pointer into the Isolate structure.
772 // Uses R4 as a temporary register for this. 772 // Uses R4 as a temporary register for this.
773 // Restore the saved top exit frame info back into the Isolate structure. 773 // Restore the saved top exit frame info back into the Isolate structure.
774 // Uses R5 as a temporary register for this. 774 // Uses R5 as a temporary register for this.
775 __ PopList((1 << R4) | (1 << R5)); 775 __ PopList((1 << R4) | (1 << R5));
776 __ StoreToOffset(kStoreWord, R4, CTX, Isolate::top_context_offset()); 776 __ StoreToOffset(kWord, R4, CTX, Isolate::top_context_offset());
777 __ StoreToOffset(kStoreWord, R5, CTX, Isolate::top_exit_frame_info_offset()); 777 __ StoreToOffset(kWord, R5, CTX, Isolate::top_exit_frame_info_offset());
778 778
779 // Restore C++ ABI callee-saved registers. 779 // Restore C++ ABI callee-saved registers.
780 __ PopList((1 << R3) | kAbiPreservedCpuRegs); // Ignore restored R3. 780 __ PopList((1 << R3) | kAbiPreservedCpuRegs); // Ignore restored R3.
781 781
782 // Restore the frame pointer and return. 782 // Restore the frame pointer and return.
783 __ LeaveStubFrame(); 783 __ LeaveStubFrame();
784 __ Ret(); 784 __ Ret();
785 } 785 }
786 786
787 787
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
1063 // R2: new object start. 1063 // R2: new object start.
1064 // R3: next object start. 1064 // R3: next object start.
1065 // R1: new object type arguments (if is_cls_parameterized). 1065 // R1: new object type arguments (if is_cls_parameterized).
1066 // First try inlining the initialization without a loop. 1066 // First try inlining the initialization without a loop.
1067 if (instance_size < (kInlineInstanceSize * kWordSize)) { 1067 if (instance_size < (kInlineInstanceSize * kWordSize)) {
1068 // Check if the object contains any non-header fields. 1068 // Check if the object contains any non-header fields.
1069 // Small objects are initialized using a consecutive set of writes. 1069 // Small objects are initialized using a consecutive set of writes.
1070 for (intptr_t current_offset = sizeof(RawObject); 1070 for (intptr_t current_offset = sizeof(RawObject);
1071 current_offset < instance_size; 1071 current_offset < instance_size;
1072 current_offset += kWordSize) { 1072 current_offset += kWordSize) {
1073 __ StoreToOffset(kStoreWord, R0, R2, current_offset); 1073 __ StoreToOffset(kWord, R0, R2, current_offset);
1074 } 1074 }
1075 } else { 1075 } else {
1076 __ add(R4, R2, ShifterOperand(sizeof(RawObject))); 1076 __ add(R4, R2, ShifterOperand(sizeof(RawObject)));
1077 // Loop until the whole object is initialized. 1077 // Loop until the whole object is initialized.
1078 // R0: raw null. 1078 // R0: raw null.
1079 // R2: new object. 1079 // R2: new object.
1080 // R3: next object start. 1080 // R3: next object start.
1081 // R4: next word to be initialized. 1081 // R4: next word to be initialized.
1082 // R1: new object type arguments (if is_cls_parameterized). 1082 // R1: new object type arguments (if is_cls_parameterized).
1083 Label init_loop; 1083 Label init_loop;
1084 Label done; 1084 Label done;
1085 __ Bind(&init_loop); 1085 __ Bind(&init_loop);
1086 __ cmp(R4, ShifterOperand(R3)); 1086 __ cmp(R4, ShifterOperand(R3));
1087 __ b(&done, CS); 1087 __ b(&done, CS);
1088 __ str(R0, Address(R4, 0)); 1088 __ str(R0, Address(R4, 0));
1089 __ AddImmediate(R4, kWordSize); 1089 __ AddImmediate(R4, kWordSize);
1090 __ b(&init_loop); 1090 __ b(&init_loop);
1091 __ Bind(&done); 1091 __ Bind(&done);
1092 } 1092 }
1093 if (is_cls_parameterized) { 1093 if (is_cls_parameterized) {
1094 // R1: new object type arguments. 1094 // R1: new object type arguments.
1095 // Set the type arguments in the new object. 1095 // Set the type arguments in the new object.
1096 __ StoreToOffset(kStoreWord, R1, R2, cls.type_arguments_field_offset()); 1096 __ StoreToOffset(kWord, R1, R2, cls.type_arguments_field_offset());
1097 } 1097 }
1098 // Done allocating and initializing the instance. 1098 // Done allocating and initializing the instance.
1099 // R2: new object still missing its heap tag. 1099 // R2: new object still missing its heap tag.
1100 __ add(R0, R2, ShifterOperand(kHeapObjectTag)); 1100 __ add(R0, R2, ShifterOperand(kHeapObjectTag));
1101 // R0: new object. 1101 // R0: new object.
1102 __ Ret(); 1102 __ Ret();
1103 1103
1104 __ Bind(&slow_case); 1104 __ Bind(&slow_case);
1105 } 1105 }
1106 if (is_cls_parameterized) { 1106 if (is_cls_parameterized) {
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
1414 __ b(&test); 1414 __ b(&test);
1415 1415
1416 __ Bind(&loop); 1416 __ Bind(&loop);
1417 for (int i = 0; i < num_args; i++) { 1417 for (int i = 0; i < num_args; i++) {
1418 if (i > 0) { 1418 if (i > 0) {
1419 // If not the first, load the next argument's class ID. 1419 // If not the first, load the next argument's class ID.
1420 __ AddImmediate(R0, R7, Smi::RawValue(-i)); 1420 __ AddImmediate(R0, R7, Smi::RawValue(-i));
1421 __ ldr(R0, Address(SP, R0, LSL, 1)); 1421 __ ldr(R0, Address(SP, R0, LSL, 1));
1422 __ bl(&get_class_id_as_smi); 1422 __ bl(&get_class_id_as_smi);
1423 // R0: next argument class ID (smi). 1423 // R0: next argument class ID (smi).
1424 __ LoadFromOffset(kLoadWord, R1, R6, i * kWordSize); 1424 __ LoadFromOffset(kWord, R1, R6, i * kWordSize);
1425 // R1: next class ID to check (smi). 1425 // R1: next class ID to check (smi).
1426 } 1426 }
1427 __ cmp(R0, ShifterOperand(R1)); // Class id match? 1427 __ cmp(R0, ShifterOperand(R1)); // Class id match?
1428 if (i < (num_args - 1)) { 1428 if (i < (num_args - 1)) {
1429 __ b(&update, NE); // Continue. 1429 __ b(&update, NE); // Continue.
1430 } else { 1430 } else {
1431 // Last check, all checks before matched. 1431 // Last check, all checks before matched.
1432 __ mov(LR, ShifterOperand(R8), EQ); // Restore return address if found. 1432 __ mov(LR, ShifterOperand(R8), EQ); // Restore return address if found.
1433 __ b(&found, EQ); // Break. 1433 __ b(&found, EQ); // Break.
1434 } 1434 }
(...skipping 23 matching lines...) Expand all
1458 // R7: address of receiver. 1458 // R7: address of receiver.
1459 // Create a stub frame as we are pushing some objects on the stack before 1459 // Create a stub frame as we are pushing some objects on the stack before
1460 // calling into the runtime. 1460 // calling into the runtime.
1461 __ EnterStubFrame(); 1461 __ EnterStubFrame();
1462 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); 1462 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
1463 // Preserve IC data object and arguments descriptor array and 1463 // Preserve IC data object and arguments descriptor array and
1464 // setup space on stack for result (target code object). 1464 // setup space on stack for result (target code object).
1465 __ PushList((1 << R0) | (1 << R4) | (1 << R5)); 1465 __ PushList((1 << R0) | (1 << R4) | (1 << R5));
1466 // Push call arguments. 1466 // Push call arguments.
1467 for (intptr_t i = 0; i < num_args; i++) { 1467 for (intptr_t i = 0; i < num_args; i++) {
1468 __ LoadFromOffset(kLoadWord, IP, R7, -i * kWordSize); 1468 __ LoadFromOffset(kWord, IP, R7, -i * kWordSize);
1469 __ Push(IP); 1469 __ Push(IP);
1470 } 1470 }
1471 // Pass IC data object and arguments descriptor array. 1471 // Pass IC data object and arguments descriptor array.
1472 __ PushList((1 << R4) | (1 << R5)); 1472 __ PushList((1 << R4) | (1 << R5));
1473 1473
1474 if (num_args == 1) { 1474 if (num_args == 1) {
1475 __ CallRuntime(kInlineCacheMissHandlerOneArgRuntimeEntry); 1475 __ CallRuntime(kInlineCacheMissHandlerOneArgRuntimeEntry);
1476 } else if (num_args == 2) { 1476 } else if (num_args == 2) {
1477 __ CallRuntime(kInlineCacheMissHandlerTwoArgsRuntimeEntry); 1477 __ CallRuntime(kInlineCacheMissHandlerTwoArgsRuntimeEntry);
1478 } else if (num_args == 3) { 1478 } else if (num_args == 3) {
(...skipping 15 matching lines...) Expand all
1494 // Mark IC call that it may be a closure call that does not collect 1494 // Mark IC call that it may be a closure call that does not collect
1495 // type feedback. 1495 // type feedback.
1496 __ mov(IP, ShifterOperand(1)); 1496 __ mov(IP, ShifterOperand(1));
1497 __ strb(IP, FieldAddress(R5, ICData::is_closure_call_offset())); 1497 __ strb(IP, FieldAddress(R5, ICData::is_closure_call_offset()));
1498 __ Branch(&StubCode::InstanceFunctionLookupLabel()); 1498 __ Branch(&StubCode::InstanceFunctionLookupLabel());
1499 1499
1500 __ Bind(&found); 1500 __ Bind(&found);
1501 // R6: pointer to an IC data check group. 1501 // R6: pointer to an IC data check group.
1502 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; 1502 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
1503 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; 1503 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
1504 __ LoadFromOffset(kLoadWord, R0, R6, target_offset); 1504 __ LoadFromOffset(kWord, R0, R6, target_offset);
1505 __ LoadFromOffset(kLoadWord, R1, R6, count_offset); 1505 __ LoadFromOffset(kWord, R1, R6, count_offset);
1506 __ adds(R1, R1, ShifterOperand(Smi::RawValue(1))); 1506 __ adds(R1, R1, ShifterOperand(Smi::RawValue(1)));
1507 __ StoreToOffset(kStoreWord, R1, R6, count_offset); 1507 __ StoreToOffset(kWord, R1, R6, count_offset);
1508 __ b(&call_target_function, VC); // No overflow. 1508 __ b(&call_target_function, VC); // No overflow.
1509 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue)); 1509 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue));
1510 __ StoreToOffset(kStoreWord, R1, R6, count_offset); 1510 __ StoreToOffset(kWord, R1, R6, count_offset);
1511 1511
1512 __ Bind(&call_target_function); 1512 __ Bind(&call_target_function);
1513 // R0: target function. 1513 // R0: target function.
1514 __ ldr(R0, FieldAddress(R0, Function::code_offset())); 1514 __ ldr(R0, FieldAddress(R0, Function::code_offset()));
1515 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); 1515 __ ldr(R0, FieldAddress(R0, Code::instructions_offset()));
1516 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag); 1516 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag);
1517 __ bx(R0); 1517 __ bx(R0);
1518 1518
1519 // Instance in R0, return its class-id in R0 as Smi. 1519 // Instance in R0, return its class-id in R0 as Smi.
1520 __ Bind(&get_class_id_as_smi); 1520 __ Bind(&get_class_id_as_smi);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1621 // R5: IC data object (preserved). 1621 // R5: IC data object (preserved).
1622 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset())); 1622 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset()));
1623 // R6: ic_data_array with entries: target functions and count. 1623 // R6: ic_data_array with entries: target functions and count.
1624 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); 1624 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag);
1625 // R6: points directly to the first ic data array element. 1625 // R6: points directly to the first ic data array element.
1626 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; 1626 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
1627 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; 1627 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
1628 1628
1629 // Increment count for this call. 1629 // Increment count for this call.
1630 Label increment_done; 1630 Label increment_done;
1631 __ LoadFromOffset(kLoadWord, R1, R6, count_offset); 1631 __ LoadFromOffset(kWord, R1, R6, count_offset);
1632 __ adds(R1, R1, ShifterOperand(Smi::RawValue(1))); 1632 __ adds(R1, R1, ShifterOperand(Smi::RawValue(1)));
1633 __ StoreToOffset(kStoreWord, R1, R6, count_offset); 1633 __ StoreToOffset(kWord, R1, R6, count_offset);
1634 __ b(&increment_done, VC); // No overflow. 1634 __ b(&increment_done, VC); // No overflow.
1635 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue)); 1635 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue));
1636 __ StoreToOffset(kStoreWord, R1, R6, count_offset); 1636 __ StoreToOffset(kWord, R1, R6, count_offset);
1637 __ Bind(&increment_done); 1637 __ Bind(&increment_done);
1638 1638
1639 Label target_is_compiled; 1639 Label target_is_compiled;
1640 // Get function and call it, if possible. 1640 // Get function and call it, if possible.
1641 __ LoadFromOffset(kLoadWord, R1, R6, target_offset); 1641 __ LoadFromOffset(kWord, R1, R6, target_offset);
1642 __ ldr(R0, FieldAddress(R1, Function::code_offset())); 1642 __ ldr(R0, FieldAddress(R1, Function::code_offset()));
1643 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); 1643 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
1644 __ b(&target_is_compiled, NE); 1644 __ b(&target_is_compiled, NE);
1645 // R1: function. 1645 // R1: function.
1646 1646
1647 __ EnterStubFrame(); 1647 __ EnterStubFrame();
1648 // Preserve target function and IC data object. 1648 // Preserve target function and IC data object.
1649 __ PushList((1 << R1) | (1 << R5)); 1649 __ PushList((1 << R1) | (1 << R5));
1650 __ Push(R1); // Pass function. 1650 __ Push(R1); // Pass function.
1651 __ CallRuntime(kCompileFunctionRuntimeEntry); 1651 __ CallRuntime(kCompileFunctionRuntimeEntry);
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
2091 __ ldr(left, Address(SP, 4 * kWordSize)); 2091 __ ldr(left, Address(SP, 4 * kWordSize));
2092 __ ldr(right, Address(SP, 3 * kWordSize)); 2092 __ ldr(right, Address(SP, 3 * kWordSize));
2093 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 2093 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2094 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); 2094 __ PopList((1 << R0) | (1 << R1) | (1 << R2));
2095 __ Ret(); 2095 __ Ret();
2096 } 2096 }
2097 2097
2098 } // namespace dart 2098 } // namespace dart
2099 2099
2100 #endif // defined TARGET_ARCH_ARM 2100 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698