Chromium Code Reviews| 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 |