| 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 |