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 1224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 // Called for inline allocation of closures. | 1243 // Called for inline allocation of closures. |
1244 // Input parameters: | 1244 // Input parameters: |
1245 // ESP + 4 : receiver (only if non-static implicit closure). | 1245 // ESP + 8 : receiver (only if implicit instance closure). |
1246 // ESP + 4 : type arguments object (only if signature class is parameterized). | |
1246 // ESP : points to return address. | 1247 // ESP : points to return address. |
siva
2011/10/13 20:52:21
if signature class is not parameterized ESP + 4 w
regis
2011/10/13 21:33:46
Done.
| |
1247 // Uses EAX, EBX, ECX, EDX as temporary registers. | 1248 // Uses EAX, EBX, ECX, EDX as temporary registers. |
1248 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, | 1249 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, |
1249 const Function& func) { | 1250 const Function& func) { |
1250 const intptr_t kReceiverOffset = 1 * kWordSize; | |
1251 const Immediate raw_null = | 1251 const Immediate raw_null = |
1252 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1252 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1253 ASSERT(func.IsClosureFunction()); | 1253 ASSERT(func.IsClosureFunction()); |
1254 const bool is_implicit_static_closure = | 1254 const bool is_implicit_static_closure = |
1255 func.IsImplicitStaticClosureFunction(); | 1255 func.IsImplicitStaticClosureFunction(); |
1256 const bool is_implicit_instance_closure = | 1256 const bool is_implicit_instance_closure = |
1257 func.IsImplicitInstanceClosureFunction(); | 1257 func.IsImplicitInstanceClosureFunction(); |
1258 const Class& cls = Class::ZoneHandle(func.signature_class()); | |
1259 const bool is_cls_parameterized = cls.IsParameterized(); | |
1260 const intptr_t kTypeArgumentsOffset = 1 * kWordSize; | |
1261 const intptr_t kReceiverOffset = (is_cls_parameterized ? 2 : 1) * kWordSize; | |
1258 const intptr_t closure_size = Closure::InstanceSize(); | 1262 const intptr_t closure_size = Closure::InstanceSize(); |
1259 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. | 1263 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. |
1260 if (FLAG_inline_alloc && | 1264 if (FLAG_inline_alloc && |
1261 PageSpace::IsPageAllocatableSize(closure_size + context_size)) { | 1265 PageSpace::IsPageAllocatableSize(closure_size + context_size)) { |
1262 const Class& cls = Class::ZoneHandle(func.signature_class()); | |
1263 Label slow_case; | 1266 Label slow_case; |
1264 Heap* heap = Isolate::Current()->heap(); | 1267 Heap* heap = Isolate::Current()->heap(); |
1265 __ movl(EAX, Address::Absolute(heap->TopAddress())); | 1268 __ movl(EAX, Address::Absolute(heap->TopAddress())); |
1266 __ leal(EBX, Address(EAX, closure_size)); | 1269 __ leal(EBX, Address(EAX, closure_size)); |
1267 if (is_implicit_instance_closure) { | 1270 if (is_implicit_instance_closure) { |
1268 __ movl(ECX, EBX); // ECX: new context address. | 1271 __ movl(ECX, EBX); // ECX: new context address. |
1269 __ addl(EBX, Immediate(context_size)); | 1272 __ addl(EBX, Immediate(context_size)); |
1270 } | 1273 } |
1271 // Check if the allocation fits into the remaining space. | 1274 // Check if the allocation fits into the remaining space. |
1272 // EAX: potential new closure object. | 1275 // EAX: potential new closure object. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1320 // Initialize the context variable to the receiver. | 1323 // Initialize the context variable to the receiver. |
1321 __ movl(EDX, Address(ESP, kReceiverOffset)); | 1324 __ movl(EDX, Address(ESP, kReceiverOffset)); |
1322 __ movl(Address(ECX, Context::variable_offset(0)), EDX); | 1325 __ movl(Address(ECX, Context::variable_offset(0)), EDX); |
1323 | 1326 |
1324 // Set the newly allocated context in the newly allocated closure. | 1327 // Set the newly allocated context in the newly allocated closure. |
1325 __ addl(ECX, Immediate(kHeapObjectTag)); | 1328 __ addl(ECX, Immediate(kHeapObjectTag)); |
1326 __ movl(Address(EAX, Closure::context_offset()), ECX); | 1329 __ movl(Address(EAX, Closure::context_offset()), ECX); |
1327 } else { | 1330 } else { |
1328 __ movl(Address(EAX, Closure::context_offset()), CTX); | 1331 __ movl(Address(EAX, Closure::context_offset()), CTX); |
1329 } | 1332 } |
1333 | |
1334 // Set the type arguments field in the newly allocated closure. | |
1335 if (is_cls_parameterized) { | |
1336 ASSERT(!is_implicit_static_closure); | |
1337 // Use the passed-in type arguments. | |
1338 __ movl(EDX, Address(ESP, kTypeArgumentsOffset)); | |
1339 __ movl(Address(EAX, Closure::type_arguments_offset()), EDX); | |
1340 } else { | |
1341 // Set to null. | |
1342 __ movl(Address(EAX, Closure::type_arguments_offset()), raw_null); | |
1343 } | |
1344 | |
1330 __ movl(Address(EAX, Closure::smrck_offset()), raw_null); | 1345 __ movl(Address(EAX, Closure::smrck_offset()), raw_null); |
1331 | 1346 |
1332 // TODO(regis): Store the actual type arguments. | |
1333 __ movl(Address(EAX, Closure::type_arguments_offset()), raw_null); | |
1334 | |
1335 // Done allocating and initializing the instance. | 1347 // Done allocating and initializing the instance. |
1336 // EAX: new object. | 1348 // EAX: new object. |
1337 __ addl(EAX, Immediate(kHeapObjectTag)); | 1349 __ addl(EAX, Immediate(kHeapObjectTag)); |
1338 __ ret(); | 1350 __ ret(); |
1339 | 1351 |
1340 __ Bind(&slow_case); | 1352 __ Bind(&slow_case); |
1341 } | 1353 } |
1354 if (is_cls_parameterized) { | |
1355 __ movl(ECX, Address(ESP, kTypeArgumentsOffset)); | |
1356 } | |
1342 if (is_implicit_instance_closure) { | 1357 if (is_implicit_instance_closure) { |
1343 __ movl(EAX, Address(ESP, kReceiverOffset)); | 1358 __ movl(EAX, Address(ESP, kReceiverOffset)); |
1344 } | 1359 } |
1345 // Create a stub frame. | 1360 // Create a stub frame. |
1346 __ EnterFrame(0); | 1361 __ EnterFrame(0); |
1347 const Closure& new_closure = Closure::ZoneHandle(); | 1362 const Closure& new_closure = Closure::ZoneHandle(); |
1348 __ PushObject(new_closure); // Push Null closure for return value. | 1363 __ PushObject(new_closure); // Push Null closure for return value. |
1349 __ PushObject(func); | 1364 __ PushObject(func); |
1365 if (is_cls_parameterized) { | |
1366 __ pushl(ECX); // Push type arguments of closure to be allocated. | |
1367 } else { | |
1368 __ PushObject(TypeArguments::ZoneHandle()); // Push null type arguments. | |
siva
2011/10/13 20:52:21
why not use pushl(raw_null) here?
regis
2011/10/13 21:33:46
Done here and at some other locations.
| |
1369 } | |
1350 if (is_implicit_static_closure) { | 1370 if (is_implicit_static_closure) { |
1351 __ CallRuntimeFromStub(kAllocateImplicitStaticClosureRuntimeEntry); | 1371 __ CallRuntimeFromStub(kAllocateImplicitStaticClosureRuntimeEntry); |
1352 } else if (is_implicit_instance_closure) { | 1372 } else if (is_implicit_instance_closure) { |
1353 __ pushl(EAX); // Receiver. | 1373 __ pushl(EAX); // Receiver. |
1354 __ CallRuntimeFromStub(kAllocateImplicitInstanceClosureRuntimeEntry); | 1374 __ CallRuntimeFromStub(kAllocateImplicitInstanceClosureRuntimeEntry); |
1355 __ popl(EAX); // Pop receiver. | 1375 __ popl(EAX); // Pop receiver. |
1356 } else { | 1376 } else { |
1357 ASSERT(func.IsNonImplicitClosureFunction()); | 1377 ASSERT(func.IsNonImplicitClosureFunction()); |
1358 __ CallRuntimeFromStub(kAllocateClosureRuntimeEntry); | 1378 __ CallRuntimeFromStub(kAllocateClosureRuntimeEntry); |
1359 } | 1379 } |
1380 __ popl(EAX); // Pop argument (type arguments of object). | |
1360 __ popl(EAX); // Pop function object. | 1381 __ popl(EAX); // Pop function object. |
1361 __ popl(EAX); | 1382 __ popl(EAX); |
1362 // EAX: new object | 1383 // EAX: new object |
1363 // Restore the frame pointer. | 1384 // Restore the frame pointer. |
1364 __ LeaveFrame(); | 1385 __ LeaveFrame(); |
1365 __ ret(); | 1386 __ ret(); |
1366 } | 1387 } |
1367 | 1388 |
1368 | 1389 |
1369 // Called for invoking noSuchMethod function from the entry code of a dart | 1390 // Called for invoking noSuchMethod function from the entry code of a dart |
(...skipping 16 matching lines...) Expand all Loading... | |
1386 // noSuchMethod(String name, Array arguments) to something like | 1407 // noSuchMethod(String name, Array arguments) to something like |
1387 // noSuchMethod(InvocationMirror call). | 1408 // noSuchMethod(InvocationMirror call). |
1388 // Also, the class NoSuchMethodException has to be modified accordingly. | 1409 // Also, the class NoSuchMethodException has to be modified accordingly. |
1389 // Total number of args is the first Smi in args descriptor array (EDX). | 1410 // Total number of args is the first Smi in args descriptor array (EDX). |
1390 __ movl(EDI, FieldAddress(EDX, Array::data_offset())); | 1411 __ movl(EDI, FieldAddress(EDX, Array::data_offset())); |
1391 __ SmiUntag(EDI); | 1412 __ SmiUntag(EDI); |
1392 __ movl(EAX, Address(EBP, EDI, TIMES_4, kWordSize)); // Get receiver. | 1413 __ movl(EAX, Address(EBP, EDI, TIMES_4, kWordSize)); // Get receiver. |
1393 | 1414 |
1394 __ EnterFrame(0); | 1415 __ EnterFrame(0); |
1395 // Setup space for return value on stack by pushing smi 0. | 1416 // Setup space for return value on stack by pushing smi 0. |
1396 // TODO(regis): Why are we using smi 0 instead of raw_null in stubs? | |
1397 __ pushl(Immediate(0)); // Result from noSuchMethod. | 1417 __ pushl(Immediate(0)); // Result from noSuchMethod. |
1398 __ pushl(EAX); // Receiver. | 1418 __ pushl(EAX); // Receiver. |
1399 __ pushl(ECX); // Function name. | 1419 __ pushl(ECX); // Function name. |
1400 __ pushl(EDX); // Arguments descriptor array. | 1420 __ pushl(EDX); // Arguments descriptor array. |
1401 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. | 1421 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. |
1402 // See stack layout below explaining "wordSize * 8" offset. | 1422 // See stack layout below explaining "wordSize * 8" offset. |
1403 PushArgumentsArray(assembler, (kWordSize * 8)); | 1423 PushArgumentsArray(assembler, (kWordSize * 8)); |
1404 | 1424 |
1405 // Stack: | 1425 // Stack: |
1406 // TOS + 0: Argument array. | 1426 // TOS + 0: Argument array. |
(...skipping 16 matching lines...) Expand all Loading... | |
1423 __ popl(EAX); // Get result into EAX. | 1443 __ popl(EAX); // Get result into EAX. |
1424 | 1444 |
1425 // Remove the stub frame as we are about to return. | 1445 // Remove the stub frame as we are about to return. |
1426 __ LeaveFrame(); | 1446 __ LeaveFrame(); |
1427 __ ret(); | 1447 __ ret(); |
1428 } | 1448 } |
1429 | 1449 |
1430 } // namespace dart | 1450 } // namespace dart |
1431 | 1451 |
1432 #endif // defined TARGET_ARCH_IA32 | 1452 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |