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

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

Issue 2842753002: Reland "Use off-heap data for type feedback in PolymorphicInstanceCallInstr" (Closed)
Patch Set: Fix AOT case Created 3 years, 7 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
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.cc ('k') | runtime/vm/flow_graph_compiler_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/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "vm/ast_printer.h" 10 #include "vm/ast_printer.h"
(...skipping 1231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1242 __ Comment("InstanceCall"); 1242 __ Comment("InstanceCall");
1243 __ LoadUniqueObject(S5, ic_data); 1243 __ LoadUniqueObject(S5, ic_data);
1244 GenerateDartCall(deopt_id, token_pos, stub_entry, RawPcDescriptors::kIcCall, 1244 GenerateDartCall(deopt_id, token_pos, stub_entry, RawPcDescriptors::kIcCall,
1245 locs); 1245 locs);
1246 __ Comment("InstanceCall return"); 1246 __ Comment("InstanceCall return");
1247 __ Drop(argument_count); 1247 __ Drop(argument_count);
1248 } 1248 }
1249 1249
1250 1250
1251 void FlowGraphCompiler::EmitMegamorphicInstanceCall( 1251 void FlowGraphCompiler::EmitMegamorphicInstanceCall(
1252 const ICData& ic_data, 1252 const String& name,
1253 const Array& arguments_descriptor,
1253 intptr_t argument_count, 1254 intptr_t argument_count,
1254 intptr_t deopt_id, 1255 intptr_t deopt_id,
1255 TokenPosition token_pos, 1256 TokenPosition token_pos,
1256 LocationSummary* locs, 1257 LocationSummary* locs,
1257 intptr_t try_index, 1258 intptr_t try_index,
1258 intptr_t slow_path_argument_count) { 1259 intptr_t slow_path_argument_count) {
1259 const String& name = String::Handle(zone(), ic_data.target_name());
1260 const Array& arguments_descriptor =
1261 Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
1262 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); 1260 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
1263 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle( 1261 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
1264 zone(), 1262 zone(),
1265 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor)); 1263 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
1266 1264
1267 __ Comment("MegamorphicCall"); 1265 __ Comment("MegamorphicCall");
1268 // Load receiver into T0, 1266 // Load receiver into T0,
1269 __ lw(T0, Address(SP, (argument_count - 1) * kWordSize)); 1267 __ lw(T0, Address(SP, (argument_count - 1) * kWordSize));
1270 __ LoadObject(S5, cache); 1268 __ LoadObject(S5, cache);
1271 __ lw(T9, Address(THR, Thread::megamorphic_call_checked_entry_offset())); 1269 __ lw(T9, Address(THR, Thread::megamorphic_call_checked_entry_offset()));
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 // TODO(zerny): clobber non-live temporary FPU registers. 1523 // TODO(zerny): clobber non-live temporary FPU registers.
1526 if (tmp.IsRegister() && 1524 if (tmp.IsRegister() &&
1527 !locs->live_registers()->ContainsRegister(tmp.reg())) { 1525 !locs->live_registers()->ContainsRegister(tmp.reg())) {
1528 __ LoadImmediate(tmp.reg(), 0xf7); 1526 __ LoadImmediate(tmp.reg(), 0xf7);
1529 } 1527 }
1530 } 1528 }
1531 } 1529 }
1532 #endif 1530 #endif
1533 1531
1534 1532
1535 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, 1533 void FlowGraphCompiler::EmitTestAndCallLoadReceiver(
1536 intptr_t argument_count, 1534 intptr_t argument_count,
1537 const Array& argument_names, 1535 const Array& arguments_descriptor) {
1538 Label* failed,
1539 Label* match_found,
1540 intptr_t deopt_id,
1541 TokenPosition token_index,
1542 LocationSummary* locs,
1543 bool complete,
1544 intptr_t total_ic_calls) {
1545 ASSERT(is_optimizing());
1546 __ Comment("EmitTestAndCall"); 1536 __ Comment("EmitTestAndCall");
1547 const Array& arguments_descriptor = Array::ZoneHandle(
1548 zone(), ArgumentsDescriptor::New(argument_count, argument_names));
1549
1550 // Load receiver into T0. 1537 // Load receiver into T0.
1551 __ LoadFromOffset(T0, SP, (argument_count - 1) * kWordSize); 1538 __ LoadFromOffset(T0, SP, (argument_count - 1) * kWordSize);
1552 __ LoadObject(S4, arguments_descriptor); 1539 __ LoadObject(S4, arguments_descriptor);
1540 }
1553 1541
1554 const bool kFirstCheckIsSmi = ic_data.GetReceiverClassIdAt(0) == kSmiCid;
1555 const intptr_t num_checks = ic_data.NumberOfChecks();
1556 1542
1557 ASSERT(!ic_data.IsNull() && (num_checks > 0)); 1543 void FlowGraphCompiler::EmitTestAndCallSmiBranch(Label* label, bool if_smi) {
1558 1544 __ andi(CMPRES1, T0, Immediate(kSmiTagMask));
1559 Label after_smi_test; 1545 if (if_smi) {
1560 if (kFirstCheckIsSmi) { 1546 // Jump if receiver is Smi.
1561 __ andi(CMPRES1, T0, Immediate(kSmiTagMask)); 1547 __ beq(CMPRES1, ZR, label);
1548 } else {
1562 // Jump if receiver is not Smi. 1549 // Jump if receiver is not Smi.
1563 if (num_checks == 1) { 1550 __ bne(CMPRES1, ZR, label);
1564 __ bne(CMPRES1, ZR, failed);
1565 } else {
1566 __ bne(CMPRES1, ZR, &after_smi_test);
1567 }
1568 // Do not use the code from the function, but let the code be patched so
1569 // that we can record the outgoing edges to other code.
1570 const Function& function =
1571 Function::ZoneHandle(zone(), ic_data.GetTargetAt(0));
1572 GenerateStaticDartCall(deopt_id, token_index,
1573 *StubCode::CallStaticFunction_entry(),
1574 RawPcDescriptors::kOther, locs, function);
1575 __ Drop(argument_count);
1576 if (num_checks > 1) {
1577 __ b(match_found);
1578 }
1579 } else {
1580 // Receiver is Smi, but Smi is not a valid class therefore fail.
1581 // (Smi class must be first in the list).
1582 if (!complete) {
1583 __ andi(CMPRES1, T0, Immediate(kSmiTagMask));
1584 __ beq(CMPRES1, ZR, failed);
1585 }
1586 }
1587
1588 __ Bind(&after_smi_test);
1589
1590 ASSERT(!ic_data.IsNull() && (num_checks > 0));
1591 GrowableArray<CidRangeTarget> sorted(num_checks);
1592 SortICDataByCount(ic_data, &sorted, /* drop_smi = */ true);
1593
1594 const intptr_t sorted_len = sorted.length();
1595 // If sorted_len is 0 then only a Smi check was needed; the Smi check above
1596 // will fail if there was only one check and receiver is not Smi.
1597 if (sorted_len == 0) return;
1598
1599 // Value is not Smi,
1600 __ LoadClassId(T2, T0);
1601
1602 bool add_megamorphic_call = false;
1603 int bias = 0;
1604
1605 for (intptr_t i = 0; i < sorted_len; i++) {
1606 const bool is_last_check = (i == (sorted_len - 1));
1607 int cid_start = sorted[i].cid_start;
1608 int cid_end = sorted[i].cid_end;
1609 int count = sorted[i].count;
1610 if (!is_last_check && !complete && count < (total_ic_calls >> 5)) {
1611 // This case is hit too rarely to be worth writing class-id checks inline
1612 // for.
1613 add_megamorphic_call = true;
1614 break;
1615 }
1616 ASSERT(cid_start > kSmiCid || cid_end < kSmiCid);
1617 Label next_test;
1618 Condition no_match;
1619 if (!complete || !is_last_check) {
1620 Label* next_label = is_last_check ? failed : &next_test;
1621 if (cid_start == cid_end) {
1622 __ BranchNotEqual(T2, Immediate(cid_start - bias), next_label);
1623 } else {
1624 __ AddImmediate(T2, T2, bias - cid_start);
1625 bias = cid_start;
1626 // TODO(erikcorry): We should use sltiu instead of the temporary TMP if
1627 // the range is small enough.
1628 __ LoadImmediate(TMP, cid_end - cid_end);
1629 // Reverse comparison so we get 1 if biased cid > tmp ie cid is out of
1630 // range.
1631 __ sltu(TMP, TMP, T2);
1632 __ bne(TMP, ZR, next_label);
1633 }
1634 }
1635 // Do not use the code from the function, but let the code be patched so
1636 // that we can record the outgoing edges to other code.
1637 const Function& function = *sorted[i].target;
1638 GenerateStaticDartCall(deopt_id, token_index,
1639 *StubCode::CallStaticFunction_entry(),
1640 RawPcDescriptors::kOther, locs, function);
1641 __ Drop(argument_count);
1642 if (!is_last_check) {
1643 __ b(match_found);
1644 }
1645 __ Bind(&next_test);
1646 }
1647 if (add_megamorphic_call) {
1648 int try_index = CatchClauseNode::kInvalidTryIndex;
1649 EmitMegamorphicInstanceCall(ic_data, argument_count, deopt_id, token_index,
1650 locs, try_index, argument_count);
1651 } 1551 }
1652 } 1552 }
1653 1553
1654 1554
1555 void FlowGraphCompiler::EmitTestAndCallLoadCid() {
1556 __ LoadClassId(T2, T0);
1557 }
1558
1559
1560 int FlowGraphCompiler::EmitTestAndCallCheckCid(Label* next_label,
1561 const CidRangeTarget& target,
1562 int bias) {
1563 intptr_t cid_start = target.cid_start;
1564 intptr_t cid_end = target.cid_end;
1565 if (cid_start == cid_end) {
1566 __ BranchNotEqual(T2, Immediate(cid_start - bias), next_label);
1567 } else {
1568 __ AddImmediate(T2, T2, bias - cid_start);
1569 bias = cid_start;
1570 // TODO(erikcorry): We should use sltiu instead of the temporary TMP if
1571 // the range is small enough.
1572 __ LoadImmediate(TMP, cid_end - cid_end);
1573 // Reverse comparison so we get 1 if biased cid > tmp ie cid is out of
1574 // range.
1575 __ sltu(TMP, TMP, T2);
1576 __ bne(TMP, ZR, next_label);
1577 }
1578 return bias;
1579 }
1580
1581
1655 #undef __ 1582 #undef __
1656 #define __ compiler_->assembler()-> 1583 #define __ compiler_->assembler()->
1657 1584
1658 1585
1659 void ParallelMoveResolver::EmitMove(int index) { 1586 void ParallelMoveResolver::EmitMove(int index) {
1660 MoveOperands* move = moves_[index]; 1587 MoveOperands* move = moves_[index];
1661 const Location source = move->src(); 1588 const Location source = move->src();
1662 const Location destination = move->dest(); 1589 const Location destination = move->dest();
1663 __ Comment("ParallelMoveResolver::EmitMove"); 1590 __ Comment("ParallelMoveResolver::EmitMove");
1664 1591
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
1888 __ AddImmediate(SP, kDoubleSize); 1815 __ AddImmediate(SP, kDoubleSize);
1889 } 1816 }
1890 1817
1891 1818
1892 #undef __ 1819 #undef __
1893 1820
1894 1821
1895 } // namespace dart 1822 } // namespace dart
1896 1823
1897 #endif // defined TARGET_ARCH_MIPS 1824 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.cc ('k') | runtime/vm/flow_graph_compiler_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698