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

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

Issue 2856543002: Use off-heap data for class check instructions (Closed)
Patch Set: Feedback from Slava: rejig inheritance of CallTargets 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
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/aot_optimizer.h" 5 #include "vm/aot_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/branch_optimizer.h" 8 #include "vm/branch_optimizer.h"
9 #include "vm/cha.h" 9 #include "vm/cha.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 Instruction* insert_before) { 441 Instruction* insert_before) {
442 if (to_check->Type()->ToCid() != kSmiCid) { 442 if (to_check->Type()->ToCid() != kSmiCid) {
443 InsertBefore(insert_before, 443 InsertBefore(insert_before,
444 new (Z) CheckSmiInstr(new (Z) Value(to_check), deopt_id, 444 new (Z) CheckSmiInstr(new (Z) Value(to_check), deopt_id,
445 insert_before->token_pos()), 445 insert_before->token_pos()),
446 deopt_environment, FlowGraph::kEffect); 446 deopt_environment, FlowGraph::kEffect);
447 } 447 }
448 } 448 }
449 449
450 450
451 Instruction* AotOptimizer::GetCheckClass(Definition* to_check,
452 const ICData& unary_checks,
453 intptr_t deopt_id,
454 TokenPosition token_pos) {
455 if ((unary_checks.NumberOfUsedChecks() == 1) &&
456 unary_checks.HasReceiverClassId(kSmiCid)) {
457 return new (Z) CheckSmiInstr(new (Z) Value(to_check), deopt_id, token_pos);
458 }
459 return new (Z) CheckClassInstr(new (Z) Value(to_check), deopt_id,
460 unary_checks, token_pos);
461 }
462
463
464 void AotOptimizer::AddCheckClass(Definition* to_check, 451 void AotOptimizer::AddCheckClass(Definition* to_check,
465 const ICData& unary_checks, 452 const Cids& cids,
466 intptr_t deopt_id, 453 intptr_t deopt_id,
467 Environment* deopt_environment, 454 Environment* deopt_environment,
468 Instruction* insert_before) { 455 Instruction* insert_before) {
469 // Type propagation has not run yet, we cannot eliminate the check. 456 // Type propagation has not run yet, we cannot eliminate the check.
470 Instruction* check = GetCheckClass(to_check, unary_checks, deopt_id, 457 Instruction* check = flow_graph_->CreateCheckClass(
471 insert_before->token_pos()); 458 to_check, cids, deopt_id, insert_before->token_pos());
472 InsertBefore(insert_before, check, deopt_environment, FlowGraph::kEffect); 459 InsertBefore(insert_before, check, deopt_environment, FlowGraph::kEffect);
473 } 460 }
474 461
475 462
476 void AotOptimizer::AddReceiverCheck(InstanceCallInstr* call) { 463 void AotOptimizer::AddChecksToArgNr(InstanceCallInstr* call,
477 AddCheckClass(call->ArgumentAt(0), 464 Definition* instr,
478 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()), 465 int argument_number) {
479 call->deopt_id(), call->env(), call); 466 const Cids* cids = Cids::Create(Z, *call->ic_data(), argument_number);
467 AddCheckClass(instr, *cids, call->deopt_id(), call->env(), call);
480 } 468 }
481 469
482 470
483 static bool ArgIsAlways(intptr_t cid, 471 static bool ArgIsAlways(intptr_t cid,
484 const ICData& ic_data, 472 const ICData& ic_data,
485 intptr_t arg_number) { 473 intptr_t arg_number) {
486 ASSERT(ic_data.NumArgsTested() > arg_number); 474 ASSERT(ic_data.NumArgsTested() > arg_number);
487 if (ic_data.NumberOfUsedChecks() == 0) { 475 if (ic_data.NumberOfUsedChecks() == 0) {
488 return false; 476 return false;
489 } 477 }
490 const intptr_t num_checks = ic_data.NumberOfChecks(); 478 const intptr_t num_checks = ic_data.NumberOfChecks();
491 for (intptr_t i = 0; i < num_checks; i++) { 479 for (intptr_t i = 0; i < num_checks; i++) {
492 if (ic_data.IsUsedAt(i) && ic_data.GetClassIdAt(i, arg_number) != cid) { 480 if (ic_data.IsUsedAt(i) && ic_data.GetClassIdAt(i, arg_number) != cid) {
493 return false; 481 return false;
494 } 482 }
495 } 483 }
496 return true; 484 return true;
497 } 485 }
498 486
499 487
500 bool AotOptimizer::TryReplaceWithIndexedOp(InstanceCallInstr* call) { 488 bool AotOptimizer::TryReplaceWithIndexedOp(InstanceCallInstr* call,
489 const ICData* unary_checks) {
501 // Check for monomorphic IC data. 490 // Check for monomorphic IC data.
502 if (!call->HasICData()) return false; 491 ASSERT(unary_checks->NumberOfChecks() > 0);
503 const ICData& ic_data = 492 if (unary_checks->NumberOfChecksIs(1)) {
504 ICData::Handle(Z, call->ic_data()->AsUnaryClassChecks());
505 if (!ic_data.NumberOfChecksIs(1)) {
506 return false; 493 return false;
507 } 494 }
508 return FlowGraphInliner::TryReplaceInstanceCallWithInline( 495 return FlowGraphInliner::TryReplaceInstanceCallWithInline(
509 flow_graph_, current_iterator(), call); 496 flow_graph_, current_iterator(), call);
510 } 497 }
511 498
512 499
513 // Return true if d is a string of length one (a constant or result from 500 // Return true if d is a string of length one (a constant or result from
514 // from string-from-char-code instruction. 501 // from string-from-char-code instruction.
515 static bool IsLengthOneString(Definition* d) { 502 static bool IsLengthOneString(Definition* d) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 555
569 Definition* to_remove_right = NULL; 556 Definition* to_remove_right = NULL;
570 Value* right_val = NULL; 557 Value* right_val = NULL;
571 if (right->IsOneByteStringFromCharCode()) { 558 if (right->IsOneByteStringFromCharCode()) {
572 // Skip string-from-char-code, and use its input as right value. 559 // Skip string-from-char-code, and use its input as right value.
573 OneByteStringFromCharCodeInstr* right_instr = 560 OneByteStringFromCharCodeInstr* right_instr =
574 right->AsOneByteStringFromCharCode(); 561 right->AsOneByteStringFromCharCode();
575 right_val = new (Z) Value(right_instr->char_code()->definition()); 562 right_val = new (Z) Value(right_instr->char_code()->definition());
576 to_remove_right = right_instr; 563 to_remove_right = right_instr;
577 } else { 564 } else {
578 const ICData& unary_checks_1 = 565 AddChecksToArgNr(call, right, /* arg_number = */ 1);
579 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecksForArgNr(1));
580 AddCheckClass(right, unary_checks_1, call->deopt_id(), call->env(), call);
581 // String-to-char-code instructions returns -1 (illegal charcode) if 566 // String-to-char-code instructions returns -1 (illegal charcode) if
582 // string is not of length one. 567 // string is not of length one.
583 StringToCharCodeInstr* char_code_right = new (Z) 568 StringToCharCodeInstr* char_code_right = new (Z)
584 StringToCharCodeInstr(new (Z) Value(right), kOneByteStringCid); 569 StringToCharCodeInstr(new (Z) Value(right), kOneByteStringCid);
585 InsertBefore(call, char_code_right, call->env(), FlowGraph::kValue); 570 InsertBefore(call, char_code_right, call->env(), FlowGraph::kValue);
586 right_val = new (Z) Value(char_code_right); 571 right_val = new (Z) Value(char_code_right);
587 } 572 }
588 573
589 // Comparing char-codes instead of strings. 574 // Comparing char-codes instead of strings.
590 EqualityCompareInstr* comp = 575 EqualityCompareInstr* comp =
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 return false; 646 return false;
662 } 647 }
663 648
664 649
665 bool AotOptimizer::TryReplaceWithEqualityOp(InstanceCallInstr* call, 650 bool AotOptimizer::TryReplaceWithEqualityOp(InstanceCallInstr* call,
666 Token::Kind op_kind) { 651 Token::Kind op_kind) {
667 const ICData& ic_data = *call->ic_data(); 652 const ICData& ic_data = *call->ic_data();
668 ASSERT(ic_data.NumArgsTested() == 2); 653 ASSERT(ic_data.NumArgsTested() == 2);
669 654
670 ASSERT(call->ArgumentCount() == 2); 655 ASSERT(call->ArgumentCount() == 2);
671 Definition* left = call->ArgumentAt(0); 656 Definition* const left = call->ArgumentAt(0);
672 Definition* right = call->ArgumentAt(1); 657 Definition* const right = call->ArgumentAt(1);
673 658
674 intptr_t cid = kIllegalCid; 659 intptr_t cid = kIllegalCid;
675 if (HasOnlyTwoOf(ic_data, kOneByteStringCid)) { 660 if (HasOnlyTwoOf(ic_data, kOneByteStringCid)) {
676 return TryStringLengthOneEquality(call, op_kind); 661 return TryStringLengthOneEquality(call, op_kind);
677 } else if (HasOnlyTwoOf(ic_data, kSmiCid)) { 662 } else if (HasOnlyTwoOf(ic_data, kSmiCid)) {
678 InsertBefore(call, 663 InsertBefore(call,
679 new (Z) CheckSmiInstr(new (Z) Value(left), call->deopt_id(), 664 new (Z) CheckSmiInstr(new (Z) Value(left), call->deopt_id(),
680 call->token_pos()), 665 call->token_pos()),
681 call->env(), FlowGraph::kEffect); 666 call->env(), FlowGraph::kEffect);
682 InsertBefore(call, 667 InsertBefore(call,
(...skipping 23 matching lines...) Expand all
706 } 691 }
707 } else { 692 } else {
708 // Check if ICDData contains checks with Smi/Null combinations. In that case 693 // Check if ICDData contains checks with Smi/Null combinations. In that case
709 // we can still emit the optimized Smi equality operation but need to add 694 // we can still emit the optimized Smi equality operation but need to add
710 // checks for null or Smi. 695 // checks for null or Smi.
711 GrowableArray<intptr_t> smi_or_null(2); 696 GrowableArray<intptr_t> smi_or_null(2);
712 smi_or_null.Add(kSmiCid); 697 smi_or_null.Add(kSmiCid);
713 smi_or_null.Add(kNullCid); 698 smi_or_null.Add(kNullCid);
714 if (ICDataHasOnlyReceiverArgumentClassIds(ic_data, smi_or_null, 699 if (ICDataHasOnlyReceiverArgumentClassIds(ic_data, smi_or_null,
715 smi_or_null)) { 700 smi_or_null)) {
716 const ICData& unary_checks_0 = 701 AddChecksToArgNr(call, left, /* arg_number = */ 0);
717 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()); 702 AddChecksToArgNr(call, right, /* arg_number = */ 1);
718 AddCheckClass(left, unary_checks_0, call->deopt_id(), call->env(), call);
719 703
720 const ICData& unary_checks_1 =
721 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecksForArgNr(1));
722 AddCheckClass(right, unary_checks_1, call->deopt_id(), call->env(), call);
723 cid = kSmiCid; 704 cid = kSmiCid;
724 } else { 705 } else {
725 // Shortcut for equality with null. 706 // Shortcut for equality with null.
726 // TODO(vegorov): this optimization is not speculative and should 707 // TODO(vegorov): this optimization is not speculative and should
727 // be hoisted out of this function. 708 // be hoisted out of this function.
728 ConstantInstr* right_const = right->AsConstant(); 709 ConstantInstr* right_const = right->AsConstant();
729 ConstantInstr* left_const = left->AsConstant(); 710 ConstantInstr* left_const = left->AsConstant();
730 if ((right_const != NULL && right_const->value().IsNull()) || 711 if ((right_const != NULL && right_const->value().IsNull()) ||
731 (left_const != NULL && left_const->value().IsNull())) { 712 (left_const != NULL && left_const->value().IsNull())) {
732 StrictCompareInstr* comp = new (Z) 713 StrictCompareInstr* comp = new (Z)
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 return true; 1051 return true;
1071 } 1052 }
1072 1053
1073 1054
1074 bool AotOptimizer::InlineFloat32x4BinaryOp(InstanceCallInstr* call, 1055 bool AotOptimizer::InlineFloat32x4BinaryOp(InstanceCallInstr* call,
1075 Token::Kind op_kind) { 1056 Token::Kind op_kind) {
1076 if (!ShouldInlineSimd()) { 1057 if (!ShouldInlineSimd()) {
1077 return false; 1058 return false;
1078 } 1059 }
1079 ASSERT(call->ArgumentCount() == 2); 1060 ASSERT(call->ArgumentCount() == 2);
1080 Definition* left = call->ArgumentAt(0); 1061 Definition* const left = call->ArgumentAt(0);
1081 Definition* right = call->ArgumentAt(1); 1062 Definition* const right = call->ArgumentAt(1);
1082 // Type check left. 1063 // Type check left and right.
1083 AddCheckClass(left, ICData::ZoneHandle( 1064 AddChecksToArgNr(call, left, /* arg_number = */ 0);
1084 Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1065 AddChecksToArgNr(call, right, /* arg_number = */ 1);
1085 call->deopt_id(), call->env(), call);
1086 // Type check right.
1087 AddCheckClass(right, ICData::ZoneHandle(
1088 Z, call->ic_data()->AsUnaryClassChecksForArgNr(1)),
1089 call->deopt_id(), call->env(), call);
1090 // Replace call. 1066 // Replace call.
1091 BinaryFloat32x4OpInstr* float32x4_bin_op = new (Z) BinaryFloat32x4OpInstr( 1067 BinaryFloat32x4OpInstr* float32x4_bin_op = new (Z) BinaryFloat32x4OpInstr(
1092 op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id()); 1068 op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id());
1093 ReplaceCall(call, float32x4_bin_op); 1069 ReplaceCall(call, float32x4_bin_op);
1094 1070
1095 return true; 1071 return true;
1096 } 1072 }
1097 1073
1098 1074
1099 bool AotOptimizer::InlineInt32x4BinaryOp(InstanceCallInstr* call, 1075 bool AotOptimizer::InlineInt32x4BinaryOp(InstanceCallInstr* call,
1100 Token::Kind op_kind) { 1076 Token::Kind op_kind) {
1101 if (!ShouldInlineSimd()) { 1077 if (!ShouldInlineSimd()) {
1102 return false; 1078 return false;
1103 } 1079 }
1104 ASSERT(call->ArgumentCount() == 2); 1080 ASSERT(call->ArgumentCount() == 2);
1105 Definition* left = call->ArgumentAt(0); 1081 Definition* const left = call->ArgumentAt(0);
1106 Definition* right = call->ArgumentAt(1); 1082 Definition* const right = call->ArgumentAt(1);
1107 // Type check left. 1083 // Type check left and right.
1108 AddCheckClass(left, ICData::ZoneHandle( 1084 AddChecksToArgNr(call, left, /* arg_number = */ 0);
1109 Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1085 AddChecksToArgNr(call, right, /* arg_number = */ 1);
1110 call->deopt_id(), call->env(), call);
1111 // Type check right.
1112 AddCheckClass(right, ICData::ZoneHandle(
1113 Z, call->ic_data()->AsUnaryClassChecksForArgNr(1)),
1114 call->deopt_id(), call->env(), call);
1115 // Replace call. 1086 // Replace call.
1116 BinaryInt32x4OpInstr* int32x4_bin_op = new (Z) BinaryInt32x4OpInstr( 1087 BinaryInt32x4OpInstr* int32x4_bin_op = new (Z) BinaryInt32x4OpInstr(
1117 op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id()); 1088 op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id());
1118 ReplaceCall(call, int32x4_bin_op); 1089 ReplaceCall(call, int32x4_bin_op);
1119 return true; 1090 return true;
1120 } 1091 }
1121 1092
1122 1093
1123 bool AotOptimizer::InlineFloat64x2BinaryOp(InstanceCallInstr* call, 1094 bool AotOptimizer::InlineFloat64x2BinaryOp(InstanceCallInstr* call,
1124 Token::Kind op_kind) { 1095 Token::Kind op_kind) {
1125 if (!ShouldInlineSimd()) { 1096 if (!ShouldInlineSimd()) {
1126 return false; 1097 return false;
1127 } 1098 }
1128 ASSERT(call->ArgumentCount() == 2); 1099 ASSERT(call->ArgumentCount() == 2);
1129 Definition* left = call->ArgumentAt(0); 1100 Definition* const left = call->ArgumentAt(0);
1130 Definition* right = call->ArgumentAt(1); 1101 Definition* const right = call->ArgumentAt(1);
1131 // Type check left. 1102 // Type check left and right.
1132 AddCheckClass( 1103 AddChecksToArgNr(call, left, /* arg_number = */ 0);
1133 left, ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1104 AddChecksToArgNr(call, right, /* arg_number = */ 1);
1134 call->deopt_id(), call->env(), call);
1135 // Type check right.
1136 AddCheckClass(
1137 right, ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecksForArgNr(1)),
1138 call->deopt_id(), call->env(), call);
1139 // Replace call. 1105 // Replace call.
1140 BinaryFloat64x2OpInstr* float64x2_bin_op = new (Z) BinaryFloat64x2OpInstr( 1106 BinaryFloat64x2OpInstr* float64x2_bin_op = new (Z) BinaryFloat64x2OpInstr(
1141 op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id()); 1107 op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id());
1142 ReplaceCall(call, float64x2_bin_op); 1108 ReplaceCall(call, float64x2_bin_op);
1143 return true; 1109 return true;
1144 } 1110 }
1145 1111
1146 1112
1147 // Only unique implicit instance getters can be currently handled. 1113 // Only unique implicit instance getters can be currently handled.
1148 bool AotOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) { 1114 bool AotOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) {
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after
1793 } 1759 }
1794 1760
1795 if ((op_kind == Token::kEQ) && TryReplaceWithHaveSameRuntimeType(instr)) { 1761 if ((op_kind == Token::kEQ) && TryReplaceWithHaveSameRuntimeType(instr)) {
1796 return; 1762 return;
1797 } 1763 }
1798 1764
1799 const ICData& unary_checks = 1765 const ICData& unary_checks =
1800 ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks()); 1766 ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks());
1801 const intptr_t number_of_checks = unary_checks.NumberOfChecks(); 1767 const intptr_t number_of_checks = unary_checks.NumberOfChecks();
1802 if (IsAllowedForInlining(instr->deopt_id()) && number_of_checks > 0) { 1768 if (IsAllowedForInlining(instr->deopt_id()) && number_of_checks > 0) {
1803 if ((op_kind == Token::kINDEX) && TryReplaceWithIndexedOp(instr)) { 1769 if ((op_kind == Token::kINDEX) &&
1770 TryReplaceWithIndexedOp(instr, &unary_checks)) {
1804 return; 1771 return;
1805 } 1772 }
1806 if ((op_kind == Token::kASSIGN_INDEX) && TryReplaceWithIndexedOp(instr)) { 1773 if ((op_kind == Token::kASSIGN_INDEX) &&
1774 TryReplaceWithIndexedOp(instr, &unary_checks)) {
1807 return; 1775 return;
1808 } 1776 }
1809 if ((op_kind == Token::kEQ) && TryReplaceWithEqualityOp(instr, op_kind)) { 1777 if ((op_kind == Token::kEQ) && TryReplaceWithEqualityOp(instr, op_kind)) {
1810 return; 1778 return;
1811 } 1779 }
1812 1780
1813 if (Token::IsRelationalOperator(op_kind) && 1781 if (Token::IsRelationalOperator(op_kind) &&
1814 TryReplaceWithRelationalOp(instr, op_kind)) { 1782 TryReplaceWithRelationalOp(instr, op_kind)) {
1815 return; 1783 return;
1816 } 1784 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1902 Class::Handle(Z, isolate()->class_table()->At(receiver_cid)); 1870 Class::Handle(Z, isolate()->class_table()->At(receiver_cid));
1903 1871
1904 const Array& args_desc_array = 1872 const Array& args_desc_array =
1905 Array::Handle(Z, ArgumentsDescriptor::New(instr->ArgumentCount(), 1873 Array::Handle(Z, ArgumentsDescriptor::New(instr->ArgumentCount(),
1906 instr->argument_names())); 1874 instr->argument_names()));
1907 ArgumentsDescriptor args_desc(args_desc_array); 1875 ArgumentsDescriptor args_desc(args_desc_array);
1908 Function& function = Function::Handle( 1876 Function& function = Function::Handle(
1909 Z, Resolver::ResolveDynamicForReceiverClass( 1877 Z, Resolver::ResolveDynamicForReceiverClass(
1910 receiver_class, instr->function_name(), args_desc)); 1878 receiver_class, instr->function_name(), args_desc));
1911 if (!function.IsNull()) { 1879 if (!function.IsNull()) {
1912 CallTargets* targets = new (Z) CallTargets(); 1880 CallTargets* targets = new (Z) CallTargets(Z);
1913 Function& target = Function::ZoneHandle(Z, function.raw()); 1881 Function& target = Function::ZoneHandle(Z, function.raw());
1914 targets->Add(CidRangeTarget(receiver_class.id(), receiver_class.id(), 1882 targets->Add(new (Z) TargetInfo(receiver_class.id(), receiver_class.id(),
1915 &target, /*count = */ 1)); 1883 &target, /*count = */ 1));
1916 PolymorphicInstanceCallInstr* call = 1884 PolymorphicInstanceCallInstr* call =
1917 new (Z) PolymorphicInstanceCallInstr(instr, *targets, 1885 new (Z) PolymorphicInstanceCallInstr(instr, *targets,
1918 /* with_checks = */ false, 1886 /* with_checks = */ false,
1919 /* complete = */ true); 1887 /* complete = */ true);
1920 instr->ReplaceWith(call, current_iterator()); 1888 instr->ReplaceWith(call, current_iterator());
1921 return; 1889 return;
1922 } 1890 }
1923 } 1891 }
1924 1892
1925 Definition* callee_receiver = instr->ArgumentAt(0); 1893 Definition* callee_receiver = instr->ArgumentAt(0);
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
2134 kDoubleCid)) { 2102 kDoubleCid)) {
2135 result_cid = kDoubleCid; 2103 result_cid = kDoubleCid;
2136 } else if (ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, 2104 } else if (ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid,
2137 kSmiCid)) { 2105 kSmiCid)) {
2138 result_cid = kSmiCid; 2106 result_cid = kSmiCid;
2139 } 2107 }
2140 if (result_cid != kIllegalCid) { 2108 if (result_cid != kIllegalCid) {
2141 MathMinMaxInstr* min_max = new (Z) MathMinMaxInstr( 2109 MathMinMaxInstr* min_max = new (Z) MathMinMaxInstr(
2142 recognized_kind, new (Z) Value(call->ArgumentAt(0)), 2110 recognized_kind, new (Z) Value(call->ArgumentAt(0)),
2143 new (Z) Value(call->ArgumentAt(1)), call->deopt_id(), result_cid); 2111 new (Z) Value(call->ArgumentAt(1)), call->deopt_id(), result_cid);
2144 const ICData& unary_checks = 2112 const Cids* cids = Cids::Create(Z, ic_data, 0);
Vyacheslav Egorov (Google) 2017/05/09 21:07:27 please add a comment here about what does 0 means.
erikcorry 2017/05/10 08:47:43 Done.
2145 ICData::ZoneHandle(Z, ic_data.AsUnaryClassChecks()); 2113 AddCheckClass(min_max->left()->definition(), *cids, call->deopt_id(),
2146 AddCheckClass(min_max->left()->definition(), unary_checks, 2114 call->env(), call);
2147 call->deopt_id(), call->env(), call); 2115 AddCheckClass(min_max->right()->definition(), *cids, call->deopt_id(),
2148 AddCheckClass(min_max->right()->definition(), unary_checks, 2116 call->env(), call);
2149 call->deopt_id(), call->env(), call);
2150 ReplaceCall(call, min_max); 2117 ReplaceCall(call, min_max);
2151 } 2118 }
2152 } 2119 }
2153 break; 2120 break;
2154 } 2121 }
2155 case MethodRecognizer::kDoubleFromInteger: { 2122 case MethodRecognizer::kDoubleFromInteger: {
2156 if (call->HasICData() && call->ic_data()->NumberOfChecksIs(1)) { 2123 if (call->HasICData() && call->ic_data()->NumberOfChecksIs(1)) {
2157 const ICData& ic_data = *call->ic_data(); 2124 const ICData& ic_data = *call->ic_data();
2158 if (CanUnboxDouble()) { 2125 if (CanUnboxDouble()) {
2159 if (ArgIsAlways(kSmiCid, ic_data, 1)) { 2126 if (ArgIsAlways(kSmiCid, ic_data, 1)) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
2255 FlowGraph::kEffect); 2222 FlowGraph::kEffect);
2256 current_iterator()->RemoveCurrentFromGraph(); 2223 current_iterator()->RemoveCurrentFromGraph();
2257 } 2224 }
2258 } 2225 }
2259 } 2226 }
2260 } 2227 }
2261 2228
2262 #endif // DART_PRECOMPILER 2229 #endif // DART_PRECOMPILER
2263 2230
2264 } // namespace dart 2231 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698