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

Side by Side Diff: runtime/vm/stub_code_x64.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
« runtime/vm/stub_code_mips.cc ('K') | « runtime/vm/stub_code_mips.cc ('k') | no next file » | 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_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 555
556 556
557 // Called for inline allocation of arrays. 557 // Called for inline allocation of arrays.
558 // Input parameters: 558 // Input parameters:
559 // R10 : Array length as Smi. 559 // R10 : Array length as Smi.
560 // RBX : array element type (either NULL or an instantiated type). 560 // RBX : array element type (either NULL or an instantiated type).
561 // NOTE: R10 cannot be clobbered here as the caller relies on it being saved. 561 // NOTE: R10 cannot be clobbered here as the caller relies on it being saved.
562 // The newly allocated object is returned in RAX. 562 // The newly allocated object is returned in RAX.
563 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { 563 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) {
564 Label slow_case; 564 Label slow_case;
565 // Compute the size to be allocated, it is based on the array length
566 // and is computed as:
567 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
568 __ movq(RDI, R10); // Array Length.
569 // Check that length is a positive Smi.
570 __ testq(RDI, Immediate(kSmiTagMask));
571 __ j(NOT_ZERO, &slow_case);
572 __ cmpq(RDI, Immediate(0));
573 __ j(LESS, &slow_case);
574 // Check for maximum allowed length.
575 const Immediate& max_len =
576 Immediate(reinterpret_cast<int64_t>(Smi::New(Array::kMaxElements)));
577 __ cmpq(RDI, max_len);
578 __ j(GREATER, &slow_case);
579 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1;
580 __ leaq(RDI, Address(RDI, TIMES_4, fixed_size)); // RDI is a Smi.
581 ASSERT(kSmiTagShift == 1);
582 __ andq(RDI, Immediate(-kObjectAlignment));
565 583
566 if (FLAG_inline_alloc) { 584 Isolate* isolate = Isolate::Current();
567 // Compute the size to be allocated, it is based on the array length 585 Heap* heap = isolate->heap();
568 // and is computed as:
569 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
570 // Assert that length is a Smi.
571 __ testq(R10, Immediate(kSmiTagMask));
572 if (FLAG_use_slow_path) {
573 __ jmp(&slow_case);
574 } else {
575 __ j(NOT_ZERO, &slow_case);
576 }
577 __ cmpq(R10, Immediate(0));
578 __ j(LESS, &slow_case);
579 586
580 // Check for maximum allowed length. 587 __ movq(RAX, Immediate(heap->TopAddress()));
581 const Immediate& max_len = 588 __ movq(RAX, Address(RAX, 0));
582 Immediate(reinterpret_cast<int64_t>(Smi::New(Array::kMaxElements)));
583 __ cmpq(R10, max_len);
584 __ j(GREATER, &slow_case);
585 589
586 __ movq(R13, FieldAddress(CTX, Context::isolate_offset())); 590 // RDI: allocation size.
587 __ movq(R13, Address(R13, Isolate::heap_offset())); 591 __ movq(RCX, RAX);
588 __ movq(R13, Address(R13, Heap::new_space_offset())); 592 __ addq(RCX, RDI);
593 __ j(CARRY, &slow_case);
589 594
590 // Calculate and align allocation size. 595 // Check if the allocation fits into the remaining space.
591 // Load new object start and calculate next object start. 596 // RAX: potential new object start.
592 // RBX: array element type. 597 // RCX: potential next object start.
593 // R10: Array length as Smi. 598 // RDI: allocation size.
594 // R13: Points to new space object. 599 __ movq(R13, Immediate(heap->EndAddress()));
595 __ movq(RAX, Address(R13, Scavenger::top_offset())); 600 __ cmpq(RCX, Address(R13, 0));
596 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; 601 __ j(ABOVE_EQUAL, &slow_case);
597 __ leaq(R12, Address(R10, TIMES_4, fixed_size)); // R10 is Smi.
598 ASSERT(kSmiTagShift == 1);
599 __ andq(R12, Immediate(-kObjectAlignment));
600 __ addq(R12, RAX);
601 __ j(CARRY, &slow_case);
602 602
603 // Check if the allocation fits into the remaining space. 603 // Successfully allocated the object(s), now update top to point to
604 // RAX: potential new object start. 604 // next object start and initialize the object.
605 // R12: potential next object start. 605 __ movq(R13, Immediate(heap->TopAddress()));
606 // RBX: array element type. 606 __ movq(Address(R13, 0), RCX);
607 // R10: Array length as Smi. 607 __ addq(RAX, Immediate(kHeapObjectTag));
608 // R13: Points to new space object. 608 __ UpdateAllocationStatsWithSize(kArrayCid, RDI);
609 __ cmpq(R12, Address(R13, Scavenger::end_offset())); 609 // Initialize the tags.
610 __ j(ABOVE_EQUAL, &slow_case); 610 // RAX: new object start as a tagged pointer.
611 // RDI: allocation size.
612 {
613 Label size_tag_overflow, done;
614 __ cmpq(RDI, Immediate(RawObject::SizeTag::kMaxSizeTag));
615 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
616 __ shlq(RDI, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2));
617 __ jmp(&done, Assembler::kNearJump);
611 618
612 // Successfully allocated the object(s), now update top to point to 619 __ Bind(&size_tag_overflow);
613 // next object start and initialize the object. 620 __ movq(RDI, Immediate(0));
614 // RAX: potential new object start.
615 // R12: potential next object start.
616 // R13: Points to new space object.
617 __ movq(Address(R13, Scavenger::top_offset()), R12);
618 __ addq(RAX, Immediate(kHeapObjectTag));
619 // R13: Size of allocation in bytes.
620 __ movq(R13, R12);
621 __ subq(R13, RAX);
622 __ UpdateAllocationStatsWithSize(kArrayCid, R13);
623
624 // RAX: new object start as a tagged pointer.
625 // R12: new object end address.
626 // RBX: array element type.
627 // R10: Array length as Smi.
628
629 // Store the type argument field.
630 __ StoreIntoObjectNoBarrier(
631 RAX, FieldAddress(RAX, Array::type_arguments_offset()), RBX);
632
633 // Set the length field.
634 __ StoreIntoObjectNoBarrier(
635 RAX, FieldAddress(RAX, Array::length_offset()), R10);
636
637 // Calculate the size tag.
638 // RAX: new object start as a tagged pointer.
639 // R12: new object end address.
640 // R10: Array length as Smi.
641 {
642 Label size_tag_overflow, done;
643 __ leaq(RBX, Address(R10, TIMES_4, fixed_size)); // R10 is Smi.
644 ASSERT(kSmiTagShift == 1);
645 __ andq(RBX, Immediate(-kObjectAlignment));
646 __ cmpq(RBX, Immediate(RawObject::SizeTag::kMaxSizeTag));
647 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
648 __ shlq(RBX, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2));
649 __ jmp(&done);
650
651 __ Bind(&size_tag_overflow);
652 __ movq(RBX, Immediate(0));
653 __ Bind(&done);
654
655 // Get the class index and insert it into the tags.
656 __ orq(RBX, Immediate(RawObject::ClassIdTag::encode(kArrayCid)));
657 __ movq(FieldAddress(RAX, Array::tags_offset()), RBX);
658 }
659
660 // Initialize all array elements to raw_null.
661 // RAX: new object start as a tagged pointer.
662 // R12: new object end address.
663 // R10: Array length as Smi.
664 __ leaq(RBX, FieldAddress(RAX, Array::data_offset()));
665 // RBX: iterator which initially points to the start of the variable
666 // data area to be initialized.
667 __ LoadObject(R13, Object::null_object(), PP);
668 Label done;
669 Label init_loop;
670 __ Bind(&init_loop);
671 __ cmpq(RBX, R12);
672 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
673 // TODO(cshapiro): StoreIntoObjectNoBarrier
674 __ movq(Address(RBX, 0), R13);
675 __ addq(RBX, Immediate(kWordSize));
676 __ jmp(&init_loop, Assembler::kNearJump);
677 __ Bind(&done); 621 __ Bind(&done);
678 622
679 // Done allocating and initializing the array. 623 // Get the class index and insert it into the tags.
680 // RAX: new object. 624 const Class& cls = Class::Handle(isolate->object_store()->array_class());
681 // R10: Array length as Smi (preserved for the caller.) 625 __ orq(RDI, Immediate(RawObject::ClassIdTag::encode(cls.id())));
682 __ ret(); 626 __ movq(FieldAddress(RAX, Array::tags_offset()), RDI); // Tags.
683 } 627 }
684 628
629 // RAX: new object start as a tagged pointer.
630 // Store the type argument field.
631 __ StoreIntoObjectNoBarrier(RAX,
632 FieldAddress(RAX, Array::type_arguments_offset()),
633 RBX);
634
635 // Set the length field.
636 __ StoreIntoObjectNoBarrier(RAX,
637 FieldAddress(RAX, Array::length_offset()),
638 R10);
639
640 // Initialize all array elements to raw_null.
641 // RAX: new object start as a tagged pointer.
642 // RCX: new object end address.
643 // RDI: iterator which initially points to the start of the variable
644 // data area to be initialized.
645 __ LoadObject(R12, Object::null_object(), PP);
646 __ leaq(RDI, FieldAddress(RAX, sizeof(RawArray)));
647 Label done;
648 Label init_loop;
649 __ Bind(&init_loop);
650 __ cmpq(RDI, RCX);
651 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
652 __ movq(Address(RDI, 0), R12);
653 __ addq(RDI, Immediate(kWordSize));
654 __ jmp(&init_loop, Assembler::kNearJump);
655 __ Bind(&done);
656 __ ret(); // returns the newly allocated object in RAX.
657
685 // Unable to allocate the array using the fast inline code, just call 658 // Unable to allocate the array using the fast inline code, just call
686 // into the runtime. 659 // into the runtime.
687 __ Bind(&slow_case); 660 __ Bind(&slow_case);
688 // Create a stub frame as we are pushing some objects on the stack before 661 // Create a stub frame as we are pushing some objects on the stack before
689 // calling into the runtime. 662 // calling into the runtime.
690 __ EnterStubFrame(); 663 __ EnterStubFrame();
691 // Setup space on stack for return value. 664 // Setup space on stack for return value.
692 __ PushObject(Object::null_object(), PP); 665 __ PushObject(Object::null_object(), PP);
693 __ pushq(R10); // Array length as Smi. 666 __ pushq(R10); // Array length as Smi.
694 __ pushq(RBX); // Element type. 667 __ pushq(RBX); // Element type.
(...skipping 1152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1847 1820
1848 __ movq(left, Address(RSP, 2 * kWordSize)); 1821 __ movq(left, Address(RSP, 2 * kWordSize));
1849 __ movq(right, Address(RSP, 1 * kWordSize)); 1822 __ movq(right, Address(RSP, 1 * kWordSize));
1850 GenerateIdenticalWithNumberCheckStub(assembler, left, right); 1823 GenerateIdenticalWithNumberCheckStub(assembler, left, right);
1851 __ ret(); 1824 __ ret();
1852 } 1825 }
1853 1826
1854 } // namespace dart 1827 } // namespace dart
1855 1828
1856 #endif // defined TARGET_ARCH_X64 1829 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/stub_code_mips.cc ('K') | « runtime/vm/stub_code_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698