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_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
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 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 __ leal(EDI, Address(EDX, TIMES_2, fixed_size)); // EDX is Smi. | 638 __ leal(EDI, Address(EDX, TIMES_2, fixed_size)); // EDX is Smi. |
639 ASSERT(kSmiTagShift == 1); | 639 ASSERT(kSmiTagShift == 1); |
640 __ andl(EDI, Immediate(-kObjectAlignment)); | 640 __ andl(EDI, Immediate(-kObjectAlignment)); |
641 | 641 |
642 // ECX: array element type. | 642 // ECX: array element type. |
643 // EDX: array length as Smi. | 643 // EDX: array length as Smi. |
644 // EDI: allocation size. | 644 // EDI: allocation size. |
645 | 645 |
646 Isolate* isolate = Isolate::Current(); | 646 Isolate* isolate = Isolate::Current(); |
647 Heap* heap = isolate->heap(); | 647 Heap* heap = isolate->heap(); |
648 | 648 const intptr_t cid = kArrayCid; |
649 __ movl(EAX, Address::Absolute(heap->TopAddress())); | 649 Heap::Space space = heap->SpaceForAllocation(cid); |
| 650 __ movl(EAX, Address::Absolute(heap->TopAddress(space))); |
650 __ movl(EBX, EAX); | 651 __ movl(EBX, EAX); |
651 | 652 |
652 // EDI: allocation size. | 653 // EDI: allocation size. |
653 __ addl(EBX, EDI); | 654 __ addl(EBX, EDI); |
654 __ j(CARRY, &slow_case); | 655 __ j(CARRY, &slow_case); |
655 | 656 |
656 // Check if the allocation fits into the remaining space. | 657 // Check if the allocation fits into the remaining space. |
657 // EAX: potential new object start. | 658 // EAX: potential new object start. |
658 // EBX: potential next object start. | 659 // EBX: potential next object start. |
659 // EDI: allocation size. | 660 // EDI: allocation size. |
660 // ECX: array element type. | 661 // ECX: array element type. |
661 // EDX: array length as Smi). | 662 // EDX: array length as Smi). |
662 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); | 663 __ cmpl(EBX, Address::Absolute(heap->EndAddress(space))); |
663 __ j(ABOVE_EQUAL, &slow_case); | 664 __ j(ABOVE_EQUAL, &slow_case); |
664 | 665 |
665 // Successfully allocated the object(s), now update top to point to | 666 // Successfully allocated the object(s), now update top to point to |
666 // next object start and initialize the object. | 667 // next object start and initialize the object. |
667 __ movl(Address::Absolute(heap->TopAddress()), EBX); | 668 __ movl(Address::Absolute(heap->TopAddress(space)), EBX); |
668 __ addl(EAX, Immediate(kHeapObjectTag)); | 669 __ addl(EAX, Immediate(kHeapObjectTag)); |
669 __ UpdateAllocationStatsWithSize(kArrayCid, EDI, kNoRegister); | 670 __ UpdateAllocationStatsWithSize(cid, EDI, kNoRegister, space); |
670 | 671 |
671 // Initialize the tags. | 672 // Initialize the tags. |
672 // EAX: new object start as a tagged pointer. | 673 // EAX: new object start as a tagged pointer. |
673 // EBX: new object end address. | 674 // EBX: new object end address. |
674 // EDI: allocation size. | 675 // EDI: allocation size. |
675 // ECX: array element type. | 676 // ECX: array element type. |
676 // EDX: array length as Smi. | 677 // EDX: array length as Smi. |
677 { | 678 { |
678 Label size_tag_overflow, done; | 679 Label size_tag_overflow, done; |
679 __ cmpl(EDI, Immediate(RawObject::SizeTag::kMaxSizeTag)); | 680 __ cmpl(EDI, Immediate(RawObject::SizeTag::kMaxSizeTag)); |
680 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | 681 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); |
681 __ shll(EDI, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2)); | 682 __ shll(EDI, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2)); |
682 __ jmp(&done, Assembler::kNearJump); | 683 __ jmp(&done, Assembler::kNearJump); |
683 | 684 |
684 __ Bind(&size_tag_overflow); | 685 __ Bind(&size_tag_overflow); |
685 __ movl(EDI, Immediate(0)); | 686 __ movl(EDI, Immediate(0)); |
686 __ Bind(&done); | 687 __ Bind(&done); |
687 | 688 |
688 // Get the class index and insert it into the tags. | 689 // Get the class index and insert it into the tags. |
689 const Class& cls = Class::Handle(isolate->object_store()->array_class()); | 690 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cid))); |
690 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cls.id()))); | |
691 __ movl(FieldAddress(EAX, Array::tags_offset()), EDI); // Tags. | 691 __ movl(FieldAddress(EAX, Array::tags_offset()), EDI); // Tags. |
692 } | 692 } |
693 // EAX: new object start as a tagged pointer. | 693 // EAX: new object start as a tagged pointer. |
694 // EBX: new object end address. | 694 // EBX: new object end address. |
695 // ECX: array element type. | 695 // ECX: array element type. |
696 // EDX: Array length as Smi (preserved). | 696 // EDX: Array length as Smi (preserved). |
697 // Store the type argument field. | 697 // Store the type argument field. |
698 __ StoreIntoObjectNoBarrier(EAX, | 698 __ StoreIntoObjectNoBarrier(EAX, |
699 FieldAddress(EAX, Array::type_arguments_offset()), | 699 FieldAddress(EAX, Array::type_arguments_offset()), |
700 ECX); | 700 ECX); |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 Isolate* isolate = Isolate::Current(); | 898 Isolate* isolate = Isolate::Current(); |
899 Heap* heap = isolate->heap(); | 899 Heap* heap = isolate->heap(); |
900 // First compute the rounded instance size. | 900 // First compute the rounded instance size. |
901 // EDX: number of context variables. | 901 // EDX: number of context variables. |
902 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1); | 902 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1); |
903 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); | 903 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); |
904 __ andl(EBX, Immediate(-kObjectAlignment)); | 904 __ andl(EBX, Immediate(-kObjectAlignment)); |
905 | 905 |
906 // Now allocate the object. | 906 // Now allocate the object. |
907 // EDX: number of context variables. | 907 // EDX: number of context variables. |
908 __ movl(EAX, Address::Absolute(heap->TopAddress())); | 908 intptr_t cid = context_class.id(); |
| 909 Heap::Space space = heap->SpaceForAllocation(cid); |
| 910 __ movl(EAX, Address::Absolute(heap->TopAddress(space))); |
909 __ addl(EBX, EAX); | 911 __ addl(EBX, EAX); |
910 // Check if the allocation fits into the remaining space. | 912 // Check if the allocation fits into the remaining space. |
911 // EAX: potential new object. | 913 // EAX: potential new object. |
912 // EBX: potential next object start. | 914 // EBX: potential next object start. |
913 // EDX: number of context variables. | 915 // EDX: number of context variables. |
914 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); | 916 __ cmpl(EBX, Address::Absolute(heap->EndAddress(space))); |
915 if (FLAG_use_slow_path) { | 917 if (FLAG_use_slow_path) { |
916 __ jmp(&slow_case); | 918 __ jmp(&slow_case); |
917 } else { | 919 } else { |
918 __ j(ABOVE_EQUAL, &slow_case, Assembler::kNearJump); | 920 __ j(ABOVE_EQUAL, &slow_case, Assembler::kNearJump); |
919 } | 921 } |
920 | 922 |
921 // Successfully allocated the object, now update top to point to | 923 // Successfully allocated the object, now update top to point to |
922 // next object start and initialize the object. | 924 // next object start and initialize the object. |
923 // EAX: new object. | 925 // EAX: new object. |
924 // EBX: next object start. | 926 // EBX: next object start. |
925 // EDX: number of context variables. | 927 // EDX: number of context variables. |
926 __ movl(Address::Absolute(heap->TopAddress()), EBX); | 928 __ movl(Address::Absolute(heap->TopAddress(space)), EBX); |
927 __ addl(EAX, Immediate(kHeapObjectTag)); | 929 __ addl(EAX, Immediate(kHeapObjectTag)); |
928 // EBX: Size of allocation in bytes. | 930 // EBX: Size of allocation in bytes. |
929 __ subl(EBX, EAX); | 931 __ subl(EBX, EAX); |
930 __ UpdateAllocationStatsWithSize(context_class.id(), EBX, kNoRegister); | 932 __ UpdateAllocationStatsWithSize(cid, EBX, kNoRegister, space); |
931 | 933 |
932 // Calculate the size tag. | 934 // Calculate the size tag. |
933 // EAX: new object. | 935 // EAX: new object. |
934 // EDX: number of context variables. | 936 // EDX: number of context variables. |
935 { | 937 { |
936 Label size_tag_overflow, done; | 938 Label size_tag_overflow, done; |
937 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); | 939 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); |
938 __ andl(EBX, Immediate(-kObjectAlignment)); | 940 __ andl(EBX, Immediate(-kObjectAlignment)); |
939 __ cmpl(EBX, Immediate(RawObject::SizeTag::kMaxSizeTag)); | 941 __ cmpl(EBX, Immediate(RawObject::SizeTag::kMaxSizeTag)); |
940 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | 942 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); |
941 __ shll(EBX, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2)); | 943 __ shll(EBX, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2)); |
942 __ jmp(&done); | 944 __ jmp(&done); |
943 | 945 |
944 __ Bind(&size_tag_overflow); | 946 __ Bind(&size_tag_overflow); |
945 // Set overflow size tag value. | 947 // Set overflow size tag value. |
946 __ movl(EBX, Immediate(0)); | 948 __ movl(EBX, Immediate(0)); |
947 | 949 |
948 __ Bind(&done); | 950 __ Bind(&done); |
949 // EAX: new object. | 951 // EAX: new object. |
950 // EDX: number of context variables. | 952 // EDX: number of context variables. |
951 // EBX: size and bit tags. | 953 // EBX: size and bit tags. |
952 __ orl(EBX, | 954 __ orl(EBX, |
953 Immediate(RawObject::ClassIdTag::encode(context_class.id()))); | 955 Immediate(RawObject::ClassIdTag::encode(cid))); |
954 __ movl(FieldAddress(EAX, Context::tags_offset()), EBX); // Tags. | 956 __ movl(FieldAddress(EAX, Context::tags_offset()), EBX); // Tags. |
955 } | 957 } |
956 | 958 |
957 // Setup up number of context variables field. | 959 // Setup up number of context variables field. |
958 // EAX: new object. | 960 // EAX: new object. |
959 // EDX: number of context variables as integer value (not object). | 961 // EDX: number of context variables as integer value (not object). |
960 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX); | 962 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX); |
961 | 963 |
962 // Setup isolate field. | 964 // Setup isolate field. |
963 // Load Isolate pointer from Context structure into EBX. | 965 // Load Isolate pointer from Context structure into EBX. |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1109 if (is_cls_parameterized) { | 1111 if (is_cls_parameterized) { |
1110 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset)); | 1112 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset)); |
1111 // EDX: instantiated type arguments. | 1113 // EDX: instantiated type arguments. |
1112 } | 1114 } |
1113 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { | 1115 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { |
1114 Label slow_case; | 1116 Label slow_case; |
1115 // Allocate the object and update top to point to | 1117 // Allocate the object and update top to point to |
1116 // next object start and initialize the allocated object. | 1118 // next object start and initialize the allocated object. |
1117 // EDX: instantiated type arguments (if is_cls_parameterized). | 1119 // EDX: instantiated type arguments (if is_cls_parameterized). |
1118 Heap* heap = Isolate::Current()->heap(); | 1120 Heap* heap = Isolate::Current()->heap(); |
1119 __ movl(EAX, Address::Absolute(heap->TopAddress())); | 1121 Heap::Space space = heap->SpaceForAllocation(cls.id()); |
| 1122 __ movl(EAX, Address::Absolute(heap->TopAddress(space))); |
1120 __ leal(EBX, Address(EAX, instance_size)); | 1123 __ leal(EBX, Address(EAX, instance_size)); |
1121 // Check if the allocation fits into the remaining space. | 1124 // Check if the allocation fits into the remaining space. |
1122 // EAX: potential new object start. | 1125 // EAX: potential new object start. |
1123 // EBX: potential next object start. | 1126 // EBX: potential next object start. |
1124 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); | 1127 __ cmpl(EBX, Address::Absolute(heap->EndAddress(space))); |
1125 if (FLAG_use_slow_path) { | 1128 if (FLAG_use_slow_path) { |
1126 __ jmp(&slow_case); | 1129 __ jmp(&slow_case); |
1127 } else { | 1130 } else { |
1128 __ j(ABOVE_EQUAL, &slow_case); | 1131 __ j(ABOVE_EQUAL, &slow_case); |
1129 } | 1132 } |
1130 __ movl(Address::Absolute(heap->TopAddress()), EBX); | 1133 __ movl(Address::Absolute(heap->TopAddress(space)), EBX); |
1131 __ UpdateAllocationStats(cls.id(), ECX); | 1134 __ UpdateAllocationStats(cls.id(), ECX, space); |
1132 | 1135 |
1133 // EAX: new object start. | 1136 // EAX: new object start. |
1134 // EBX: next object start. | 1137 // EBX: next object start. |
1135 // EDX: new object type arguments (if is_cls_parameterized). | 1138 // EDX: new object type arguments (if is_cls_parameterized). |
1136 // Set the tags. | 1139 // Set the tags. |
1137 uword tags = 0; | 1140 uword tags = 0; |
1138 tags = RawObject::SizeTag::update(instance_size, tags); | 1141 tags = RawObject::SizeTag::update(instance_size, tags); |
1139 ASSERT(cls.id() != kIllegalCid); | 1142 ASSERT(cls.id() != kIllegalCid); |
1140 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 1143 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
1141 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags)); | 1144 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags)); |
(...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2048 const Register temp = ECX; | 2051 const Register temp = ECX; |
2049 __ movl(left, Address(ESP, 2 * kWordSize)); | 2052 __ movl(left, Address(ESP, 2 * kWordSize)); |
2050 __ movl(right, Address(ESP, 1 * kWordSize)); | 2053 __ movl(right, Address(ESP, 1 * kWordSize)); |
2051 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2054 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
2052 __ ret(); | 2055 __ ret(); |
2053 } | 2056 } |
2054 | 2057 |
2055 } // namespace dart | 2058 } // namespace dart |
2056 | 2059 |
2057 #endif // defined TARGET_ARCH_IA32 | 2060 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |