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

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

Issue 259903002: Enables all codegen tests for arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 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/intermediate_language_arm64.cc ('k') | runtime/vm/unit_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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
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"
11 #include "vm/dart_entry.h" 11 #include "vm/dart_entry.h"
12 #include "vm/flow_graph_compiler.h" 12 #include "vm/flow_graph_compiler.h"
13 #include "vm/heap.h" 13 #include "vm/heap.h"
14 #include "vm/instructions.h" 14 #include "vm/instructions.h"
15 #include "vm/object_store.h" 15 #include "vm/object_store.h"
16 #include "vm/stack_frame.h" 16 #include "vm/stack_frame.h"
17 #include "vm/stub_code.h" 17 #include "vm/stub_code.h"
18 #include "vm/tags.h" 18 #include "vm/tags.h"
19 19
20 #define __ assembler-> 20 #define __ assembler->
21 21
22 namespace dart { 22 namespace dart {
23 23
24 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects.");
25 DEFINE_FLAG(bool, use_slow_path, false,
26 "Set to true for debugging & verifying the slow paths.");
27
24 // Input parameters: 28 // Input parameters:
25 // LR : return address. 29 // LR : return address.
26 // SP : address of last argument in argument array. 30 // SP : address of last argument in argument array.
27 // SP + 8*R4 - 8 : address of first argument in argument array. 31 // SP + 8*R4 - 8 : address of first argument in argument array.
28 // SP + 8*R4 : address of return value. 32 // SP + 8*R4 : address of return value.
29 // R5 : address of the runtime function to call. 33 // R5 : address of the runtime function to call.
30 // R4 : number of arguments to the call. 34 // R4 : number of arguments to the call.
31 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { 35 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
32 const intptr_t isolate_offset = NativeArguments::isolate_offset(); 36 const intptr_t isolate_offset = NativeArguments::isolate_offset();
33 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); 37 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 __ LeaveFrame(); 126 __ LeaveFrame();
123 __ ret(); 127 __ ret();
124 } 128 }
125 129
126 130
127 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { 131 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) {
128 __ Stop("GeneratePrintStopMessageStub"); 132 __ Stop("GeneratePrintStopMessageStub");
129 } 133 }
130 134
131 135
136 // Input parameters:
137 // LR : return address.
138 // SP : address of return value.
139 // R5 : address of the native function to call.
140 // R2 : address of first argument in argument array.
141 // R1 : argc_tag including number of arguments and function kind.
132 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { 142 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
133 __ Stop("GenerateCallNativeCFunctionStub"); 143 const intptr_t isolate_offset = NativeArguments::isolate_offset();
144 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
145 const intptr_t argv_offset = NativeArguments::argv_offset();
146 const intptr_t retval_offset = NativeArguments::retval_offset();
147
148 __ EnterFrame(0);
149
150 // Load current Isolate pointer from Context structure into R0.
151 __ LoadFieldFromOffset(R0, CTX, Context::isolate_offset());
152
153 // Save exit frame information to enable stack walking as we are about
154 // to transition to native code.
155 __ StoreToOffset(SP, R0, Isolate::top_exit_frame_info_offset());
156
157 // Save current Context pointer into Isolate structure.
158 __ StoreToOffset(CTX, R0, Isolate::top_context_offset());
159
160 // Cache Isolate pointer into CTX while executing native code.
161 __ mov(CTX, R0);
162
163 #if defined(DEBUG)
164 { Label ok;
165 // Check that we are always entering from Dart code.
166 __ LoadFromOffset(R6, CTX, Isolate::vm_tag_offset());
167 __ CompareImmediate(R6, VMTag::kScriptTagId, PP);
168 __ b(&ok, EQ);
169 __ Stop("Not coming from Dart code.");
170 __ Bind(&ok);
171 }
172 #endif
173
174 // Mark that the isolate is executing Native code.
175 __ StoreToOffset(R5, CTX, Isolate::vm_tag_offset());
176
177 // Reserve space for the native arguments structure passed on the stack (the
178 // outgoing pointer parameter to the native arguments structure is passed in
179 // R0) and align frame before entering the C++ world.
180 __ ReserveAlignedFrameSpace(sizeof(NativeArguments));
181
182 // Initialize NativeArguments structure and call native function.
183 // Registers R0, R1, R2, and R3 are used.
184
185 ASSERT(isolate_offset == 0 * kWordSize);
186 // Set isolate in NativeArgs: R0 already contains CTX.
187
188 // There are no native calls to closures, so we do not need to set the tag
189 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
190 ASSERT(argc_tag_offset == 1 * kWordSize);
191 // Set argc in NativeArguments: R1 already contains argc.
192
193 ASSERT(argv_offset == 2 * kWordSize);
194 // Set argv in NativeArguments: R2 already contains argv.
195
196 // Set retval in NativeArgs.
197 ASSERT(retval_offset == 3 * kWordSize);
198 __ AddImmediate(R3, FP, 2 * kWordSize, PP);
199
200 // TODO(regis): Should we pass the structure by value as in runtime calls?
201 // It would require changing Dart API for native functions.
202 // For now, space is reserved on the stack and we pass a pointer to it.
203 __ StoreToOffset(R0, SP, isolate_offset);
204 __ StoreToOffset(R1, SP, argc_tag_offset);
205 __ StoreToOffset(R2, SP, argv_offset);
206 __ StoreToOffset(R3, SP, retval_offset);
207 __ mov(R0, SP); // Pass the pointer to the NativeArguments.
208
209 // Call native function (setsup scope if not leaf function).
210 Label leaf_call;
211 Label done;
212 __ TestImmediate(R1, NativeArguments::AutoSetupScopeMask(), PP);
213 __ b(&leaf_call, EQ);
214
215 __ mov(R1, R5); // Pass the function entrypoint to call.
216 // Call native function invocation wrapper or redirection via simulator.
217 #if defined(USING_SIMULATOR)
218 uword entry = reinterpret_cast<uword>(NativeEntry::NativeCallWrapper);
219 entry = Simulator::RedirectExternalReference(
220 entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments);
221 __ LoadImmediate(R2, entry, PP);
222 __ blr(R2);
223 #else
224 __ BranchLink(&NativeEntry::NativeCallWrapperLabel());
225 #endif
226 __ b(&done);
227
228 __ Bind(&leaf_call);
229 // Call native function or redirection via simulator.
230 __ blr(R5);
231
232 __ Bind(&done);
233
234 // Mark that the isolate is executing Dart code.
235 __ LoadImmediate(R2, VMTag::kScriptTagId, PP);
236 __ StoreToOffset(R2, CTX, Isolate::vm_tag_offset());
237
238 // Reset exit frame information in Isolate structure.
239 __ LoadImmediate(R2, 0, PP);
240 __ StoreToOffset(R2, CTX, Isolate::top_exit_frame_info_offset());
241
242 // Load Context pointer from Isolate structure into R2.
243 __ LoadFromOffset(R2, CTX, Isolate::top_context_offset());
244
245 // Reset Context pointer in Isolate structure.
246 __ LoadObject(R3, Object::null_object(), PP);
247 __ StoreToOffset(R3, CTX, Isolate::top_context_offset());
248
249 // Cache Context pointer into CTX while executing Dart code.
250 __ mov(CTX, R2);
251
252 __ LeaveFrame();
253 __ ret();
134 } 254 }
135 255
136 256
137 // Input parameters: 257 // Input parameters:
138 // LR : return address. 258 // LR : return address.
139 // SP : address of return value. 259 // SP : address of return value.
140 // R5 : address of the native function to call. 260 // R5 : address of the native function to call.
141 // R2 : address of first argument in argument array. 261 // R2 : address of first argument in argument array.
142 // R1 : argc_tag including number of arguments and function kind. 262 // R1 : argc_tag including number of arguments and function kind.
143 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { 263 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 596
477 __ EnterCallRuntimeFrame(0 * kWordSize); 597 __ EnterCallRuntimeFrame(0 * kWordSize);
478 __ LoadFieldFromOffset(R0, CTX, Context::isolate_offset()); 598 __ LoadFieldFromOffset(R0, CTX, Context::isolate_offset());
479 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); 599 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1);
480 // Restore callee-saved registers, tear down frame. 600 // Restore callee-saved registers, tear down frame.
481 __ LeaveCallRuntimeFrame(); 601 __ LeaveCallRuntimeFrame();
482 __ ret(); 602 __ ret();
483 } 603 }
484 604
485 605
606 // Called for inline allocation of objects.
607 // Input parameters:
608 // LR : return address.
609 // SP + 0 : type arguments object (only if class is parameterized).
486 void StubCode::GenerateAllocationStubForClass(Assembler* assembler, 610 void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
487 const Class& cls) { 611 const Class& cls) {
488 __ Stop("GenerateAllocationStubForClass"); 612 // The generated code is different if the class is parameterized.
613 const bool is_cls_parameterized = cls.NumTypeArguments() > 0;
614 ASSERT(!is_cls_parameterized ||
615 (cls.type_arguments_field_offset() != Class::kNoTypeArguments));
616 // kInlineInstanceSize is a constant used as a threshold for determining
617 // when the object initialization should be done as a loop or as
618 // straight line code.
619 const int kInlineInstanceSize = 12;
620 const intptr_t instance_size = cls.instance_size();
621 ASSERT(instance_size > 0);
622 if (is_cls_parameterized) {
623 __ ldr(R1, Address(SP));
624 // R1: instantiated type arguments.
625 }
626 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
627 Label slow_case;
628 // Allocate the object and update top to point to
629 // next object start and initialize the allocated object.
630 // R1: instantiated type arguments (if is_cls_parameterized).
631 Heap* heap = Isolate::Current()->heap();
632 __ LoadImmediate(R5, heap->TopAddress(), PP);
633 __ ldr(R2, Address(R5));
634 __ AddImmediate(R3, R2, instance_size, PP);
635 // Check if the allocation fits into the remaining space.
636 // R2: potential new object start.
637 // R3: potential next object start.
638 __ LoadImmediate(TMP, heap->EndAddress(), PP);
639 __ ldr(TMP, Address(TMP));
640 __ CompareRegisters(R3, TMP);
641 if (FLAG_use_slow_path) {
642 __ b(&slow_case);
643 } else {
644 __ b(&slow_case, CS); // Unsigned higher or equal.
645 }
646 __ str(R3, Address(R5));
647 __ UpdateAllocationStats(cls.id(), R5);
648
649 // R2: new object start.
650 // R3: next object start.
651 // R1: new object type arguments (if is_cls_parameterized).
652 // Set the tags.
653 uword tags = 0;
654 tags = RawObject::SizeTag::update(instance_size, tags);
655 ASSERT(cls.id() != kIllegalCid);
656 tags = RawObject::ClassIdTag::update(cls.id(), tags);
657 __ LoadImmediate(R0, tags, PP);
658 __ StoreToOffset(R0, R2, Instance::tags_offset());
659
660 // Initialize the remaining words of the object.
661 __ LoadObject(R0, Object::null_object(), PP);
662
663 // R0: raw null.
664 // R2: new object start.
665 // R3: next object start.
666 // R1: new object type arguments (if is_cls_parameterized).
667 // First try inlining the initialization without a loop.
668 if (instance_size < (kInlineInstanceSize * kWordSize)) {
669 // Check if the object contains any non-header fields.
670 // Small objects are initialized using a consecutive set of writes.
671 for (intptr_t current_offset = Instance::NextFieldOffset();
672 current_offset < instance_size;
673 current_offset += kWordSize) {
674 __ StoreToOffset(R0, R2, current_offset);
675 }
676 } else {
677 __ AddImmediate(R4, R2, Instance::NextFieldOffset(), PP);
678 // Loop until the whole object is initialized.
679 // R0: raw null.
680 // R2: new object.
681 // R3: next object start.
682 // R4: next word to be initialized.
683 // R1: new object type arguments (if is_cls_parameterized).
684 Label init_loop;
685 Label done;
686 __ Bind(&init_loop);
687 __ CompareRegisters(R4, R3);
688 __ b(&done, CS);
689 __ str(R0, Address(R4));
690 __ AddImmediate(R4, R4, kWordSize, PP);
691 __ b(&init_loop);
692 __ Bind(&done);
693 }
694 if (is_cls_parameterized) {
695 // R1: new object type arguments.
696 // Set the type arguments in the new object.
697 __ StoreToOffset(R1, R2, cls.type_arguments_field_offset());
698 }
699 // Done allocating and initializing the instance.
700 // R2: new object still missing its heap tag.
701 __ add(R0, R2, Operand(kHeapObjectTag));
702 // R0: new object.
703 __ ret();
704
705 __ Bind(&slow_case);
706 }
707 // If is_cls_parameterized:
708 // R1: new object type arguments.
709 // Create a stub frame as we are pushing some objects on the stack before
710 // calling into the runtime.
711 __ EnterStubFrame(true); // Uses pool pointer to pass cls to runtime.
712 // Setup space on stack for return value.
713 __ PushObject(Object::null_object(), PP);
714 __ PushObject(cls, PP); // Push class of object to be allocated.
715 if (is_cls_parameterized) {
716 // Push type arguments.
717 __ Push(R1);
718 } else {
719 // Push null type arguments.
720 __ Push(R2);
721 }
722 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object.
723 __ Drop(2); // Pop arguments.
724 __ Pop(R0); // Pop result (newly allocated object).
725 // R0: new object
726 // Restore the frame pointer.
727 __ LeaveStubFrame();
728 __ ret();
489 } 729 }
490 730
491 731
492 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { 732 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
493 __ Stop("GenerateCallNoSuchMethodFunctionStub"); 733 __ Stop("GenerateCallNoSuchMethodFunctionStub");
494 } 734 }
495 735
496 736
497 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { 737 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
498 __ Stop("GenerateOptimizedUsageCounterIncrement"); 738 __ Stop("GenerateOptimizedUsageCounterIncrement");
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 1240
1001 1241
1002 void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub( 1242 void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub(
1003 Assembler* assembler) { 1243 Assembler* assembler) {
1004 __ Stop("GenerateOptimizedIdenticalWithNumberCheckStub"); 1244 __ Stop("GenerateOptimizedIdenticalWithNumberCheckStub");
1005 } 1245 }
1006 1246
1007 } // namespace dart 1247 } // namespace dart
1008 1248
1009 #endif // defined TARGET_ARCH_ARM64 1249 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm64.cc ('k') | runtime/vm/unit_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698