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

Side by Side Diff: vm/stub_code_x64.cc

Issue 9072011: - Add a size field to the header. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: '' Created 8 years, 11 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
« vm/stub_code_ia32.cc ('K') | « vm/stub_code_ia32.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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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/code_generator.h" 8 #include "vm/code_generator.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/ic_data.h" 10 #include "vm/ic_data.h"
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 564
565 if (FLAG_inline_alloc) { 565 if (FLAG_inline_alloc) {
566 // Compute the size to be allocated, it is based on the array length 566 // Compute the size to be allocated, it is based on the array length
567 // and it computed as: 567 // and it computed as:
568 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). 568 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
569 // Assert that length is a Smi. 569 // Assert that length is a Smi.
570 __ testq(R10, Immediate(kSmiTagSize)); 570 __ testq(R10, Immediate(kSmiTagSize));
571 if (FLAG_use_slow_path) { 571 if (FLAG_use_slow_path) {
572 __ jmp(&slow_case); 572 __ jmp(&slow_case);
573 } else { 573 } else {
574 __ j(NOT_ZERO, &slow_case, Assembler::kNearJump); 574 __ j(NOT_ZERO, &slow_case);
575 } 575 }
576 __ movq(R13, FieldAddress(CTX, Context::isolate_offset())); 576 __ movq(R13, FieldAddress(CTX, Context::isolate_offset()));
577 __ movq(R13, Address(R13, Isolate::heap_offset())); 577 __ movq(R13, Address(R13, Isolate::heap_offset()));
578 __ movq(R13, Address(R13, Heap::new_space_offset())); 578 __ movq(R13, Address(R13, Heap::new_space_offset()));
579 579
580 // Calculate and align allocation size. 580 // Calculate and align allocation size.
581 // Load new object start and calculate next object start. 581 // Load new object start and calculate next object start.
582 // RBX: array element type. 582 // RBX: array element type.
583 // R10: Array length as Smi. 583 // R10: Array length as Smi.
584 // R13: Points to new space object. 584 // R13: Points to new space object.
585 __ movq(RAX, Address(R13, Scavenger::top_offset())); 585 __ movq(RAX, Address(R13, Scavenger::top_offset()));
586 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; 586 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1;
587 __ leaq(R12, Address(R10, TIMES_4, fixed_size)); // R10 is Smi. 587 __ leaq(R12, Address(R10, TIMES_4, fixed_size)); // R10 is Smi.
588 ASSERT(kSmiTagShift == 1); 588 ASSERT(kSmiTagShift == 1);
589 __ andq(R12, Immediate(-kObjectAlignment)); 589 __ andq(R12, Immediate(-kObjectAlignment));
590 __ leaq(R12, Address(RAX, R12, TIMES_1, 0)); 590 __ leaq(R12, Address(RAX, R12, TIMES_1, 0));
591 591
592 // Check if the allocation fits into the remaining space. 592 // Check if the allocation fits into the remaining space.
593 // RAX: potential new object start. 593 // RAX: potential new object start.
594 // R12: potential next object start. 594 // R12: potential next object start.
595 // RBX: array element type. 595 // RBX: array element type.
596 // R10: Array length as Smi. 596 // R10: Array length as Smi.
597 // R13: Points to new space object. 597 // R13: Points to new space object.
598 __ cmpq(R12, Address(R13, Scavenger::end_offset())); 598 __ cmpq(R12, Address(R13, Scavenger::end_offset()));
599 __ j(ABOVE_EQUAL, &slow_case, Assembler::kNearJump); 599 __ j(ABOVE_EQUAL, &slow_case);
600 600
601 // Successfully allocated the object(s), now update top to point to 601 // Successfully allocated the object(s), now update top to point to
602 // next object start and initialize the object. 602 // next object start and initialize the object.
603 // RAX: potential new object start. 603 // RAX: potential new object start.
604 // R12: potential next object start. 604 // R12: potential next object start.
605 // R13: Points to new space object. 605 // R13: Points to new space object.
606 __ movq(Address(R13, Scavenger::top_offset()), R12); 606 __ movq(Address(R13, Scavenger::top_offset()), R12);
607 __ addq(RAX, Immediate(kHeapObjectTag)); 607 __ addq(RAX, Immediate(kHeapObjectTag));
608 608
609 // RAX: new object start as a tagged pointer. 609 // RAX: new object start as a tagged pointer.
610 // R12: new object end address. 610 // R12: new object end address.
611 // RBX: array element type. 611 // RBX: array element type.
612 // R10: Array length as Smi. 612 // R10: Array length as Smi.
613 613
614 // Store the type argument field. 614 // Store the type argument field.
615 __ StoreIntoObject(RAX, 615 __ StoreIntoObject(RAX,
616 FieldAddress(RAX, Array::type_arguments_offset()), 616 FieldAddress(RAX, Array::type_arguments_offset()),
617 RBX); 617 RBX);
618 618
619 // Set the length field. 619 // Set the length field.
620 __ StoreIntoObject(RAX, FieldAddress(RAX, Array::length_offset()), R10); 620 __ StoreIntoObject(RAX, FieldAddress(RAX, Array::length_offset()), R10);
621 621
622 // Store class value for array. 622 // Store class value for array.
623 __ movq(RBX, FieldAddress(CTX, Context::isolate_offset())); 623 __ movq(RBX, FieldAddress(CTX, Context::isolate_offset()));
624 __ movq(RBX, Address(RBX, Isolate::object_store_offset())); 624 __ movq(RBX, Address(RBX, Isolate::object_store_offset()));
625 __ movq(RBX, Address(RBX, ObjectStore::array_class_offset())); 625 __ movq(RBX, Address(RBX, ObjectStore::array_class_offset()));
626 __ StoreIntoObject(RAX, FieldAddress(RAX, Array::class_offset()), RBX); 626 __ StoreIntoObject(RAX, FieldAddress(RAX, Array::class_offset()), RBX);
627 __ movq(FieldAddress(RAX, Array::tags_offset()), Immediate(0)); // Tags. 627 // Calculate the size tag.
628 // RAX: new object start as a tagged pointer.
629 // R12: new object end address.
630 // R10: Array length as Smi.
631 {
632 Label size_tag_overflow, done;
633 __ leaq(RBX, Address(R10, TIMES_2, fixed_size)); // R10 is Smi.
634 ASSERT(kSmiTagShift == 1);
635 __ andq(RBX, Immediate(-kObjectAlignment));
636 __ cmpq(RBX,
637 Immediate(RawObject::SizeTag::kMaxSizeTag));
siva 2012/01/04 01:56:03 Can this fit in one line?
Ivan Posva 2012/01/04 07:59:42 Done.
638 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
639 __ shlq(RBX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2));
640 __ movq(FieldAddress(RAX, Array::tags_offset()), RBX);
641 __ jmp(&done);
642
643 __ Bind(&size_tag_overflow);
644 __ movq(FieldAddress(RAX, Array::tags_offset()), Immediate(0));
645 __ Bind(&done);
646 }
628 647
629 // Initialize all array elements to raw_null. 648 // Initialize all array elements to raw_null.
630 // RAX: new object start as a tagged pointer. 649 // RAX: new object start as a tagged pointer.
631 // R12: new object end address. 650 // R12: new object end address.
632 // RBX: iterator which initially points to the start of the variable 651 // RBX: iterator which initially points to the start of the variable
633 // data area to be initialized. 652 // data area to be initialized.
634 __ leaq(RBX, FieldAddress(RAX, Array::data_offset())); 653 __ leaq(RBX, FieldAddress(RAX, Array::data_offset()));
635 Label done; 654 Label done;
636 Label init_loop; 655 Label init_loop;
637 __ Bind(&init_loop); 656 __ Bind(&init_loop);
638 __ cmpq(RBX, R12); 657 __ cmpq(RBX, R12);
639 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); 658 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
640 __ movq(Address(RBX, 0), raw_null); 659 __ movq(Address(RBX, 0), raw_null);
641 __ addq(RBX, Immediate(kWordSize)); 660 __ addq(RBX, Immediate(kWordSize));
642 __ jmp(&init_loop, Assembler::kNearJump); 661 __ jmp(&init_loop, Assembler::kNearJump);
643 __ Bind(&done); 662 __ Bind(&done);
644 663
645 // Done allocating and initializing the array. 664 // Done allocating and initializing the array.
646 // RAX: new object. 665 // RAX: new object.
666 // R10: Array length as Smi (preserved for the caller.)
647 __ ret(); 667 __ ret();
648 } 668 }
649 669
650 // Unable to allocate the array using the fast inline code, just call 670 // Unable to allocate the array using the fast inline code, just call
651 // into the runtime. 671 // into the runtime.
652 __ Bind(&slow_case); 672 __ Bind(&slow_case);
653 __ EnterFrame(0); 673 __ EnterFrame(0);
654 __ pushq(raw_null); // Setup space on stack for return value. 674 __ pushq(raw_null); // Setup space on stack for return value.
655 __ pushq(R10); // Array length as Smi. 675 __ pushq(R10); // Array length as Smi.
656 __ pushq(RBX); // Element type. 676 __ pushq(RBX); // Element type.
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 __ movq(Address(RCX, 907 __ movq(Address(RCX,
888 InstantiatedTypeArguments::uninstantiated_type_arguments_offset()), 908 InstantiatedTypeArguments::uninstantiated_type_arguments_offset()),
889 RDI); 909 RDI);
890 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset)); 910 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset));
891 __ movq(Address(RCX, 911 __ movq(Address(RCX,
892 InstantiatedTypeArguments::instantiator_type_arguments_offset()), 912 InstantiatedTypeArguments::instantiator_type_arguments_offset()),
893 RDX); 913 RDX);
894 __ LoadObject(RDX, 914 __ LoadObject(RDX,
895 Class::ZoneHandle(Object::instantiated_type_arguments_class())); 915 Class::ZoneHandle(Object::instantiated_type_arguments_class()));
896 __ movq(Address(RCX, Instance::class_offset()), RDX); // Set its class. 916 __ movq(Address(RCX, Instance::class_offset()), RDX); // Set its class.
897 __ movq(Address(RCX, Instance::tags_offset()), Immediate(0)); // Tags. 917 // Set the tags.
siva 2012/01/04 01:56:03 ASSERT(type_args_size <= RawObject::SizeTag::kMaxS
Ivan Posva 2012/01/04 07:59:42 ditto.
918 __ movq(Address(RCX, Instance::tags_offset()),
919 Immediate(RawObject::SizeTag::encode(type_args_size)));
898 // Set the new InstantiatedTypeArguments object (RCX) as the type 920 // Set the new InstantiatedTypeArguments object (RCX) as the type
899 // arguments (RDI) of the new object (RAX). 921 // arguments (RDI) of the new object (RAX).
900 __ movq(RDI, RCX); 922 __ movq(RDI, RCX);
901 __ addq(RDI, Immediate(kHeapObjectTag)); 923 __ addq(RDI, Immediate(kHeapObjectTag));
902 // Set RBX to new object end. 924 // Set RBX to new object end.
903 __ movq(RBX, RCX); 925 __ movq(RBX, RCX);
904 __ Bind(&type_arguments_ready); 926 __ Bind(&type_arguments_ready);
905 // RAX: new object. 927 // RAX: new object.
906 // RDI: new object type arguments. 928 // RDI: new object type arguments.
907 } 929 }
908 930
909 // Initialize the class field in the object. 931 // Initialize the class field in the object.
910 // RAX: new object start. 932 // RAX: new object start.
911 // RBX: next object start. 933 // RBX: next object start.
912 // RDI: new object type arguments (if is_cls_parameterized). 934 // RDI: new object type arguments (if is_cls_parameterized).
913 __ LoadObject(RDX, cls); // Load class of object to be allocated. 935 __ LoadObject(RDX, cls); // Load class of object to be allocated.
914 __ movq(Address(RAX, Instance::class_offset()), RDX); 936 __ movq(Address(RAX, Instance::class_offset()), RDX);
915 __ movq(Address(RAX, Instance::tags_offset()), Immediate(0)); // Tags. 937 // Set the tags.
siva 2012/01/04 01:56:03 ASSERT(instance_size <= RawObject::SizeTag::kMaxSi
Ivan Posva 2012/01/04 07:59:42 ditto.
938 __ movq(Address(RAX, Instance::tags_offset()),
939 Immediate(RawObject::SizeTag::encode(instance_size)));
916 940
917 // Initialize the remaining words of the object. 941 // Initialize the remaining words of the object.
918 const Immediate raw_null = 942 const Immediate raw_null =
919 Immediate(reinterpret_cast<intptr_t>(Object::null())); 943 Immediate(reinterpret_cast<intptr_t>(Object::null()));
920 944
921 // RAX: new object start. 945 // RAX: new object start.
922 // RBX: next object start. 946 // RBX: next object start.
923 // RDX: class of the object to be allocated. 947 // RDX: class of the object to be allocated.
924 // First try inlining the initialization without a loop. 948 // First try inlining the initialization without a loop.
925 if (instance_size < (kInlineInstanceSize * kWordSize) && 949 if (instance_size < (kInlineInstanceSize * kWordSize) &&
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
1243 } 1267 }
1244 1268
1245 1269
1246 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { 1270 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
1247 __ Unimplemented("BreakpointDynamic stub"); 1271 __ Unimplemented("BreakpointDynamic stub");
1248 } 1272 }
1249 1273
1250 } // namespace dart 1274 } // namespace dart
1251 1275
1252 #endif // defined TARGET_ARCH_X64 1276 #endif // defined TARGET_ARCH_X64
OLDNEW
« vm/stub_code_ia32.cc ('K') | « vm/stub_code_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698