OLD | NEW |
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 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 __ Pop(R0); | 351 __ Pop(R0); |
352 // Remove the stub frame. | 352 // Remove the stub frame. |
353 __ LeaveStubFrame(); | 353 __ LeaveStubFrame(); |
354 // Jump to the dart function. | 354 // Jump to the dart function. |
355 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); | 355 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); |
356 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); | 356 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); |
357 __ bx(R0); | 357 __ bx(R0); |
358 } | 358 } |
359 | 359 |
360 | 360 |
361 // Called from array allocate instruction when the allocation stub has been | |
362 // disabled. | |
363 // R1: element type (preserved). | |
364 // R2: length (preserved). | |
365 void StubCode::GenerateFixAllocateArrayStubTargetStub(Assembler* assembler) { | |
366 __ EnterStubFrame(); | |
367 // Setup space on stack for return value and preserve length, element type. | |
368 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | |
369 __ PushList((1 << R0) | (1 << R1) | (1 << R2)); | |
370 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); | |
371 // Get Code object result and restore length, element type. | |
372 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); | |
373 // Remove the stub frame. | |
374 __ LeaveStubFrame(); | |
375 // Jump to the dart function. | |
376 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); | |
377 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); | |
378 __ bx(R0); | |
379 } | |
380 | |
381 | |
382 // Input parameters: | 361 // Input parameters: |
383 // R2: smi-tagged argument count, may be zero. | 362 // R2: smi-tagged argument count, may be zero. |
384 // FP[kParamEndSlotFromFp + 1]: last argument. | 363 // FP[kParamEndSlotFromFp + 1]: last argument. |
385 static void PushArgumentsArray(Assembler* assembler) { | 364 static void PushArgumentsArray(Assembler* assembler) { |
386 StubCode* stub_code = Isolate::Current()->stub_code(); | |
387 // Allocate array to store arguments of caller. | 365 // Allocate array to store arguments of caller. |
388 __ LoadImmediate(R1, reinterpret_cast<intptr_t>(Object::null())); | 366 __ LoadImmediate(R1, reinterpret_cast<intptr_t>(Object::null())); |
389 // R1: null element type for raw Array. | 367 // R1: null element type for raw Array. |
390 // R2: smi-tagged argument count, may be zero. | 368 // R2: smi-tagged argument count, may be zero. |
391 const Code& array_stub = Code::Handle(stub_code->GetAllocateArrayStub()); | 369 const ExternalLabel array_label(StubCode::AllocateArrayEntryPoint()); |
392 const ExternalLabel array_label(array_stub.EntryPoint()); | |
393 __ BranchLink(&array_label); | 370 __ BranchLink(&array_label); |
394 // R0: newly allocated array. | 371 // R0: newly allocated array. |
395 // R2: smi-tagged argument count, may be zero (was preserved by the stub). | 372 // R2: smi-tagged argument count, may be zero (was preserved by the stub). |
396 __ Push(R0); // Array is in R0 and on top of stack. | 373 __ Push(R0); // Array is in R0 and on top of stack. |
397 __ AddImmediate(R1, FP, kParamEndSlotFromFp * kWordSize); | 374 __ AddImmediate(R1, FP, kParamEndSlotFromFp * kWordSize); |
398 __ AddImmediate(R3, R0, Array::data_offset() - kHeapObjectTag); | 375 __ AddImmediate(R3, R0, Array::data_offset() - kHeapObjectTag); |
399 // Copy arguments from stack to array (starting at the end). | 376 // Copy arguments from stack to array (starting at the end). |
400 // R1: address just beyond last argument on stack. | 377 // R1: address just beyond last argument on stack. |
401 // R3: address of first argument in array. | 378 // R3: address of first argument in array. |
402 Label enter; | 379 Label enter; |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 __ bx(R2); | 598 __ bx(R2); |
622 } | 599 } |
623 | 600 |
624 | 601 |
625 // Called for inline allocation of arrays. | 602 // Called for inline allocation of arrays. |
626 // Input parameters: | 603 // Input parameters: |
627 // LR: return address. | 604 // LR: return address. |
628 // R1: array element type (either NULL or an instantiated type). | 605 // R1: array element type (either NULL or an instantiated type). |
629 // R2: array length as Smi (must be preserved). | 606 // R2: array length as Smi (must be preserved). |
630 // The newly allocated object is returned in R0. | 607 // The newly allocated object is returned in R0. |
631 void StubCode::GeneratePatchableAllocateArrayStub(Assembler* assembler, | 608 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { |
632 uword* entry_patch_offset, uword* patch_code_pc_offset) { | |
633 *entry_patch_offset = assembler->CodeSize(); | |
634 Label slow_case; | 609 Label slow_case; |
635 Isolate* isolate = Isolate::Current(); | |
636 // Compute the size to be allocated, it is based on the array length | 610 // Compute the size to be allocated, it is based on the array length |
637 // and is computed as: | 611 // and is computed as: |
638 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). | 612 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). |
639 __ MoveRegister(R3, R2); // Array length. | 613 __ MoveRegister(R3, R2); // Array length. |
640 const Class& cls = Class::Handle(isolate->object_store()->array_class()); | |
641 ASSERT(!cls.IsNull()); | |
642 // Check that length is a positive Smi. | 614 // Check that length is a positive Smi. |
643 __ tst(R3, Operand(kSmiTagMask)); | 615 __ tst(R3, Operand(kSmiTagMask)); |
644 if (FLAG_use_slow_path || cls.trace_allocation()) { | 616 if (FLAG_use_slow_path) { |
645 __ b(&slow_case); | 617 __ b(&slow_case); |
646 } else { | 618 } else { |
647 __ b(&slow_case, NE); | 619 __ b(&slow_case, NE); |
648 } | 620 } |
649 __ cmp(R3, Operand(0)); | 621 __ cmp(R3, Operand(0)); |
650 __ b(&slow_case, LT); | 622 __ b(&slow_case, LT); |
651 | 623 |
652 // Check for maximum allowed length. | 624 // Check for maximum allowed length. |
653 const intptr_t max_len = | 625 const intptr_t max_len = |
654 reinterpret_cast<int32_t>(Smi::New(Array::kMaxElements)); | 626 reinterpret_cast<int32_t>(Smi::New(Array::kMaxElements)); |
655 __ CompareImmediate(R3, max_len); | 627 __ CompareImmediate(R3, max_len); |
656 __ b(&slow_case, GT); | 628 __ b(&slow_case, GT); |
657 | 629 |
| 630 const intptr_t cid = kArrayCid; |
| 631 __ MaybeTraceAllocation(cid, R4, &slow_case, |
| 632 /* inline_isolate = */ false); |
| 633 |
658 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; | 634 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; |
659 __ LoadImmediate(R9, fixed_size); | 635 __ LoadImmediate(R9, fixed_size); |
660 __ add(R9, R9, Operand(R3, LSL, 1)); // R3 is a Smi. | 636 __ add(R9, R9, Operand(R3, LSL, 1)); // R3 is a Smi. |
661 ASSERT(kSmiTagShift == 1); | 637 ASSERT(kSmiTagShift == 1); |
662 __ bic(R9, R9, Operand(kObjectAlignment - 1)); | 638 __ bic(R9, R9, Operand(kObjectAlignment - 1)); |
663 | 639 |
664 // R9: Allocation size. | 640 // R9: Allocation size. |
665 | |
666 Heap* heap = isolate->heap(); | |
667 const intptr_t cid = kArrayCid; | |
668 Heap::Space space = Heap::SpaceForAllocation(cid); | 641 Heap::Space space = Heap::SpaceForAllocation(cid); |
669 __ LoadImmediate(R6, heap->TopAddress(space)); | 642 __ LoadIsolate(R6); |
670 __ ldr(R0, Address(R6, 0)); // Potential new object start. | 643 __ ldr(R6, Address(R6, Isolate::heap_offset())); |
| 644 // Potential new object start. |
| 645 __ ldr(R0, Address(R6, Heap::TopOffset(space))); |
671 __ adds(R7, R0, Operand(R9)); // Potential next object start. | 646 __ adds(R7, R0, Operand(R9)); // Potential next object start. |
672 __ b(&slow_case, CS); // Branch if unsigned overflow. | 647 __ b(&slow_case, CS); // Branch if unsigned overflow. |
673 | 648 |
674 // Check if the allocation fits into the remaining space. | 649 // Check if the allocation fits into the remaining space. |
675 // R0: potential new object start. | 650 // R0: potential new object start. |
676 // R7: potential next object start. | 651 // R7: potential next object start. |
677 // R9: allocation size. | 652 // R9: allocation size. |
678 __ LoadImmediate(R3, heap->EndAddress(space)); | 653 __ ldr(R3, Address(R6, Heap::EndOffset(space))); |
679 __ ldr(R3, Address(R3, 0)); | |
680 __ cmp(R7, Operand(R3)); | 654 __ cmp(R7, Operand(R3)); |
681 __ b(&slow_case, CS); | 655 __ b(&slow_case, CS); |
682 | 656 |
683 // Successfully allocated the object(s), now update top to point to | 657 // Successfully allocated the object(s), now update top to point to |
684 // next object start and initialize the object. | 658 // next object start and initialize the object. |
685 __ LoadAllocationStatsAddress(R3, cid); | 659 __ LoadAllocationStatsAddress(R3, cid, /* inline_isolate = */ false); |
686 __ str(R7, Address(R6, 0)); | 660 __ str(R7, Address(R6, Heap::TopOffset(space))); |
687 __ add(R0, R0, Operand(kHeapObjectTag)); | 661 __ add(R0, R0, Operand(kHeapObjectTag)); |
688 | 662 |
689 // Initialize the tags. | 663 // Initialize the tags. |
690 // R0: new object start as a tagged pointer. | 664 // R0: new object start as a tagged pointer. |
691 // R3: allocation stats address. | 665 // R3: allocation stats address. |
692 // R7: new object end address. | 666 // R7: new object end address. |
693 // R9: allocation size. | 667 // R9: allocation size. |
694 { | 668 { |
695 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; | 669 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; |
696 | 670 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 716 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); |
743 // Setup space on stack for return value. | 717 // Setup space on stack for return value. |
744 // Push array length as Smi and element type. | 718 // Push array length as Smi and element type. |
745 __ PushList((1 << R1) | (1 << R2) | (1 << IP)); | 719 __ PushList((1 << R1) | (1 << R2) | (1 << IP)); |
746 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); | 720 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); |
747 // Pop arguments; result is popped in IP. | 721 // Pop arguments; result is popped in IP. |
748 __ PopList((1 << R1) | (1 << R2) | (1 << IP)); // R2 is restored. | 722 __ PopList((1 << R1) | (1 << R2) | (1 << IP)); // R2 is restored. |
749 __ mov(R0, Operand(IP)); | 723 __ mov(R0, Operand(IP)); |
750 __ LeaveStubFrame(); | 724 __ LeaveStubFrame(); |
751 __ Ret(); | 725 __ Ret(); |
752 *patch_code_pc_offset = assembler->CodeSize(); | |
753 StubCode* stub_code = Isolate::Current()->stub_code(); | |
754 __ BranchPatchable(&stub_code->FixAllocateArrayStubTargetLabel()); | |
755 } | 726 } |
756 | 727 |
757 | 728 |
758 // Called when invoking Dart code from C++ (VM code). | 729 // Called when invoking Dart code from C++ (VM code). |
759 // Input parameters: | 730 // Input parameters: |
760 // LR : points to return address. | 731 // LR : points to return address. |
761 // R0 : entrypoint of the Dart function to call. | 732 // R0 : entrypoint of the Dart function to call. |
762 // R1 : arguments descriptor array. | 733 // R1 : arguments descriptor array. |
763 // R2 : arguments array. | 734 // R2 : arguments array. |
764 // R3 : current thread. | 735 // R3 : current thread. |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1195 __ Push(R2); | 1166 __ Push(R2); |
1196 } | 1167 } |
1197 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object. | 1168 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object. |
1198 __ Drop(2); // Pop arguments. | 1169 __ Drop(2); // Pop arguments. |
1199 __ Pop(R0); // Pop result (newly allocated object). | 1170 __ Pop(R0); // Pop result (newly allocated object). |
1200 // R0: new object | 1171 // R0: new object |
1201 // Restore the frame pointer. | 1172 // Restore the frame pointer. |
1202 __ LeaveStubFrame(); | 1173 __ LeaveStubFrame(); |
1203 __ Ret(); | 1174 __ Ret(); |
1204 *patch_code_pc_offset = assembler->CodeSize(); | 1175 *patch_code_pc_offset = assembler->CodeSize(); |
1205 StubCode* stub_code = Isolate::Current()->stub_code(); | 1176 __ BranchPatchable(&StubCode::FixAllocationStubTargetLabel()); |
1206 __ BranchPatchable(&stub_code->FixAllocationStubTargetLabel()); | |
1207 } | 1177 } |
1208 | 1178 |
1209 | 1179 |
1210 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function | 1180 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function |
1211 // from the entry code of a dart function after an error in passed argument | 1181 // from the entry code of a dart function after an error in passed argument |
1212 // name or number is detected. | 1182 // name or number is detected. |
1213 // Input parameters: | 1183 // Input parameters: |
1214 // LR : return address. | 1184 // LR : return address. |
1215 // SP : address of last argument. | 1185 // SP : address of last argument. |
1216 // R4: arguments descriptor array. | 1186 // R4: arguments descriptor array. |
(...skipping 909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2126 // Result: | 2096 // Result: |
2127 // R1: entry point. | 2097 // R1: entry point. |
2128 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2098 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
2129 EmitMegamorphicLookup(assembler, R0, R1, R1); | 2099 EmitMegamorphicLookup(assembler, R0, R1, R1); |
2130 __ Ret(); | 2100 __ Ret(); |
2131 } | 2101 } |
2132 | 2102 |
2133 } // namespace dart | 2103 } // namespace dart |
2134 | 2104 |
2135 #endif // defined TARGET_ARCH_ARM | 2105 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |