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

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
« no previous file with comments | « 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.
regis 2012/01/10 20:27:48 It should be TIMES_4. I'll fix it in my next cl.
634 ASSERT(kSmiTagShift == 1);
635 __ andq(RBX, Immediate(-kObjectAlignment));
636 __ cmpq(RBX, Immediate(RawObject::SizeTag::kMaxSizeTag));
637 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
638 __ shlq(RBX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2));
639 __ movq(FieldAddress(RAX, Array::tags_offset()), RBX);
640 __ jmp(&done);
641
642 __ Bind(&size_tag_overflow);
643 __ movq(FieldAddress(RAX, Array::tags_offset()), Immediate(0));
644 __ Bind(&done);
645 }
628 646
629 // Initialize all array elements to raw_null. 647 // Initialize all array elements to raw_null.
630 // RAX: new object start as a tagged pointer. 648 // RAX: new object start as a tagged pointer.
631 // R12: new object end address. 649 // R12: new object end address.
632 // RBX: iterator which initially points to the start of the variable 650 // RBX: iterator which initially points to the start of the variable
633 // data area to be initialized. 651 // data area to be initialized.
634 __ leaq(RBX, FieldAddress(RAX, Array::data_offset())); 652 __ leaq(RBX, FieldAddress(RAX, Array::data_offset()));
635 Label done; 653 Label done;
636 Label init_loop; 654 Label init_loop;
637 __ Bind(&init_loop); 655 __ Bind(&init_loop);
638 __ cmpq(RBX, R12); 656 __ cmpq(RBX, R12);
639 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); 657 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
640 __ movq(Address(RBX, 0), raw_null); 658 __ movq(Address(RBX, 0), raw_null);
641 __ addq(RBX, Immediate(kWordSize)); 659 __ addq(RBX, Immediate(kWordSize));
642 __ jmp(&init_loop, Assembler::kNearJump); 660 __ jmp(&init_loop, Assembler::kNearJump);
643 __ Bind(&done); 661 __ Bind(&done);
644 662
645 // Done allocating and initializing the array. 663 // Done allocating and initializing the array.
646 // RAX: new object. 664 // RAX: new object.
665 // R10: Array length as Smi (preserved for the caller.)
647 __ ret(); 666 __ ret();
648 } 667 }
649 668
650 // Unable to allocate the array using the fast inline code, just call 669 // Unable to allocate the array using the fast inline code, just call
651 // into the runtime. 670 // into the runtime.
652 __ Bind(&slow_case); 671 __ Bind(&slow_case);
653 __ EnterFrame(0); 672 __ EnterFrame(0);
654 __ pushq(raw_null); // Setup space on stack for return value. 673 __ pushq(raw_null); // Setup space on stack for return value.
655 __ pushq(R10); // Array length as Smi. 674 __ pushq(R10); // Array length as Smi.
656 __ pushq(RBX); // Element type. 675 __ pushq(RBX); // Element type.
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 __ movq(Address(RCX, 906 __ movq(Address(RCX,
888 InstantiatedTypeArguments::uninstantiated_type_arguments_offset()), 907 InstantiatedTypeArguments::uninstantiated_type_arguments_offset()),
889 RDI); 908 RDI);
890 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset)); 909 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset));
891 __ movq(Address(RCX, 910 __ movq(Address(RCX,
892 InstantiatedTypeArguments::instantiator_type_arguments_offset()), 911 InstantiatedTypeArguments::instantiator_type_arguments_offset()),
893 RDX); 912 RDX);
894 __ LoadObject(RDX, 913 __ LoadObject(RDX,
895 Class::ZoneHandle(Object::instantiated_type_arguments_class())); 914 Class::ZoneHandle(Object::instantiated_type_arguments_class()));
896 __ movq(Address(RCX, Instance::class_offset()), RDX); // Set its class. 915 __ movq(Address(RCX, Instance::class_offset()), RDX); // Set its class.
897 __ movq(Address(RCX, Instance::tags_offset()), Immediate(0)); // Tags. 916 // Set the tags.
917 __ movq(Address(RCX, Instance::tags_offset()),
918 Immediate(RawObject::SizeTag::encode(type_args_size)));
898 // Set the new InstantiatedTypeArguments object (RCX) as the type 919 // Set the new InstantiatedTypeArguments object (RCX) as the type
899 // arguments (RDI) of the new object (RAX). 920 // arguments (RDI) of the new object (RAX).
900 __ movq(RDI, RCX); 921 __ movq(RDI, RCX);
901 __ addq(RDI, Immediate(kHeapObjectTag)); 922 __ addq(RDI, Immediate(kHeapObjectTag));
902 // Set RBX to new object end. 923 // Set RBX to new object end.
903 __ movq(RBX, RCX); 924 __ movq(RBX, RCX);
904 __ Bind(&type_arguments_ready); 925 __ Bind(&type_arguments_ready);
905 // RAX: new object. 926 // RAX: new object.
906 // RDI: new object type arguments. 927 // RDI: new object type arguments.
907 } 928 }
908 929
909 // Initialize the class field in the object. 930 // Initialize the class field in the object.
910 // RAX: new object start. 931 // RAX: new object start.
911 // RBX: next object start. 932 // RBX: next object start.
912 // RDI: new object type arguments (if is_cls_parameterized). 933 // RDI: new object type arguments (if is_cls_parameterized).
913 __ LoadObject(RDX, cls); // Load class of object to be allocated. 934 __ LoadObject(RDX, cls); // Load class of object to be allocated.
914 __ movq(Address(RAX, Instance::class_offset()), RDX); 935 __ movq(Address(RAX, Instance::class_offset()), RDX);
915 __ movq(Address(RAX, Instance::tags_offset()), Immediate(0)); // Tags. 936 // Set the tags.
937 __ movq(Address(RAX, Instance::tags_offset()),
938 Immediate(RawObject::SizeTag::encode(instance_size)));
916 939
917 // Initialize the remaining words of the object. 940 // Initialize the remaining words of the object.
918 const Immediate raw_null = 941 const Immediate raw_null =
919 Immediate(reinterpret_cast<intptr_t>(Object::null())); 942 Immediate(reinterpret_cast<intptr_t>(Object::null()));
920 943
921 // RAX: new object start. 944 // RAX: new object start.
922 // RBX: next object start. 945 // RBX: next object start.
923 // RDX: class of the object to be allocated. 946 // RDX: class of the object to be allocated.
924 // First try inlining the initialization without a loop. 947 // First try inlining the initialization without a loop.
925 if (instance_size < (kInlineInstanceSize * kWordSize) && 948 if (instance_size < (kInlineInstanceSize * kWordSize) &&
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
1243 } 1266 }
1244 1267
1245 1268
1246 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { 1269 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
1247 __ Unimplemented("BreakpointDynamic stub"); 1270 __ Unimplemented("BreakpointDynamic stub");
1248 } 1271 }
1249 1272
1250 } // namespace dart 1273 } // namespace dart
1251 1274
1252 #endif // defined TARGET_ARCH_X64 1275 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « vm/stub_code_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698