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

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

Issue 815173002: Add code comments to inline cache stubs. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years 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 1333 matching lines...) Expand 10 before | Expand all | Expand 10 after
1344 1344
1345 1345
1346 // Note: S5 must be preserved. 1346 // Note: S5 must be preserved.
1347 // Attempt a quick Smi operation for known operations ('kind'). The ICData 1347 // Attempt a quick Smi operation for known operations ('kind'). The ICData
1348 // must have been primed with a Smi/Smi check that will be used for counting 1348 // must have been primed with a Smi/Smi check that will be used for counting
1349 // the invocations. 1349 // the invocations.
1350 static void EmitFastSmiOp(Assembler* assembler, 1350 static void EmitFastSmiOp(Assembler* assembler,
1351 Token::Kind kind, 1351 Token::Kind kind,
1352 intptr_t num_args, 1352 intptr_t num_args,
1353 Label* not_smi_or_overflow) { 1353 Label* not_smi_or_overflow) {
1354 __ Comment("Fast Smi op");
1354 ASSERT(num_args == 2); 1355 ASSERT(num_args == 2);
1355 __ lw(T0, Address(SP, 0 * kWordSize)); // Left. 1356 __ lw(T0, Address(SP, 0 * kWordSize)); // Left.
1356 __ lw(T1, Address(SP, 1 * kWordSize)); // Right. 1357 __ lw(T1, Address(SP, 1 * kWordSize)); // Right.
1357 __ or_(CMPRES1, T0, T1); 1358 __ or_(CMPRES1, T0, T1);
1358 __ andi(CMPRES1, CMPRES1, Immediate(kSmiTagMask)); 1359 __ andi(CMPRES1, CMPRES1, Immediate(kSmiTagMask));
1359 __ bne(CMPRES1, ZR, not_smi_or_overflow); 1360 __ bne(CMPRES1, ZR, not_smi_or_overflow);
1360 switch (kind) { 1361 switch (kind) {
1361 case Token::kADD: { 1362 case Token::kADD: {
1362 __ AdduDetectOverflow(V0, T1, T0, CMPRES1); // Add. 1363 __ AdduDetectOverflow(V0, T1, T0, CMPRES1); // Add.
1363 __ bltz(CMPRES1, not_smi_or_overflow); // Fall through on overflow. 1364 __ bltz(CMPRES1, not_smi_or_overflow); // Fall through on overflow.
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 __ lw(T0, FieldAddress(S5, ICData::state_bits_offset())); 1436 __ lw(T0, FieldAddress(S5, ICData::state_bits_offset()));
1436 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. 1437 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed.
1437 __ andi(T0, T0, Immediate(ICData::NumArgsTestedMask())); 1438 __ andi(T0, T0, Immediate(ICData::NumArgsTestedMask()));
1438 __ BranchEqual(T0, Immediate(num_args), &ok); 1439 __ BranchEqual(T0, Immediate(num_args), &ok);
1439 __ Stop("Incorrect stub for IC data"); 1440 __ Stop("Incorrect stub for IC data");
1440 __ Bind(&ok); 1441 __ Bind(&ok);
1441 } 1442 }
1442 #endif // DEBUG 1443 #endif // DEBUG
1443 1444
1444 1445
1445 // Check single stepping. 1446 __ Comment("Check single stepping");
1446 Label stepping, done_stepping; 1447 Label stepping, done_stepping;
1447 __ LoadIsolate(T0); 1448 __ LoadIsolate(T0);
1448 __ lbu(T0, Address(T0, Isolate::single_step_offset())); 1449 __ lbu(T0, Address(T0, Isolate::single_step_offset()));
1449 __ BranchNotEqual(T0, Immediate(0), &stepping); 1450 __ BranchNotEqual(T0, Immediate(0), &stepping);
1450 __ Bind(&done_stepping); 1451 __ Bind(&done_stepping);
1451 1452
1453 __ Comment("Range feedback collection");
1452 Label not_smi_or_overflow; 1454 Label not_smi_or_overflow;
1453 if (range_collection_mode == kCollectRanges) { 1455 if (range_collection_mode == kCollectRanges) {
1454 ASSERT((num_args == 1) || (num_args == 2)); 1456 ASSERT((num_args == 1) || (num_args == 2));
1455 if (num_args == 2) { 1457 if (num_args == 2) {
1456 __ lw(T0, Address(SP, 1 * kWordSize)); 1458 __ lw(T0, Address(SP, 1 * kWordSize));
1457 __ UpdateRangeFeedback(T0, 0, S5, T1, &not_smi_or_overflow); 1459 __ UpdateRangeFeedback(T0, 0, S5, T1, &not_smi_or_overflow);
1458 } 1460 }
1459 1461
1460 __ lw(T0, Address(SP, 0 * kWordSize)); 1462 __ lw(T0, Address(SP, 0 * kWordSize));
1461 __ UpdateRangeFeedback(T0, num_args - 1, S5, T1, &not_smi_or_overflow); 1463 __ UpdateRangeFeedback(T0, num_args - 1, S5, T1, &not_smi_or_overflow);
1462 } 1464 }
1463 if (kind != Token::kILLEGAL) { 1465 if (kind != Token::kILLEGAL) {
1464 EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow); 1466 EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
1465 } 1467 }
1466 __ Bind(&not_smi_or_overflow); 1468 __ Bind(&not_smi_or_overflow);
1467 1469
1470 __ Comment("Extract ICData initial values and receiver cid");
1468 // Load argument descriptor into S4. 1471 // Load argument descriptor into S4.
1469 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset())); 1472 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset()));
1470 // Preserve return address, since RA is needed for subroutine call. 1473 // Preserve return address, since RA is needed for subroutine call.
1471 __ mov(T2, RA); 1474 __ mov(T2, RA);
1472 // Loop that checks if there is an IC data match. 1475 // Loop that checks if there is an IC data match.
1473 Label loop, update, test, found; 1476 Label loop, update, test, found;
1474 // S5: IC data object (preserved). 1477 // S5: IC data object (preserved).
1475 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset())); 1478 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset()));
1476 // T0: ic_data_array with check entries: classes and target functions. 1479 // T0: ic_data_array with check entries: classes and target functions.
1477 __ AddImmediate(T0, Array::data_offset() - kHeapObjectTag); 1480 __ AddImmediate(T0, Array::data_offset() - kHeapObjectTag);
1478 // T0: points directly to the first ic data array element. 1481 // T0: points directly to the first ic data array element.
1479 1482
1480 // Get the receiver's class ID (first read number of arguments from 1483 // Get the receiver's class ID (first read number of arguments from
1481 // arguments descriptor array and then access the receiver from the stack). 1484 // arguments descriptor array and then access the receiver from the stack).
1482 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); 1485 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset()));
1483 __ LoadImmediate(TMP, Smi::RawValue(1)); 1486 __ LoadImmediate(TMP, Smi::RawValue(1));
1484 __ subu(T1, T1, TMP); 1487 __ subu(T1, T1, TMP);
1485 __ sll(T3, T1, 1); // T1 (argument_count - 1) is smi. 1488 __ sll(T3, T1, 1); // T1 (argument_count - 1) is smi.
1486 __ addu(T3, T3, SP); 1489 __ addu(T3, T3, SP);
1487 __ lw(T3, Address(T3)); 1490 __ lw(T3, Address(T3));
1488 __ LoadTaggedClassIdMayBeSmi(T3, T3); 1491 __ LoadTaggedClassIdMayBeSmi(T3, T3);
1489 1492
1490 // T1: argument_count - 1 (smi). 1493 // T1: argument_count - 1 (smi).
1491 // T3: receiver's class ID (smi). 1494 // T3: receiver's class ID (smi).
1492 __ b(&test); 1495 __ b(&test);
1493 __ delay_slot()->lw(T4, Address(T0)); // First class id (smi) to check. 1496 __ delay_slot()->lw(T4, Address(T0)); // First class id (smi) to check.
1494 1497
1498 __ Comment("ICData loop");
1495 __ Bind(&loop); 1499 __ Bind(&loop);
1496 for (int i = 0; i < num_args; i++) { 1500 for (int i = 0; i < num_args; i++) {
1497 if (i > 0) { 1501 if (i > 0) {
1498 // If not the first, load the next argument's class ID. 1502 // If not the first, load the next argument's class ID.
1499 __ LoadImmediate(T3, Smi::RawValue(-i)); 1503 __ LoadImmediate(T3, Smi::RawValue(-i));
1500 __ addu(T3, T1, T3); 1504 __ addu(T3, T1, T3);
1501 __ sll(T3, T3, 1); 1505 __ sll(T3, T3, 1);
1502 __ addu(T3, SP, T3); 1506 __ addu(T3, SP, T3);
1503 __ lw(T3, Address(T3)); 1507 __ lw(T3, Address(T3));
1504 __ LoadTaggedClassIdMayBeSmi(T3, T3); 1508 __ LoadTaggedClassIdMayBeSmi(T3, T3);
(...skipping 21 matching lines...) Expand all
1526 __ LoadTaggedClassIdMayBeSmi(T3, T3); 1530 __ LoadTaggedClassIdMayBeSmi(T3, T3);
1527 } 1531 }
1528 1532
1529 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; 1533 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize;
1530 __ AddImmediate(T0, entry_size); // Next entry. 1534 __ AddImmediate(T0, entry_size); // Next entry.
1531 __ lw(T4, Address(T0)); // Next class ID. 1535 __ lw(T4, Address(T0)); // Next class ID.
1532 1536
1533 __ Bind(&test); 1537 __ Bind(&test);
1534 __ BranchNotEqual(T4, Immediate(Smi::RawValue(kIllegalCid)), &loop); // Done? 1538 __ BranchNotEqual(T4, Immediate(Smi::RawValue(kIllegalCid)), &loop); // Done?
1535 1539
1536 // IC miss. 1540 __ Comment("IC miss");
1537 // Restore return address. 1541 // Restore return address.
1538 __ mov(RA, T2); 1542 __ mov(RA, T2);
1539 1543
1540 // Compute address of arguments (first read number of arguments from 1544 // Compute address of arguments (first read number of arguments from
1541 // arguments descriptor array and then compute address on the stack). 1545 // arguments descriptor array and then compute address on the stack).
1542 // T1: argument_count - 1 (smi). 1546 // T1: argument_count - 1 (smi).
1543 __ sll(T1, T1, 1); // T1 is Smi. 1547 __ sll(T1, T1, 1); // T1 is Smi.
1544 __ addu(T1, SP, T1); 1548 __ addu(T1, SP, T1);
1545 // T1: address of receiver. 1549 // T1: address of receiver.
1546 // Create a stub frame as we are pushing some objects on the stack before 1550 // Create a stub frame as we are pushing some objects on the stack before
(...skipping 23 matching lines...) Expand all
1570 __ lw(S5, Address(SP, (num_slots - 1) * kWordSize)); 1574 __ lw(S5, Address(SP, (num_slots - 1) * kWordSize));
1571 // Remove the call arguments pushed earlier, including the IC data object 1575 // Remove the call arguments pushed earlier, including the IC data object
1572 // and the arguments descriptor array. 1576 // and the arguments descriptor array.
1573 __ addiu(SP, SP, Immediate(num_slots * kWordSize)); 1577 __ addiu(SP, SP, Immediate(num_slots * kWordSize));
1574 __ LeaveStubFrame(); 1578 __ LeaveStubFrame();
1575 1579
1576 Label call_target_function; 1580 Label call_target_function;
1577 __ b(&call_target_function); 1581 __ b(&call_target_function);
1578 1582
1579 __ Bind(&found); 1583 __ Bind(&found);
1584 __ Comment("Update caller's counter");
1580 // T0: Pointer to an IC data check group. 1585 // T0: Pointer to an IC data check group.
1581 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; 1586 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
1582 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; 1587 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
1583 __ lw(T3, Address(T0, target_offset)); 1588 __ lw(T3, Address(T0, target_offset));
1584 1589
1585 // Update counter. 1590 // Update counter.
1586 __ lw(T4, Address(T0, count_offset)); 1591 __ lw(T4, Address(T0, count_offset));
1587 __ AddImmediateDetectOverflow(T7, T4, Smi::RawValue(1), T5, T6); 1592 __ AddImmediateDetectOverflow(T7, T4, Smi::RawValue(1), T5, T6);
1588 __ slt(CMPRES1, T5, ZR); // T5 is < 0 if there was overflow. 1593 __ slt(CMPRES1, T5, ZR); // T5 is < 0 if there was overflow.
1589 __ LoadImmediate(T4, Smi::RawValue(Smi::kMaxValue)); 1594 __ LoadImmediate(T4, Smi::RawValue(Smi::kMaxValue));
1590 __ movz(T4, T7, CMPRES1); 1595 __ movz(T4, T7, CMPRES1);
1591 __ sw(T4, Address(T0, count_offset)); 1596 __ sw(T4, Address(T0, count_offset));
1592 1597
1598 __ Comment("Call target");
1593 __ Bind(&call_target_function); 1599 __ Bind(&call_target_function);
1594 // T0 <- T3: Target function. 1600 // T0 <- T3: Target function.
1595 __ mov(T0, T3); 1601 __ mov(T0, T3);
1596 Label is_compiled; 1602 Label is_compiled;
1597 __ lw(T4, FieldAddress(T0, Function::instructions_offset())); 1603 __ lw(T4, FieldAddress(T0, Function::instructions_offset()));
1598 __ AddImmediate(T4, Instructions::HeaderSize() - kHeapObjectTag); 1604 __ AddImmediate(T4, Instructions::HeaderSize() - kHeapObjectTag);
1599 if (range_collection_mode == kCollectRanges) { 1605 if (range_collection_mode == kCollectRanges) {
1600 const intptr_t frame_size = num_args + 2; 1606 const intptr_t frame_size = num_args + 2;
1601 __ lw(T3, Address(SP, 0 * kWordSize)); 1607 __ lw(T3, Address(SP, 0 * kWordSize));
1602 if (num_args == 2) { 1608 if (num_args == 2) {
(...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after
2241 const Register right = T0; 2247 const Register right = T0;
2242 __ lw(left, Address(SP, 1 * kWordSize)); 2248 __ lw(left, Address(SP, 1 * kWordSize));
2243 __ lw(right, Address(SP, 0 * kWordSize)); 2249 __ lw(right, Address(SP, 0 * kWordSize));
2244 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); 2250 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2);
2245 __ Ret(); 2251 __ Ret();
2246 } 2252 }
2247 2253
2248 } // namespace dart 2254 } // namespace dart
2249 2255
2250 #endif // defined TARGET_ARCH_MIPS 2256 #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