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

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

Issue 313083008: Add LoadTaggedClassIdMayBeSmi to assembly and improve performance of inline cache stubs. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 6 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 1427 matching lines...) Expand 10 before | Expand all | Expand 10 after
1438 __ addiu(SP, SP, Immediate(2 * kWordSize)); 1438 __ addiu(SP, SP, Immediate(2 * kWordSize));
1439 __ LeaveStubFrame(); 1439 __ LeaveStubFrame();
1440 __ Bind(&not_stepping); 1440 __ Bind(&not_stepping);
1441 } 1441 }
1442 1442
1443 // Load argument descriptor into S4. 1443 // Load argument descriptor into S4.
1444 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset())); 1444 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset()));
1445 // Preserve return address, since RA is needed for subroutine call. 1445 // Preserve return address, since RA is needed for subroutine call.
1446 __ mov(T2, RA); 1446 __ mov(T2, RA);
1447 // Loop that checks if there is an IC data match. 1447 // Loop that checks if there is an IC data match.
1448 Label loop, update, test, found, get_class_id_as_smi; 1448 Label loop, update, test, found;
1449 // S5: IC data object (preserved). 1449 // S5: IC data object (preserved).
1450 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset())); 1450 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset()));
1451 // T0: ic_data_array with check entries: classes and target functions. 1451 // T0: ic_data_array with check entries: classes and target functions.
1452 __ AddImmediate(T0, Array::data_offset() - kHeapObjectTag); 1452 __ AddImmediate(T0, Array::data_offset() - kHeapObjectTag);
1453 // T0: points directly to the first ic data array element. 1453 // T0: points directly to the first ic data array element.
1454 1454
1455 // Get the receiver's class ID (first read number of arguments from 1455 // Get the receiver's class ID (first read number of arguments from
1456 // arguments descriptor array and then access the receiver from the stack). 1456 // arguments descriptor array and then access the receiver from the stack).
1457 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); 1457 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset()));
1458 __ LoadImmediate(TMP, Smi::RawValue(1)); 1458 __ LoadImmediate(TMP, Smi::RawValue(1));
1459 __ subu(T1, T1, TMP); 1459 __ subu(T1, T1, TMP);
1460 __ sll(T3, T1, 1); // T1 (argument_count - 1) is smi. 1460 __ sll(T3, T1, 1); // T1 (argument_count - 1) is smi.
1461 __ addu(T3, T3, SP); 1461 __ addu(T3, T3, SP);
1462 __ bal(&get_class_id_as_smi); 1462 __ lw(T3, Address(T3));
1463 __ delay_slot()->lw(T3, Address(T3)); 1463 __ LoadTaggedClassIdMayBeSmi(T3, T3);
1464
1464 // T1: argument_count - 1 (smi). 1465 // T1: argument_count - 1 (smi).
1465 // T3: receiver's class ID (smi). 1466 // T3: receiver's class ID (smi).
1466 __ b(&test); 1467 __ b(&test);
1467 __ delay_slot()->lw(T4, Address(T0)); // First class id (smi) to check. 1468 __ delay_slot()->lw(T4, Address(T0)); // First class id (smi) to check.
1468 1469
1469 __ Bind(&loop); 1470 __ Bind(&loop);
1470 for (int i = 0; i < num_args; i++) { 1471 for (int i = 0; i < num_args; i++) {
1471 if (i > 0) { 1472 if (i > 0) {
1472 // If not the first, load the next argument's class ID. 1473 // If not the first, load the next argument's class ID.
1473 __ LoadImmediate(T3, Smi::RawValue(-i)); 1474 __ LoadImmediate(T3, Smi::RawValue(-i));
1474 __ addu(T3, T1, T3); 1475 __ addu(T3, T1, T3);
1475 __ sll(T3, T3, 1); 1476 __ sll(T3, T3, 1);
1476 __ addu(T3, SP, T3); 1477 __ addu(T3, SP, T3);
1477 __ bal(&get_class_id_as_smi); 1478 __ lw(T3, Address(T3));
1478 __ delay_slot()->lw(T3, Address(T3)); 1479 __ LoadTaggedClassIdMayBeSmi(T3, T3);
1479 // T3: next argument class ID (smi). 1480 // T3: next argument class ID (smi).
1480 __ lw(T4, Address(T0, i * kWordSize)); 1481 __ lw(T4, Address(T0, i * kWordSize));
1481 // T4: next class ID to check (smi). 1482 // T4: next class ID to check (smi).
1482 } 1483 }
1483 if (i < (num_args - 1)) { 1484 if (i < (num_args - 1)) {
1484 __ bne(T3, T4, &update); // Continue. 1485 __ bne(T3, T4, &update); // Continue.
1485 } else { 1486 } else {
1486 // Last check, all checks before matched. 1487 // Last check, all checks before matched.
1487 Label skip; 1488 Label skip;
1488 __ bne(T3, T4, &skip); 1489 __ bne(T3, T4, &skip);
1489 __ b(&found); // Break. 1490 __ b(&found); // Break.
1490 __ delay_slot()->mov(RA, T2); // Restore return address if found. 1491 __ delay_slot()->mov(RA, T2); // Restore return address if found.
1491 __ Bind(&skip); 1492 __ Bind(&skip);
1492 } 1493 }
1493 } 1494 }
1494 __ Bind(&update); 1495 __ Bind(&update);
1495 // Reload receiver class ID. It has not been destroyed when num_args == 1. 1496 // Reload receiver class ID. It has not been destroyed when num_args == 1.
1496 if (num_args > 1) { 1497 if (num_args > 1) {
1497 __ sll(T3, T1, 1); 1498 __ sll(T3, T1, 1);
1498 __ addu(T3, T3, SP); 1499 __ addu(T3, T3, SP);
1499 __ bal(&get_class_id_as_smi); 1500 __ lw(T3, Address(T3));
1500 __ delay_slot()->lw(T3, Address(T3)); 1501 __ LoadTaggedClassIdMayBeSmi(T3, T3);
1501 } 1502 }
1502 1503
1503 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; 1504 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize;
1504 __ AddImmediate(T0, entry_size); // Next entry. 1505 __ AddImmediate(T0, entry_size); // Next entry.
1505 __ lw(T4, Address(T0)); // Next class ID. 1506 __ lw(T4, Address(T0)); // Next class ID.
1506 1507
1507 __ Bind(&test); 1508 __ Bind(&test);
1508 __ BranchNotEqual(T4, Smi::RawValue(kIllegalCid), &loop); // Done? 1509 __ BranchNotEqual(T4, Smi::RawValue(kIllegalCid), &loop); // Done?
1509 1510
1510 // IC miss. 1511 // IC miss.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1565 __ LoadImmediate(T1, Smi::RawValue(Smi::kMaxValue)); 1566 __ LoadImmediate(T1, Smi::RawValue(Smi::kMaxValue));
1566 __ sw(T1, Address(T0, count_offset)); 1567 __ sw(T1, Address(T0, count_offset));
1567 1568
1568 __ Bind(&call_target_function); 1569 __ Bind(&call_target_function);
1569 // T0 <- T3: Target function. 1570 // T0 <- T3: Target function.
1570 __ mov(T0, T3); 1571 __ mov(T0, T3);
1571 Label is_compiled; 1572 Label is_compiled;
1572 __ lw(T4, FieldAddress(T0, Function::instructions_offset())); 1573 __ lw(T4, FieldAddress(T0, Function::instructions_offset()));
1573 __ AddImmediate(T4, Instructions::HeaderSize() - kHeapObjectTag); 1574 __ AddImmediate(T4, Instructions::HeaderSize() - kHeapObjectTag);
1574 __ jr(T4); 1575 __ jr(T4);
1575
1576 // Instance in T3, return its class-id in T3 as Smi.
1577 __ Bind(&get_class_id_as_smi);
1578 Label not_smi;
1579 // Test if Smi -> load Smi class for comparison.
1580 __ andi(CMPRES1, T3, Immediate(kSmiTagMask));
1581 __ bne(CMPRES1, ZR, &not_smi);
1582 __ jr(RA);
1583 __ delay_slot()->addiu(T3, ZR, Immediate(Smi::RawValue(kSmiCid)));
1584
1585 __ Bind(&not_smi);
1586 __ LoadClassId(T3, T3);
1587 __ jr(RA);
1588 __ delay_slot()->SmiTag(T3);
1589 } 1576 }
1590 1577
1591 1578
1592 // Use inline cache data array to invoke the target or continue in inline 1579 // Use inline cache data array to invoke the target or continue in inline
1593 // cache miss handler. Stub for 1-argument check (receiver class). 1580 // cache miss handler. Stub for 1-argument check (receiver class).
1594 // RA: Return address. 1581 // RA: Return address.
1595 // S5: Inline cache data object. 1582 // S5: Inline cache data object.
1596 // Inline cache data object structure: 1583 // Inline cache data object structure:
1597 // 0: function-name 1584 // 0: function-name
1598 // 1: N, number of arguments checked. 1585 // 1: N, number of arguments checked.
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
2092 const Register right = T0; 2079 const Register right = T0;
2093 __ lw(left, Address(SP, 1 * kWordSize)); 2080 __ lw(left, Address(SP, 1 * kWordSize));
2094 __ lw(right, Address(SP, 0 * kWordSize)); 2081 __ lw(right, Address(SP, 0 * kWordSize));
2095 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); 2082 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2);
2096 __ Ret(); 2083 __ Ret();
2097 } 2084 }
2098 2085
2099 } // namespace dart 2086 } // namespace dart
2100 2087
2101 #endif // defined TARGET_ARCH_MIPS 2088 #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