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

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

Issue 163683006: Simplify generated code for object allocation with type arguments. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: addressed comments Created 6 years, 10 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_ia32.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 1269 matching lines...) Expand 10 before | Expand all | Expand 10 after
1280 __ TraceSimMsg("UpdateStoreBufferStub return"); 1280 __ TraceSimMsg("UpdateStoreBufferStub return");
1281 // Restore callee-saved registers, tear down frame. 1281 // Restore callee-saved registers, tear down frame.
1282 __ LeaveCallRuntimeFrame(); 1282 __ LeaveCallRuntimeFrame();
1283 __ Ret(); 1283 __ Ret();
1284 } 1284 }
1285 1285
1286 1286
1287 // Called for inline allocation of objects. 1287 // Called for inline allocation of objects.
1288 // Input parameters: 1288 // Input parameters:
1289 // RA : return address. 1289 // RA : return address.
1290 // SP + 4 : type arguments object (only if class is parameterized). 1290 // SP + 0 : type arguments object (only if class is parameterized).
1291 // SP + 0 : type arguments of instantiator (only if class is parameterized).
1292 void StubCode::GenerateAllocationStubForClass(Assembler* assembler, 1291 void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
1293 const Class& cls) { 1292 const Class& cls) {
1294 __ TraceSimMsg("AllocationStubForClass"); 1293 __ TraceSimMsg("AllocationStubForClass");
1295 // The generated code is different if the class is parameterized. 1294 // The generated code is different if the class is parameterized.
1296 const bool is_cls_parameterized = cls.NumTypeArguments() > 0; 1295 const bool is_cls_parameterized = cls.NumTypeArguments() > 0;
1297 ASSERT(!is_cls_parameterized || 1296 ASSERT(!is_cls_parameterized ||
1298 (cls.type_arguments_field_offset() != Class::kNoTypeArguments)); 1297 (cls.type_arguments_field_offset() != Class::kNoTypeArguments));
1299 // kInlineInstanceSize is a constant used as a threshold for determining 1298 // kInlineInstanceSize is a constant used as a threshold for determining
1300 // when the object initialization should be done as a loop or as 1299 // when the object initialization should be done as a loop or as
1301 // straight line code. 1300 // straight line code.
1302 const int kInlineInstanceSize = 12; 1301 const int kInlineInstanceSize = 12;
1303 const intptr_t instance_size = cls.instance_size(); 1302 const intptr_t instance_size = cls.instance_size();
1304 ASSERT(instance_size > 0); 1303 ASSERT(instance_size > 0);
1305 Label slow_case_with_type_arguments; 1304 Label slow_case_with_type_arguments;
1306 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { 1305 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
1307 Label slow_case_reload_type_arguments; 1306 Label slow_case_reload_type_arguments;
1308 if (is_cls_parameterized) { 1307 if (is_cls_parameterized) {
1309 // Instantiation of the type arguments vector is only required if an 1308 __ lw(T1, Address(SP, 0 * kWordSize));
1310 // instantiator is provided (not kNoInstantiator, but may be null). 1309 // T1: type arguments.
1311 __ lw(T1, Address(SP, 1 * kWordSize));
1312 __ lw(T0, Address(SP, 0 * kWordSize));
1313 // R1: type arguments, instantiated or not.
1314 // R0: instantiator type arguments or kNoInstantiator.
1315 Label type_arguments_ready;
1316 __ BranchEqual(T0, Smi::RawValue(StubCode::kNoInstantiator),
1317 &type_arguments_ready);
1318 // Lookup instantiator EDI in instantiations array of type arguments EDX
1319 // and, if found, use cached instantiated type arguments.
1320 __ lw(T2, FieldAddress(T1, TypeArguments::instantiations_offset()));
1321 __ lw(T3, FieldAddress(T2, Array::length_offset()));
1322 __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag);
1323 __ sll(TMP, T3, 1); // T3 is Smi.
1324 __ addu(T3, T2, TMP);
1325 Label loop, found;
1326 __ Bind(&loop);
1327 __ BranchUnsignedGreaterEqual(T2, T3, &slow_case_reload_type_arguments);
1328 __ lw(T1, Address(T2, 0 * kWordSize)); // Cached instantiator.
1329 __ beq(T1, T0, &found);
1330 __ BranchEqual(T1, Smi::RawValue(StubCode::kNoInstantiator),
1331 &slow_case_reload_type_arguments);
1332 __ b(&loop);
1333 __ delay_slot()->addiu(T2, T2, Immediate(2 * kWordSize));
1334 __ Bind(&found);
1335 __ lw(T1, Address(T2, 1 * kWordSize)); // Cached instantiated args.
1336 __ LoadImmediate(T0, Smi::RawValue(StubCode::kNoInstantiator));
1337 __ Bind(&type_arguments_ready);
1338 // T0: instantiated type arguments.
1339 // T1: kNoInstantiator.
1340 } 1310 }
1341 // Allocate the object and update top to point to 1311 // Allocate the object and update top to point to
1342 // next object start and initialize the allocated object. 1312 // next object start and initialize the allocated object.
1343 // T0: instantiated type arguments (if is_cls_parameterized). 1313 // T1: instantiated type arguments (if is_cls_parameterized).
1344 // T1: kNoInstantiator (if is_cls_parameterized).
1345 Heap* heap = Isolate::Current()->heap(); 1314 Heap* heap = Isolate::Current()->heap();
1346 __ LoadImmediate(T5, heap->TopAddress()); 1315 __ LoadImmediate(T5, heap->TopAddress());
1347 __ lw(T2, Address(T5)); 1316 __ lw(T2, Address(T5));
1348 __ LoadImmediate(T4, instance_size); 1317 __ LoadImmediate(T4, instance_size);
1349 __ addu(T3, T2, T4); 1318 __ addu(T3, T2, T4);
1350 // Check if the allocation fits into the remaining space. 1319 // Check if the allocation fits into the remaining space.
1351 // T2: potential new object start. 1320 // T2: potential new object start.
1352 // T3: potential next object start. 1321 // T3: potential next object start.
1353 __ LoadImmediate(TMP, heap->EndAddress()); 1322 __ LoadImmediate(TMP, heap->EndAddress());
1354 __ lw(CMPRES1, Address(TMP)); 1323 __ lw(CMPRES1, Address(TMP));
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1398 // T1: new object type arguments (if is_cls_parameterized). 1367 // T1: new object type arguments (if is_cls_parameterized).
1399 Label loop, loop_exit; 1368 Label loop, loop_exit;
1400 __ BranchUnsignedGreaterEqual(T4, T3, &loop_exit); 1369 __ BranchUnsignedGreaterEqual(T4, T3, &loop_exit);
1401 __ Bind(&loop); 1370 __ Bind(&loop);
1402 __ addiu(T4, T4, Immediate(kWordSize)); 1371 __ addiu(T4, T4, Immediate(kWordSize));
1403 __ bne(T4, T3, &loop); 1372 __ bne(T4, T3, &loop);
1404 __ delay_slot()->sw(T7, Address(T4, -kWordSize)); 1373 __ delay_slot()->sw(T7, Address(T4, -kWordSize));
1405 __ Bind(&loop_exit); 1374 __ Bind(&loop_exit);
1406 } 1375 }
1407 if (is_cls_parameterized) { 1376 if (is_cls_parameterized) {
1408 // R1: new object type arguments. 1377 // T1: new object type arguments.
1409 // Set the type arguments in the new object. 1378 // Set the type arguments in the new object.
1410 __ sw(T1, Address(T2, cls.type_arguments_field_offset())); 1379 __ sw(T1, Address(T2, cls.type_arguments_field_offset()));
1411 } 1380 }
1412 // Done allocating and initializing the instance. 1381 // Done allocating and initializing the instance.
1413 // T2: new object still missing its heap tag. 1382 // T2: new object still missing its heap tag.
1414 __ Ret(); 1383 __ Ret();
1415 __ delay_slot()->addiu(V0, T2, Immediate(kHeapObjectTag)); 1384 __ delay_slot()->addiu(V0, T2, Immediate(kHeapObjectTag));
1416 1385
1417 __ Bind(&slow_case_reload_type_arguments); 1386 __ Bind(&slow_case_reload_type_arguments);
1418 } 1387 }
1419 if (is_cls_parameterized) { 1388 if (is_cls_parameterized) {
1420 __ lw(T1, Address(SP, 1 * kWordSize)); 1389 __ lw(T1, Address(SP, 0 * kWordSize));
1421 __ lw(T0, Address(SP, 0 * kWordSize));
1422 } 1390 }
1423 __ Bind(&slow_case_with_type_arguments); 1391 __ Bind(&slow_case_with_type_arguments);
1424 // If is_cls_parameterized: 1392 // If is_cls_parameterized:
1425 // T1: new object type arguments (instantiated or not). 1393 // T1: new object type arguments (instantiated or not).
1426 // T0: instantiator type arguments or kNoInstantiator.
1427 // Create a stub frame as we are pushing some objects on the stack before 1394 // Create a stub frame as we are pushing some objects on the stack before
1428 // calling into the runtime. 1395 // calling into the runtime.
1429 __ EnterStubFrame(true); // Uses pool pointer to pass cls to runtime. 1396 __ EnterStubFrame(true); // Uses pool pointer to pass cls to runtime.
1430 __ LoadObject(TMP, cls); 1397 __ LoadObject(TMP, cls);
1431 1398
1432 __ addiu(SP, SP, Immediate(-4 * kWordSize)); 1399 __ addiu(SP, SP, Immediate(-4 * kWordSize));
1433 // Space on stack for return value. 1400 // Space on stack for return value.
1434 __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); 1401 __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null()));
1435 __ sw(T7, Address(SP, 3 * kWordSize)); 1402 __ sw(T7, Address(SP, 2 * kWordSize));
1436 __ sw(TMP, Address(SP, 2 * kWordSize)); // Class of object to be allocated. 1403 __ sw(TMP, Address(SP, 1 * kWordSize)); // Class of object to be allocated.
1437 1404
1438 if (is_cls_parameterized) { 1405 if (is_cls_parameterized) {
1439 // Push type arguments of object to be allocated and of instantiator. 1406 // Push type arguments of object to be allocated and of instantiator.
1440 __ sw(T1, Address(SP, 1 * kWordSize)); 1407 __ sw(T1, Address(SP, 0 * kWordSize));
1441 __ sw(T0, Address(SP, 0 * kWordSize));
1442 } else { 1408 } else {
1443 // Push null type arguments and kNoInstantiator. 1409 // Push null type arguments.
1444 __ LoadImmediate(T1, Smi::RawValue(StubCode::kNoInstantiator)); 1410 __ sw(T7, Address(SP, 0 * kWordSize));
1445 __ sw(T7, Address(SP, 1 * kWordSize));
1446 __ sw(T1, Address(SP, 0 * kWordSize));
1447 } 1411 }
1448 __ CallRuntime(kAllocateObjectRuntimeEntry, 3); // Allocate object. 1412 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object.
1449 __ TraceSimMsg("AllocationStubForClass return"); 1413 __ TraceSimMsg("AllocationStubForClass return");
1450 // Pop result (newly allocated object). 1414 // Pop result (newly allocated object).
1451 __ lw(V0, Address(SP, 3 * kWordSize)); 1415 __ lw(V0, Address(SP, 2 * kWordSize));
1452 __ addiu(SP, SP, Immediate(4 * kWordSize)); // Pop arguments. 1416 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Pop arguments.
1453 // V0: new object 1417 // V0: new object
1454 // Restore the frame pointer and return. 1418 // Restore the frame pointer and return.
1455 __ LeaveStubFrameAndReturn(RA); 1419 __ LeaveStubFrameAndReturn(RA);
1456 } 1420 }
1457 1421
1458 1422
1459 // Called for inline allocation of closures. 1423 // Called for inline allocation of closures.
1460 // Input parameters: 1424 // Input parameters:
1461 // RA: return address. 1425 // RA: return address.
1462 // SP + 4 : receiver (null if not an implicit instance closure). 1426 // SP + 4 : receiver (null if not an implicit instance closure).
(...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after
2424 const Register right = T0; 2388 const Register right = T0;
2425 __ lw(left, Address(SP, 1 * kWordSize)); 2389 __ lw(left, Address(SP, 1 * kWordSize));
2426 __ lw(right, Address(SP, 0 * kWordSize)); 2390 __ lw(right, Address(SP, 0 * kWordSize));
2427 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); 2391 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2);
2428 __ Ret(); 2392 __ Ret();
2429 } 2393 }
2430 2394
2431 } // namespace dart 2395 } // namespace dart
2432 2396
2433 #endif // defined TARGET_ARCH_MIPS 2397 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_ia32.cc ('k') | runtime/vm/stub_code_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698