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 1084 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1095 __ movl(Address(ESP, 0), EAX); // Push the isolate as the only argument. | 1095 __ movl(Address(ESP, 0), EAX); // Push the isolate as the only argument. |
1096 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); | 1096 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); |
1097 // Restore callee-saved registers, tear down frame. | 1097 // Restore callee-saved registers, tear down frame. |
1098 __ LeaveCallRuntimeFrame(); | 1098 __ LeaveCallRuntimeFrame(); |
1099 __ ret(); | 1099 __ ret(); |
1100 } | 1100 } |
1101 | 1101 |
1102 | 1102 |
1103 // Called for inline allocation of objects. | 1103 // Called for inline allocation of objects. |
1104 // Input parameters: | 1104 // Input parameters: |
1105 // ESP + 8 : type arguments object (only if class is parameterized). | 1105 // ESP + 4 : type arguments object (only if class is parameterized). |
1106 // ESP + 4 : type arguments of instantiator (only if class is parameterized). | |
1107 // ESP : points to return address. | 1106 // ESP : points to return address. |
1108 // Uses EAX, EBX, ECX, EDX, EDI as temporary registers. | 1107 // Uses EAX, EBX, ECX, EDX, EDI as temporary registers. |
1109 void StubCode::GenerateAllocationStubForClass(Assembler* assembler, | 1108 void StubCode::GenerateAllocationStubForClass(Assembler* assembler, |
1110 const Class& cls) { | 1109 const Class& cls) { |
1111 const intptr_t kObjectTypeArgumentsOffset = 2 * kWordSize; | 1110 const intptr_t kObjectTypeArgumentsOffset = 1 * kWordSize; |
1112 const intptr_t kInstantiatorTypeArgumentsOffset = 1 * kWordSize; | |
1113 const Immediate& raw_null = | 1111 const Immediate& raw_null = |
1114 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1112 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1115 // The generated code is different if the class is parameterized. | 1113 // The generated code is different if the class is parameterized. |
1116 const bool is_cls_parameterized = cls.NumTypeArguments() > 0; | 1114 const bool is_cls_parameterized = cls.NumTypeArguments() > 0; |
1117 ASSERT(!is_cls_parameterized || | 1115 ASSERT(!is_cls_parameterized || |
1118 (cls.type_arguments_field_offset() != Class::kNoTypeArguments)); | 1116 (cls.type_arguments_field_offset() != Class::kNoTypeArguments)); |
1119 // kInlineInstanceSize is a constant used as a threshold for determining | 1117 // kInlineInstanceSize is a constant used as a threshold for determining |
1120 // 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 |
1121 // straight line code. | 1119 // straight line code. |
1122 const int kInlineInstanceSize = 12; // In words. | 1120 const int kInlineInstanceSize = 12; // In words. |
1123 const intptr_t instance_size = cls.instance_size(); | 1121 const intptr_t instance_size = cls.instance_size(); |
1124 ASSERT(instance_size > 0); | 1122 ASSERT(instance_size > 0); |
1125 Label slow_case_with_type_arguments; | 1123 Label slow_case_with_type_arguments; |
1126 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { | 1124 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { |
1127 Label slow_case_reload_type_arguments; | 1125 Label slow_case_reload_type_arguments; |
1128 if (is_cls_parameterized) { | 1126 if (is_cls_parameterized) { |
1129 // Instantiation of the type arguments vector is only required if an | |
1130 // instantiator is provided (not kNoInstantiator, but may be null). | |
1131 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset)); | 1127 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset)); |
1132 __ movl(EDI, Address(ESP, kInstantiatorTypeArgumentsOffset)); | |
1133 Label type_arguments_ready; | |
1134 __ cmpl(EDI, Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | |
1135 __ j(EQUAL, &type_arguments_ready, Assembler::kNearJump); | |
1136 // Lookup instantiator EDI in instantiations array of type arguments EDX | |
1137 // and, if found, use cached instantiated type arguments. | |
1138 __ movl(EAX, FieldAddress(EDX, TypeArguments::instantiations_offset())); | |
1139 __ movl(EBX, FieldAddress(EAX, Array::length_offset())); | |
1140 __ leal(EAX, FieldAddress(EAX, Array::data_offset())); | |
1141 __ leal(EBX, Address(EAX, EBX, TIMES_2, 0)); // EBX is smi. | |
1142 Label loop, found; | |
1143 __ Bind(&loop); | |
1144 __ cmpl(EAX, EBX); | |
1145 __ j(ABOVE_EQUAL, &slow_case_reload_type_arguments); | |
1146 __ movl(EDX, Address(EAX, 0 * kWordSize)); // Cached instantiator. | |
1147 __ cmpl(EDX, EDI); | |
1148 __ j(EQUAL, &found, Assembler::kNearJump); | |
1149 __ cmpl(EDX, Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | |
1150 __ j(EQUAL, &slow_case_reload_type_arguments); | |
1151 __ addl(EAX, Immediate(2 * kWordSize)); | |
1152 __ jmp(&loop, Assembler::kNearJump); | |
1153 __ Bind(&found); | |
1154 __ movl(EDX, Address(EAX, 1 * kWordSize)); // Cached instantiated args. | |
1155 __ movl(EDI, Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | |
1156 __ Bind(&type_arguments_ready); | |
1157 // EDX: instantiated type arguments. | 1128 // EDX: instantiated type arguments. |
1158 // EDI: kNoInstantiator. | |
1159 } | 1129 } |
1160 // Allocate the object and update top to point to | 1130 // Allocate the object and update top to point to |
1161 // next object start and initialize the allocated object. | 1131 // next object start and initialize the allocated object. |
1162 // EDX: instantiated type arguments (if is_cls_parameterized). | 1132 // EDX: instantiated type arguments (if is_cls_parameterized). |
1163 // EDI: kNoInstantiator (if is_cls_parameterized). | |
1164 Heap* heap = Isolate::Current()->heap(); | 1133 Heap* heap = Isolate::Current()->heap(); |
1165 __ movl(EAX, Address::Absolute(heap->TopAddress())); | 1134 __ movl(EAX, Address::Absolute(heap->TopAddress())); |
1166 __ leal(EBX, Address(EAX, instance_size)); | 1135 __ leal(EBX, Address(EAX, instance_size)); |
1167 // Check if the allocation fits into the remaining space. | 1136 // Check if the allocation fits into the remaining space. |
1168 // EAX: potential new object start. | 1137 // EAX: potential new object start. |
1169 // EBX: potential next object start. | 1138 // EBX: potential next object start. |
1170 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); | 1139 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); |
1171 if (FLAG_use_slow_path) { | 1140 if (FLAG_use_slow_path) { |
1172 __ jmp(&slow_case_with_type_arguments); | 1141 __ jmp(&slow_case_with_type_arguments); |
1173 } else { | 1142 } else { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1226 } | 1195 } |
1227 // Done allocating and initializing the instance. | 1196 // Done allocating and initializing the instance. |
1228 // EAX: new object. | 1197 // EAX: new object. |
1229 __ addl(EAX, Immediate(kHeapObjectTag)); | 1198 __ addl(EAX, Immediate(kHeapObjectTag)); |
1230 __ ret(); | 1199 __ ret(); |
1231 | 1200 |
1232 __ Bind(&slow_case_reload_type_arguments); | 1201 __ Bind(&slow_case_reload_type_arguments); |
1233 } | 1202 } |
1234 if (is_cls_parameterized) { | 1203 if (is_cls_parameterized) { |
1235 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset)); | 1204 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset)); |
1236 __ movl(EDI, Address(ESP, kInstantiatorTypeArgumentsOffset)); | |
1237 } | 1205 } |
1238 __ Bind(&slow_case_with_type_arguments); | 1206 __ Bind(&slow_case_with_type_arguments); |
1239 // If is_cls_parameterized: | 1207 // If is_cls_parameterized: |
1240 // EDX: new object type arguments (instantiated or not). | 1208 // EDX: new object type arguments. |
1241 // EDI: instantiator type arguments or kNoInstantiator. | |
1242 // Create a stub frame as we are pushing some objects on the stack before | 1209 // Create a stub frame as we are pushing some objects on the stack before |
1243 // calling into the runtime. | 1210 // calling into the runtime. |
1244 __ EnterStubFrame(); | 1211 __ EnterStubFrame(); |
1245 __ pushl(raw_null); // Setup space on stack for return value. | 1212 __ pushl(raw_null); // Setup space on stack for return value. |
1246 __ PushObject(cls); // Push class of object to be allocated. | 1213 __ PushObject(cls); // Push class of object to be allocated. |
1247 if (is_cls_parameterized) { | 1214 if (is_cls_parameterized) { |
1248 __ pushl(EDX); // Push type arguments of object to be allocated. | 1215 __ pushl(EDX); // Push type arguments of object to be allocated. |
1249 __ pushl(EDI); // Push type arguments of instantiator. | |
1250 } else { | 1216 } else { |
1251 __ pushl(raw_null); // Push null type arguments. | 1217 __ pushl(raw_null); // Push null type arguments. |
1252 __ pushl(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | |
1253 } | 1218 } |
1254 __ CallRuntime(kAllocateObjectRuntimeEntry, 3); // Allocate object. | 1219 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object. |
1255 __ popl(EAX); // Pop argument (instantiator). | |
1256 __ popl(EAX); // Pop argument (type arguments of object). | 1220 __ popl(EAX); // Pop argument (type arguments of object). |
1257 __ popl(EAX); // Pop argument (class of object). | 1221 __ popl(EAX); // Pop argument (class of object). |
1258 __ popl(EAX); // Pop result (newly allocated object). | 1222 __ popl(EAX); // Pop result (newly allocated object). |
1259 // EAX: new object | 1223 // EAX: new object |
1260 // Restore the frame pointer. | 1224 // Restore the frame pointer. |
1261 __ LeaveFrame(); | 1225 __ LeaveFrame(); |
1262 __ ret(); | 1226 __ ret(); |
1263 } | 1227 } |
1264 | 1228 |
1265 | 1229 |
(...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2157 const Register temp = ECX; | 2121 const Register temp = ECX; |
2158 __ movl(left, Address(ESP, 2 * kWordSize)); | 2122 __ movl(left, Address(ESP, 2 * kWordSize)); |
2159 __ movl(right, Address(ESP, 1 * kWordSize)); | 2123 __ movl(right, Address(ESP, 1 * kWordSize)); |
2160 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2124 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
2161 __ ret(); | 2125 __ ret(); |
2162 } | 2126 } |
2163 | 2127 |
2164 } // namespace dart | 2128 } // namespace dart |
2165 | 2129 |
2166 #endif // defined TARGET_ARCH_IA32 | 2130 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |