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

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

Issue 2809583002: Use off-heap data for type feedback in PolymorphicInstanceCallInstr (Closed)
Patch Set: More feedback from Slava Created 3 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
« no previous file with comments | « runtime/vm/flow_graph_compiler.cc ('k') | runtime/vm/flow_graph_compiler_arm64.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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
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 1195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1206 LocationSummary* locs) { 1206 LocationSummary* locs) {
1207 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0); 1207 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
1208 __ LoadUniqueObject(R9, ic_data); 1208 __ LoadUniqueObject(R9, ic_data);
1209 GenerateDartCall(deopt_id, token_pos, stub_entry, RawPcDescriptors::kIcCall, 1209 GenerateDartCall(deopt_id, token_pos, stub_entry, RawPcDescriptors::kIcCall,
1210 locs); 1210 locs);
1211 __ Drop(argument_count); 1211 __ Drop(argument_count);
1212 } 1212 }
1213 1213
1214 1214
1215 void FlowGraphCompiler::EmitMegamorphicInstanceCall( 1215 void FlowGraphCompiler::EmitMegamorphicInstanceCall(
1216 const ICData& ic_data, 1216 const String& name,
1217 const Array& arguments_descriptor,
1217 intptr_t argument_count, 1218 intptr_t argument_count,
1218 intptr_t deopt_id, 1219 intptr_t deopt_id,
1219 TokenPosition token_pos, 1220 TokenPosition token_pos,
1220 LocationSummary* locs, 1221 LocationSummary* locs,
1221 intptr_t try_index, 1222 intptr_t try_index,
1222 intptr_t slow_path_argument_count) { 1223 intptr_t slow_path_argument_count) {
1223 const String& name = String::Handle(zone(), ic_data.target_name());
1224 const Array& arguments_descriptor =
1225 Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
1226 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); 1224 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
1227 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle( 1225 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
1228 zone(), 1226 zone(),
1229 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor)); 1227 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
1230 1228
1231 __ Comment("MegamorphicCall"); 1229 __ Comment("MegamorphicCall");
1232 // Load receiver into R0. 1230 // Load receiver into R0.
1233 __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize); 1231 __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
1234 __ LoadObject(R9, cache); 1232 __ LoadObject(R9, cache);
1235 __ ldr(LR, Address(THR, Thread::megamorphic_call_checked_entry_offset())); 1233 __ ldr(LR, Address(THR, Thread::megamorphic_call_checked_entry_offset()));
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1473 // TODO(zerny): clobber non-live temporary FPU registers. 1471 // TODO(zerny): clobber non-live temporary FPU registers.
1474 if (tmp.IsRegister() && 1472 if (tmp.IsRegister() &&
1475 !locs->live_registers()->ContainsRegister(tmp.reg())) { 1473 !locs->live_registers()->ContainsRegister(tmp.reg())) {
1476 __ mov(tmp.reg(), Operand(0xf7)); 1474 __ mov(tmp.reg(), Operand(0xf7));
1477 } 1475 }
1478 } 1476 }
1479 } 1477 }
1480 #endif 1478 #endif
1481 1479
1482 1480
1483 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, 1481 void FlowGraphCompiler::EmitTestAndCallLoadReceiver(
1484 intptr_t argument_count, 1482 intptr_t argument_count,
1485 const Array& argument_names, 1483 const Array& arguments_descriptor) {
1486 Label* failed,
1487 Label* match_found,
1488 intptr_t deopt_id,
1489 TokenPosition token_index,
1490 LocationSummary* locs,
1491 bool complete,
1492 intptr_t total_ic_calls) {
1493 ASSERT(is_optimizing());
1494 __ Comment("EmitTestAndCall"); 1484 __ Comment("EmitTestAndCall");
1495 const Array& arguments_descriptor = Array::ZoneHandle(
1496 zone(), ArgumentsDescriptor::New(argument_count, argument_names));
1497
1498 // Load receiver into R0. 1485 // Load receiver into R0.
1499 __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize); 1486 __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
1500 __ LoadObject(R4, arguments_descriptor); 1487 __ LoadObject(R4, arguments_descriptor);
1501
1502 const bool kFirstCheckIsSmi = ic_data.GetReceiverClassIdAt(0) == kSmiCid;
1503 const intptr_t num_checks = ic_data.NumberOfChecks();
1504
1505 ASSERT(!ic_data.IsNull() && (num_checks > 0));
1506
1507 Label after_smi_test;
1508 if (kFirstCheckIsSmi) {
1509 __ tst(R0, Operand(kSmiTagMask));
1510 // Jump if receiver is not Smi.
1511 if (num_checks == 1) {
1512 __ b(failed, NE);
1513 } else {
1514 __ b(&after_smi_test, NE);
1515 }
1516 // Do not use the code from the function, but let the code be patched so
1517 // that we can record the outgoing edges to other code.
1518 const Function& function =
1519 Function::ZoneHandle(zone(), ic_data.GetTargetAt(0));
1520 GenerateStaticDartCall(deopt_id, token_index,
1521 *StubCode::CallStaticFunction_entry(),
1522 RawPcDescriptors::kOther, locs, function);
1523 __ Drop(argument_count);
1524 if (num_checks > 1) {
1525 __ b(match_found);
1526 }
1527 } else {
1528 // Receiver is Smi, but Smi is not a valid class therefore fail.
1529 // (Smi class must be first in the list).
1530 if (!complete) {
1531 __ tst(R0, Operand(kSmiTagMask));
1532 __ b(failed, EQ);
1533 }
1534 }
1535 __ Bind(&after_smi_test);
1536
1537 ASSERT(!ic_data.IsNull() && (num_checks > 0));
1538 GrowableArray<CidRangeTarget> sorted(num_checks);
1539 SortICDataByCount(ic_data, &sorted, /* drop_smi = */ true);
1540
1541 const intptr_t sorted_len = sorted.length();
1542 // If sorted_len is 0 then only a Smi check was needed; the Smi check above
1543 // will fail if there was only one check and receiver is not Smi.
1544 if (sorted_len == 0) return;
1545
1546 // Value is not Smi,
1547 __ LoadClassId(R2, R0);
1548
1549 bool add_megamorphic_call = false;
1550 const int kMaxImmediateInInstruction = 256;
1551 int bias =
1552 ComputeGoodBiasForCidComparison(sorted, kMaxImmediateInInstruction);
1553 if (bias != 0) __ AddImmediate(R2, R2, -bias);
1554
1555 for (intptr_t i = 0; i < sorted_len; i++) {
1556 const bool is_last_check = (i == (sorted_len - 1));
1557 int cid_start = sorted[i].cid_start;
1558 int cid_end = sorted[i].cid_end;
1559 int count = sorted[i].count;
1560 if (!is_last_check && !complete && count < (total_ic_calls >> 5)) {
1561 // This case is hit too rarely to be worth writing class-id checks inline
1562 // for.
1563 add_megamorphic_call = true;
1564 break;
1565 }
1566 ASSERT(cid_start > kSmiCid || cid_end < kSmiCid);
1567 Label next_test;
1568 if (!complete || !is_last_check) {
1569 Label* next_label = is_last_check ? failed : &next_test;
1570 if (cid_start == cid_end) {
1571 __ CompareImmediate(R2, cid_start - bias);
1572 __ b(next_label, NE);
1573 } else {
1574 __ AddImmediate(R2, R2, bias - cid_start);
1575 bias = cid_start;
1576 __ CompareImmediate(R2, cid_end - cid_start);
1577 __ b(next_label, HI); // Unsigned higher.
1578 }
1579 }
1580 // Do not use the code from the function, but let the code be patched so
1581 // that we can record the outgoing edges to other code.
1582 const Function& function = *sorted[i].target;
1583 GenerateStaticDartCall(deopt_id, token_index,
1584 *StubCode::CallStaticFunction_entry(),
1585 RawPcDescriptors::kOther, locs, function);
1586 __ Drop(argument_count);
1587 if (!is_last_check) {
1588 __ b(match_found);
1589 }
1590 __ Bind(&next_test);
1591 }
1592 if (add_megamorphic_call) {
1593 int try_index = CatchClauseNode::kInvalidTryIndex;
1594 EmitMegamorphicInstanceCall(ic_data, argument_count, deopt_id, token_index,
1595 locs, try_index, argument_count);
1596 }
1597 } 1488 }
1598 1489
1599 1490
1491 void FlowGraphCompiler::EmitTestAndCallSmiBranch(Label* label, bool if_smi) {
1492 __ tst(R0, Operand(kSmiTagMask));
1493 // Jump if receiver is not Smi.
1494 __ b(label, if_smi ? EQ : NE);
1495 }
1496
1497
1498 void FlowGraphCompiler::EmitTestAndCallLoadCid() {
1499 __ LoadClassId(R2, R0);
1500 }
1501
1502
1503 int FlowGraphCompiler::EmitTestAndCallCheckCid(Label* next_label,
1504 const CidRangeTarget& target,
1505 int bias) {
1506 intptr_t cid_start = target.cid_start;
1507 intptr_t cid_end = target.cid_end;
1508 if (cid_start == cid_end) {
1509 __ CompareImmediate(R2, cid_start - bias);
1510 __ b(next_label, NE);
1511 } else {
1512 __ AddImmediate(R2, R2, bias - cid_start);
1513 bias = cid_start;
1514 __ CompareImmediate(R2, cid_end - cid_start);
1515 __ b(next_label, HI); // Unsigned higher.
1516 }
1517 return bias;
1518 }
1519
1520
1600 #undef __ 1521 #undef __
1601 #define __ compiler_->assembler()-> 1522 #define __ compiler_->assembler()->
1602 1523
1603 1524
1604 void ParallelMoveResolver::EmitMove(int index) { 1525 void ParallelMoveResolver::EmitMove(int index) {
1605 MoveOperands* move = moves_[index]; 1526 MoveOperands* move = moves_[index];
1606 const Location source = move->src(); 1527 const Location source = move->src();
1607 const Location destination = move->dest(); 1528 const Location destination = move->dest();
1608 1529
1609 if (source.IsRegister()) { 1530 if (source.IsRegister()) {
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
1889 DRegister dreg = EvenDRegisterOf(reg); 1810 DRegister dreg = EvenDRegisterOf(reg);
1890 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex)); 1811 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex));
1891 } 1812 }
1892 1813
1893 1814
1894 #undef __ 1815 #undef __
1895 1816
1896 } // namespace dart 1817 } // namespace dart
1897 1818
1898 #endif // defined TARGET_ARCH_ARM 1819 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler.cc ('k') | runtime/vm/flow_graph_compiler_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698