| 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 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1113 // The generated code is different if the class is parameterized. | 1113 // The generated code is different if the class is parameterized. |
| 1114 const bool is_cls_parameterized = cls.NumTypeArguments() > 0; | 1114 const bool is_cls_parameterized = cls.NumTypeArguments() > 0; |
| 1115 ASSERT(!is_cls_parameterized || | 1115 ASSERT(!is_cls_parameterized || |
| 1116 (cls.type_arguments_field_offset() != Class::kNoTypeArguments)); | 1116 (cls.type_arguments_field_offset() != Class::kNoTypeArguments)); |
| 1117 // kInlineInstanceSize is a constant used as a threshold for determining | 1117 // kInlineInstanceSize is a constant used as a threshold for determining |
| 1118 // when the object initialization should be done as a loop or as | 1118 // when the object initialization should be done as a loop or as |
| 1119 // straight line code. | 1119 // straight line code. |
| 1120 const int kInlineInstanceSize = 12; // In words. | 1120 const int kInlineInstanceSize = 12; // In words. |
| 1121 const intptr_t instance_size = cls.instance_size(); | 1121 const intptr_t instance_size = cls.instance_size(); |
| 1122 ASSERT(instance_size > 0); | 1122 ASSERT(instance_size > 0); |
| 1123 Label slow_case_with_type_arguments; | 1123 if (is_cls_parameterized) { |
| 1124 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset)); |
| 1125 // EDX: instantiated type arguments. |
| 1126 } |
| 1124 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { | 1127 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { |
| 1125 Label slow_case_reload_type_arguments; | 1128 Label slow_case; |
| 1126 if (is_cls_parameterized) { | |
| 1127 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset)); | |
| 1128 // EDX: instantiated type arguments. | |
| 1129 } | |
| 1130 // Allocate the object and update top to point to | 1129 // Allocate the object and update top to point to |
| 1131 // next object start and initialize the allocated object. | 1130 // next object start and initialize the allocated object. |
| 1132 // EDX: instantiated type arguments (if is_cls_parameterized). | 1131 // EDX: instantiated type arguments (if is_cls_parameterized). |
| 1133 Heap* heap = Isolate::Current()->heap(); | 1132 Heap* heap = Isolate::Current()->heap(); |
| 1134 __ movl(EAX, Address::Absolute(heap->TopAddress())); | 1133 __ movl(EAX, Address::Absolute(heap->TopAddress())); |
| 1135 __ leal(EBX, Address(EAX, instance_size)); | 1134 __ leal(EBX, Address(EAX, instance_size)); |
| 1136 // Check if the allocation fits into the remaining space. | 1135 // Check if the allocation fits into the remaining space. |
| 1137 // EAX: potential new object start. | 1136 // EAX: potential new object start. |
| 1138 // EBX: potential next object start. | 1137 // EBX: potential next object start. |
| 1139 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); | 1138 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); |
| 1140 if (FLAG_use_slow_path) { | 1139 if (FLAG_use_slow_path) { |
| 1141 __ jmp(&slow_case_with_type_arguments); | 1140 __ jmp(&slow_case); |
| 1142 } else { | 1141 } else { |
| 1143 __ j(ABOVE_EQUAL, &slow_case_with_type_arguments); | 1142 __ j(ABOVE_EQUAL, &slow_case); |
| 1144 } | 1143 } |
| 1145 __ movl(Address::Absolute(heap->TopAddress()), EBX); | 1144 __ movl(Address::Absolute(heap->TopAddress()), EBX); |
| 1146 __ UpdateAllocationStats(cls.id(), ECX); | 1145 __ UpdateAllocationStats(cls.id(), ECX); |
| 1147 | 1146 |
| 1148 // EAX: new object start. | 1147 // EAX: new object start. |
| 1149 // EBX: next object start. | 1148 // EBX: next object start. |
| 1150 // EDX: new object type arguments (if is_cls_parameterized). | 1149 // EDX: new object type arguments (if is_cls_parameterized). |
| 1151 // Set the tags. | 1150 // Set the tags. |
| 1152 uword tags = 0; | 1151 uword tags = 0; |
| 1153 tags = RawObject::SizeTag::update(instance_size, tags); | 1152 tags = RawObject::SizeTag::update(instance_size, tags); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1191 if (is_cls_parameterized) { | 1190 if (is_cls_parameterized) { |
| 1192 // EDX: new object type arguments. | 1191 // EDX: new object type arguments. |
| 1193 // Set the type arguments in the new object. | 1192 // Set the type arguments in the new object. |
| 1194 __ movl(Address(EAX, cls.type_arguments_field_offset()), EDX); | 1193 __ movl(Address(EAX, cls.type_arguments_field_offset()), EDX); |
| 1195 } | 1194 } |
| 1196 // Done allocating and initializing the instance. | 1195 // Done allocating and initializing the instance. |
| 1197 // EAX: new object. | 1196 // EAX: new object. |
| 1198 __ addl(EAX, Immediate(kHeapObjectTag)); | 1197 __ addl(EAX, Immediate(kHeapObjectTag)); |
| 1199 __ ret(); | 1198 __ ret(); |
| 1200 | 1199 |
| 1201 __ Bind(&slow_case_reload_type_arguments); | 1200 __ Bind(&slow_case); |
| 1202 } | 1201 } |
| 1203 if (is_cls_parameterized) { | |
| 1204 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset)); | |
| 1205 } | |
| 1206 __ Bind(&slow_case_with_type_arguments); | |
| 1207 // If is_cls_parameterized: | 1202 // If is_cls_parameterized: |
| 1208 // EDX: new object type arguments. | 1203 // EDX: new object type arguments. |
| 1209 // Create a stub frame as we are pushing some objects on the stack before | 1204 // Create a stub frame as we are pushing some objects on the stack before |
| 1210 // calling into the runtime. | 1205 // calling into the runtime. |
| 1211 __ EnterStubFrame(); | 1206 __ EnterStubFrame(); |
| 1212 __ pushl(raw_null); // Setup space on stack for return value. | 1207 __ pushl(raw_null); // Setup space on stack for return value. |
| 1213 __ PushObject(cls); // Push class of object to be allocated. | 1208 __ PushObject(cls); // Push class of object to be allocated. |
| 1214 if (is_cls_parameterized) { | 1209 if (is_cls_parameterized) { |
| 1215 __ pushl(EDX); // Push type arguments of object to be allocated. | 1210 __ pushl(EDX); // Push type arguments of object to be allocated. |
| 1216 } else { | 1211 } else { |
| (...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2121 const Register temp = ECX; | 2116 const Register temp = ECX; |
| 2122 __ movl(left, Address(ESP, 2 * kWordSize)); | 2117 __ movl(left, Address(ESP, 2 * kWordSize)); |
| 2123 __ movl(right, Address(ESP, 1 * kWordSize)); | 2118 __ movl(right, Address(ESP, 1 * kWordSize)); |
| 2124 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2119 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 2125 __ ret(); | 2120 __ ret(); |
| 2126 } | 2121 } |
| 2127 | 2122 |
| 2128 } // namespace dart | 2123 } // namespace dart |
| 2129 | 2124 |
| 2130 #endif // defined TARGET_ARCH_IA32 | 2125 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |