Chromium Code Reviews| 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 const intptr_t cid = kArrayCid; |
| 607 __ movq(RAX, Immediate(heap->TopAddress())); | 607 Heap::Space space = heap->SpaceForAllocation(cid); |
| 608 __ movq(RAX, Immediate(heap->TopAddress(space))); | |
| 608 __ movq(RAX, Address(RAX, 0)); | 609 __ movq(RAX, Address(RAX, 0)); |
| 609 | 610 |
| 610 // RDI: allocation size. | 611 // RDI: allocation size. |
| 611 __ movq(RCX, RAX); | 612 __ movq(RCX, RAX); |
| 612 __ addq(RCX, RDI); | 613 __ addq(RCX, RDI); |
| 613 __ j(CARRY, &slow_case); | 614 __ j(CARRY, &slow_case); |
| 614 | 615 |
| 615 // Check if the allocation fits into the remaining space. | 616 // Check if the allocation fits into the remaining space. |
| 616 // RAX: potential new object start. | 617 // RAX: potential new object start. |
| 617 // RCX: potential next object start. | 618 // RCX: potential next object start. |
| 618 // RDI: allocation size. | 619 // RDI: allocation size. |
| 619 __ movq(R13, Immediate(heap->EndAddress())); | 620 __ movq(R13, Immediate(heap->EndAddress(space))); |
| 620 __ cmpq(RCX, Address(R13, 0)); | 621 __ cmpq(RCX, Address(R13, 0)); |
| 621 __ j(ABOVE_EQUAL, &slow_case); | 622 __ j(ABOVE_EQUAL, &slow_case); |
| 622 | 623 |
| 623 // Successfully allocated the object(s), now update top to point to | 624 // Successfully allocated the object(s), now update top to point to |
| 624 // next object start and initialize the object. | 625 // next object start and initialize the object. |
| 625 __ movq(R13, Immediate(heap->TopAddress())); | 626 __ movq(R13, Immediate(heap->TopAddress(space))); |
| 626 __ movq(Address(R13, 0), RCX); | 627 __ movq(Address(R13, 0), RCX); |
| 627 __ addq(RAX, Immediate(kHeapObjectTag)); | 628 __ addq(RAX, Immediate(kHeapObjectTag)); |
| 628 __ UpdateAllocationStatsWithSize(kArrayCid, RDI); | 629 __ UpdateAllocationStatsWithSize(cid, RDI, space); |
| 629 // Initialize the tags. | 630 // Initialize the tags. |
| 630 // RAX: new object start as a tagged pointer. | 631 // RAX: new object start as a tagged pointer. |
| 631 // RDI: allocation size. | 632 // RDI: allocation size. |
| 632 { | 633 { |
| 633 Label size_tag_overflow, done; | 634 Label size_tag_overflow, done; |
| 634 __ cmpq(RDI, Immediate(RawObject::SizeTag::kMaxSizeTag)); | 635 __ cmpq(RDI, Immediate(RawObject::SizeTag::kMaxSizeTag)); |
| 635 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | 636 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); |
| 636 __ shlq(RDI, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2)); | 637 __ shlq(RDI, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2)); |
| 637 __ jmp(&done, Assembler::kNearJump); | 638 __ jmp(&done, Assembler::kNearJump); |
| 638 | 639 |
| 639 __ Bind(&size_tag_overflow); | 640 __ Bind(&size_tag_overflow); |
| 640 __ movq(RDI, Immediate(0)); | 641 __ movq(RDI, Immediate(0)); |
| 641 __ Bind(&done); | 642 __ Bind(&done); |
| 642 | 643 |
| 643 // Get the class index and insert it into the tags. | 644 // Get the class index and insert it into the tags. |
| 644 const Class& cls = Class::Handle(isolate->object_store()->array_class()); | 645 __ orq(RDI, Immediate(RawObject::ClassIdTag::encode(cid))); |
| 645 __ orq(RDI, Immediate(RawObject::ClassIdTag::encode(cls.id()))); | |
| 646 __ movq(FieldAddress(RAX, Array::tags_offset()), RDI); // Tags. | 646 __ movq(FieldAddress(RAX, Array::tags_offset()), RDI); // Tags. |
| 647 } | 647 } |
| 648 | 648 |
| 649 // RAX: new object start as a tagged pointer. | 649 // RAX: new object start as a tagged pointer. |
| 650 // Store the type argument field. | 650 // Store the type argument field. |
| 651 __ StoreIntoObjectNoBarrier(RAX, | 651 __ StoreIntoObjectNoBarrier(RAX, |
| 652 FieldAddress(RAX, Array::type_arguments_offset()), | 652 FieldAddress(RAX, Array::type_arguments_offset()), |
| 653 RBX); | 653 RBX); |
| 654 | 654 |
| 655 // Set the length field. | 655 // Set the length field. |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 882 Isolate* isolate = Isolate::Current(); | 882 Isolate* isolate = Isolate::Current(); |
| 883 Heap* heap = isolate->heap(); | 883 Heap* heap = isolate->heap(); |
| 884 // First compute the rounded instance size. | 884 // First compute the rounded instance size. |
| 885 // R10: number of context variables. | 885 // R10: number of context variables. |
| 886 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1); | 886 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1); |
| 887 __ leaq(R13, Address(R10, TIMES_8, fixed_size)); | 887 __ leaq(R13, Address(R10, TIMES_8, fixed_size)); |
| 888 __ andq(R13, Immediate(-kObjectAlignment)); | 888 __ andq(R13, Immediate(-kObjectAlignment)); |
| 889 | 889 |
| 890 // Now allocate the object. | 890 // Now allocate the object. |
| 891 // R10: number of context variables. | 891 // R10: number of context variables. |
| 892 __ movq(RAX, Immediate(heap->TopAddress())); | 892 intptr_t cid = context_class.id(); |
|
Ivan Posva
2014/09/19 22:24:35
?
koda
2014/09/19 23:46:59
Done.
| |
| 893 Heap::Space space = heap->SpaceForAllocation(cid); | |
| 894 __ movq(RAX, Immediate(heap->TopAddress(space))); | |
| 893 __ movq(RAX, Address(RAX, 0)); | 895 __ movq(RAX, Address(RAX, 0)); |
| 894 __ addq(R13, RAX); | 896 __ addq(R13, RAX); |
| 895 // Check if the allocation fits into the remaining space. | 897 // Check if the allocation fits into the remaining space. |
| 896 // RAX: potential new object. | 898 // RAX: potential new object. |
| 897 // R13: potential next object start. | 899 // R13: potential next object start. |
| 898 // R10: number of context variables. | 900 // R10: number of context variables. |
| 899 __ movq(RDI, Immediate(heap->EndAddress())); | 901 __ movq(RDI, Immediate(heap->EndAddress(space))); |
| 900 __ cmpq(R13, Address(RDI, 0)); | 902 __ cmpq(R13, Address(RDI, 0)); |
| 901 if (FLAG_use_slow_path) { | 903 if (FLAG_use_slow_path) { |
| 902 __ jmp(&slow_case); | 904 __ jmp(&slow_case); |
| 903 } else { | 905 } else { |
| 904 __ j(ABOVE_EQUAL, &slow_case); | 906 __ j(ABOVE_EQUAL, &slow_case); |
| 905 } | 907 } |
| 906 | 908 |
| 907 // Successfully allocated the object, now update top to point to | 909 // Successfully allocated the object, now update top to point to |
| 908 // next object start and initialize the object. | 910 // next object start and initialize the object. |
| 909 // RAX: new object. | 911 // RAX: new object. |
| 910 // R13: next object start. | 912 // R13: next object start. |
| 911 // R10: number of context variables. | 913 // R10: number of context variables. |
| 912 __ movq(RDI, Immediate(heap->TopAddress())); | 914 __ movq(RDI, Immediate(heap->TopAddress(space))); |
| 913 __ movq(Address(RDI, 0), R13); | 915 __ movq(Address(RDI, 0), R13); |
| 914 __ addq(RAX, Immediate(kHeapObjectTag)); | 916 __ addq(RAX, Immediate(kHeapObjectTag)); |
| 915 // R13: Size of allocation in bytes. | 917 // R13: Size of allocation in bytes. |
| 916 __ subq(R13, RAX); | 918 __ subq(R13, RAX); |
| 917 __ UpdateAllocationStatsWithSize(context_class.id(), R13); | 919 __ UpdateAllocationStatsWithSize(cid, R13, space); |
| 918 | 920 |
| 919 // Calculate the size tag. | 921 // Calculate the size tag. |
| 920 // RAX: new object. | 922 // RAX: new object. |
| 921 // R10: number of context variables. | 923 // R10: number of context variables. |
| 922 { | 924 { |
| 923 Label size_tag_overflow, done; | 925 Label size_tag_overflow, done; |
| 924 __ leaq(R13, Address(R10, TIMES_8, fixed_size)); | 926 __ leaq(R13, Address(R10, TIMES_8, fixed_size)); |
| 925 __ andq(R13, Immediate(-kObjectAlignment)); | 927 __ andq(R13, Immediate(-kObjectAlignment)); |
| 926 __ cmpq(R13, Immediate(RawObject::SizeTag::kMaxSizeTag)); | 928 __ cmpq(R13, Immediate(RawObject::SizeTag::kMaxSizeTag)); |
| 927 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | 929 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); |
| 928 __ shlq(R13, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2)); | 930 __ shlq(R13, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2)); |
| 929 __ jmp(&done); | 931 __ jmp(&done); |
| 930 | 932 |
| 931 __ Bind(&size_tag_overflow); | 933 __ Bind(&size_tag_overflow); |
| 932 // Set overflow size tag value. | 934 // Set overflow size tag value. |
| 933 __ movq(R13, Immediate(0)); | 935 __ movq(R13, Immediate(0)); |
| 934 | 936 |
| 935 __ Bind(&done); | 937 __ Bind(&done); |
| 936 // RAX: new object. | 938 // RAX: new object. |
| 937 // R10: number of context variables. | 939 // R10: number of context variables. |
| 938 // R13: size and bit tags. | 940 // R13: size and bit tags. |
| 939 __ orq(R13, | 941 __ orq(R13, |
| 940 Immediate(RawObject::ClassIdTag::encode(context_class.id()))); | 942 Immediate(RawObject::ClassIdTag::encode(cid))); |
| 941 __ movq(FieldAddress(RAX, Context::tags_offset()), R13); // Tags. | 943 __ movq(FieldAddress(RAX, Context::tags_offset()), R13); // Tags. |
| 942 } | 944 } |
| 943 | 945 |
| 944 // Setup up number of context variables field. | 946 // Setup up number of context variables field. |
| 945 // RAX: new object. | 947 // RAX: new object. |
| 946 // R10: number of context variables as integer value (not object). | 948 // R10: number of context variables as integer value (not object). |
| 947 __ movq(FieldAddress(RAX, Context::num_variables_offset()), R10); | 949 __ movq(FieldAddress(RAX, Context::num_variables_offset()), R10); |
| 948 | 950 |
| 949 // Setup isolate field. | 951 // Setup isolate field. |
| 950 // RAX: new object. | 952 // RAX: new object. |
| (...skipping 133 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 901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2021 | 2024 |
| 2022 __ movq(left, Address(RSP, 2 * kWordSize)); | 2025 __ movq(left, Address(RSP, 2 * kWordSize)); |
| 2023 __ movq(right, Address(RSP, 1 * kWordSize)); | 2026 __ movq(right, Address(RSP, 1 * kWordSize)); |
| 2024 GenerateIdenticalWithNumberCheckStub(assembler, left, right); | 2027 GenerateIdenticalWithNumberCheckStub(assembler, left, right); |
| 2025 __ ret(); | 2028 __ ret(); |
| 2026 } | 2029 } |
| 2027 | 2030 |
| 2028 } // namespace dart | 2031 } // namespace dart |
| 2029 | 2032 |
| 2030 #endif // defined TARGET_ARCH_X64 | 2033 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |