OLD | NEW |
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 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 Immediate(reinterpret_cast<int64_t>(Smi::New(Array::kMaxElements))); | 596 Immediate(reinterpret_cast<int64_t>(Smi::New(Array::kMaxElements))); |
597 __ cmpq(RDI, max_len); | 597 __ cmpq(RDI, max_len); |
598 __ j(GREATER, &slow_case); | 598 __ j(GREATER, &slow_case); |
599 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; | 599 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; |
600 __ leaq(RDI, Address(RDI, TIMES_4, fixed_size)); // RDI is a Smi. | 600 __ leaq(RDI, Address(RDI, TIMES_4, fixed_size)); // RDI is a Smi. |
601 ASSERT(kSmiTagShift == 1); | 601 ASSERT(kSmiTagShift == 1); |
602 __ andq(RDI, Immediate(-kObjectAlignment)); | 602 __ andq(RDI, Immediate(-kObjectAlignment)); |
603 | 603 |
604 Isolate* isolate = Isolate::Current(); | 604 Isolate* isolate = Isolate::Current(); |
605 Heap* heap = isolate->heap(); | 605 Heap* heap = isolate->heap(); |
606 | 606 Heap::Space space = heap->SpaceForAllocation(kArrayCid); |
607 __ movq(RAX, Immediate(heap->TopAddress())); | 607 __ movq(RAX, Immediate(heap->TopAddress(space))); |
608 __ movq(RAX, Address(RAX, 0)); | 608 __ movq(RAX, Address(RAX, 0)); |
609 | 609 |
610 // RDI: allocation size. | 610 // RDI: allocation size. |
611 __ movq(RCX, RAX); | 611 __ movq(RCX, RAX); |
612 __ addq(RCX, RDI); | 612 __ addq(RCX, RDI); |
613 __ j(CARRY, &slow_case); | 613 __ j(CARRY, &slow_case); |
614 | 614 |
615 // Check if the allocation fits into the remaining space. | 615 // Check if the allocation fits into the remaining space. |
616 // RAX: potential new object start. | 616 // RAX: potential new object start. |
617 // RCX: potential next object start. | 617 // RCX: potential next object start. |
618 // RDI: allocation size. | 618 // RDI: allocation size. |
619 __ movq(R13, Immediate(heap->EndAddress())); | 619 __ movq(R13, Immediate(heap->EndAddress(space))); |
620 __ cmpq(RCX, Address(R13, 0)); | 620 __ cmpq(RCX, Address(R13, 0)); |
621 __ j(ABOVE_EQUAL, &slow_case); | 621 __ j(ABOVE_EQUAL, &slow_case); |
622 | 622 |
623 // Successfully allocated the object(s), now update top to point to | 623 // Successfully allocated the object(s), now update top to point to |
624 // next object start and initialize the object. | 624 // next object start and initialize the object. |
625 __ movq(R13, Immediate(heap->TopAddress())); | 625 __ movq(R13, Immediate(heap->TopAddress(space))); |
626 __ movq(Address(R13, 0), RCX); | 626 __ movq(Address(R13, 0), RCX); |
627 __ addq(RAX, Immediate(kHeapObjectTag)); | 627 __ addq(RAX, Immediate(kHeapObjectTag)); |
628 __ UpdateAllocationStatsWithSize(kArrayCid, RDI); | 628 __ UpdateAllocationStatsWithSize(kArrayCid, RDI, space); |
629 // Initialize the tags. | 629 // Initialize the tags. |
630 // RAX: new object start as a tagged pointer. | 630 // RAX: new object start as a tagged pointer. |
631 // RDI: allocation size. | 631 // RDI: allocation size. |
632 { | 632 { |
633 Label size_tag_overflow, done; | 633 Label size_tag_overflow, done; |
634 __ cmpq(RDI, Immediate(RawObject::SizeTag::kMaxSizeTag)); | 634 __ cmpq(RDI, Immediate(RawObject::SizeTag::kMaxSizeTag)); |
635 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | 635 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); |
636 __ shlq(RDI, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2)); | 636 __ shlq(RDI, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2)); |
637 __ jmp(&done, Assembler::kNearJump); | 637 __ jmp(&done, Assembler::kNearJump); |
638 | 638 |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
886 Label slow_case; | 886 Label slow_case; |
887 Heap* heap = Isolate::Current()->heap(); | 887 Heap* heap = Isolate::Current()->heap(); |
888 // First compute the rounded instance size. | 888 // First compute the rounded instance size. |
889 // R10: number of context variables. | 889 // R10: number of context variables. |
890 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1); | 890 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1); |
891 __ leaq(R13, Address(R10, TIMES_8, fixed_size)); | 891 __ leaq(R13, Address(R10, TIMES_8, fixed_size)); |
892 __ andq(R13, Immediate(-kObjectAlignment)); | 892 __ andq(R13, Immediate(-kObjectAlignment)); |
893 | 893 |
894 // Now allocate the object. | 894 // Now allocate the object. |
895 // R10: number of context variables. | 895 // R10: number of context variables. |
896 __ movq(RAX, Immediate(heap->TopAddress())); | 896 intptr_t cid = context_class.id(); |
| 897 Heap::Space space = heap->SpaceForAllocation(cid); |
| 898 __ movq(RAX, Immediate(heap->TopAddress(space))); |
897 __ movq(RAX, Address(RAX, 0)); | 899 __ movq(RAX, Address(RAX, 0)); |
898 __ addq(R13, RAX); | 900 __ addq(R13, RAX); |
899 // Check if the allocation fits into the remaining space. | 901 // Check if the allocation fits into the remaining space. |
900 // RAX: potential new object. | 902 // RAX: potential new object. |
901 // R13: potential next object start. | 903 // R13: potential next object start. |
902 // R10: number of context variables. | 904 // R10: number of context variables. |
903 __ movq(RDI, Immediate(heap->EndAddress())); | 905 __ movq(RDI, Immediate(heap->EndAddress(space))); |
904 __ cmpq(R13, Address(RDI, 0)); | 906 __ cmpq(R13, Address(RDI, 0)); |
905 if (FLAG_use_slow_path) { | 907 if (FLAG_use_slow_path) { |
906 __ jmp(&slow_case); | 908 __ jmp(&slow_case); |
907 } else { | 909 } else { |
908 __ j(ABOVE_EQUAL, &slow_case); | 910 __ j(ABOVE_EQUAL, &slow_case); |
909 } | 911 } |
910 | 912 |
911 // Successfully allocated the object, now update top to point to | 913 // Successfully allocated the object, now update top to point to |
912 // next object start and initialize the object. | 914 // next object start and initialize the object. |
913 // RAX: new object. | 915 // RAX: new object. |
914 // R13: next object start. | 916 // R13: next object start. |
915 // R10: number of context variables. | 917 // R10: number of context variables. |
916 __ movq(RDI, Immediate(heap->TopAddress())); | 918 __ movq(RDI, Immediate(heap->TopAddress(space))); |
917 __ movq(Address(RDI, 0), R13); | 919 __ movq(Address(RDI, 0), R13); |
918 __ addq(RAX, Immediate(kHeapObjectTag)); | 920 __ addq(RAX, Immediate(kHeapObjectTag)); |
919 // R13: Size of allocation in bytes. | 921 // R13: Size of allocation in bytes. |
920 __ subq(R13, RAX); | 922 __ subq(R13, RAX); |
921 __ UpdateAllocationStatsWithSize(context_class.id(), R13); | 923 __ UpdateAllocationStatsWithSize(cid, R13, space); |
922 | 924 |
923 // Calculate the size tag. | 925 // Calculate the size tag. |
924 // RAX: new object. | 926 // RAX: new object. |
925 // R10: number of context variables. | 927 // R10: number of context variables. |
926 { | 928 { |
927 Label size_tag_overflow, done; | 929 Label size_tag_overflow, done; |
928 __ leaq(R13, Address(R10, TIMES_8, fixed_size)); | 930 __ leaq(R13, Address(R10, TIMES_8, fixed_size)); |
929 __ andq(R13, Immediate(-kObjectAlignment)); | 931 __ andq(R13, Immediate(-kObjectAlignment)); |
930 __ cmpq(R13, Immediate(RawObject::SizeTag::kMaxSizeTag)); | 932 __ cmpq(R13, Immediate(RawObject::SizeTag::kMaxSizeTag)); |
931 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | 933 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); |
932 __ shlq(R13, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2)); | 934 __ shlq(R13, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2)); |
933 __ jmp(&done); | 935 __ jmp(&done); |
934 | 936 |
935 __ Bind(&size_tag_overflow); | 937 __ Bind(&size_tag_overflow); |
936 // Set overflow size tag value. | 938 // Set overflow size tag value. |
937 __ movq(R13, Immediate(0)); | 939 __ movq(R13, Immediate(0)); |
938 | 940 |
939 __ Bind(&done); | 941 __ Bind(&done); |
940 // RAX: new object. | 942 // RAX: new object. |
941 // R10: number of context variables. | 943 // R10: number of context variables. |
942 // R13: size and bit tags. | 944 // R13: size and bit tags. |
943 __ orq(R13, | 945 __ orq(R13, |
944 Immediate(RawObject::ClassIdTag::encode(context_class.id()))); | 946 Immediate(RawObject::ClassIdTag::encode(cid))); |
945 __ movq(FieldAddress(RAX, Context::tags_offset()), R13); // Tags. | 947 __ movq(FieldAddress(RAX, Context::tags_offset()), R13); // Tags. |
946 } | 948 } |
947 | 949 |
948 // Setup up number of context variables field. | 950 // Setup up number of context variables field. |
949 // RAX: new object. | 951 // RAX: new object. |
950 // R10: number of context variables as integer value (not object). | 952 // R10: number of context variables as integer value (not object). |
951 __ movq(FieldAddress(RAX, Context::num_variables_offset()), R10); | 953 __ movq(FieldAddress(RAX, Context::num_variables_offset()), R10); |
952 | 954 |
953 // Setup isolate field. | 955 // Setup isolate field. |
954 // Load Isolate pointer from Context structure into R13. | 956 // Load Isolate pointer from Context structure into R13. |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1084 if (is_cls_parameterized) { | 1086 if (is_cls_parameterized) { |
1085 __ movq(RDX, Address(RSP, kObjectTypeArgumentsOffset)); | 1087 __ movq(RDX, Address(RSP, kObjectTypeArgumentsOffset)); |
1086 // RDX: instantiated type arguments. | 1088 // RDX: instantiated type arguments. |
1087 } | 1089 } |
1088 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { | 1090 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { |
1089 Label slow_case; | 1091 Label slow_case; |
1090 // Allocate the object and update top to point to | 1092 // Allocate the object and update top to point to |
1091 // next object start and initialize the allocated object. | 1093 // next object start and initialize the allocated object. |
1092 // RDX: instantiated type arguments (if is_cls_parameterized). | 1094 // RDX: instantiated type arguments (if is_cls_parameterized). |
1093 Heap* heap = Isolate::Current()->heap(); | 1095 Heap* heap = Isolate::Current()->heap(); |
1094 __ movq(RCX, Immediate(heap->TopAddress())); | 1096 Heap::Space space = heap->SpaceForAllocation(cls.id()); |
| 1097 __ movq(RCX, Immediate(heap->TopAddress(space))); |
1095 __ movq(RAX, Address(RCX, 0)); | 1098 __ movq(RAX, Address(RCX, 0)); |
1096 __ leaq(RBX, Address(RAX, instance_size)); | 1099 __ leaq(RBX, Address(RAX, instance_size)); |
1097 // Check if the allocation fits into the remaining space. | 1100 // Check if the allocation fits into the remaining space. |
1098 // RAX: potential new object start. | 1101 // RAX: potential new object start. |
1099 // RBX: potential next object start. | 1102 // RBX: potential next object start. |
1100 // RCX: heap top address. | 1103 // RCX: heap top address. |
1101 __ movq(R13, Immediate(heap->EndAddress())); | 1104 __ movq(R13, Immediate(heap->EndAddress(space))); |
1102 __ cmpq(RBX, Address(R13, 0)); | 1105 __ cmpq(RBX, Address(R13, 0)); |
1103 if (FLAG_use_slow_path) { | 1106 if (FLAG_use_slow_path) { |
1104 __ jmp(&slow_case); | 1107 __ jmp(&slow_case); |
1105 } else { | 1108 } else { |
1106 __ j(ABOVE_EQUAL, &slow_case); | 1109 __ j(ABOVE_EQUAL, &slow_case); |
1107 } | 1110 } |
1108 __ movq(Address(RCX, 0), RBX); | 1111 __ movq(Address(RCX, 0), RBX); |
1109 __ UpdateAllocationStats(cls.id()); | 1112 __ UpdateAllocationStats(cls.id(), space); |
1110 | 1113 |
1111 // RAX: new object start. | 1114 // RAX: new object start. |
1112 // RBX: next object start. | 1115 // RBX: next object start. |
1113 // RDX: new object type arguments (if is_cls_parameterized). | 1116 // RDX: new object type arguments (if is_cls_parameterized). |
1114 // Set the tags. | 1117 // Set the tags. |
1115 uword tags = 0; | 1118 uword tags = 0; |
1116 tags = RawObject::SizeTag::update(instance_size, tags); | 1119 tags = RawObject::SizeTag::update(instance_size, tags); |
1117 ASSERT(cls.id() != kIllegalCid); | 1120 ASSERT(cls.id() != kIllegalCid); |
1118 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 1121 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
1119 __ movq(Address(RAX, Instance::tags_offset()), Immediate(tags)); | 1122 __ movq(Address(RAX, Instance::tags_offset()), Immediate(tags)); |
(...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2022 | 2025 |
2023 __ movq(left, Address(RSP, 2 * kWordSize)); | 2026 __ movq(left, Address(RSP, 2 * kWordSize)); |
2024 __ movq(right, Address(RSP, 1 * kWordSize)); | 2027 __ movq(right, Address(RSP, 1 * kWordSize)); |
2025 GenerateIdenticalWithNumberCheckStub(assembler, left, right); | 2028 GenerateIdenticalWithNumberCheckStub(assembler, left, right); |
2026 __ ret(); | 2029 __ ret(); |
2027 } | 2030 } |
2028 | 2031 |
2029 } // namespace dart | 2032 } // namespace dart |
2030 | 2033 |
2031 #endif // defined TARGET_ARCH_X64 | 2034 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |