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

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

Issue 1247783002: Make array allocation stub shared between isolates. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 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
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/cpu.h" 10 #include "vm/cpu.h"
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698