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

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

Issue 14153004: Implement missing features to run Hello world! on simulated ARM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 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
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/dart_entry.h" 11 #include "vm/dart_entry.h"
11 #include "vm/flow_graph_compiler.h" 12 #include "vm/flow_graph_compiler.h"
12 #include "vm/instructions.h" 13 #include "vm/instructions.h"
14 #include "vm/object_store.h"
13 #include "vm/stack_frame.h" 15 #include "vm/stack_frame.h"
14 #include "vm/stub_code.h" 16 #include "vm/stub_code.h"
15 17
16 #define __ assembler-> 18 #define __ assembler->
17 19
18 namespace dart { 20 namespace dart {
19 21
20 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects."); 22 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects.");
21 DEFINE_FLAG(bool, use_slow_path, false, 23 DEFINE_FLAG(bool, use_slow_path, false,
22 "Set to true for debugging & verifying the slow paths."); 24 "Set to true for debugging & verifying the slow paths.");
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); 212 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag);
211 __ bx(R0); 213 __ bx(R0);
212 } 214 }
213 215
214 216
215 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { 217 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
216 __ Unimplemented("FixCallersTarget stub"); 218 __ Unimplemented("FixCallersTarget stub");
217 } 219 }
218 220
219 221
222 // Input parameters:
223 // R2: Smi-tagged argument count, may be zero.
224 // FP[kLastParamSlotIndex]: Last argument.
225 static void PushArgumentsArray(Assembler* assembler) {
226 // Allocate array to store arguments of caller.
227 __ LoadImmediate(R1, reinterpret_cast<intptr_t>(Object::null()));
228 // R1: Null element type for raw Array.
229 // R2: Smi-tagged argument count, may be zero.
230 __ BranchLink(&StubCode::AllocateArrayLabel());
231 // R0: newly allocated array.
232 // R2: Smi-tagged argument count, may be zero (was preserved by the stub).
233 __ Push(R0); // Array is in R0 and on top of stack.
234 __ add(R1, FP, ShifterOperand(R2, LSL, 1));
235 __ AddImmediate(R1, (kLastParamSlotIndex - 1) * kWordSize);
236 __ AddImmediate(R3, R0, Array::data_offset() - kHeapObjectTag);
237 Label loop, loop_condition;
238 __ b(&loop_condition);
239 __ Bind(&loop);
240 __ ldr(IP, Address(R1, 0));
241 __ str(IP, Address(R3, 0));
242 __ AddImmediate(R1, -kWordSize);
243 __ AddImmediate(R3, kWordSize);
244 __ Bind(&loop_condition);
245 __ subs(R2, R2, ShifterOperand(Smi::RawValue(1))); // R2 is Smi.
246 __ b(&loop, PL);
247 }
248
249
220 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { 250 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) {
221 __ Unimplemented("InstanceFunctionLookup stub"); 251 __ Unimplemented("InstanceFunctionLookup stub");
222 } 252 }
223 253
224 254
225 void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) { 255 void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) {
226 __ Unimplemented("DeoptimizeLazy stub"); 256 __ Unimplemented("DeoptimizeLazy stub");
227 } 257 }
228 258
229 259
230 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { 260 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
231 __ Unimplemented("Deoptimize stub"); 261 __ Unimplemented("Deoptimize stub");
232 } 262 }
233 263
234 264
235 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { 265 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
236 __ Unimplemented("MegamorphicMiss stub"); 266 __ Unimplemented("MegamorphicMiss stub");
237 } 267 }
238 268
239 269
270 // Called for inline allocation of arrays.
271 // Input parameters:
272 // LR: return address.
273 // R2: Array length as Smi.
274 // R1: array element type (either NULL or an instantiated type).
275 // NOTE: R2 cannot be clobbered here as the caller relies on it being saved.
276 // The newly allocated object is returned in R0.
240 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { 277 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) {
241 __ Unimplemented("AllocateArray stub"); 278 Label slow_case;
279 if (FLAG_inline_alloc) {
280 // Compute the size to be allocated, it is based on the array length
281 // and is computed as:
282 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
283 // Assert that length is a Smi.
284 __ tst(R2, ShifterOperand(kSmiTagSize));
zra 2013/04/16 23:17:42 Just noticed this. Should this be kSmiTagMask? bot
regis 2013/04/16 23:22:04 You are right. It is a typo on all architectures,
285 if (FLAG_use_slow_path) {
286 __ b(&slow_case);
287 } else {
288 __ b(&slow_case, NE);
289 }
290 __ ldr(R8, FieldAddress(CTX, Context::isolate_offset()));
291 __ LoadFromOffset(kLoadWord, R8, R8, Isolate::heap_offset());
292 __ LoadFromOffset(kLoadWord, R8, R8, Heap::new_space_offset());
293
294 // Calculate and align allocation size.
295 // Load new object start and calculate next object start.
296 // R1: array element type.
297 // R2: Array length as Smi.
298 // R8: Points to new space object.
299 __ LoadFromOffset(kLoadWord, R0, R8, Scavenger::top_offset());
300 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1;
301 __ LoadImmediate(R7, fixed_size);
302 __ add(R7, R7, ShifterOperand(R2, LSL, 1)); // R2 is Smi.
303 ASSERT(kSmiTagShift == 1);
304 __ bic(R7, R7, ShifterOperand(kObjectAlignment - 1));
305 __ add(R7, R7, ShifterOperand(R0));
306
307 // Check if the allocation fits into the remaining space.
308 // R0: potential new object start.
309 // R1: array element type.
310 // R2: Array length as Smi.
311 // R7: potential next object start.
312 // R8: Points to new space object.
313 __ LoadFromOffset(kLoadWord, IP, R8, Scavenger::end_offset());
314 __ cmp(R7, ShifterOperand(IP));
315 __ b(&slow_case, CS); // Branch if unsigned higher or equal.
316
317 // Successfully allocated the object(s), now update top to point to
318 // next object start and initialize the object.
319 // R0: potential new object start.
320 // R7: potential next object start.
321 // R8: Points to new space object.
322 __ StoreToOffset(kStoreWord, R7, R8, Scavenger::top_offset());
323 __ add(R0, R0, ShifterOperand(kHeapObjectTag));
324
325 // R0: new object start as a tagged pointer.
326 // R1: array element type.
327 // R2: Array length as Smi.
328 // R7: new object end address.
329
330 // Store the type argument field.
331 __ StoreIntoObjectNoBarrier(
332 R0,
333 FieldAddress(R0, Array::type_arguments_offset()),
334 R1);
335
336 // Set the length field.
337 __ StoreIntoObjectNoBarrier(
338 R0,
339 FieldAddress(R0, Array::length_offset()),
340 R2);
341
342 // Calculate the size tag.
343 // R0: new object start as a tagged pointer.
344 // R2: Array length as Smi.
345 // R7: new object end address.
346 {
347 Label size_tag_overflow, done;
zra 2013/04/16 21:12:29 These labels aren't used.
regis 2013/04/16 21:43:39 Removed. And removed local scope.
348 __ LoadImmediate(R1, fixed_size);
349 __ add(R1, R1, ShifterOperand(R2, LSL, 1)); // R2 is Smi.
350 ASSERT(kSmiTagShift == 1);
351 __ bic(R1, R1, ShifterOperand(kObjectAlignment - 1));
352 const intptr_t shift = RawObject::kSizeTagBit - kObjectAlignmentLog2;
353 __ CompareImmediate(R1, RawObject::SizeTag::kMaxSizeTag);
354 // If no size tag overflow, shift R1 left, else set R1 to zero.
355 __ mov(R1, ShifterOperand(R1, LSL, shift), LS);
356 __ mov(R1, ShifterOperand(0), HI);
357
358 // Get the class index and insert it into the tags.
359 __ LoadImmediate(IP, RawObject::ClassIdTag::encode(kArrayCid));
360 __ orr(R1, R1, ShifterOperand(IP));
361 __ str(R1, FieldAddress(R0, Array::tags_offset()));
362 }
363
364 // Initialize all array elements to raw_null.
365 // R0: new object start as a tagged pointer.
366 // R7: new object end address.
367 // R2: Array length as Smi.
368 __ AddImmediate(R1, R0, Array::data_offset() - kHeapObjectTag);
369 // R1: iterator which initially points to the start of the variable
370 // data area to be initialized.
371 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
372 Label loop, test;
373 __ b(&test);
374 __ Bind(&loop);
375 // TODO(cshapiro): StoreIntoObjectNoBarrier
376 __ str(IP, Address(R1, 0));
377 __ AddImmediate(R1, kWordSize);
378 __ Bind(&test);
379 __ cmp(R1, ShifterOperand(R7));
380 __ b(&loop, NE);
381
382 // Done allocating and initializing the array.
383 // R0: new object.
384 // R2: Array length as Smi (preserved for the caller.)
385 __ Ret();
386 }
387
388 // Unable to allocate the array using the fast inline code, just call
389 // into the runtime.
390 __ Bind(&slow_case);
391 // Create a stub frame as we are pushing some objects on the stack before
392 // calling into the runtime.
393 __ EnterStubFrame();
394 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
395 // Setup space on stack for return value.
396 // Push array length as Smi and element type.
397 __ PushList((1 << R1) | (1 << R2) | (1 << IP));
398 __ CallRuntime(kAllocateArrayRuntimeEntry);
399 // Pop arguments; result is popped in IP.
400 __ PopList((1 << R1) | (1 << R2) | (1 << IP)); // R2 is restored.
401 __ mov(R0, ShifterOperand(IP));
402 __ LeaveStubFrame();
403 __ Ret();
242 } 404 }
243 405
244 406
407 // Input parameters:
408 // LR: return address.
409 // SP: address of last argument.
410 // R4: Arguments descriptor array.
411 // Note: The closure object is the first argument to the function being
412 // called, the stub accesses the closure from this location directly
413 // when trying to resolve the call.
245 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) { 414 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) {
246 __ Unimplemented("CallClosureFunction stub"); 415 // Load num_args.
416 __ ldr(R0, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
417 __ sub(R0, R0, ShifterOperand(Smi::RawValue(1)));
418 // Load closure object in R1.
419 __ ldr(R1, Address(SP, R0, LSL, 1)); // R0 (num_args - 1) is a Smi.
420
421 // Verify that R1 is a closure by checking its class.
422 Label not_closure;
423 __ LoadImmediate(R8, reinterpret_cast<intptr_t>(Object::null()));
424 __ cmp(R1, ShifterOperand(R8));
425 // Not a closure, but null object.
426 __ b(&not_closure, EQ);
427 __ tst(R1, ShifterOperand(kSmiTagMask));
428 __ b(&not_closure, EQ); // Not a closure, but a smi.
429 // Verify that the class of the object is a closure class by checking that
430 // class.signature_function() is not null.
431 __ LoadClass(R0, R1, R2);
432 __ ldr(R0, FieldAddress(R0, Class::signature_function_offset()));
433 __ cmp(R0, ShifterOperand(R8)); // R8 is raw null.
434 // Actual class is not a closure class.
435 __ b(&not_closure, EQ);
436
437 // R0 is just the signature function. Load the actual closure function.
438 __ ldr(R2, FieldAddress(R1, Closure::function_offset()));
439
440 // Load closure context in CTX; note that CTX has already been preserved.
441 __ ldr(CTX, FieldAddress(R1, Closure::context_offset()));
442
443 // Load closure function code in EAX.
zra 2013/04/16 21:12:29 R0?
regis 2013/04/16 21:43:39 Done.
444 __ ldr(R0, FieldAddress(R2, Function::code_offset()));
445 __ cmp(R0, ShifterOperand(R8)); // R8 is raw null.
446 Label function_compiled;
447 __ b(&function_compiled, NE);
448
449 // Create a stub frame as we are pushing some objects on the stack before
450 // calling into the runtime.
451 __ EnterStubFrame();
452
453 // Preserve arguments descriptor array and read-only function object argument.
454 __ PushList((1 << R2) | (1 << R4));
455 __ CallRuntime(kCompileFunctionRuntimeEntry);
456 // Restore arguments descriptor array and read-only function object argument.
457 __ PopList((1 << R2) | (1 << R4));
458 // Restore R0.
459 __ ldr(R0, FieldAddress(R2, Function::code_offset()));
460
461 // Remove the stub frame as we are about to jump to the closure function.
462 __ LeaveStubFrame();
463
464 __ Bind(&function_compiled);
465 // R0: Code.
466 // R4: Arguments descriptor array.
467 __ ldr(R0, FieldAddress(R0, Code::instructions_offset()));
468 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag);
469 __ bx(R0);
470
471 __ Bind(&not_closure);
472 // Call runtime to attempt to resolve and invoke a call method on a
473 // non-closure object, passing the non-closure object and its arguments array,
474 // returning here.
475 // If no call method exists, throw a NoSuchMethodError.
476 // R1: non-closure object.
477 // R4: arguments descriptor array.
478
479 // Create a stub frame as we are pushing some objects on the stack before
480 // calling into the runtime.
481 __ EnterStubFrame();
482
483 // Setup space on stack for result from error reporting.
484 __ PushList((1 << R4) | (1 << R8)); // Arguments descriptor and raw null.
485
486 // Load smi-tagged arguments array length, including the non-closure.
487 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
488 PushArgumentsArray(assembler);
489
490 // Stack:
491 // TOS + 0: Argument array.
492 // TOS + 1: Arguments descriptor array.
493 // TOS + 2: Place for result from the call.
494 // TOS + 3: Saved FP of previous frame.
495 // TOS + 4: Dart code return address
496 // TOS + 5: PC marker (0 for stub).
497 // TOS + 6: Last argument of caller.
498 // ....
499 __ CallRuntime(kInvokeNonClosureRuntimeEntry);
500 // Remove arguments.
501 __ Drop(2);
502 __ Pop(R0); // Get result into R0.
503
504 // Remove the stub frame as we are about to return.
505 __ LeaveStubFrame();
506 __ Ret();
247 } 507 }
248 508
249 509
250 // Called when invoking Dart code from C++ (VM code). 510 // Called when invoking Dart code from C++ (VM code).
251 // Input parameters: 511 // Input parameters:
252 // LR : points to return address. 512 // LR : points to return address.
253 // R0 : entrypoint of the Dart function to call. 513 // R0 : entrypoint of the Dart function to call.
254 // R1 : arguments descriptor array. 514 // R1 : arguments descriptor array.
255 // R2 : arguments array. 515 // R2 : arguments array.
256 // R3 : new context containing the current isolate pointer. 516 // R3 : new context containing the current isolate pointer.
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 // A new InstantiatedTypeArguments object only needs to be allocated if 695 // A new InstantiatedTypeArguments object only needs to be allocated if
436 // the instantiator is provided (not kNoInstantiator, but may be null). 696 // the instantiator is provided (not kNoInstantiator, but may be null).
437 __ CompareImmediate(R0, Smi::RawValue(StubCode::kNoInstantiator)); 697 __ CompareImmediate(R0, Smi::RawValue(StubCode::kNoInstantiator));
438 __ AddImmediate(R3, type_args_size, NE); 698 __ AddImmediate(R3, type_args_size, NE);
439 // R4: potential new object end and, if R4 != R3, potential new 699 // R4: potential new object end and, if R4 != R3, potential new
440 // InstantiatedTypeArguments object start. 700 // InstantiatedTypeArguments object start.
441 } 701 }
442 // Check if the allocation fits into the remaining space. 702 // Check if the allocation fits into the remaining space.
443 // R2: potential new object start. 703 // R2: potential new object start.
444 // R3: potential next object start. 704 // R3: potential next object start.
705 __ LoadImmediate(IP, heap->EndAddress());
706 __ cmp(R3, ShifterOperand(IP));
445 if (FLAG_use_slow_path) { 707 if (FLAG_use_slow_path) {
446 __ b(&slow_case); 708 __ b(&slow_case);
447 } else { 709 } else {
448 __ LoadImmediate(IP, heap->EndAddress());
449 __ cmp(R3, ShifterOperand(IP));
450 __ b(&slow_case, CS); // Branch if unsigned higher or equal. 710 __ b(&slow_case, CS); // Branch if unsigned higher or equal.
451 } 711 }
452 712
453 // Successfully allocated the object(s), now update top to point to 713 // Successfully allocated the object(s), now update top to point to
454 // next object start and initialize the object. 714 // next object start and initialize the object.
455 __ str(R3, Address(R5, 0)); 715 __ str(R3, Address(R5, 0));
456 716
457 if (is_cls_parameterized) { 717 if (is_cls_parameterized) {
458 // Initialize the type arguments field in the object. 718 // Initialize the type arguments field in the object.
459 // R2: new object start. 719 // R2: new object start.
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object. 823 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object.
564 __ Drop(3); // Pop arguments. 824 __ Drop(3); // Pop arguments.
565 __ Pop(R0); // Pop result (newly allocated object). 825 __ Pop(R0); // Pop result (newly allocated object).
566 // R0: new object 826 // R0: new object
567 // Restore the frame pointer. 827 // Restore the frame pointer.
568 __ LeaveStubFrame(true); 828 __ LeaveStubFrame(true);
569 __ Ret(); 829 __ Ret();
570 } 830 }
571 831
572 832
833 // Called for inline allocation of closures.
834 // Input parameters:
835 // LR : return address.
836 // SP + 4 : receiver (null if not an implicit instance closure).
837 // SP + 0 : type arguments object (null if class is no parameterized).
573 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, 838 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler,
574 const Function& func) { 839 const Function& func) {
575 __ Unimplemented("AllocateClosure stub"); 840 ASSERT(func.IsClosureFunction());
841 const bool is_implicit_static_closure =
842 func.IsImplicitStaticClosureFunction();
843 const bool is_implicit_instance_closure =
844 func.IsImplicitInstanceClosureFunction();
845 const Class& cls = Class::ZoneHandle(func.signature_class());
846 const bool has_type_arguments = cls.HasTypeArguments();
847
848 __ EnterStubFrame(true); // Uses pool pointer to refer to function.
849 const intptr_t kTypeArgumentsFPOffset = 3 * kWordSize;
850 const intptr_t kReceiverFPOffset = 4 * kWordSize;
851 const intptr_t closure_size = Closure::InstanceSize();
852 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver.
853 if (FLAG_inline_alloc &&
854 PageSpace::IsPageAllocatableSize(closure_size + context_size)) {
855 Label slow_case;
856 Heap* heap = Isolate::Current()->heap();
857 __ LoadImmediate(R5, heap->TopAddress());
858 __ ldr(R2, Address(R5, 0));
859 __ AddImmediate(R3, R2, closure_size);
860 if (is_implicit_instance_closure) {
861 __ mov(R4, ShifterOperand(R3)); // R4: new context address.
862 __ AddImmediate(R3, context_size);
863 }
864 // Check if the allocation fits into the remaining space.
865 // R2: potential new closure object.
866 // R3: potential next object start.
867 // R4: potential new context object (only if is_implicit_closure).
868 __ LoadImmediate(IP, heap->EndAddress());
869 __ cmp(R3, ShifterOperand(IP));
870 if (FLAG_use_slow_path) {
871 __ b(&slow_case);
872 } else {
873 __ b(&slow_case, CS); // Branch if unsigned higher or equal.
874 }
875
876 // Successfully allocated the object, now update top to point to
877 // next object start and initialize the object.
878 __ str(R3, Address(R5, 0));
879
880 // R2: new closure object.
881 // R4: new context object (only if is_implicit_closure).
882 // Set the tags.
883 uword tags = 0;
884 tags = RawObject::SizeTag::update(closure_size, tags);
885 tags = RawObject::ClassIdTag::update(cls.id(), tags);
886 __ LoadImmediate(R0, tags);
887 __ str(R0, Address(R2, Instance::tags_offset()));
888
889 // Initialize the function field in the object.
890 // R2: new closure object.
891 // R4: new context object (only if is_implicit_closure).
892 __ LoadObject(R0, func); // Load function of closure to be allocated.
893 __ str(R0, Address(R2, Closure::function_offset()));
894
895 // Setup the context for this closure.
896 if (is_implicit_static_closure) {
897 ObjectStore* object_store = Isolate::Current()->object_store();
898 ASSERT(object_store != NULL);
899 const Context& empty_context =
900 Context::ZoneHandle(object_store->empty_context());
901 __ LoadObject(R0, empty_context);
902 __ str(R0, Address(R2, Closure::context_offset()));
903 } else if (is_implicit_instance_closure) {
904 // Initialize the new context capturing the receiver.
905 const Class& context_class = Class::ZoneHandle(Object::context_class());
906 // Set the tags.
907 uword tags = 0;
908 tags = RawObject::SizeTag::update(context_size, tags);
909 tags = RawObject::ClassIdTag::update(context_class.id(), tags);
910 __ LoadImmediate(R0, tags);
911 __ str(R0, Address(R4, Context::tags_offset()));
912
913 // Set number of variables field to 1 (for captured receiver).
914 __ LoadImmediate(R0, 1);
915 __ str(R0, Address(R4, Context::num_variables_offset()));
916
917 // Set isolate field to isolate of current context.
918 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset()));
919 __ str(R0, Address(R4, Context::isolate_offset()));
920
921 // Set the parent to null.
922 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
923 __ str(R0, Address(R4, Context::parent_offset()));
924
925 // Initialize the context variable to the receiver.
926 __ ldr(R0, Address(FP, kReceiverFPOffset));
927 __ str(R0, Address(R4, Context::variable_offset(0)));
928
929 // Set the newly allocated context in the newly allocated closure.
930 __ add(R1, R4, ShifterOperand(kHeapObjectTag));
931 __ str(R1, Address(R2, Closure::context_offset()));
932 } else {
933 __ str(CTX, Address(R2, Closure::context_offset()));
934 }
935
936 // Set the type arguments field in the newly allocated closure.
937 __ ldr(R0, Address(FP, kTypeArgumentsFPOffset));
938 __ str(R0, Address(R2, Closure::type_arguments_offset()));
939
940 // Done allocating and initializing the instance.
941 // EAX: new object.
zra 2013/04/16 21:12:29 R0
regis 2013/04/16 21:43:39 Done.
942 __ add(R0, R2, ShifterOperand(kHeapObjectTag));
943 __ LeaveStubFrame(true);
944 __ Ret();
945
946 __ Bind(&slow_case);
947 }
948 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
949 __ Push(R0); // Setup space on stack for return value.
950 __ PushObject(func);
951 if (is_implicit_static_closure) {
952 __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry);
953 } else {
954 if (is_implicit_instance_closure) {
955 __ ldr(R1, Address(FP, kReceiverFPOffset));
956 __ Push(R1); // Receiver.
957 }
958 // R0: raw null.
959 if (has_type_arguments) {
960 __ ldr(R0, Address(FP, kTypeArgumentsFPOffset));
961 }
962 __ Push(R0); // Push type arguments of closure to be allocated or null.
963
964 if (is_implicit_instance_closure) {
965 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry);
966 __ Drop(2); // Pop arguments (type arguments of object and receiver).
967 } else {
968 ASSERT(func.IsNonImplicitClosureFunction());
969 __ CallRuntime(kAllocateClosureRuntimeEntry);
970 __ Drop(1); // Pop argument (type arguments of object).
971 }
972 }
973 __ Drop(1); // Pop function object.
974 __ Pop(R0);
975 // R0: new object
976 // Restore the frame pointer.
977 __ LeaveStubFrame(true);
978 __ Ret();
576 } 979 }
577 980
578 981
579 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { 982 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
580 __ Unimplemented("CallNoSuchMethodFunction stub"); 983 __ Unimplemented("CallNoSuchMethodFunction stub");
581 } 984 }
582 985
583 986
584 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { 987 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
585 __ Unimplemented("OptimizedUsageCounterIncrement stub"); 988 __ Unimplemented("OptimizedUsageCounterIncrement stub");
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 __ ldr(R1, Address(R6, 0)); // Next class ID. 1093 __ ldr(R1, Address(R6, 0)); // Next class ID.
691 1094
692 __ Bind(&test); 1095 __ Bind(&test);
693 __ CompareImmediate(R1, Smi::RawValue(kIllegalCid)); // Done? 1096 __ CompareImmediate(R1, Smi::RawValue(kIllegalCid)); // Done?
694 __ b(&loop, NE); 1097 __ b(&loop, NE);
695 1098
696 // IC miss. 1099 // IC miss.
697 // Restore return address. 1100 // Restore return address.
698 __ mov(LR, ShifterOperand(R8)); 1101 __ mov(LR, ShifterOperand(R8));
699 1102
700 // Compute address of arguments (first read number of arguments from 1103 // Compute address of arguments.
701 // arguments descriptor array and then compute address on the stack).
702 // R7: argument_count - 1 (smi). 1104 // R7: argument_count - 1 (smi).
703 __ add(R7, SP, ShifterOperand(R7, LSL, 1)); // R7 is Smi. 1105 __ add(R7, SP, ShifterOperand(R7, LSL, 1)); // R7 is Smi.
704 // R7: address of receiver. 1106 // R7: address of receiver.
705 // Create a stub frame as we are pushing some objects on the stack before 1107 // Create a stub frame as we are pushing some objects on the stack before
706 // calling into the runtime. 1108 // calling into the runtime.
707 __ EnterStubFrame(); 1109 __ EnterStubFrame();
708 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); 1110 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
709 // Preserve IC data object and arguments descriptor array and 1111 // Preserve IC data object and arguments descriptor array and
710 // setup space on stack for result (target code object). 1112 // setup space on stack for result (target code object).
711 __ PushList((1 << R0) | (1 << R4) | (1 << R5)); 1113 __ PushList((1 << R0) | (1 << R4) | (1 << R5));
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 __ Bind(&reference_compare); 1485 __ Bind(&reference_compare);
1084 __ cmp(left, ShifterOperand(right)); 1486 __ cmp(left, ShifterOperand(right));
1085 __ Bind(&done); 1487 __ Bind(&done);
1086 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); 1488 __ PopList((1 << R0) | (1 << R1) | (1 << R2));
1087 __ Ret(); 1489 __ Ret();
1088 } 1490 }
1089 1491
1090 } // namespace dart 1492 } // namespace dart
1091 1493
1092 #endif // defined TARGET_ARCH_ARM 1494 #endif // defined TARGET_ARCH_ARM
OLDNEW
« runtime/vm/intermediate_language_arm.cc ('K') | « runtime/vm/intrinsifier_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698