OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/code_generator.h" | 8 #include "vm/code_generator.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/object_store.h" | 10 #include "vm/object_store.h" |
(...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1233 __ popl(EAX); // Pop argument (type arguments of object). | 1233 __ popl(EAX); // Pop argument (type arguments of object). |
1234 __ popl(EAX); // Pop argument (class of object). | 1234 __ popl(EAX); // Pop argument (class of object). |
1235 __ popl(EAX); // Pop result (newly allocated object). | 1235 __ popl(EAX); // Pop result (newly allocated object). |
1236 // EAX: new object | 1236 // EAX: new object |
1237 // Restore the frame pointer. | 1237 // Restore the frame pointer. |
1238 __ LeaveFrame(); | 1238 __ LeaveFrame(); |
1239 __ ret(); | 1239 __ ret(); |
1240 } | 1240 } |
1241 | 1241 |
1242 | 1242 |
1243 static void ClosureAllocationStub(Assembler* assembler, | 1243 // Called for inline allocation of closures. |
1244 const Function& func, | 1244 // Input parameters: |
1245 bool is_static_implicit_closure) { | 1245 // ESP + 4 : receiver (only if non-static implicit closure). |
| 1246 // ESP : points to return address. |
| 1247 // Uses EAX, EBX, ECX, EDX as temporary registers. |
| 1248 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, |
| 1249 const Function& func) { |
| 1250 const intptr_t kReceiverOffset = 1 * kWordSize; |
1246 const Immediate raw_null = | 1251 const Immediate raw_null = |
1247 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1252 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1248 intptr_t instance_size = Closure::InstanceSize(); | 1253 ASSERT(func.IsClosureFunction()); |
1249 if (FLAG_inline_alloc && PageSpace::IsPageAllocatableSize(instance_size)) { | 1254 const bool is_implicit_static_closure = |
| 1255 func.IsImplicitStaticClosureFunction(); |
| 1256 const bool is_implicit_instance_closure = |
| 1257 func.IsImplicitInstanceClosureFunction(); |
| 1258 const intptr_t closure_size = Closure::InstanceSize(); |
| 1259 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. |
| 1260 if (FLAG_inline_alloc && |
| 1261 PageSpace::IsPageAllocatableSize(closure_size + context_size)) { |
1250 const Class& cls = Class::ZoneHandle(func.signature_class()); | 1262 const Class& cls = Class::ZoneHandle(func.signature_class()); |
1251 Label slow_case; | 1263 Label slow_case; |
1252 Heap* heap = Isolate::Current()->heap(); | 1264 Heap* heap = Isolate::Current()->heap(); |
1253 __ movl(EAX, Address::Absolute(heap->TopAddress())); | 1265 __ movl(EAX, Address::Absolute(heap->TopAddress())); |
1254 __ leal(EBX, Address(EAX, instance_size)); | 1266 __ leal(EBX, Address(EAX, closure_size)); |
| 1267 if (is_implicit_instance_closure) { |
| 1268 __ movl(ECX, EBX); // ECX: new context address. |
| 1269 __ addl(EBX, Immediate(context_size)); |
| 1270 } |
1255 // Check if the allocation fits into the remaining space. | 1271 // Check if the allocation fits into the remaining space. |
1256 // EAX: potential new object. | 1272 // EAX: potential new closure object. |
| 1273 // ECX: potential new context object (only if is_implicit_closure). |
1257 // EBX: potential next object start. | 1274 // EBX: potential next object start. |
1258 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); | 1275 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); |
1259 __ j(ABOVE_EQUAL, &slow_case, Assembler::kNearJump); | 1276 __ j(ABOVE_EQUAL, &slow_case, Assembler::kNearJump); |
1260 | 1277 |
1261 // Successfully allocated the object, now update top to point to | 1278 // Successfully allocated the object, now update top to point to |
1262 // next object start and initialize the object. | 1279 // next object start and initialize the object. |
1263 __ movl(Address::Absolute(heap->TopAddress()), EBX); | 1280 __ movl(Address::Absolute(heap->TopAddress()), EBX); |
1264 | 1281 |
1265 // Initialize the class field in the object. | 1282 // Initialize the class field in the object. |
1266 // EAX: new object. | 1283 // EAX: new closure object. |
1267 // EBX: next object start. | 1284 // ECX: new context object (only if is_implicit_closure). |
1268 __ LoadObject(ECX, cls); // Load signature class of closure. | 1285 __ LoadObject(EDX, cls); // Load signature class of closure. |
1269 __ movl(Address(EAX, Closure::class_offset()), ECX); | 1286 __ movl(Address(EAX, Closure::class_offset()), EDX); |
1270 | 1287 |
1271 // Initialize the function field in the object. | 1288 // Initialize the function field in the object. |
1272 // EAX: new object. | 1289 // EAX: new closure object. |
| 1290 // ECX: new context object (only if is_implicit_closure). |
1273 // EBX: next object start. | 1291 // EBX: next object start. |
1274 __ LoadObject(ECX, func); // Load function of closure to be allocated. | 1292 __ LoadObject(EDX, func); // Load function of closure to be allocated. |
1275 __ movl(Address(EAX, Closure::function_offset()), ECX); | 1293 __ movl(Address(EAX, Closure::function_offset()), EDX); |
1276 | 1294 |
1277 // Setup the context for this closure. | 1295 // Setup the context for this closure. |
1278 if (is_static_implicit_closure) { | 1296 if (is_implicit_static_closure) { |
1279 ObjectStore* object_store = Isolate::Current()->object_store(); | 1297 ObjectStore* object_store = Isolate::Current()->object_store(); |
1280 ASSERT(object_store != NULL); | 1298 ASSERT(object_store != NULL); |
1281 const Context& empty_context = | 1299 const Context& empty_context = |
1282 Context::ZoneHandle(object_store->empty_context()); | 1300 Context::ZoneHandle(object_store->empty_context()); |
1283 __ LoadObject(ECX, empty_context); | 1301 __ LoadObject(EDX, empty_context); |
| 1302 __ movl(Address(EAX, Closure::context_offset()), EDX); |
| 1303 } else if (is_implicit_instance_closure) { |
| 1304 // Initialize the new context capturing the receiver. |
| 1305 |
| 1306 // Set the class field to the Context class. |
| 1307 __ LoadObject(EBX, Class::ZoneHandle(Object::context_class())); |
| 1308 __ movl(Address(ECX, Context::class_offset()), EBX); |
| 1309 |
| 1310 // Set number of variables field to 1 (for captured receiver). |
| 1311 __ movl(Address(ECX, Context::num_variables_offset()), Immediate(1)); |
| 1312 |
| 1313 // Set isolate field to isolate of current context. |
| 1314 __ movl(EDX, FieldAddress(CTX, Context::isolate_offset())); |
| 1315 __ movl(Address(ECX, Context::isolate_offset()), EDX); |
| 1316 |
| 1317 // Set the parent field to null. |
| 1318 __ movl(Address(ECX, Context::parent_offset()), raw_null); |
| 1319 |
| 1320 // Initialize the context variable to the receiver. |
| 1321 __ movl(EDX, Address(ESP, kReceiverOffset)); |
| 1322 __ movl(Address(ECX, Context::variable_offset(0)), EDX); |
| 1323 |
| 1324 // Set the newly allocated context in the newly allocated closure. |
| 1325 __ addl(ECX, Immediate(kHeapObjectTag)); |
1284 __ movl(Address(EAX, Closure::context_offset()), ECX); | 1326 __ movl(Address(EAX, Closure::context_offset()), ECX); |
1285 } else { | 1327 } else { |
1286 __ movl(Address(EAX, Closure::context_offset()), CTX); | 1328 __ movl(Address(EAX, Closure::context_offset()), CTX); |
1287 } | 1329 } |
1288 __ movl(Address(EAX, Closure::smrck_offset()), raw_null); | 1330 __ movl(Address(EAX, Closure::smrck_offset()), raw_null); |
1289 | 1331 |
1290 // TODO(regis): Store the actual type arguments. | 1332 // TODO(regis): Store the actual type arguments. |
1291 __ movl(Address(EAX, Closure::type_arguments_offset()), raw_null); | 1333 __ movl(Address(EAX, Closure::type_arguments_offset()), raw_null); |
1292 | 1334 |
1293 // Done allocating and initializing the instance. | 1335 // Done allocating and initializing the instance. |
1294 // EAX: new object. | 1336 // EAX: new object. |
1295 __ addl(EAX, Immediate(kHeapObjectTag)); | 1337 __ addl(EAX, Immediate(kHeapObjectTag)); |
1296 __ ret(); | 1338 __ ret(); |
1297 | 1339 |
1298 __ Bind(&slow_case); | 1340 __ Bind(&slow_case); |
1299 } | 1341 } |
| 1342 if (is_implicit_instance_closure) { |
| 1343 __ movl(EAX, Address(ESP, kReceiverOffset)); |
| 1344 } |
1300 // Create a stub frame. | 1345 // Create a stub frame. |
1301 __ EnterFrame(0); | 1346 __ EnterFrame(0); |
1302 const Closure& new_closure = Closure::ZoneHandle(); | 1347 const Closure& new_closure = Closure::ZoneHandle(); |
1303 __ PushObject(new_closure); // Push Null closure for return value. | 1348 __ PushObject(new_closure); // Push Null closure for return value. |
1304 __ PushObject(func); | 1349 __ PushObject(func); |
1305 if (is_static_implicit_closure) { | 1350 if (is_implicit_static_closure) { |
1306 __ CallRuntimeFromStub(kAllocateStaticImplicitClosureRuntimeEntry); | 1351 __ CallRuntimeFromStub(kAllocateImplicitStaticClosureRuntimeEntry); |
| 1352 } else if (is_implicit_instance_closure) { |
| 1353 __ pushl(EAX); // Receiver. |
| 1354 __ CallRuntimeFromStub(kAllocateImplicitInstanceClosureRuntimeEntry); |
| 1355 __ popl(EAX); // Pop receiver. |
1307 } else { | 1356 } else { |
| 1357 ASSERT(func.IsNonImplicitClosureFunction()); |
1308 __ CallRuntimeFromStub(kAllocateClosureRuntimeEntry); | 1358 __ CallRuntimeFromStub(kAllocateClosureRuntimeEntry); |
1309 } | 1359 } |
1310 __ popl(EAX); // Pop function object. | 1360 __ popl(EAX); // Pop function object. |
1311 __ popl(EAX); | 1361 __ popl(EAX); |
1312 // EAX: new object | 1362 // EAX: new object |
1313 // Restore the frame pointer. | 1363 // Restore the frame pointer. |
1314 __ LeaveFrame(); | 1364 __ LeaveFrame(); |
1315 __ ret(); | 1365 __ ret(); |
1316 } | 1366 } |
1317 | 1367 |
1318 | 1368 |
1319 // Called for inline allocation of closures. | |
1320 // Input parameters: | |
1321 // Uses EAX, EBX, ECX as temporary registers. | |
1322 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, | |
1323 const Function& func) { | |
1324 static const bool kIsNotStaticImplicitClosure = false; | |
1325 ClosureAllocationStub(assembler, func, kIsNotStaticImplicitClosure); | |
1326 } | |
1327 | |
1328 | |
1329 // Called for inline allocation of implicit closures. | |
1330 // Input parameters: | |
1331 // Uses EAX, EBX, ECX as temporary registers. | |
1332 void StubCode::GenerateAllocationStubForStaticImplicitClosure( | |
1333 Assembler* assembler, const Function& func) { | |
1334 static const bool kIsStaticImplicitClosure = true; | |
1335 ClosureAllocationStub(assembler, func, kIsStaticImplicitClosure); | |
1336 } | |
1337 | |
1338 | |
1339 // Called for invoking noSuchMethod function from the entry code of a dart | 1369 // Called for invoking noSuchMethod function from the entry code of a dart |
1340 // function after an error in passed named arguments is detected. | 1370 // function after an error in passed named arguments is detected. |
1341 // Input parameters: | 1371 // Input parameters: |
1342 // EBP : points to previous frame pointer. | 1372 // EBP : points to previous frame pointer. |
1343 // EBP + 4 : points to return address. | 1373 // EBP + 4 : points to return address. |
1344 // EBP + 8 : address of last argument (arg n-1). | 1374 // EBP + 8 : address of last argument (arg n-1). |
1345 // EBP + 8 + 4*(n-1) : address of first argument (arg 0). | 1375 // EBP + 8 + 4*(n-1) : address of first argument (arg 0). |
1346 // ECX : function name. | 1376 // ECX : function name. |
1347 // EDX : arguments descriptor array. | 1377 // EDX : arguments descriptor array. |
1348 // Uses EAX, EBX, EDI as temporary registers. | 1378 // Uses EAX, EBX, EDI as temporary registers. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1393 __ popl(EAX); // Get result into EAX. | 1423 __ popl(EAX); // Get result into EAX. |
1394 | 1424 |
1395 // Remove the stub frame as we are about to return. | 1425 // Remove the stub frame as we are about to return. |
1396 __ LeaveFrame(); | 1426 __ LeaveFrame(); |
1397 __ ret(); | 1427 __ ret(); |
1398 } | 1428 } |
1399 | 1429 |
1400 } // namespace dart | 1430 } // namespace dart |
1401 | 1431 |
1402 #endif // defined TARGET_ARCH_IA32 | 1432 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |