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

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

Issue 14238036: Improve type optimization reusing the type argument vector of the instantiator (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 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/intermediate_language_ia32.cc ('k') | runtime/vm/intermediate_language_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" // Needed here to get TARGET_ARCH_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1294 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1295 Register instance_reg = locs()->in(0).reg(); 1295 Register instance_reg = locs()->in(0).reg();
1296 Register result_reg = locs()->out().reg(); 1296 Register result_reg = locs()->out().reg();
1297 1297
1298 __ lw(result_reg, Address(instance_reg, offset_in_bytes() - kHeapObjectTag)); 1298 __ lw(result_reg, Address(instance_reg, offset_in_bytes() - kHeapObjectTag));
1299 } 1299 }
1300 1300
1301 1301
1302 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { 1302 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const {
1303 const intptr_t kNumInputs = 1; 1303 const intptr_t kNumInputs = 1;
1304 const intptr_t kNumTemps = 1; 1304 const intptr_t kNumTemps = 0;
1305 LocationSummary* locs = 1305 LocationSummary* locs =
1306 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1306 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1307 locs->set_in(0, Location::RegisterLocation(T0)); 1307 locs->set_in(0, Location::RegisterLocation(T0));
1308 locs->set_temp(0, Location::RegisterLocation(T1));
1309 locs->set_out(Location::RegisterLocation(T0)); 1308 locs->set_out(Location::RegisterLocation(T0));
1310 return locs; 1309 return locs;
1311 } 1310 }
1312 1311
1313 1312
1314 void InstantiateTypeArgumentsInstr::EmitNativeCode( 1313 void InstantiateTypeArgumentsInstr::EmitNativeCode(
1315 FlowGraphCompiler* compiler) { 1314 FlowGraphCompiler* compiler) {
1316 __ TraceSimMsg("InstantiateTypeArgumentsInstr"); 1315 __ TraceSimMsg("InstantiateTypeArgumentsInstr");
1317 Register instantiator_reg = locs()->in(0).reg(); 1316 Register instantiator_reg = locs()->in(0).reg();
1318 Register temp = locs()->temp(0).reg();
1319 Register result_reg = locs()->out().reg(); 1317 Register result_reg = locs()->out().reg();
1320 1318
1321 // 'instantiator_reg' is the instantiator AbstractTypeArguments object 1319 // 'instantiator_reg' is the instantiator AbstractTypeArguments object
1322 // (or null). 1320 // (or null).
1323 // If the instantiator is null and if the type argument vector 1321 if (!type_arguments().IsUninstantiatedIdentity()) {
1324 // instantiated from null becomes a vector of dynamic, then use null as 1322 // If the instantiator is null and if the type argument vector
1325 // the type arguments. 1323 // instantiated from null becomes a vector of dynamic, then use null as
1326 Label type_arguments_instantiated; 1324 // the type arguments.
1327 const intptr_t len = type_arguments().Length(); 1325 Label type_arguments_instantiated;
1328 if (type_arguments().IsRawInstantiatedRaw(len)) { 1326 const intptr_t len = type_arguments().Length();
1329 __ BranchEqual(instantiator_reg, reinterpret_cast<intptr_t>(Object::null()), 1327 if (type_arguments().IsRawInstantiatedRaw(len)) {
1330 &type_arguments_instantiated); 1328 __ BranchEqual(instantiator_reg,
1329 reinterpret_cast<intptr_t>(Object::null()),
1330 &type_arguments_instantiated);
1331 }
1332 // Instantiate non-null type arguments.
1333 // A runtime call to instantiate the type arguments is required.
1334 __ addiu(SP, SP, Immediate(-3 * kWordSize));
1335 __ LoadObject(TMP1, Object::ZoneHandle());
1336 __ LoadObject(TMP2, type_arguments());
1337 __ sw(TMP1, Address(SP, 2 * kWordSize)); // Make room for the result.
1338 __ sw(TMP2, Address(SP, 1 * kWordSize));
1339 // Push instantiator type arguments.
1340 __ sw(instantiator_reg, Address(SP, 0 * kWordSize));
1341
1342 compiler->GenerateCallRuntime(token_pos(),
1343 deopt_id(),
1344 kInstantiateTypeArgumentsRuntimeEntry,
1345 locs());
1346 // Pop instantiated type arguments.
1347 __ lw(result_reg, Address(SP, 2 * kWordSize));
1348 // Drop instantiator and uninstantiated type arguments.
1349 __ addiu(SP, SP, Immediate(3 * kWordSize));
1350 __ Bind(&type_arguments_instantiated);
1331 } 1351 }
1332 // Instantiate non-null type arguments.
1333 if (type_arguments().IsUninstantiatedIdentity()) {
1334 // Check if the instantiator type argument vector is a TypeArguments of a
1335 // matching length and, if so, use it as the instantiated type_arguments.
1336 // No need to check the instantiator ('instantiator_reg') for null here,
1337 // because a null instantiator will have the wrong class (Null instead of
1338 // TypeArguments).
1339 Label type_arguments_uninstantiated;
1340 __ LoadClassId(temp, instantiator_reg);
1341 __ BranchNotEqual(temp, kTypeArgumentsCid, &type_arguments_uninstantiated);
1342 __ lw(temp, FieldAddress(instantiator_reg, TypeArguments::length_offset()));
1343 __ BranchEqual(temp, Smi::RawValue(len), &type_arguments_instantiated);
1344 __ Bind(&type_arguments_uninstantiated);
1345 }
1346 // A runtime call to instantiate the type arguments is required.
1347 __ addiu(SP, SP, Immediate(-3 * kWordSize));
1348 __ LoadObject(TMP1, Object::ZoneHandle());
1349 __ LoadObject(TMP2, type_arguments());
1350 __ sw(TMP1, Address(SP, 2 * kWordSize)); // Make room for the result.
1351 __ sw(TMP2, Address(SP, 1 * kWordSize));
1352 // Push instantiator type arguments.
1353 __ sw(instantiator_reg, Address(SP, 0 * kWordSize));
1354
1355 compiler->GenerateCallRuntime(token_pos(),
1356 deopt_id(),
1357 kInstantiateTypeArgumentsRuntimeEntry,
1358 locs());
1359 // Pop instantiated type arguments.
1360 __ lw(result_reg, Address(SP, 2 * kWordSize));
1361 // Drop instantiator and uninstantiated type arguments.
1362 __ addiu(SP, SP, Immediate(3 * kWordSize));
1363 __ Bind(&type_arguments_instantiated);
1364 ASSERT(instantiator_reg == result_reg); 1352 ASSERT(instantiator_reg == result_reg);
1365 // 'result_reg': Instantiated type arguments. 1353 // 'result_reg': Instantiated type arguments.
1366 } 1354 }
1367 1355
1368 1356
1369 LocationSummary* 1357 LocationSummary*
1370 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { 1358 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const {
1371 const intptr_t kNumInputs = 1; 1359 const intptr_t kNumInputs = 1;
1372 const intptr_t kNumTemps = 1; 1360 const intptr_t kNumTemps = 0;
1373 LocationSummary* locs = 1361 LocationSummary* locs =
1374 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1362 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1375 locs->set_in(0, Location::RequiresRegister()); 1363 locs->set_in(0, Location::RequiresRegister());
1376 locs->set_out(Location::SameAsFirstInput()); 1364 locs->set_out(Location::SameAsFirstInput());
1377 locs->set_temp(0, Location::RequiresRegister());
1378 return locs; 1365 return locs;
1379 } 1366 }
1380 1367
1381 1368
1382 void ExtractConstructorTypeArgumentsInstr::EmitNativeCode( 1369 void ExtractConstructorTypeArgumentsInstr::EmitNativeCode(
1383 FlowGraphCompiler* compiler) { 1370 FlowGraphCompiler* compiler) {
1384 Register instantiator_reg = locs()->in(0).reg(); 1371 Register instantiator_reg = locs()->in(0).reg();
1385 Register result_reg = locs()->out().reg(); 1372 Register result_reg = locs()->out().reg();
1386 ASSERT(instantiator_reg == result_reg); 1373 ASSERT(instantiator_reg == result_reg);
1387 Register temp_reg = locs()->temp(0).reg();
1388 1374
1389 // instantiator_reg is the instantiator type argument vector, i.e. an 1375 // instantiator_reg is the instantiator type argument vector, i.e. an
1390 // AbstractTypeArguments object (or null). 1376 // AbstractTypeArguments object (or null).
1391 // If the instantiator is null and if the type argument vector 1377 if (!type_arguments().IsUninstantiatedIdentity()) {
1392 // instantiated from null becomes a vector of dynamic, then use null as 1378 // If the instantiator is null and if the type argument vector
1393 // the type arguments. 1379 // instantiated from null becomes a vector of dynamic, then use null as
1394 Label type_arguments_instantiated; 1380 // the type arguments.
1395 const intptr_t len = type_arguments().Length(); 1381 Label type_arguments_instantiated;
1396 if (type_arguments().IsRawInstantiatedRaw(len)) { 1382 const intptr_t len = type_arguments().Length();
1397 __ BranchEqual(instantiator_reg, reinterpret_cast<intptr_t>(Object::null()), 1383 if (type_arguments().IsRawInstantiatedRaw(len)) {
1398 &type_arguments_instantiated); 1384 __ BranchEqual(instantiator_reg,
1385 reinterpret_cast<intptr_t>(Object::null()),
1386 &type_arguments_instantiated);
1387 }
1388 // Instantiate non-null type arguments.
1389 // In the non-factory case, we rely on the allocation stub to
1390 // instantiate the type arguments.
1391 __ LoadObject(result_reg, type_arguments());
1392 // result_reg: uninstantiated type arguments.
1393 __ Bind(&type_arguments_instantiated);
1399 } 1394 }
1400 // Instantiate non-null type arguments. 1395 ASSERT(instantiator_reg == result_reg);
1401 if (type_arguments().IsUninstantiatedIdentity()) {
1402 // Check if the instantiator type argument vector is a TypeArguments of a
1403 // matching length and, if so, use it as the instantiated type_arguments.
1404 // No need to check instantiator_reg for null here, because a null
1405 // instantiator will have the wrong class (Null instead of TypeArguments).
1406 Label type_arguments_uninstantiated;
1407 __ LoadClassId(temp_reg, instantiator_reg);
1408 __ BranchNotEqual(temp_reg, kTypeArgumentsCid,
1409 &type_arguments_uninstantiated);
1410 __ lw(temp_reg,
1411 FieldAddress(instantiator_reg, TypeArguments::length_offset()));
1412 __ BranchEqual(temp_reg, Smi::RawValue(type_arguments().Length()),
1413 &type_arguments_instantiated);
1414 __ Bind(&type_arguments_uninstantiated);
1415 }
1416 // In the non-factory case, we rely on the allocation stub to
1417 // instantiate the type arguments.
1418 __ LoadObject(result_reg, type_arguments());
1419 // result_reg: uninstantiated type arguments.
1420 __ Bind(&type_arguments_instantiated);
1421 // result_reg: uninstantiated or instantiated type arguments. 1396 // result_reg: uninstantiated or instantiated type arguments.
1422 } 1397 }
1423 1398
1424 1399
1425 LocationSummary* 1400 LocationSummary*
1426 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const { 1401 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const {
1427 const intptr_t kNumInputs = 1; 1402 const intptr_t kNumInputs = 1;
1428 const intptr_t kNumTemps = 1; 1403 const intptr_t kNumTemps = 0;
1429 LocationSummary* locs = 1404 LocationSummary* locs =
1430 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1405 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1431 locs->set_in(0, Location::RequiresRegister()); 1406 locs->set_in(0, Location::RequiresRegister());
1432 locs->set_out(Location::SameAsFirstInput()); 1407 locs->set_out(Location::SameAsFirstInput());
1433 locs->set_temp(0, Location::RequiresRegister());
1434 return locs; 1408 return locs;
1435 } 1409 }
1436 1410
1437 1411
1438 void ExtractConstructorInstantiatorInstr::EmitNativeCode( 1412 void ExtractConstructorInstantiatorInstr::EmitNativeCode(
1439 FlowGraphCompiler* compiler) { 1413 FlowGraphCompiler* compiler) {
1440 Register instantiator_reg = locs()->in(0).reg(); 1414 Register instantiator_reg = locs()->in(0).reg();
1441 ASSERT(locs()->out().reg() == instantiator_reg); 1415 ASSERT(locs()->out().reg() == instantiator_reg);
1442 Register temp_reg = locs()->temp(0).reg();
1443 1416
1444 // instantiator_reg is the instantiator AbstractTypeArguments object 1417 // instantiator_reg is the instantiator AbstractTypeArguments object
1445 // (or null). If the instantiator is null and if the type argument vector 1418 // (or null).
1446 // instantiated from null becomes a vector of dynamic, then use null as
1447 // the type arguments and do not pass the instantiator.
1448 Label done;
1449 const intptr_t len = type_arguments().Length();
1450 if (type_arguments().IsRawInstantiatedRaw(len)) {
1451 Label instantiator_not_null;
1452 __ BranchNotEqual(instantiator_reg,
1453 reinterpret_cast<intptr_t>(Object::null()), &instantiator_not_null);
1454 // Null was used in VisitExtractConstructorTypeArguments as the
1455 // instantiated type arguments, no proper instantiator needed.
1456 __ LoadImmediate(instantiator_reg,
1457 Smi::RawValue(StubCode::kNoInstantiator));
1458 __ b(&done);
1459 __ Bind(&instantiator_not_null);
1460 }
1461 // Instantiate non-null type arguments.
1462 if (type_arguments().IsUninstantiatedIdentity()) { 1419 if (type_arguments().IsUninstantiatedIdentity()) {
1463 // TODO(regis): The following emitted code is duplicated in
1464 // VisitExtractConstructorTypeArguments above. The reason is that the code
1465 // is split between two computations, so that each one produces a
1466 // single value, rather than producing a pair of values.
1467 // If this becomes an issue, we should expose these tests at the IL level.
1468
1469 // Check if the instantiator type argument vector is a TypeArguments of a
1470 // matching length and, if so, use it as the instantiated type_arguments.
1471 // No need to check the instantiator ('instantiator_reg') for null here,
1472 // because a null instantiator will have the wrong class (Null instead of
1473 // TypeArguments).
1474 __ LoadClassId(temp_reg, instantiator_reg);
1475 __ BranchNotEqual(temp_reg, kTypeArgumentsCid, &done);
1476 __ lw(temp_reg,
1477 FieldAddress(instantiator_reg, TypeArguments::length_offset()));
1478 __ BranchNotEqual(temp_reg, Smi::RawValue(type_arguments().Length()),
1479 &done);
1480 // The instantiator was used in VisitExtractConstructorTypeArguments as the 1420 // The instantiator was used in VisitExtractConstructorTypeArguments as the
1481 // instantiated type arguments, no proper instantiator needed. 1421 // instantiated type arguments, no proper instantiator needed.
1482 __ LoadImmediate(instantiator_reg, 1422 __ LoadImmediate(instantiator_reg,
1483 Smi::RawValue(StubCode::kNoInstantiator)); 1423 Smi::RawValue(StubCode::kNoInstantiator));
1424 } else {
1425 // If the instantiator is null and if the type argument vector
1426 // instantiated from null becomes a vector of dynamic, then use null as
1427 // the type arguments and do not pass the instantiator.
1428 const intptr_t len = type_arguments().Length();
1429 if (type_arguments().IsRawInstantiatedRaw(len)) {
1430 Label instantiator_not_null;
1431 __ BranchNotEqual(instantiator_reg,
1432 reinterpret_cast<intptr_t>(Object::null()), &instantiator_not_null);
1433 // Null was used in VisitExtractConstructorTypeArguments as the
1434 // instantiated type arguments, no proper instantiator needed.
1435 __ LoadImmediate(instantiator_reg,
1436 Smi::RawValue(StubCode::kNoInstantiator));
1437 __ Bind(&instantiator_not_null);
1438 }
1484 } 1439 }
1485 __ Bind(&done);
1486 // instantiator_reg: instantiator or kNoInstantiator. 1440 // instantiator_reg: instantiator or kNoInstantiator.
1487 } 1441 }
1488 1442
1489 1443
1490 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { 1444 LocationSummary* AllocateContextInstr::MakeLocationSummary() const {
1491 const intptr_t kNumInputs = 0; 1445 const intptr_t kNumInputs = 0;
1492 const intptr_t kNumTemps = 1; 1446 const intptr_t kNumTemps = 1;
1493 LocationSummary* locs = 1447 LocationSummary* locs =
1494 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1448 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1495 locs->set_temp(0, Location::RegisterLocation(T1)); 1449 locs->set_temp(0, Location::RegisterLocation(T1));
(...skipping 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after
2498 &label, 2452 &label,
2499 PcDescriptors::kOther, 2453 PcDescriptors::kOther,
2500 locs()); 2454 locs());
2501 __ Drop(2); // Discard type arguments and receiver. 2455 __ Drop(2); // Discard type arguments and receiver.
2502 } 2456 }
2503 2457
2504 } // namespace dart 2458 } // namespace dart
2505 2459
2506 #endif // defined TARGET_ARCH_MIPS 2460 #endif // defined TARGET_ARCH_MIPS
2507 2461
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698