| 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 |