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

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

Issue 284013002: Improve performance of stubcode based array allocation moving stub to isolate specific area. (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/stub_code.h ('k') | runtime/vm/stub_code_arm64.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) 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/compiler.h"
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 __ ldr(R2, FieldAddress(R0, Function::code_offset())); 589 __ ldr(R2, FieldAddress(R0, Function::code_offset()));
590 __ ldr(R2, FieldAddress(R2, Code::instructions_offset())); 590 __ ldr(R2, FieldAddress(R2, Code::instructions_offset()));
591 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag); 591 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
592 __ bx(R2); 592 __ bx(R2);
593 } 593 }
594 594
595 595
596 // Called for inline allocation of arrays. 596 // Called for inline allocation of arrays.
597 // Input parameters: 597 // Input parameters:
598 // LR: return address. 598 // LR: return address.
599 // R2: array length as Smi.
600 // R1: array element type (either NULL or an instantiated type). 599 // R1: array element type (either NULL or an instantiated type).
601 // NOTE: R2 cannot be clobbered here as the caller relies on it being saved. 600 // R2: array length as Smi (must be preserved).
602 // The newly allocated object is returned in R0. 601 // The newly allocated object is returned in R0.
603 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { 602 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) {
604 Label slow_case; 603 Label slow_case;
605 if (FLAG_inline_alloc) {
606 // Compute the size to be allocated, it is based on the array length
607 // and is computed as:
608 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
609 // Assert that length is a Smi.
610 __ tst(R2, ShifterOperand(kSmiTagMask));
611 if (FLAG_use_slow_path) {
612 __ b(&slow_case);
613 } else {
614 __ b(&slow_case, NE);
615 }
616 __ cmp(R2, ShifterOperand(0));
617 __ b(&slow_case, LT);
618 604
619 // Check for maximum allowed length. 605 // Compute the size to be allocated, it is based on the array length
620 const intptr_t max_len = 606 // and is computed as:
621 reinterpret_cast<int32_t>(Smi::New(Array::kMaxElements)); 607 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
622 __ CompareImmediate(R2, max_len); 608 __ MoveRegister(R3, R2); // Array length.
623 __ b(&slow_case, GT);
624 609
625 __ ldr(R8, FieldAddress(CTX, Context::isolate_offset())); 610 // Check that length is a positive Smi.
626 __ LoadFromOffset(kWord, R8, R8, Isolate::heap_offset()); 611 __ tst(R3, ShifterOperand(kSmiTagMask));
627 __ LoadFromOffset(kWord, R8, R8, Heap::new_space_offset()); 612 __ b(&slow_case, NE);
613 __ cmp(R3, ShifterOperand(0));
614 __ b(&slow_case, LT);
628 615
629 // Calculate and align allocation size. 616 // Check for maximum allowed length.
630 // Load new object start and calculate next object start. 617 const intptr_t max_len =
631 // R1: array element type. 618 reinterpret_cast<int32_t>(Smi::New(Array::kMaxElements));
632 // R2: array length as Smi. 619 __ CompareImmediate(R3, max_len);
633 // R8: points to new space object. 620 __ b(&slow_case, GT);
634 __ LoadFromOffset(kWord, R0, R8, Scavenger::top_offset());
635 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1;
636 __ LoadImmediate(R3, fixed_size);
637 __ add(R3, R3, ShifterOperand(R2, LSL, 1)); // R2 is Smi.
638 ASSERT(kSmiTagShift == 1);
639 __ bic(R3, R3, ShifterOperand(kObjectAlignment - 1));
640 __ adds(R7, R3, ShifterOperand(R0));
641 __ b(&slow_case, VS);
642 621
643 // Check if the allocation fits into the remaining space. 622 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1;
644 // R0: potential new object start. 623 __ LoadImmediate(R8, fixed_size);
645 // R1: array element type. 624 __ add(R8, R8, ShifterOperand(R3, LSL, 1)); // R3 is a Smi.
646 // R2: array length as Smi. 625 ASSERT(kSmiTagShift == 1);
647 // R3: array size. 626 __ bic(R8, R8, ShifterOperand(kObjectAlignment - 1));
648 // R7: potential next object start.
649 // R8: points to new space object.
650 __ LoadFromOffset(kWord, IP, R8, Scavenger::end_offset());
651 __ cmp(R7, ShifterOperand(IP));
652 __ b(&slow_case, CS); // Branch if unsigned higher or equal.
653 627
654 // Successfully allocated the object(s), now update top to point to 628 // R8: Allocation size.
655 // next object start and initialize the object.
656 // R0: potential new object start.
657 // R3: array size.
658 // R7: potential next object start.
659 // R8: Points to new space object.
660 __ StoreToOffset(kWord, R7, R8, Scavenger::top_offset());
661 __ add(R0, R0, ShifterOperand(kHeapObjectTag));
662 __ UpdateAllocationStatsWithSize(kArrayCid, R3, R8);
663 629
664 // R0: new object start as a tagged pointer. 630 Isolate* isolate = Isolate::Current();
665 // R1: array element type. 631 Heap* heap = isolate->heap();
666 // R2: array length as Smi.
667 // R3: array size.
668 // R7: new object end address.
669 632
670 // Store the type argument field. 633 __ LoadImmediate(R6, heap->TopAddress());
671 __ StoreIntoObjectNoBarrier( 634 __ ldr(R0, Address(R6, 0)); // Potential new object start.
672 R0, 635 __ adds(R7, R0, ShifterOperand(R8)); // Potential next object start.
673 FieldAddress(R0, Array::type_arguments_offset()), 636 __ b(&slow_case, VS);
674 R1);
675 637
676 // Set the length field. 638 // Check if the allocation fits into the remaining space.
677 __ StoreIntoObjectNoBarrier( 639 // R0: potential new object start.
678 R0, 640 // R7: potential next object start.
679 FieldAddress(R0, Array::length_offset()), 641 // R8: allocation size.
680 R2); 642 __ LoadImmediate(R3, heap->EndAddress());
643 __ ldr(R3, Address(R3, 0));
644 __ cmp(R7, ShifterOperand(R3));
645 __ b(&slow_case, CS);
681 646
682 // Calculate the size tag. 647 // Successfully allocated the object(s), now update top to point to
683 // R0: new object start as a tagged pointer. 648 // next object start and initialize the object.
684 // R2: array length as Smi. 649 __ str(R7, Address(R6, 0));
685 // R3: array size. 650 __ add(R0, R0, ShifterOperand(kHeapObjectTag));
686 // R7: new object end address. 651 __ UpdateAllocationStatsWithSize(kArrayCid, R8, R4);
652
653 // Initialize the tags.
654 // R0: new object start as a tagged pointer.
655 // R7: new object end address.
656 // R8: allocation size.
657 {
687 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; 658 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
688 __ CompareImmediate(R3, RawObject::SizeTag::kMaxSizeTag); 659 const Class& cls = Class::Handle(isolate->object_store()->array_class());
689 // If no size tag overflow, shift R1 left, else set R1 to zero. 660
690 __ mov(R1, ShifterOperand(R3, LSL, shift), LS); 661 __ CompareImmediate(R8, RawObject::SizeTag::kMaxSizeTag);
691 __ mov(R1, ShifterOperand(0), HI); 662 __ mov(R8, ShifterOperand(R8, LSL, shift), LS);
663 __ mov(R8, ShifterOperand(0), HI);
692 664
693 // Get the class index and insert it into the tags. 665 // Get the class index and insert it into the tags.
694 __ LoadImmediate(IP, RawObject::ClassIdTag::encode(kArrayCid)); 666 // R8: size and bit tags.
695 __ orr(R1, R1, ShifterOperand(IP)); 667 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cls.id()));
696 __ str(R1, FieldAddress(R0, Array::tags_offset())); 668 __ orr(R8, R8, ShifterOperand(TMP));
697 669 __ str(R8, FieldAddress(R0, Array::tags_offset())); // Store tags.
698 // Initialize all array elements to raw_null.
699 // R0: new object start as a tagged pointer.
700 // R7: new object end address.
701 // R2: array length as Smi.
702 __ AddImmediate(R1, R0, Array::data_offset() - kHeapObjectTag);
703 // R1: iterator which initially points to the start of the variable
704 // data area to be initialized.
705 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
706 Label loop;
707 __ Bind(&loop);
708 // TODO(cshapiro): StoreIntoObjectNoBarrier
709 __ cmp(R1, ShifterOperand(R7));
710 __ str(IP, Address(R1, 0), CC); // Store if unsigned lower.
711 __ AddImmediate(R1, kWordSize, CC);
712 __ b(&loop, CC); // Loop until R1 == R7.
713
714 // Done allocating and initializing the array.
715 // R0: new object.
716 // R2: array length as Smi (preserved for the caller.)
717 __ Ret();
718 } 670 }
719 671
672 // R0: new object start as a tagged pointer.
673 // R7: new object end address.
674 // Store the type argument field.
675 __ StoreIntoObjectNoBarrier(R0,
676 FieldAddress(R0, Array::type_arguments_offset()),
677 R1);
678
679 // Set the length field.
680 __ StoreIntoObjectNoBarrier(R0,
681 FieldAddress(R0, Array::length_offset()),
682 R2);
683
684 // Initialize all array elements to raw_null.
685 // R0: new object start as a tagged pointer.
686 // R7: new object end address.
687 // R8: iterator which initially points to the start of the variable
688 // data area to be initialized.
689 // R3: null
690 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null()));
691 __ AddImmediate(R8, R0, sizeof(RawArray) - kHeapObjectTag);
692
693 Label init_loop;
694 __ Bind(&init_loop);
695 __ cmp(R8, ShifterOperand(R7));
696 __ str(R3, Address(R8, 0), CC);
697 __ AddImmediate(R8, kWordSize, CC);
698 __ b(&init_loop, CC);
699
700 __ Ret(); // Returns the newly allocated object in R0.
720 // Unable to allocate the array using the fast inline code, just call 701 // Unable to allocate the array using the fast inline code, just call
721 // into the runtime. 702 // into the runtime.
722 __ Bind(&slow_case); 703 __ Bind(&slow_case);
704
723 // Create a stub frame as we are pushing some objects on the stack before 705 // Create a stub frame as we are pushing some objects on the stack before
724 // calling into the runtime. 706 // calling into the runtime.
725 __ EnterStubFrame(); 707 __ EnterStubFrame();
726 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); 708 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
727 // Setup space on stack for return value. 709 // Setup space on stack for return value.
728 // Push array length as Smi and element type. 710 // Push array length as Smi and element type.
729 __ PushList((1 << R1) | (1 << R2) | (1 << IP)); 711 __ PushList((1 << R1) | (1 << R2) | (1 << IP));
730 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); 712 __ CallRuntime(kAllocateArrayRuntimeEntry, 2);
731 // Pop arguments; result is popped in IP. 713 // Pop arguments; result is popped in IP.
732 __ PopList((1 << R1) | (1 << R2) | (1 << IP)); // R2 is restored. 714 __ PopList((1 << R1) | (1 << R2) | (1 << IP)); // R2 is restored.
(...skipping 1123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1856 const Register right = R0; 1838 const Register right = R0;
1857 __ ldr(left, Address(SP, 1 * kWordSize)); 1839 __ ldr(left, Address(SP, 1 * kWordSize));
1858 __ ldr(right, Address(SP, 0 * kWordSize)); 1840 __ ldr(right, Address(SP, 0 * kWordSize));
1859 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 1841 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
1860 __ Ret(); 1842 __ Ret();
1861 } 1843 }
1862 1844
1863 } // namespace dart 1845 } // namespace dart
1864 1846
1865 #endif // defined TARGET_ARCH_ARM 1847 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/stub_code.h ('k') | runtime/vm/stub_code_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698