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

Side by Side Diff: runtime/vm/flow_graph_compiler_arm64.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_arm.cc ('k') | runtime/vm/flow_graph_compiler_ia32.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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
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 1206 matching lines...) Expand 10 before | Expand all | Expand 10 after
1217 LocationSummary* locs) { 1217 LocationSummary* locs) {
1218 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0); 1218 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
1219 __ LoadUniqueObject(R5, ic_data); 1219 __ LoadUniqueObject(R5, ic_data);
1220 GenerateDartCall(deopt_id, token_pos, stub_entry, RawPcDescriptors::kIcCall, 1220 GenerateDartCall(deopt_id, token_pos, stub_entry, RawPcDescriptors::kIcCall,
1221 locs); 1221 locs);
1222 __ Drop(argument_count); 1222 __ Drop(argument_count);
1223 } 1223 }
1224 1224
1225 1225
1226 void FlowGraphCompiler::EmitMegamorphicInstanceCall( 1226 void FlowGraphCompiler::EmitMegamorphicInstanceCall(
1227 const ICData& ic_data, 1227 const String& name,
1228 const Array& arguments_descriptor,
1228 intptr_t argument_count, 1229 intptr_t argument_count,
1229 intptr_t deopt_id, 1230 intptr_t deopt_id,
1230 TokenPosition token_pos, 1231 TokenPosition token_pos,
1231 LocationSummary* locs, 1232 LocationSummary* locs,
1232 intptr_t try_index, 1233 intptr_t try_index,
1233 intptr_t slow_path_argument_count) { 1234 intptr_t slow_path_argument_count) {
1234 const String& name = String::Handle(zone(), ic_data.target_name());
1235 const Array& arguments_descriptor =
1236 Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
1237 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); 1235 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
1238 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle( 1236 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
1239 zone(), 1237 zone(),
1240 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor)); 1238 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
1241 1239
1242 __ Comment("MegamorphicCall"); 1240 __ Comment("MegamorphicCall");
1243 // Load receiver into R0. 1241 // Load receiver into R0.
1244 __ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize); 1242 __ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize);
1245 1243
1246 __ LoadObject(R5, cache); 1244 __ LoadObject(R5, cache);
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1459 // TODO(zerny): clobber non-live temporary FPU registers. 1457 // TODO(zerny): clobber non-live temporary FPU registers.
1460 if (tmp.IsRegister() && 1458 if (tmp.IsRegister() &&
1461 !locs->live_registers()->ContainsRegister(tmp.reg())) { 1459 !locs->live_registers()->ContainsRegister(tmp.reg())) {
1462 __ movz(tmp.reg(), Immediate(0xf7), 0); 1460 __ movz(tmp.reg(), Immediate(0xf7), 0);
1463 } 1461 }
1464 } 1462 }
1465 } 1463 }
1466 #endif 1464 #endif
1467 1465
1468 1466
1469 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, 1467 void FlowGraphCompiler::EmitTestAndCallLoadReceiver(
1470 intptr_t argument_count, 1468 intptr_t argument_count,
1471 const Array& argument_names, 1469 const Array& arguments_descriptor) {
1472 Label* failed,
1473 Label* match_found,
1474 intptr_t deopt_id,
1475 TokenPosition token_index,
1476 LocationSummary* locs,
1477 bool complete,
1478 intptr_t total_ic_calls) {
1479 ASSERT(is_optimizing());
1480 __ Comment("EmitTestAndCall"); 1470 __ Comment("EmitTestAndCall");
1481 const Array& arguments_descriptor = Array::ZoneHandle(
1482 zone(), ArgumentsDescriptor::New(argument_count, argument_names));
1483
1484 // Load receiver into R0. 1471 // Load receiver into R0.
1485 __ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize); 1472 __ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize);
1486 __ LoadObject(R4, arguments_descriptor); 1473 __ LoadObject(R4, arguments_descriptor);
1487
1488 const bool kFirstCheckIsSmi = ic_data.GetReceiverClassIdAt(0) == kSmiCid;
1489 const intptr_t num_checks = ic_data.NumberOfChecks();
1490
1491 ASSERT(!ic_data.IsNull() && (num_checks > 0));
1492
1493 Label after_smi_test;
1494 if (kFirstCheckIsSmi) {
1495 __ tsti(R0, Immediate(kSmiTagMask));
1496 // Jump if receiver is not Smi.
1497 if (num_checks == 1) {
1498 __ b(failed, NE);
1499 } else {
1500 __ b(&after_smi_test, NE);
1501 }
1502 // Do not use the code from the function, but let the code be patched so
1503 // that we can record the outgoing edges to other code.
1504 const Function& function =
1505 Function::ZoneHandle(zone(), ic_data.GetTargetAt(0));
1506 GenerateStaticDartCall(deopt_id, token_index,
1507 *StubCode::CallStaticFunction_entry(),
1508 RawPcDescriptors::kOther, locs, function);
1509 __ Drop(argument_count);
1510 if (num_checks > 1) {
1511 __ b(match_found);
1512 }
1513 } else {
1514 // Receiver is Smi, but Smi is not a valid class therefore fail.
1515 // (Smi class must be first in the list).
1516 if (!complete) {
1517 __ tsti(R0, Immediate(kSmiTagMask));
1518 __ b(failed, EQ);
1519 }
1520 }
1521 __ Bind(&after_smi_test);
1522
1523 ASSERT(!ic_data.IsNull() && (num_checks > 0));
1524 GrowableArray<CidRangeTarget> sorted(num_checks);
1525 SortICDataByCount(ic_data, &sorted, /* drop_smi = */ true);
1526
1527 const intptr_t sorted_len = sorted.length();
1528 // If sorted_len is 0 then only a Smi check was needed; the Smi check above
1529 // will fail if there was only one check and receiver is not Smi.
1530 if (sorted_len == 0) return;
1531
1532 // Value is not Smi,
1533 __ LoadClassId(R2, R0);
1534
1535 bool add_megamorphic_call = false;
1536 const int kMaxImmediateInInstruction = 256;
1537 int bias =
1538 ComputeGoodBiasForCidComparison(sorted, kMaxImmediateInInstruction);
1539 if (bias != 0) __ AddImmediate(R2, R2, -bias);
1540
1541 for (intptr_t i = 0; i < sorted_len; i++) {
1542 const bool is_last_check = (i == (sorted_len - 1));
1543 int cid_start = sorted[i].cid_start;
1544 int cid_end = sorted[i].cid_end;
1545 int count = sorted[i].count;
1546 if (!is_last_check && !complete && count < (total_ic_calls >> 5)) {
1547 // This case is hit too rarely to be worth writing class-id checks inline
1548 // for.
1549 add_megamorphic_call = true;
1550 break;
1551 }
1552 ASSERT(cid_start > kSmiCid || cid_end < kSmiCid);
1553 Label next_test;
1554 if (!complete || !is_last_check) {
1555 Label* next_label = is_last_check ? failed : &next_test;
1556 if (cid_start == cid_end) {
1557 __ CompareImmediate(R2, cid_start - bias);
1558 __ b(next_label, NE);
1559 } else {
1560 __ AddImmediate(R2, R2, bias - cid_start);
1561 bias = cid_start;
1562 __ CompareImmediate(R2, cid_end - cid_start);
1563 __ b(next_label, HI); // Unsigned higher.
1564 }
1565 }
1566 // Do not use the code from the function, but let the code be patched so
1567 // that we can record the outgoing edges to other code.
1568 const Function& function = *sorted[i].target;
1569 GenerateStaticDartCall(deopt_id, token_index,
1570 *StubCode::CallStaticFunction_entry(),
1571 RawPcDescriptors::kOther, locs, function);
1572 __ Drop(argument_count);
1573 if (!is_last_check) {
1574 __ b(match_found);
1575 }
1576 __ Bind(&next_test);
1577 }
1578 if (add_megamorphic_call) {
1579 int try_index = CatchClauseNode::kInvalidTryIndex;
1580 EmitMegamorphicInstanceCall(ic_data, argument_count, deopt_id, token_index,
1581 locs, try_index, argument_count);
1582 }
1583 } 1474 }
1584 1475
1585 1476
1477 void FlowGraphCompiler::EmitTestAndCallSmiBranch(Label* label, bool if_smi) {
1478 __ tsti(R0, Immediate(kSmiTagMask));
1479 // Jump if receiver is not Smi.
1480 __ b(label, if_smi ? EQ : NE);
1481 }
1482
1483
1484 void FlowGraphCompiler::EmitTestAndCallLoadCid() {
1485 __ LoadClassId(R2, R0);
1486 }
1487
1488
1489 int FlowGraphCompiler::EmitTestAndCallCheckCid(Label* next_label,
1490 const CidRangeTarget& target,
1491 int bias) {
1492 intptr_t cid_start = target.cid_start;
1493 intptr_t cid_end = target.cid_end;
1494 if (cid_start == cid_end) {
1495 __ CompareImmediate(R2, cid_start - bias);
1496 __ b(next_label, NE);
1497 } else {
1498 __ AddImmediate(R2, R2, bias - cid_start);
1499 bias = cid_start;
1500 __ CompareImmediate(R2, cid_end - cid_start);
1501 __ b(next_label, HI); // Unsigned higher.
1502 }
1503 return bias;
1504 }
1505
1506
1586 #undef __ 1507 #undef __
1587 #define __ compiler_->assembler()-> 1508 #define __ compiler_->assembler()->
1588 1509
1589 1510
1590 void ParallelMoveResolver::EmitMove(int index) { 1511 void ParallelMoveResolver::EmitMove(int index) {
1591 MoveOperands* move = moves_[index]; 1512 MoveOperands* move = moves_[index];
1592 const Location source = move->src(); 1513 const Location source = move->src();
1593 const Location destination = move->dest(); 1514 const Location destination = move->dest();
1594 1515
1595 if (source.IsRegister()) { 1516 if (source.IsRegister()) {
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
1855 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { 1776 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
1856 __ PopDouble(reg); 1777 __ PopDouble(reg);
1857 } 1778 }
1858 1779
1859 1780
1860 #undef __ 1781 #undef __
1861 1782
1862 } // namespace dart 1783 } // namespace dart
1863 1784
1864 #endif // defined TARGET_ARCH_ARM64 1785 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_arm.cc ('k') | runtime/vm/flow_graph_compiler_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698