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

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

Issue 1184093004: Faster checks in polymorphic instance calls if Smi-s are involved (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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
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 1491 matching lines...) Expand 10 before | Expand all | Expand 10 after
1502 if (tmp.IsRegister() && 1502 if (tmp.IsRegister() &&
1503 !locs->live_registers()->ContainsRegister(tmp.reg())) { 1503 !locs->live_registers()->ContainsRegister(tmp.reg())) {
1504 __ movl(tmp.reg(), Immediate(0xf7)); 1504 __ movl(tmp.reg(), Immediate(0xf7));
1505 } 1505 }
1506 } 1506 }
1507 } 1507 }
1508 #endif 1508 #endif
1509 1509
1510 1510
1511 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, 1511 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
1512 Register class_id_reg,
1513 intptr_t argument_count, 1512 intptr_t argument_count,
1514 const Array& argument_names, 1513 const Array& argument_names,
1515 Label* deopt, 1514 Label* failed,
1515 Label* match_found,
1516 intptr_t deopt_id, 1516 intptr_t deopt_id,
1517 intptr_t token_index, 1517 intptr_t token_index,
1518 LocationSummary* locs) { 1518 LocationSummary* locs) {
1519 ASSERT(is_optimizing()); 1519 ASSERT(is_optimizing());
1520 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfUsedChecks() > 0)); 1520 __ Comment("EmitTestAndCall");
1521 Label match_found;
1522 const intptr_t len = ic_data.NumberOfChecks();
1523 GrowableArray<CidTarget> sorted(len);
1524 SortICDataByCount(ic_data, &sorted, /* drop_smi = */ false);
1525 ASSERT(class_id_reg != EDX);
1526 ASSERT(len > 0); // Why bother otherwise.
1527 const Array& arguments_descriptor = 1521 const Array& arguments_descriptor =
1528 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, 1522 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
1529 argument_names)); 1523 argument_names));
1530 StubCode* stub_code = isolate()->stub_code(); 1524 StubCode* stub_code = isolate()->stub_code();
1525 // Load receiver into EAX.
1526 __ movl(EAX, Address(ESP, (argument_count - 1) * kWordSize));
1527 __ LoadObject(EDX, arguments_descriptor);
1531 1528
1532 __ LoadObject(EDX, arguments_descriptor); 1529 const bool kFirstCheckIsSmi = ic_data.GetReceiverClassIdAt(0) == kSmiCid;
1533 for (intptr_t i = 0; i < len; i++) { 1530 const intptr_t kNumChecks = ic_data.NumberOfChecks();
1534 const bool is_last_check = (i == (len - 1)); 1531
1532 ASSERT(!ic_data.IsNull() && (kNumChecks > 0));
1533
1534 Label next_test;
zra 2015/06/15 20:17:23 'Label after_smi_test' as in other arches to avoid
srdjan 2015/06/15 20:54:13 Changed to after_smi_test
1535 __ testl(EAX, Immediate(kSmiTagMask));
1536 if (kFirstCheckIsSmi) {
1537 // Jump if receiver is not Smi.
1538 if (kNumChecks == 1) {
1539 __ j(NOT_ZERO, failed);
1540 } else {
1541 __ j(NOT_ZERO, &next_test);
1542 }
1543 // Do not use the code from the function, but let the code be patched so
1544 // that we can record the outgoing edges to other code.
1545 GenerateDartCall(deopt_id,
1546 token_index,
1547 &stub_code->CallStaticFunctionLabel(),
1548 RawPcDescriptors::kOther,
1549 locs);
1550 const Function& function = Function::Handle(ic_data.GetTargetAt(0));
1551 AddStaticCallTarget(function);
1552 __ Drop(argument_count);
1553 if (kNumChecks > 1) {
1554 __ jmp(match_found);
1555 }
1556 } else {
1557 // It is Smi, butSmi is not handled here.
1558 __ j(ZERO, failed);
1559 }
1560 __ Bind(&next_test);
1561
1562 ASSERT(!ic_data.IsNull() && (kNumChecks > 0));
1563 GrowableArray<CidTarget> sorted(kNumChecks);
1564 SortICDataByCount(ic_data, &sorted, /* drop_smi = */ true);
1565
1566 // Value is not Smi,
1567 // LoadValueCid(this, EDI, EAX, failed);
1568 const intptr_t kSortedLen = sorted.length();
1569 if (kSortedLen == 0) return;
1570
1571 __ LoadClassId(EDI, EAX);
1572 for (intptr_t i = 0; i < kSortedLen; i++) {
1573 const bool kIsLastCheck = (i == (kSortedLen - 1));
1535 Label next_test; 1574 Label next_test;
1536 assembler()->cmpl(class_id_reg, Immediate(sorted[i].cid)); 1575 assembler()->cmpl(EDI, Immediate(sorted[i].cid));
zra 2015/06/15 20:17:23 __ is used above for assembler()->. Is it availabl
srdjan 2015/06/15 20:54:13 Yes, replaced with __
1537 if (is_last_check) { 1576 if (kIsLastCheck) {
1538 assembler()->j(NOT_EQUAL, deopt); 1577 assembler()->j(NOT_EQUAL, failed);
1539 } else { 1578 } else {
1540 assembler()->j(NOT_EQUAL, &next_test); 1579 assembler()->j(NOT_EQUAL, &next_test);
1541 } 1580 }
1542 // Do not use the code from the function, but let the code be patched so 1581 // Do not use the code from the function, but let the code be patched so
1543 // that we can record the outgoing edges to other code. 1582 // that we can record the outgoing edges to other code.
1544 GenerateDartCall(deopt_id, 1583 GenerateDartCall(deopt_id,
1545 token_index, 1584 token_index,
1546 &stub_code->CallStaticFunctionLabel(), 1585 &stub_code->CallStaticFunctionLabel(),
1547 RawPcDescriptors::kOther, 1586 RawPcDescriptors::kOther,
1548 locs); 1587 locs);
1549 const Function& function = *sorted[i].target; 1588 const Function& function = *sorted[i].target;
1550 AddStaticCallTarget(function); 1589 AddStaticCallTarget(function);
1551 __ Drop(argument_count); 1590 __ Drop(argument_count);
1552 if (!is_last_check) { 1591 if (!kIsLastCheck) {
1553 assembler()->jmp(&match_found); 1592 __ jmp(match_found);
1554 } 1593 }
1555 assembler()->Bind(&next_test); 1594 __ Bind(&next_test);
1556 } 1595 }
1557 assembler()->Bind(&match_found);
1558 } 1596 }
1559 1597
1560 1598
1561 #undef __ 1599 #undef __
1562 #define __ compiler_->assembler()-> 1600 #define __ compiler_->assembler()->
1563 1601
1564 1602
1565 void ParallelMoveResolver::EmitMove(int index) { 1603 void ParallelMoveResolver::EmitMove(int index) {
1566 MoveOperands* move = moves_[index]; 1604 MoveOperands* move = moves_[index];
1567 const Location source = move->src(); 1605 const Location source = move->src();
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
1818 __ movups(reg, Address(ESP, 0)); 1856 __ movups(reg, Address(ESP, 0));
1819 __ addl(ESP, Immediate(kFpuRegisterSize)); 1857 __ addl(ESP, Immediate(kFpuRegisterSize));
1820 } 1858 }
1821 1859
1822 1860
1823 #undef __ 1861 #undef __
1824 1862
1825 } // namespace dart 1863 } // namespace dart
1826 1864
1827 #endif // defined TARGET_ARCH_IA32 1865 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698