| 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/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/assembler_macros.h" | 9 #include "vm/assembler_macros.h" |
| 10 #include "vm/code_generator.h" | 10 #include "vm/code_generator.h" |
| (...skipping 1278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1289 __ popl(EAX); // Pop result (newly allocated object). | 1289 __ popl(EAX); // Pop result (newly allocated object). |
| 1290 // EAX: new object | 1290 // EAX: new object |
| 1291 // Restore the frame pointer. | 1291 // Restore the frame pointer. |
| 1292 __ LeaveFrame(); | 1292 __ LeaveFrame(); |
| 1293 __ ret(); | 1293 __ ret(); |
| 1294 } | 1294 } |
| 1295 | 1295 |
| 1296 | 1296 |
| 1297 // Called for inline allocation of closures. | 1297 // Called for inline allocation of closures. |
| 1298 // Input parameters: | 1298 // Input parameters: |
| 1299 // If the signature class is not parameterized, the receiver, if any, will be | 1299 // ESP + 8 : receiver (only if implicit instance closure). |
| 1300 // at ESP + 4 instead of ESP + 8, since no type arguments are passed. | 1300 // ESP + 4 : type arguments object (null if class is no parameterized). |
| 1301 // ESP + 8 (or ESP + 4): receiver (only if implicit instance closure). | |
| 1302 // ESP + 4 : type arguments object (only if signature class is parameterized). | |
| 1303 // ESP : points to return address. | 1301 // ESP : points to return address. |
| 1304 // Uses EAX, EBX, ECX, EDX as temporary registers. | 1302 // Uses EAX, EBX, ECX, EDX as temporary registers. |
| 1305 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, | 1303 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, |
| 1306 const Function& func) { | 1304 const Function& func) { |
| 1307 const Immediate raw_null = | 1305 const Immediate raw_null = |
| 1308 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1306 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1309 ASSERT(func.IsClosureFunction()); | 1307 ASSERT(func.IsClosureFunction()); |
| 1310 const bool is_implicit_static_closure = | 1308 const bool is_implicit_static_closure = |
| 1311 func.IsImplicitStaticClosureFunction(); | 1309 func.IsImplicitStaticClosureFunction(); |
| 1312 const bool is_implicit_instance_closure = | 1310 const bool is_implicit_instance_closure = |
| 1313 func.IsImplicitInstanceClosureFunction(); | 1311 func.IsImplicitInstanceClosureFunction(); |
| 1314 const Class& cls = Class::ZoneHandle(func.signature_class()); | 1312 const Class& cls = Class::ZoneHandle(func.signature_class()); |
| 1315 const bool has_type_arguments = cls.HasTypeArguments(); | 1313 const bool has_type_arguments = cls.HasTypeArguments(); |
| 1316 const intptr_t kTypeArgumentsOffset = 1 * kWordSize; | 1314 const intptr_t kTypeArgumentsOffset = 1 * kWordSize; |
| 1317 const intptr_t kReceiverOffset = (has_type_arguments ? 2 : 1) * kWordSize; | 1315 const intptr_t kReceiverOffset = 2 * kWordSize; |
| 1318 const intptr_t closure_size = Closure::InstanceSize(); | 1316 const intptr_t closure_size = Closure::InstanceSize(); |
| 1319 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. | 1317 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. |
| 1320 if (FLAG_inline_alloc && | 1318 if (FLAG_inline_alloc && |
| 1321 PageSpace::IsPageAllocatableSize(closure_size + context_size)) { | 1319 PageSpace::IsPageAllocatableSize(closure_size + context_size)) { |
| 1322 Label slow_case; | 1320 Label slow_case; |
| 1323 Heap* heap = Isolate::Current()->heap(); | 1321 Heap* heap = Isolate::Current()->heap(); |
| 1324 __ movl(EAX, Address::Absolute(heap->TopAddress())); | 1322 __ movl(EAX, Address::Absolute(heap->TopAddress())); |
| 1325 __ leal(EBX, Address(EAX, closure_size)); | 1323 __ leal(EBX, Address(EAX, closure_size)); |
| 1326 if (is_implicit_instance_closure) { | 1324 if (is_implicit_instance_closure) { |
| 1327 __ movl(ECX, EBX); // ECX: new context address. | 1325 __ movl(ECX, EBX); // ECX: new context address. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1396 __ movl(Address(ECX, Context::variable_offset(0)), EDX); | 1394 __ movl(Address(ECX, Context::variable_offset(0)), EDX); |
| 1397 | 1395 |
| 1398 // Set the newly allocated context in the newly allocated closure. | 1396 // Set the newly allocated context in the newly allocated closure. |
| 1399 __ addl(ECX, Immediate(kHeapObjectTag)); | 1397 __ addl(ECX, Immediate(kHeapObjectTag)); |
| 1400 __ movl(Address(EAX, Closure::context_offset()), ECX); | 1398 __ movl(Address(EAX, Closure::context_offset()), ECX); |
| 1401 } else { | 1399 } else { |
| 1402 __ movl(Address(EAX, Closure::context_offset()), CTX); | 1400 __ movl(Address(EAX, Closure::context_offset()), CTX); |
| 1403 } | 1401 } |
| 1404 | 1402 |
| 1405 // Set the type arguments field in the newly allocated closure. | 1403 // Set the type arguments field in the newly allocated closure. |
| 1406 if (has_type_arguments) { | 1404 __ movl(EDX, Address(ESP, kTypeArgumentsOffset)); |
| 1407 ASSERT(!is_implicit_static_closure); | 1405 __ movl(Address(EAX, Closure::type_arguments_offset()), EDX); |
| 1408 // Use the passed-in type arguments. | |
| 1409 __ movl(EDX, Address(ESP, kTypeArgumentsOffset)); | |
| 1410 __ movl(Address(EAX, Closure::type_arguments_offset()), EDX); | |
| 1411 } else { | |
| 1412 // Set to null. | |
| 1413 __ movl(Address(EAX, Closure::type_arguments_offset()), raw_null); | |
| 1414 } | |
| 1415 | 1406 |
| 1416 __ movl(Address(EAX, Closure::smrck_offset()), raw_null); | 1407 __ movl(Address(EAX, Closure::smrck_offset()), raw_null); |
| 1417 | 1408 |
| 1418 // Done allocating and initializing the instance. | 1409 // Done allocating and initializing the instance. |
| 1419 // EAX: new object. | 1410 // EAX: new object. |
| 1420 __ addl(EAX, Immediate(kHeapObjectTag)); | 1411 __ addl(EAX, Immediate(kHeapObjectTag)); |
| 1421 __ ret(); | 1412 __ ret(); |
| 1422 | 1413 |
| 1423 __ Bind(&slow_case); | 1414 __ Bind(&slow_case); |
| 1424 } | 1415 } |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1892 // TOS + 2: instance. | 1883 // TOS + 2: instance. |
| 1893 // TOS + 3: cache array. | 1884 // TOS + 3: cache array. |
| 1894 // Result in ECX: null -> not found, otherwise result (true or false). | 1885 // Result in ECX: null -> not found, otherwise result (true or false). |
| 1895 void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) { | 1886 void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) { |
| 1896 GenerateSubtypeNTestCacheStub(assembler, 3); | 1887 GenerateSubtypeNTestCacheStub(assembler, 3); |
| 1897 } | 1888 } |
| 1898 | 1889 |
| 1899 } // namespace dart | 1890 } // namespace dart |
| 1900 | 1891 |
| 1901 #endif // defined TARGET_ARCH_IA32 | 1892 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |