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

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

Issue 2833413002: Revert "Use off-heap data for type feedback in PolymorphicInstanceCallInstr" (Closed)
Patch Set: 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_arm64.cc ('k') | runtime/vm/flow_graph_compiler_mips.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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 1113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1124 if (is_optimizing()) { 1124 if (is_optimizing()) {
1125 AddDeoptIndexAtCall(deopt_id_after); 1125 AddDeoptIndexAtCall(deopt_id_after);
1126 } else { 1126 } else {
1127 // Add deoptimization continuation point after the call and before the 1127 // Add deoptimization continuation point after the call and before the
1128 // arguments are removed. 1128 // arguments are removed.
1129 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); 1129 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
1130 } 1130 }
1131 } 1131 }
1132 1132
1133 1133
1134 void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
1135 TokenPosition token_pos,
1136 const StubEntry& stub_entry,
1137 RawPcDescriptors::Kind kind,
1138 LocationSummary* locs,
1139 const Function& target) {
1140 GenerateDartCall(deopt_id, token_pos, stub_entry, kind, locs);
1141 AddStaticCallTarget(target);
1142 }
1143
1144
1145 void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos, 1134 void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos,
1146 intptr_t deopt_id, 1135 intptr_t deopt_id,
1147 const RuntimeEntry& entry, 1136 const RuntimeEntry& entry,
1148 intptr_t argument_count, 1137 intptr_t argument_count,
1149 LocationSummary* locs) { 1138 LocationSummary* locs) {
1150 __ CallRuntime(entry, argument_count); 1139 __ CallRuntime(entry, argument_count);
1151 EmitCallsiteMetaData(token_pos, deopt_id, RawPcDescriptors::kOther, locs); 1140 EmitCallsiteMetaData(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
1152 if (deopt_id != Thread::kNoDeoptId) { 1141 if (deopt_id != Thread::kNoDeoptId) {
1153 // Marks either the continuation point in unoptimized code or the 1142 // Marks either the continuation point in unoptimized code or the
1154 // deoptimization point in optimized code, after call. 1143 // deoptimization point in optimized code, after call.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1220 LocationSummary* locs) { 1209 LocationSummary* locs) {
1221 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); 1210 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
1222 __ LoadObject(ECX, ic_data); 1211 __ LoadObject(ECX, ic_data);
1223 GenerateDartCall(deopt_id, token_pos, stub_entry, RawPcDescriptors::kIcCall, 1212 GenerateDartCall(deopt_id, token_pos, stub_entry, RawPcDescriptors::kIcCall,
1224 locs); 1213 locs);
1225 __ Drop(argument_count); 1214 __ Drop(argument_count);
1226 } 1215 }
1227 1216
1228 1217
1229 void FlowGraphCompiler::EmitMegamorphicInstanceCall( 1218 void FlowGraphCompiler::EmitMegamorphicInstanceCall(
1230 const String& name, 1219 const ICData& ic_data,
1231 const Array& arguments_descriptor,
1232 intptr_t argument_count, 1220 intptr_t argument_count,
1233 intptr_t deopt_id, 1221 intptr_t deopt_id,
1234 TokenPosition token_pos, 1222 TokenPosition token_pos,
1235 LocationSummary* locs, 1223 LocationSummary* locs,
1236 intptr_t try_index, 1224 intptr_t try_index,
1237 intptr_t slow_path_argument_count) { 1225 intptr_t slow_path_argument_count) {
1226 const String& name = String::Handle(zone(), ic_data.target_name());
1227 const Array& arguments_descriptor =
1228 Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
1238 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); 1229 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
1239 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle( 1230 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
1240 zone(), 1231 zone(),
1241 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor)); 1232 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
1242 1233
1243 __ Comment("MegamorphicCall"); 1234 __ Comment("MegamorphicCall");
1244 // Load receiver into EBX. 1235 // Load receiver into EBX.
1245 __ movl(EBX, Address(ESP, (argument_count - 1) * kWordSize)); 1236 __ movl(EBX, Address(ESP, (argument_count - 1) * kWordSize));
1246 __ LoadObject(ECX, cache); 1237 __ LoadObject(ECX, cache);
1247 __ call(Address(THR, Thread::megamorphic_call_checked_entry_offset())); 1238 __ call(Address(THR, Thread::megamorphic_call_checked_entry_offset()));
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1427 // TODO(zerny): clobber non-live temporary FPU registers. 1418 // TODO(zerny): clobber non-live temporary FPU registers.
1428 if (tmp.IsRegister() && 1419 if (tmp.IsRegister() &&
1429 !locs->live_registers()->ContainsRegister(tmp.reg())) { 1420 !locs->live_registers()->ContainsRegister(tmp.reg())) {
1430 __ movl(tmp.reg(), Immediate(0xf7)); 1421 __ movl(tmp.reg(), Immediate(0xf7));
1431 } 1422 }
1432 } 1423 }
1433 } 1424 }
1434 #endif 1425 #endif
1435 1426
1436 1427
1437 void FlowGraphCompiler::EmitTestAndCallLoadReceiver( 1428 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
1438 intptr_t argument_count, 1429 intptr_t argument_count,
1439 const Array& arguments_descriptor) { 1430 const Array& argument_names,
1431 Label* failed,
1432 Label* match_found,
1433 intptr_t deopt_id,
1434 TokenPosition token_index,
1435 LocationSummary* locs,
1436 bool complete,
1437 intptr_t total_ic_calls) {
1438 ASSERT(is_optimizing());
1439 ASSERT(!complete);
1440 __ Comment("EmitTestAndCall"); 1440 __ Comment("EmitTestAndCall");
1441 const Array& arguments_descriptor = Array::ZoneHandle(
1442 zone(), ArgumentsDescriptor::New(argument_count, argument_names));
1441 // Load receiver into EAX. 1443 // Load receiver into EAX.
1442 __ movl(EAX, Address(ESP, (argument_count - 1) * kWordSize)); 1444 __ movl(EAX, Address(ESP, (argument_count - 1) * kWordSize));
1443 __ LoadObject(EDX, arguments_descriptor); 1445 __ LoadObject(EDX, arguments_descriptor);
1446
1447 const bool kFirstCheckIsSmi = ic_data.GetReceiverClassIdAt(0) == kSmiCid;
1448 const intptr_t num_checks = ic_data.NumberOfChecks();
1449
1450 ASSERT(!ic_data.IsNull() && (num_checks > 0));
1451
1452 Label after_smi_test;
1453 __ testl(EAX, Immediate(kSmiTagMask));
1454 if (kFirstCheckIsSmi) {
1455 // Jump if receiver is not Smi.
1456 if (num_checks == 1) {
1457 __ j(NOT_ZERO, failed);
1458 } else {
1459 __ j(NOT_ZERO, &after_smi_test);
1460 }
1461 // Do not use the code from the function, but let the code be patched so
1462 // that we can record the outgoing edges to other code.
1463 GenerateDartCall(deopt_id, token_index,
1464 *StubCode::CallStaticFunction_entry(),
1465 RawPcDescriptors::kOther, locs);
1466 const Function& function =
1467 Function::ZoneHandle(zone(), ic_data.GetTargetAt(0));
1468 AddStaticCallTarget(function);
1469 __ Drop(argument_count);
1470 if (num_checks > 1) {
1471 __ jmp(match_found);
1472 }
1473 } else {
1474 // Receiver is Smi, but Smi is not a valid class therefore fail.
1475 // (Smi class must be first in the list).
1476 __ j(ZERO, failed);
1477 }
1478 __ Bind(&after_smi_test);
1479
1480 ASSERT(!ic_data.IsNull() && (num_checks > 0));
1481 GrowableArray<CidRangeTarget> sorted(num_checks);
1482 SortICDataByCount(ic_data, &sorted, /* drop_smi = */ true);
1483
1484 const intptr_t sorted_len = sorted.length();
1485 // If sorted_len is 0 then only a Smi check was needed; the Smi check above
1486 // will fail if there was only one check and receiver is not Smi.
1487 if (sorted_len == 0) return;
1488
1489 // Value is not Smi,
1490 __ LoadClassId(EDI, EAX);
1491
1492 bool add_megamorphic_call = false;
1493 const int kMaxImmediateInInstruction = 127;
1494 int bias =
1495 ComputeGoodBiasForCidComparison(sorted, kMaxImmediateInInstruction);
1496 if (bias != 0) __ addl(EDI, Immediate(-bias));
1497
1498 for (intptr_t i = 0; i < sorted_len; i++) {
1499 const bool is_last_check = (i == (sorted_len - 1));
1500 int cid_start = sorted[i].cid_start;
1501 int cid_end = sorted[i].cid_end;
1502 int count = sorted[i].count;
1503 if (!is_last_check && !complete && count < (total_ic_calls >> 5)) {
1504 // This case is hit too rarely to be worth writing class-id checks inline
1505 // for.
1506 add_megamorphic_call = true;
1507 break;
1508 }
1509 ASSERT(cid_start > kSmiCid || cid_end < kSmiCid);
1510 Label next_test;
1511 if (!complete || !is_last_check) {
1512 Label* next_label = is_last_check ? failed : &next_test;
1513 if (cid_start == cid_end) {
1514 __ cmpl(EDI, Immediate(cid_start - bias));
1515 __ j(NOT_EQUAL, next_label);
1516 } else {
1517 __ addl(EDI, Immediate(bias - cid_start));
1518 bias = cid_start;
1519 __ cmpl(EDI, Immediate(cid_end - cid_start));
1520 __ j(ABOVE, next_label); // Unsigned higher.
1521 }
1522 }
1523 // Do not use the code from the function, but let the code be patched so
1524 // that we can record the outgoing edges to other code.
1525 const Function& function = *sorted[i].target;
1526 GenerateDartCall(deopt_id, token_index,
1527 *StubCode::CallStaticFunction_entry(),
1528 RawPcDescriptors::kOther, locs);
1529 AddStaticCallTarget(function);
1530 __ Drop(argument_count);
1531 if (!is_last_check) {
1532 __ jmp(match_found);
1533 }
1534 __ Bind(&next_test);
1535 }
1536 if (add_megamorphic_call) {
1537 int try_index = CatchClauseNode::kInvalidTryIndex;
1538 EmitMegamorphicInstanceCall(ic_data, argument_count, deopt_id, token_index,
1539 locs, try_index, argument_count);
1540 }
1444 } 1541 }
1445 1542
1446 1543
1447 void FlowGraphCompiler::EmitTestAndCallSmiBranch(Label* label, bool if_smi) {
1448 __ testl(EAX, Immediate(kSmiTagMask));
1449 // Jump if receiver is (not) Smi.
1450 __ j(if_smi ? ZERO : NOT_ZERO, label);
1451 }
1452
1453
1454 void FlowGraphCompiler::EmitTestAndCallLoadCid() {
1455 __ LoadClassId(EDI, EAX);
1456 }
1457
1458
1459 int FlowGraphCompiler::EmitTestAndCallCheckCid(Label* next_label,
1460 const CidRangeTarget& target,
1461 int bias) {
1462 intptr_t cid_start = target.cid_start;
1463 intptr_t cid_end = target.cid_end;
1464 if (cid_start == cid_end) {
1465 __ cmpl(EDI, Immediate(cid_start - bias));
1466 __ j(NOT_EQUAL, next_label);
1467 } else {
1468 __ addl(EDI, Immediate(bias - cid_start));
1469 bias = cid_start;
1470 __ cmpl(EDI, Immediate(cid_end - cid_start));
1471 __ j(ABOVE, next_label); // Unsigned higher.
1472 }
1473 return bias;
1474 }
1475
1476
1477 #undef __ 1544 #undef __
1478 #define __ compiler_->assembler()-> 1545 #define __ compiler_->assembler()->
1479 1546
1480 1547
1481 void ParallelMoveResolver::EmitMove(int index) { 1548 void ParallelMoveResolver::EmitMove(int index) {
1482 MoveOperands* move = moves_[index]; 1549 MoveOperands* move = moves_[index];
1483 const Location source = move->src(); 1550 const Location source = move->src();
1484 const Location destination = move->dest(); 1551 const Location destination = move->dest();
1485 1552
1486 if (source.IsRegister()) { 1553 if (source.IsRegister()) {
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
1733 __ movups(reg, Address(ESP, 0)); 1800 __ movups(reg, Address(ESP, 0));
1734 __ addl(ESP, Immediate(kFpuRegisterSize)); 1801 __ addl(ESP, Immediate(kFpuRegisterSize));
1735 } 1802 }
1736 1803
1737 1804
1738 #undef __ 1805 #undef __
1739 1806
1740 } // namespace dart 1807 } // namespace dart
1741 1808
1742 #endif // defined TARGET_ARCH_IA32 1809 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_arm64.cc ('k') | runtime/vm/flow_graph_compiler_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698