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

Side by Side Diff: runtime/vm/flow_graph_compiler_arm.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.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 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 LocationSummary* locs) { 1232 LocationSummary* locs) {
1233 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0); 1233 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
1234 __ LoadUniqueObject(R9, ic_data); 1234 __ LoadUniqueObject(R9, ic_data);
1235 GenerateDartCall(deopt_id, token_pos, stub_entry, RawPcDescriptors::kIcCall, 1235 GenerateDartCall(deopt_id, token_pos, stub_entry, RawPcDescriptors::kIcCall,
1236 locs); 1236 locs);
1237 __ Drop(argument_count); 1237 __ Drop(argument_count);
1238 } 1238 }
1239 1239
1240 1240
1241 void FlowGraphCompiler::EmitMegamorphicInstanceCall( 1241 void FlowGraphCompiler::EmitMegamorphicInstanceCall(
1242 const ICData& ic_data, 1242 const String& name,
1243 const Array& arguments_descriptor,
1243 intptr_t argument_count, 1244 intptr_t argument_count,
1244 intptr_t deopt_id, 1245 intptr_t deopt_id,
1245 TokenPosition token_pos, 1246 TokenPosition token_pos,
1246 LocationSummary* locs, 1247 LocationSummary* locs,
1247 intptr_t try_index, 1248 intptr_t try_index,
1248 intptr_t slow_path_argument_count) { 1249 intptr_t slow_path_argument_count) {
1249 const String& name = String::Handle(zone(), ic_data.target_name());
1250 const Array& arguments_descriptor =
1251 Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
1252 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); 1250 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
1253 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle( 1251 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
1254 zone(), 1252 zone(),
1255 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor)); 1253 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
1256 1254
1257 __ Comment("MegamorphicCall"); 1255 __ Comment("MegamorphicCall");
1258 // Load receiver into R0. 1256 // Load receiver into R0.
1259 __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize); 1257 __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
1260 __ LoadObject(R9, cache); 1258 __ LoadObject(R9, cache);
1261 __ ldr(LR, Address(THR, Thread::megamorphic_call_checked_entry_offset())); 1259 __ ldr(LR, Address(THR, Thread::megamorphic_call_checked_entry_offset()));
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1495 // TODO(zerny): clobber non-live temporary FPU registers. 1493 // TODO(zerny): clobber non-live temporary FPU registers.
1496 if (tmp.IsRegister() && 1494 if (tmp.IsRegister() &&
1497 !locs->live_registers()->ContainsRegister(tmp.reg())) { 1495 !locs->live_registers()->ContainsRegister(tmp.reg())) {
1498 __ mov(tmp.reg(), Operand(0xf7)); 1496 __ mov(tmp.reg(), Operand(0xf7));
1499 } 1497 }
1500 } 1498 }
1501 } 1499 }
1502 #endif 1500 #endif
1503 1501
1504 1502
1505 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, 1503 void FlowGraphCompiler::EmitTestAndCallLoadReceiver(
1506 intptr_t argument_count, 1504 intptr_t argument_count,
1507 const Array& argument_names, 1505 const Array& arguments_descriptor) {
1508 Label* failed,
1509 Label* match_found,
1510 intptr_t deopt_id,
1511 TokenPosition token_index,
1512 LocationSummary* locs,
1513 bool complete,
1514 intptr_t total_ic_calls) {
1515 ASSERT(is_optimizing());
1516 __ Comment("EmitTestAndCall"); 1506 __ Comment("EmitTestAndCall");
1517 const Array& arguments_descriptor = Array::ZoneHandle(
1518 zone(), ArgumentsDescriptor::New(argument_count, argument_names));
1519
1520 // Load receiver into R0. 1507 // Load receiver into R0.
1521 __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize); 1508 __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
1522 __ LoadObject(R4, arguments_descriptor); 1509 __ LoadObject(R4, arguments_descriptor);
1523
1524 const bool kFirstCheckIsSmi = ic_data.GetReceiverClassIdAt(0) == kSmiCid;
1525 const intptr_t num_checks = ic_data.NumberOfChecks();
1526
1527 ASSERT(!ic_data.IsNull() && (num_checks > 0));
1528
1529 Label after_smi_test;
1530 if (kFirstCheckIsSmi) {
1531 __ tst(R0, Operand(kSmiTagMask));
1532 // Jump if receiver is not Smi.
1533 if (num_checks == 1) {
1534 __ b(failed, NE);
1535 } else {
1536 __ b(&after_smi_test, NE);
1537 }
1538 // Do not use the code from the function, but let the code be patched so
1539 // that we can record the outgoing edges to other code.
1540 const Function& function =
1541 Function::ZoneHandle(zone(), ic_data.GetTargetAt(0));
1542 GenerateStaticDartCall(deopt_id, token_index,
1543 *StubCode::CallStaticFunction_entry(),
1544 RawPcDescriptors::kOther, locs, function);
1545 __ Drop(argument_count);
1546 if (num_checks > 1) {
1547 __ b(match_found);
1548 }
1549 } else {
1550 // Receiver is Smi, but Smi is not a valid class therefore fail.
1551 // (Smi class must be first in the list).
1552 if (!complete) {
1553 __ tst(R0, Operand(kSmiTagMask));
1554 __ b(failed, EQ);
1555 }
1556 }
1557 __ Bind(&after_smi_test);
1558
1559 ASSERT(!ic_data.IsNull() && (num_checks > 0));
1560 GrowableArray<CidRangeTarget> sorted(num_checks);
1561 SortICDataByCount(ic_data, &sorted, /* drop_smi = */ true);
1562
1563 const intptr_t sorted_len = sorted.length();
1564 // If sorted_len is 0 then only a Smi check was needed; the Smi check above
1565 // will fail if there was only one check and receiver is not Smi.
1566 if (sorted_len == 0) return;
1567
1568 // Value is not Smi,
1569 __ LoadClassId(R2, R0);
1570
1571 bool add_megamorphic_call = false;
1572 const int kMaxImmediateInInstruction = 256;
1573 int bias =
1574 ComputeGoodBiasForCidComparison(sorted, kMaxImmediateInInstruction);
1575 if (bias != 0) __ AddImmediate(R2, R2, -bias);
1576
1577 for (intptr_t i = 0; i < sorted_len; i++) {
1578 const bool is_last_check = (i == (sorted_len - 1));
1579 int cid_start = sorted[i].cid_start;
1580 int cid_end = sorted[i].cid_end;
1581 int count = sorted[i].count;
1582 if (!is_last_check && !complete && count < (total_ic_calls >> 5)) {
1583 // This case is hit too rarely to be worth writing class-id checks inline
1584 // for.
1585 add_megamorphic_call = true;
1586 break;
1587 }
1588 ASSERT(cid_start > kSmiCid || cid_end < kSmiCid);
1589 Label next_test;
1590 if (!complete || !is_last_check) {
1591 Label* next_label = is_last_check ? failed : &next_test;
1592 if (cid_start == cid_end) {
1593 __ CompareImmediate(R2, cid_start - bias);
1594 __ b(next_label, NE);
1595 } else {
1596 __ AddImmediate(R2, R2, bias - cid_start);
1597 bias = cid_start;
1598 __ CompareImmediate(R2, cid_end - cid_start);
1599 __ b(next_label, HI); // Unsigned higher.
1600 }
1601 }
1602 // Do not use the code from the function, but let the code be patched so
1603 // that we can record the outgoing edges to other code.
1604 const Function& function = *sorted[i].target;
1605 GenerateStaticDartCall(deopt_id, token_index,
1606 *StubCode::CallStaticFunction_entry(),
1607 RawPcDescriptors::kOther, locs, function);
1608 __ Drop(argument_count);
1609 if (!is_last_check) {
1610 __ b(match_found);
1611 }
1612 __ Bind(&next_test);
1613 }
1614 if (add_megamorphic_call) {
1615 int try_index = CatchClauseNode::kInvalidTryIndex;
1616 EmitMegamorphicInstanceCall(ic_data, argument_count, deopt_id, token_index,
1617 locs, try_index, argument_count);
1618 }
1619 } 1510 }
1620 1511
1621 1512
1513 void FlowGraphCompiler::EmitTestAndCallSmiBranch(Label* label, bool if_smi) {
1514 __ tst(R0, Operand(kSmiTagMask));
1515 // Jump if receiver is not Smi.
1516 __ b(label, if_smi ? EQ : NE);
1517 }
1518
1519
1520 void FlowGraphCompiler::EmitTestAndCallLoadCid() {
1521 __ LoadClassId(R2, R0);
1522 }
1523
1524
1525 int FlowGraphCompiler::EmitTestAndCallCheckCid(Label* next_label,
1526 const CidRangeTarget& target,
1527 int bias) {
1528 intptr_t cid_start = target.cid_start;
1529 intptr_t cid_end = target.cid_end;
1530 if (cid_start == cid_end) {
1531 __ CompareImmediate(R2, cid_start - bias);
1532 __ b(next_label, NE);
1533 } else {
1534 __ AddImmediate(R2, R2, bias - cid_start);
1535 bias = cid_start;
1536 __ CompareImmediate(R2, cid_end - cid_start);
1537 __ b(next_label, HI); // Unsigned higher.
1538 }
1539 return bias;
1540 }
1541
1542
1622 #undef __ 1543 #undef __
1623 #define __ compiler_->assembler()-> 1544 #define __ compiler_->assembler()->
1624 1545
1625 1546
1626 void ParallelMoveResolver::EmitMove(int index) { 1547 void ParallelMoveResolver::EmitMove(int index) {
1627 MoveOperands* move = moves_[index]; 1548 MoveOperands* move = moves_[index];
1628 const Location source = move->src(); 1549 const Location source = move->src();
1629 const Location destination = move->dest(); 1550 const Location destination = move->dest();
1630 1551
1631 if (source.IsRegister()) { 1552 if (source.IsRegister()) {
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
1911 DRegister dreg = EvenDRegisterOf(reg); 1832 DRegister dreg = EvenDRegisterOf(reg);
1912 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex)); 1833 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex));
1913 } 1834 }
1914 1835
1915 1836
1916 #undef __ 1837 #undef __
1917 1838
1918 } // namespace dart 1839 } // namespace dart
1919 1840
1920 #endif // defined TARGET_ARCH_ARM 1841 #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