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

Side by Side Diff: runtime/vm/stub_code_arm64.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
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
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 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 605
606 // Called for inline allocation of arrays. 606 // Called for inline allocation of arrays.
607 // Input parameters: 607 // Input parameters:
608 // LR: return address. 608 // LR: return address.
609 // R2: array length as Smi. 609 // R2: array length as Smi.
610 // R1: array element type (either NULL or an instantiated type). 610 // R1: array element type (either NULL or an instantiated type).
611 // NOTE: R2 cannot be clobbered here as the caller relies on it being saved. 611 // NOTE: R2 cannot be clobbered here as the caller relies on it being saved.
612 // The newly allocated object is returned in R0. 612 // The newly allocated object is returned in R0.
613 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { 613 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) {
614 Label slow_case; 614 Label slow_case;
615 if (FLAG_inline_alloc) { 615 // Compute the size to be allocated, it is based on the array length
616 // Compute the size to be allocated, it is based on the array length 616 // and is computed as:
617 // and is computed as: 617 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
618 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). 618 // Assert that length is a Smi.
619 // Assert that length is a Smi. 619 __ tsti(R2, kSmiTagMask);
620 __ tsti(R2, kSmiTagMask); 620 if (FLAG_use_slow_path) {
621 if (FLAG_use_slow_path) { 621 __ b(&slow_case);
622 __ b(&slow_case); 622 } else {
623 } else { 623 __ b(&slow_case, NE);
624 __ b(&slow_case, NE); 624 }
625 } 625 __ cmp(R2, Operand(0));
626 __ cmp(R2, Operand(0)); 626 __ b(&slow_case, LT);
627 __ b(&slow_case, LT); 627 __ LoadFieldFromOffset(R8, CTX, Context::isolate_offset(), kNoPP);
628 __ LoadFieldFromOffset(R8, CTX, Context::isolate_offset(), kNoPP); 628 __ LoadFromOffset(R8, R8, Isolate::heap_offset(), kNoPP);
629 __ LoadFromOffset(R8, R8, Isolate::heap_offset(), kNoPP); 629 __ LoadFromOffset(R8, R8, Heap::new_space_offset(), kNoPP);
630 __ LoadFromOffset(R8, R8, Heap::new_space_offset(), kNoPP);
631 630
632 // Calculate and align allocation size. 631 // Calculate and align allocation size.
633 // Load new object start and calculate next object start. 632 // Load new object start and calculate next object start.
634 // R1: array element type. 633 // R1: array element type.
635 // R2: array length as Smi. 634 // R2: array length as Smi.
636 // R8: points to new space object. 635 // R8: points to new space object.
637 __ LoadFromOffset(R0, R8, Scavenger::top_offset(), kNoPP); 636 __ LoadFromOffset(R0, R8, Scavenger::top_offset(), kNoPP);
638 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; 637 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1;
639 __ LoadImmediate(R3, fixed_size, kNoPP); 638 __ LoadImmediate(R3, fixed_size, kNoPP);
640 __ add(R3, R3, Operand(R2, LSL, 2)); // R2 is Smi. 639 __ add(R3, R3, Operand(R2, LSL, 2)); // R2 is Smi.
641 ASSERT(kSmiTagShift == 1); 640 ASSERT(kSmiTagShift == 1);
642 __ andi(R3, R3, ~(kObjectAlignment - 1)); 641 __ andi(R3, R3, ~(kObjectAlignment - 1));
643 __ adds(R7, R3, Operand(R0)); 642 __ adds(R7, R3, Operand(R0));
644 __ b(&slow_case, VS); 643 __ b(&slow_case, VS);
645 644
646 // Check if the allocation fits into the remaining space. 645 // Check if the allocation fits into the remaining space.
647 // R0: potential new object start. 646 // R0: potential new object start.
648 // R1: array element type. 647 // R1: array element type.
649 // R2: array length as Smi. 648 // R2: array length as Smi.
650 // R3: array size. 649 // R3: array size.
651 // R7: potential next object start. 650 // R7: potential next object start.
652 // R8: points to new space object. 651 // R8: points to new space object.
653 __ LoadFromOffset(TMP, R8, Scavenger::end_offset(), kNoPP); 652 __ LoadFromOffset(TMP, R8, Scavenger::end_offset(), kNoPP);
654 __ CompareRegisters(R7, TMP); 653 __ CompareRegisters(R7, TMP);
655 __ b(&slow_case, CS); // Branch if unsigned higher or equal. 654 __ b(&slow_case, CS); // Branch if unsigned higher or equal.
656 655
657 // Successfully allocated the object(s), now update top to point to 656 // Successfully allocated the object(s), now update top to point to
658 // next object start and initialize the object. 657 // next object start and initialize the object.
659 // R0: potential new object start. 658 // R0: potential new object start.
660 // R3: array size. 659 // R3: array size.
661 // R7: potential next object start. 660 // R7: potential next object start.
662 // R8: Points to new space object. 661 // R8: Points to new space object.
663 __ StoreToOffset(R7, R8, Scavenger::top_offset(), kNoPP); 662 __ StoreToOffset(R7, R8, Scavenger::top_offset(), kNoPP);
664 __ add(R0, R0, Operand(kHeapObjectTag)); 663 __ add(R0, R0, Operand(kHeapObjectTag));
665 __ UpdateAllocationStatsWithSize(kArrayCid, R3, R8, kNoPP); 664 __ UpdateAllocationStatsWithSize(kArrayCid, R3, R8, kNoPP);
666 665
667 // R0: new object start as a tagged pointer. 666 // R0: new object start as a tagged pointer.
668 // R1: array element type. 667 // R1: array element type.
669 // R2: array length as Smi. 668 // R2: array length as Smi.
670 // R3: array size. 669 // R3: array size.
671 // R7: new object end address. 670 // R7: new object end address.
672 671
673 // Store the type argument field. 672 // Store the type argument field.
674 __ StoreIntoObjectOffsetNoBarrier( 673 __ StoreIntoObjectOffsetNoBarrier(
675 R0, Array::type_arguments_offset(), R1, PP); 674 R0, Array::type_arguments_offset(), R1, PP);
676 675
677 // Set the length field. 676 // Set the length field.
678 __ StoreIntoObjectOffsetNoBarrier(R0, Array::length_offset(), R2, PP); 677 __ StoreIntoObjectOffsetNoBarrier(R0, Array::length_offset(), R2, PP);
679 678
680 // Calculate the size tag. 679 // Calculate the size tag.
681 // R0: new object start as a tagged pointer. 680 // R0: new object start as a tagged pointer.
682 // R2: array length as Smi. 681 // R2: array length as Smi.
683 // R3: array size. 682 // R3: array size.
684 // R7: new object end address. 683 // R7: new object end address.
685 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; 684 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
686 __ CompareImmediate(R3, RawObject::SizeTag::kMaxSizeTag, kNoPP); 685 __ CompareImmediate(R3, RawObject::SizeTag::kMaxSizeTag, kNoPP);
687 // If no size tag overflow, shift R1 left, else set R1 to zero. 686 // If no size tag overflow, shift R1 left, else set R1 to zero.
688 __ Lsl(TMP, R3, shift); 687 __ Lsl(TMP, R3, shift);
689 __ csel(R1, TMP, R1, LS); 688 __ csel(R1, TMP, R1, LS);
690 __ csel(R1, ZR, R1, HI); 689 __ csel(R1, ZR, R1, HI);
691 690
692 // Get the class index and insert it into the tags. 691 // Get the class index and insert it into the tags.
693 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(kArrayCid), kNoPP); 692 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(kArrayCid), kNoPP);
694 __ orr(R1, R1, Operand(TMP)); 693 __ orr(R1, R1, Operand(TMP));
695 __ StoreFieldToOffset(R1, R0, Array::tags_offset(), kNoPP); 694 __ StoreFieldToOffset(R1, R0, Array::tags_offset(), kNoPP);
696 695
697 // Initialize all array elements to raw_null. 696 // Initialize all array elements to raw_null.
698 // R0: new object start as a tagged pointer. 697 // R0: new object start as a tagged pointer.
699 // R7: new object end address. 698 // R7: new object end address.
700 // R2: array length as Smi. 699 // R2: array length as Smi.
701 __ AddImmediate(R1, R0, Array::data_offset() - kHeapObjectTag, kNoPP); 700 __ AddImmediate(R1, R0, Array::data_offset() - kHeapObjectTag, kNoPP);
702 // R1: iterator which initially points to the start of the variable 701 // R1: iterator which initially points to the start of the variable
703 // data area to be initialized. 702 // data area to be initialized.
704 __ LoadObject(TMP, Object::null_object(), PP); 703 __ LoadObject(TMP, Object::null_object(), PP);
705 Label loop, done; 704 Label loop, done;
706 __ Bind(&loop); 705 __ Bind(&loop);
707 // TODO(cshapiro): StoreIntoObjectNoBarrier 706 // TODO(cshapiro): StoreIntoObjectNoBarrier
708 __ CompareRegisters(R1, R7); 707 __ CompareRegisters(R1, R7);
709 __ b(&done, CS); 708 __ b(&done, CS);
710 __ str(TMP, Address(R1)); // Store if unsigned lower. 709 __ str(TMP, Address(R1)); // Store if unsigned lower.
711 __ AddImmediate(R1, R1, kWordSize, kNoPP); 710 __ AddImmediate(R1, R1, kWordSize, kNoPP);
712 __ b(&loop); // Loop until R1 == R7. 711 __ b(&loop); // Loop until R1 == R7.
713 __ Bind(&done); 712 __ Bind(&done);
714 713
715 // Done allocating and initializing the array. 714 // Done allocating and initializing the array.
716 // R0: new object. 715 // R0: new object.
717 // R2: array length as Smi (preserved for the caller.) 716 // R2: array length as Smi (preserved for the caller.)
718 __ ret(); 717 __ ret();
719 }
720 718
721 // Unable to allocate the array using the fast inline code, just call 719 // Unable to allocate the array using the fast inline code, just call
722 // into the runtime. 720 // into the runtime.
723 __ Bind(&slow_case); 721 __ Bind(&slow_case);
724 // Create a stub frame as we are pushing some objects on the stack before 722 // Create a stub frame as we are pushing some objects on the stack before
725 // calling into the runtime. 723 // calling into the runtime.
726 __ EnterStubFrame(); 724 __ EnterStubFrame();
727 // Setup space on stack for return value. 725 // Setup space on stack for return value.
728 // Push array length as Smi and element type. 726 // Push array length as Smi and element type.
729 __ PushObject(Object::null_object(), PP); 727 __ PushObject(Object::null_object(), PP);
(...skipping 1186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1916 const Register right = R0; 1914 const Register right = R0;
1917 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP); 1915 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP);
1918 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP); 1916 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP);
1919 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 1917 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
1920 __ ret(); 1918 __ ret();
1921 } 1919 }
1922 1920
1923 } // namespace dart 1921 } // namespace dart
1924 1922
1925 #endif // defined TARGET_ARCH_ARM64 1923 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698