| 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 Heap::Space space = heap->SpaceForAllocation(kArrayCid); |
| 649 __ movl(EAX, Address::Absolute(heap->TopAddress())); | 649 __ movl(EAX, Address::Absolute(heap->TopAddress(space))); |
| 650 __ movl(EBX, EAX); | 650 __ movl(EBX, EAX); |
| 651 | 651 |
| 652 // EDI: allocation size. | 652 // EDI: allocation size. |
| 653 __ addl(EBX, EDI); | 653 __ addl(EBX, EDI); |
| 654 __ j(CARRY, &slow_case); | 654 __ j(CARRY, &slow_case); |
| 655 | 655 |
| 656 // Check if the allocation fits into the remaining space. | 656 // Check if the allocation fits into the remaining space. |
| 657 // EAX: potential new object start. | 657 // EAX: potential new object start. |
| 658 // EBX: potential next object start. | 658 // EBX: potential next object start. |
| 659 // EDI: allocation size. | 659 // EDI: allocation size. |
| 660 // ECX: array element type. | 660 // ECX: array element type. |
| 661 // EDX: array length as Smi). | 661 // EDX: array length as Smi). |
| 662 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); | 662 __ cmpl(EBX, Address::Absolute(heap->EndAddress(space))); |
| 663 __ j(ABOVE_EQUAL, &slow_case); | 663 __ j(ABOVE_EQUAL, &slow_case); |
| 664 | 664 |
| 665 // Successfully allocated the object(s), now update top to point to | 665 // Successfully allocated the object(s), now update top to point to |
| 666 // next object start and initialize the object. | 666 // next object start and initialize the object. |
| 667 __ movl(Address::Absolute(heap->TopAddress()), EBX); | 667 __ movl(Address::Absolute(heap->TopAddress(space)), EBX); |
| 668 __ addl(EAX, Immediate(kHeapObjectTag)); | 668 __ addl(EAX, Immediate(kHeapObjectTag)); |
| 669 __ UpdateAllocationStatsWithSize(kArrayCid, EDI, kNoRegister); | 669 __ UpdateAllocationStatsWithSize(kArrayCid, EDI, kNoRegister, space); |
| 670 | 670 |
| 671 // Initialize the tags. | 671 // Initialize the tags. |
| 672 // EAX: new object start as a tagged pointer. | 672 // EAX: new object start as a tagged pointer. |
| 673 // EBX: new object end address. | 673 // EBX: new object end address. |
| 674 // EDI: allocation size. | 674 // EDI: allocation size. |
| 675 // ECX: array element type. | 675 // ECX: array element type. |
| 676 // EDX: array length as Smi. | 676 // EDX: array length as Smi. |
| 677 { | 677 { |
| 678 Label size_tag_overflow, done; | 678 Label size_tag_overflow, done; |
| 679 __ cmpl(EDI, Immediate(RawObject::SizeTag::kMaxSizeTag)); | 679 __ cmpl(EDI, Immediate(RawObject::SizeTag::kMaxSizeTag)); |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 Label slow_case; | 903 Label slow_case; |
| 904 Heap* heap = Isolate::Current()->heap(); | 904 Heap* heap = Isolate::Current()->heap(); |
| 905 // First compute the rounded instance size. | 905 // First compute the rounded instance size. |
| 906 // EDX: number of context variables. | 906 // EDX: number of context variables. |
| 907 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1); | 907 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1); |
| 908 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); | 908 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); |
| 909 __ andl(EBX, Immediate(-kObjectAlignment)); | 909 __ andl(EBX, Immediate(-kObjectAlignment)); |
| 910 | 910 |
| 911 // Now allocate the object. | 911 // Now allocate the object. |
| 912 // EDX: number of context variables. | 912 // EDX: number of context variables. |
| 913 __ movl(EAX, Address::Absolute(heap->TopAddress())); | 913 intptr_t cid = context_class.id(); |
| 914 Heap::Space space = heap->SpaceForAllocation(cid); |
| 915 __ movl(EAX, Address::Absolute(heap->TopAddress(space))); |
| 914 __ addl(EBX, EAX); | 916 __ addl(EBX, EAX); |
| 915 // Check if the allocation fits into the remaining space. | 917 // Check if the allocation fits into the remaining space. |
| 916 // EAX: potential new object. | 918 // EAX: potential new object. |
| 917 // EBX: potential next object start. | 919 // EBX: potential next object start. |
| 918 // EDX: number of context variables. | 920 // EDX: number of context variables. |
| 919 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); | 921 __ cmpl(EBX, Address::Absolute(heap->EndAddress(space))); |
| 920 if (FLAG_use_slow_path) { | 922 if (FLAG_use_slow_path) { |
| 921 __ jmp(&slow_case); | 923 __ jmp(&slow_case); |
| 922 } else { | 924 } else { |
| 923 __ j(ABOVE_EQUAL, &slow_case, Assembler::kNearJump); | 925 __ j(ABOVE_EQUAL, &slow_case, Assembler::kNearJump); |
| 924 } | 926 } |
| 925 | 927 |
| 926 // Successfully allocated the object, now update top to point to | 928 // Successfully allocated the object, now update top to point to |
| 927 // next object start and initialize the object. | 929 // next object start and initialize the object. |
| 928 // EAX: new object. | 930 // EAX: new object. |
| 929 // EBX: next object start. | 931 // EBX: next object start. |
| 930 // EDX: number of context variables. | 932 // EDX: number of context variables. |
| 931 __ movl(Address::Absolute(heap->TopAddress()), EBX); | 933 __ movl(Address::Absolute(heap->TopAddress(space)), EBX); |
| 932 __ addl(EAX, Immediate(kHeapObjectTag)); | 934 __ addl(EAX, Immediate(kHeapObjectTag)); |
| 933 // EBX: Size of allocation in bytes. | 935 // EBX: Size of allocation in bytes. |
| 934 __ subl(EBX, EAX); | 936 __ subl(EBX, EAX); |
| 935 __ UpdateAllocationStatsWithSize(context_class.id(), EBX, kNoRegister); | 937 __ UpdateAllocationStatsWithSize(cid, EBX, kNoRegister, space); |
| 936 | 938 |
| 937 // Calculate the size tag. | 939 // Calculate the size tag. |
| 938 // EAX: new object. | 940 // EAX: new object. |
| 939 // EDX: number of context variables. | 941 // EDX: number of context variables. |
| 940 { | 942 { |
| 941 Label size_tag_overflow, done; | 943 Label size_tag_overflow, done; |
| 942 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); | 944 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); |
| 943 __ andl(EBX, Immediate(-kObjectAlignment)); | 945 __ andl(EBX, Immediate(-kObjectAlignment)); |
| 944 __ cmpl(EBX, Immediate(RawObject::SizeTag::kMaxSizeTag)); | 946 __ cmpl(EBX, Immediate(RawObject::SizeTag::kMaxSizeTag)); |
| 945 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | 947 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); |
| 946 __ shll(EBX, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2)); | 948 __ shll(EBX, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2)); |
| 947 __ jmp(&done); | 949 __ jmp(&done); |
| 948 | 950 |
| 949 __ Bind(&size_tag_overflow); | 951 __ Bind(&size_tag_overflow); |
| 950 // Set overflow size tag value. | 952 // Set overflow size tag value. |
| 951 __ movl(EBX, Immediate(0)); | 953 __ movl(EBX, Immediate(0)); |
| 952 | 954 |
| 953 __ Bind(&done); | 955 __ Bind(&done); |
| 954 // EAX: new object. | 956 // EAX: new object. |
| 955 // EDX: number of context variables. | 957 // EDX: number of context variables. |
| 956 // EBX: size and bit tags. | 958 // EBX: size and bit tags. |
| 957 __ orl(EBX, | 959 __ orl(EBX, |
| 958 Immediate(RawObject::ClassIdTag::encode(context_class.id()))); | 960 Immediate(RawObject::ClassIdTag::encode(cid))); |
| 959 __ movl(FieldAddress(EAX, Context::tags_offset()), EBX); // Tags. | 961 __ movl(FieldAddress(EAX, Context::tags_offset()), EBX); // Tags. |
| 960 } | 962 } |
| 961 | 963 |
| 962 // Setup up number of context variables field. | 964 // Setup up number of context variables field. |
| 963 // EAX: new object. | 965 // EAX: new object. |
| 964 // EDX: number of context variables as integer value (not object). | 966 // EDX: number of context variables as integer value (not object). |
| 965 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX); | 967 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX); |
| 966 | 968 |
| 967 // Setup isolate field. | 969 // Setup isolate field. |
| 968 // Load Isolate pointer from Context structure into EBX. | 970 // Load Isolate pointer from Context structure into EBX. |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1113 if (is_cls_parameterized) { | 1115 if (is_cls_parameterized) { |
| 1114 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset)); | 1116 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset)); |
| 1115 // EDX: instantiated type arguments. | 1117 // EDX: instantiated type arguments. |
| 1116 } | 1118 } |
| 1117 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { | 1119 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { |
| 1118 Label slow_case; | 1120 Label slow_case; |
| 1119 // Allocate the object and update top to point to | 1121 // Allocate the object and update top to point to |
| 1120 // next object start and initialize the allocated object. | 1122 // next object start and initialize the allocated object. |
| 1121 // EDX: instantiated type arguments (if is_cls_parameterized). | 1123 // EDX: instantiated type arguments (if is_cls_parameterized). |
| 1122 Heap* heap = Isolate::Current()->heap(); | 1124 Heap* heap = Isolate::Current()->heap(); |
| 1123 __ movl(EAX, Address::Absolute(heap->TopAddress())); | 1125 Heap::Space space = heap->SpaceForAllocation(cls.id()); |
| 1126 __ movl(EAX, Address::Absolute(heap->TopAddress(space))); |
| 1124 __ leal(EBX, Address(EAX, instance_size)); | 1127 __ leal(EBX, Address(EAX, instance_size)); |
| 1125 // Check if the allocation fits into the remaining space. | 1128 // Check if the allocation fits into the remaining space. |
| 1126 // EAX: potential new object start. | 1129 // EAX: potential new object start. |
| 1127 // EBX: potential next object start. | 1130 // EBX: potential next object start. |
| 1128 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); | 1131 __ cmpl(EBX, Address::Absolute(heap->EndAddress(space))); |
| 1129 if (FLAG_use_slow_path) { | 1132 if (FLAG_use_slow_path) { |
| 1130 __ jmp(&slow_case); | 1133 __ jmp(&slow_case); |
| 1131 } else { | 1134 } else { |
| 1132 __ j(ABOVE_EQUAL, &slow_case); | 1135 __ j(ABOVE_EQUAL, &slow_case); |
| 1133 } | 1136 } |
| 1134 __ movl(Address::Absolute(heap->TopAddress()), EBX); | 1137 __ movl(Address::Absolute(heap->TopAddress(space)), EBX); |
| 1135 __ UpdateAllocationStats(cls.id(), ECX); | 1138 __ UpdateAllocationStats(cls.id(), ECX, space); |
| 1136 | 1139 |
| 1137 // EAX: new object start. | 1140 // EAX: new object start. |
| 1138 // EBX: next object start. | 1141 // EBX: next object start. |
| 1139 // EDX: new object type arguments (if is_cls_parameterized). | 1142 // EDX: new object type arguments (if is_cls_parameterized). |
| 1140 // Set the tags. | 1143 // Set the tags. |
| 1141 uword tags = 0; | 1144 uword tags = 0; |
| 1142 tags = RawObject::SizeTag::update(instance_size, tags); | 1145 tags = RawObject::SizeTag::update(instance_size, tags); |
| 1143 ASSERT(cls.id() != kIllegalCid); | 1146 ASSERT(cls.id() != kIllegalCid); |
| 1144 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 1147 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
| 1145 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags)); | 1148 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags)); |
| (...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2052 const Register temp = ECX; | 2055 const Register temp = ECX; |
| 2053 __ movl(left, Address(ESP, 2 * kWordSize)); | 2056 __ movl(left, Address(ESP, 2 * kWordSize)); |
| 2054 __ movl(right, Address(ESP, 1 * kWordSize)); | 2057 __ movl(right, Address(ESP, 1 * kWordSize)); |
| 2055 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2058 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 2056 __ ret(); | 2059 __ ret(); |
| 2057 } | 2060 } |
| 2058 | 2061 |
| 2059 } // namespace dart | 2062 } // namespace dart |
| 2060 | 2063 |
| 2061 #endif // defined TARGET_ARCH_IA32 | 2064 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |