Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(573)

Side by Side Diff: runtime/vm/stub_code_ia32.cc

Issue 8234016: Inline allocation of implicit closures. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/stub_code_arm.cc ('k') | runtime/vm/stub_code_x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_arm.cc ('k') | runtime/vm/stub_code_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698