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

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

Issue 2856543002: Use off-heap data for class check instructions (Closed)
Patch Set: 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 #ifndef DART_PRECOMPILED_RUNTIME 4 #ifndef DART_PRECOMPILED_RUNTIME
5 #include "vm/jit_optimizer.h" 5 #include "vm/jit_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 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 Instruction* insert_before) { 382 Instruction* insert_before) {
383 if (to_check->Type()->ToCid() != kSmiCid) { 383 if (to_check->Type()->ToCid() != kSmiCid) {
384 InsertBefore(insert_before, 384 InsertBefore(insert_before,
385 new (Z) CheckSmiInstr(new (Z) Value(to_check), deopt_id, 385 new (Z) CheckSmiInstr(new (Z) Value(to_check), deopt_id,
386 insert_before->token_pos()), 386 insert_before->token_pos()),
387 deopt_environment, FlowGraph::kEffect); 387 deopt_environment, FlowGraph::kEffect);
388 } 388 }
389 } 389 }
390 390
391 391
392 Instruction* JitOptimizer::GetCheckClass(Definition* to_check,
393 const ICData& unary_checks,
394 intptr_t deopt_id,
395 TokenPosition token_pos) {
396 if ((unary_checks.NumberOfUsedChecks() == 1) &&
397 unary_checks.HasReceiverClassId(kSmiCid)) {
398 return new (Z) CheckSmiInstr(new (Z) Value(to_check), deopt_id, token_pos);
399 }
400 return new (Z) CheckClassInstr(new (Z) Value(to_check), deopt_id,
401 unary_checks, token_pos);
402 }
403
404
405 void JitOptimizer::AddCheckClass(Definition* to_check, 392 void JitOptimizer::AddCheckClass(Definition* to_check,
406 const ICData& unary_checks, 393 const CallTargets& targets,
407 intptr_t deopt_id, 394 intptr_t deopt_id,
408 Environment* deopt_environment, 395 Environment* deopt_environment,
409 Instruction* insert_before) { 396 Instruction* insert_before) {
410 // Type propagation has not run yet, we cannot eliminate the check. 397 // Type propagation has not run yet, we cannot eliminate the check.
411 Instruction* check = GetCheckClass(to_check, unary_checks, deopt_id, 398 Instruction* check = flow_graph_->GetCheckClass(to_check, targets, deopt_id,
412 insert_before->token_pos()); 399 insert_before->token_pos());
413 InsertBefore(insert_before, check, deopt_environment, FlowGraph::kEffect); 400 InsertBefore(insert_before, check, deopt_environment, FlowGraph::kEffect);
414 } 401 }
415 402
416 403
417 void JitOptimizer::AddReceiverCheck(InstanceCallInstr* call) { 404 void JitOptimizer::AddReceiverCheck(InstanceCallInstr* call) {
418 AddCheckClass(call->ArgumentAt(0), 405 AddCheckClass(
419 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()), 406 call->ArgumentAt(0),
420 call->deopt_id(), call->env(), call); 407 *CallTargets::Create(Z, *call->ic_data(), /* argument_number = */ 0),
408 call->deopt_id(), call->env(), call);
421 } 409 }
422 410
423 411
424 static bool ArgIsAlways(intptr_t cid, 412 static bool ArgIsAlways(intptr_t cid,
425 const ICData& ic_data, 413 const ICData& ic_data,
426 intptr_t arg_number) { 414 intptr_t arg_number) {
427 ASSERT(ic_data.NumArgsTested() > arg_number); 415 ASSERT(ic_data.NumArgsTested() > arg_number);
428 if (ic_data.NumberOfUsedChecks() == 0) { 416 if (ic_data.NumberOfUsedChecks() == 0) {
429 return false; 417 return false;
430 } 418 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 497
510 Definition* to_remove_right = NULL; 498 Definition* to_remove_right = NULL;
511 Value* right_val = NULL; 499 Value* right_val = NULL;
512 if (right->IsOneByteStringFromCharCode()) { 500 if (right->IsOneByteStringFromCharCode()) {
513 // Skip string-from-char-code, and use its input as right value. 501 // Skip string-from-char-code, and use its input as right value.
514 OneByteStringFromCharCodeInstr* right_instr = 502 OneByteStringFromCharCodeInstr* right_instr =
515 right->AsOneByteStringFromCharCode(); 503 right->AsOneByteStringFromCharCode();
516 right_val = new (Z) Value(right_instr->char_code()->definition()); 504 right_val = new (Z) Value(right_instr->char_code()->definition());
517 to_remove_right = right_instr; 505 to_remove_right = right_instr;
518 } else { 506 } else {
519 const ICData& unary_checks_1 = 507 const CallTargets* targets_1 =
520 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecksForArgNr(1)); 508 CallTargets::Create(Z, *call->ic_data(), 1);
521 AddCheckClass(right, unary_checks_1, call->deopt_id(), call->env(), call); 509 AddCheckClass(right, *targets_1, call->deopt_id(), call->env(), call);
522 // String-to-char-code instructions returns -1 (illegal charcode) if 510 // String-to-char-code instructions returns -1 (illegal charcode) if
523 // string is not of length one. 511 // string is not of length one.
524 StringToCharCodeInstr* char_code_right = new (Z) 512 StringToCharCodeInstr* char_code_right = new (Z)
525 StringToCharCodeInstr(new (Z) Value(right), kOneByteStringCid); 513 StringToCharCodeInstr(new (Z) Value(right), kOneByteStringCid);
526 InsertBefore(call, char_code_right, call->env(), FlowGraph::kValue); 514 InsertBefore(call, char_code_right, call->env(), FlowGraph::kValue);
527 right_val = new (Z) Value(char_code_right); 515 right_val = new (Z) Value(char_code_right);
528 } 516 }
529 517
530 // Comparing char-codes instead of strings. 518 // Comparing char-codes instead of strings.
531 EqualityCompareInstr* comp = 519 EqualityCompareInstr* comp =
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 } 590 }
603 } else { 591 } else {
604 // Check if ICDData contains checks with Smi/Null combinations. In that case 592 // Check if ICDData contains checks with Smi/Null combinations. In that case
605 // we can still emit the optimized Smi equality operation but need to add 593 // we can still emit the optimized Smi equality operation but need to add
606 // checks for null or Smi. 594 // checks for null or Smi.
607 GrowableArray<intptr_t> smi_or_null(2); 595 GrowableArray<intptr_t> smi_or_null(2);
608 smi_or_null.Add(kSmiCid); 596 smi_or_null.Add(kSmiCid);
609 smi_or_null.Add(kNullCid); 597 smi_or_null.Add(kNullCid);
610 if (ICDataHasOnlyReceiverArgumentClassIds(ic_data, smi_or_null, 598 if (ICDataHasOnlyReceiverArgumentClassIds(ic_data, smi_or_null,
611 smi_or_null)) { 599 smi_or_null)) {
612 const ICData& unary_checks_0 = 600 const CallTargets* targets_0 =
613 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()); 601 CallTargets::Create(Z, *call->ic_data(), 0);
614 AddCheckClass(left, unary_checks_0, call->deopt_id(), call->env(), call); 602 AddCheckClass(left, *targets_0, call->deopt_id(), call->env(), call);
615 603
616 const ICData& unary_checks_1 = 604 const CallTargets* targets_1 =
617 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecksForArgNr(1)); 605 CallTargets::Create(Z, *call->ic_data(), 1);
618 AddCheckClass(right, unary_checks_1, call->deopt_id(), call->env(), call); 606 AddCheckClass(right, *targets_1, call->deopt_id(), call->env(), call);
619 cid = kSmiCid; 607 cid = kSmiCid;
620 } else { 608 } else {
621 // Shortcut for equality with null. 609 // Shortcut for equality with null.
622 ConstantInstr* right_const = right->AsConstant(); 610 ConstantInstr* right_const = right->AsConstant();
623 ConstantInstr* left_const = left->AsConstant(); 611 ConstantInstr* left_const = left->AsConstant();
624 if ((right_const != NULL && right_const->value().IsNull()) || 612 if ((right_const != NULL && right_const->value().IsNull()) ||
625 (left_const != NULL && left_const->value().IsNull())) { 613 (left_const != NULL && left_const->value().IsNull())) {
626 StrictCompareInstr* comp = new (Z) 614 StrictCompareInstr* comp = new (Z)
627 StrictCompareInstr(call->token_pos(), Token::kEQ_STRICT, 615 StrictCompareInstr(call->token_pos(), Token::kEQ_STRICT,
628 new (Z) Value(left), new (Z) Value(right), 616 new (Z) Value(left), new (Z) Value(right),
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
973 961
974 bool JitOptimizer::InlineFloat32x4BinaryOp(InstanceCallInstr* call, 962 bool JitOptimizer::InlineFloat32x4BinaryOp(InstanceCallInstr* call,
975 Token::Kind op_kind) { 963 Token::Kind op_kind) {
976 if (!ShouldInlineSimd()) { 964 if (!ShouldInlineSimd()) {
977 return false; 965 return false;
978 } 966 }
979 ASSERT(call->ArgumentCount() == 2); 967 ASSERT(call->ArgumentCount() == 2);
980 Definition* left = call->ArgumentAt(0); 968 Definition* left = call->ArgumentAt(0);
981 Definition* right = call->ArgumentAt(1); 969 Definition* right = call->ArgumentAt(1);
982 // Type check left. 970 // Type check left.
983 AddCheckClass(left, ICData::ZoneHandle( 971 AddCheckClass(left, *CallTargets::Create(Z, *call->ic_data(), 0),
984 Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
985 call->deopt_id(), call->env(), call); 972 call->deopt_id(), call->env(), call);
986 // Type check right. 973 // Type check right.
987 AddCheckClass(right, ICData::ZoneHandle( 974 AddCheckClass(right, *CallTargets::Create(Z, *call->ic_data(), 1),
988 Z, call->ic_data()->AsUnaryClassChecksForArgNr(1)),
989 call->deopt_id(), call->env(), call); 975 call->deopt_id(), call->env(), call);
990 // Replace call. 976 // Replace call.
991 BinaryFloat32x4OpInstr* float32x4_bin_op = new (Z) BinaryFloat32x4OpInstr( 977 BinaryFloat32x4OpInstr* float32x4_bin_op = new (Z) BinaryFloat32x4OpInstr(
992 op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id()); 978 op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id());
993 ReplaceCall(call, float32x4_bin_op); 979 ReplaceCall(call, float32x4_bin_op);
994 980
995 return true; 981 return true;
996 } 982 }
997 983
998 984
999 bool JitOptimizer::InlineInt32x4BinaryOp(InstanceCallInstr* call, 985 bool JitOptimizer::InlineInt32x4BinaryOp(InstanceCallInstr* call,
1000 Token::Kind op_kind) { 986 Token::Kind op_kind) {
1001 if (!ShouldInlineSimd()) { 987 if (!ShouldInlineSimd()) {
1002 return false; 988 return false;
1003 } 989 }
1004 ASSERT(call->ArgumentCount() == 2); 990 ASSERT(call->ArgumentCount() == 2);
1005 Definition* left = call->ArgumentAt(0); 991 Definition* left = call->ArgumentAt(0);
1006 Definition* right = call->ArgumentAt(1); 992 Definition* right = call->ArgumentAt(1);
1007 // Type check left. 993 // Type check left.
1008 AddCheckClass(left, ICData::ZoneHandle( 994 AddCheckClass(left, *CallTargets::Create(Z, *call->ic_data(), 0),
1009 Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1010 call->deopt_id(), call->env(), call); 995 call->deopt_id(), call->env(), call);
1011 // Type check right. 996 // Type check right.
1012 AddCheckClass(right, ICData::ZoneHandle( 997 AddCheckClass(right, *CallTargets::Create(Z, *call->ic_data(), 1),
1013 Z, call->ic_data()->AsUnaryClassChecksForArgNr(1)),
1014 call->deopt_id(), call->env(), call); 998 call->deopt_id(), call->env(), call);
1015 // Replace call. 999 // Replace call.
1016 BinaryInt32x4OpInstr* int32x4_bin_op = new (Z) BinaryInt32x4OpInstr( 1000 BinaryInt32x4OpInstr* int32x4_bin_op = new (Z) BinaryInt32x4OpInstr(
1017 op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id()); 1001 op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id());
1018 ReplaceCall(call, int32x4_bin_op); 1002 ReplaceCall(call, int32x4_bin_op);
1019 return true; 1003 return true;
1020 } 1004 }
1021 1005
1022 1006
1023 bool JitOptimizer::InlineFloat64x2BinaryOp(InstanceCallInstr* call, 1007 bool JitOptimizer::InlineFloat64x2BinaryOp(InstanceCallInstr* call,
1024 Token::Kind op_kind) { 1008 Token::Kind op_kind) {
1025 if (!ShouldInlineSimd()) { 1009 if (!ShouldInlineSimd()) {
1026 return false; 1010 return false;
1027 } 1011 }
1028 ASSERT(call->ArgumentCount() == 2); 1012 ASSERT(call->ArgumentCount() == 2);
1029 Definition* left = call->ArgumentAt(0); 1013 Definition* left = call->ArgumentAt(0);
1030 Definition* right = call->ArgumentAt(1); 1014 Definition* right = call->ArgumentAt(1);
1031 // Type check left. 1015 // Type check left.
1032 AddCheckClass( 1016 AddCheckClass(left, *CallTargets::Create(Z, *call->ic_data(), 0),
1033 left, ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1017 call->deopt_id(), call->env(), call);
1034 call->deopt_id(), call->env(), call);
1035 // Type check right. 1018 // Type check right.
1036 AddCheckClass( 1019 AddCheckClass(right, *CallTargets::Create(Z, *call->ic_data(), 1),
1037 right, ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecksForArgNr(1)), 1020 call->deopt_id(), call->env(), call);
1038 call->deopt_id(), call->env(), call);
1039 // Replace call. 1021 // Replace call.
1040 BinaryFloat64x2OpInstr* float64x2_bin_op = new (Z) BinaryFloat64x2OpInstr( 1022 BinaryFloat64x2OpInstr* float64x2_bin_op = new (Z) BinaryFloat64x2OpInstr(
1041 op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id()); 1023 op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id());
1042 ReplaceCall(call, float64x2_bin_op); 1024 ReplaceCall(call, float64x2_bin_op);
1043 return true; 1025 return true;
1044 } 1026 }
1045 1027
1046 1028
1047 // Only unique implicit instance getters can be currently handled. 1029 // Only unique implicit instance getters can be currently handled.
1048 bool JitOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) { 1030 bool JitOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) {
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
1502 return; 1484 return;
1503 } 1485 }
1504 if ((op_kind == Token::kSET) && 1486 if ((op_kind == Token::kSET) &&
1505 TryInlineInstanceSetter(instr, unary_checks)) { 1487 TryInlineInstanceSetter(instr, unary_checks)) {
1506 return; 1488 return;
1507 } 1489 }
1508 if (TryInlineInstanceMethod(instr)) { 1490 if (TryInlineInstanceMethod(instr)) {
1509 return; 1491 return;
1510 } 1492 }
1511 1493
1512 CallTargets* targets = CallTargets::Create(Z, unary_checks); 1494 const CallTargets& targets = *CallTargets::CreateAndExpand(Z, unary_checks);
1513 1495
1514 bool has_one_target = targets->HasSingleTarget(); 1496 bool has_one_target = targets.HasSingleTarget();
1515 1497
1516 if (has_one_target) { 1498 if (has_one_target) {
1517 // Check if the single target is a polymorphic target, if it is, 1499 // Check if the single target is a polymorphic target, if it is,
1518 // we don't have one target. 1500 // we don't have one target.
1519 const Function& target = Function::Handle(Z, unary_checks.GetTargetAt(0)); 1501 const Function& target = Function::Handle(Z, unary_checks.GetTargetAt(0));
1520 if (target.recognized_kind() == MethodRecognizer::kObjectRuntimeType) { 1502 if (target.recognized_kind() == MethodRecognizer::kObjectRuntimeType) {
1521 has_one_target = PolymorphicInstanceCallInstr::ComputeRuntimeType( 1503 has_one_target = PolymorphicInstanceCallInstr::ComputeRuntimeType(
1522 *targets) != Type::null(); 1504 targets) != Type::null();
1523 } else { 1505 } else {
1524 const bool polymorphic_target = 1506 const bool polymorphic_target =
1525 MethodRecognizer::PolymorphicTarget(target); 1507 MethodRecognizer::PolymorphicTarget(target);
1526 has_one_target = !polymorphic_target; 1508 has_one_target = !polymorphic_target;
1527 } 1509 }
1528 } 1510 }
1529 1511
1530 if (has_one_target) { 1512 if (has_one_target) {
1531 const Function& target = Function::Handle(Z, unary_checks.GetTargetAt(0)); 1513 const Function& target = Function::Handle(Z, unary_checks.GetTargetAt(0));
1532 const RawFunction::Kind function_kind = target.kind(); 1514 const RawFunction::Kind function_kind = target.kind();
1533 if (!flow_graph()->InstanceCallNeedsClassCheck(instr, function_kind)) { 1515 if (!flow_graph()->InstanceCallNeedsClassCheck(instr, function_kind)) {
1534 PolymorphicInstanceCallInstr* call = 1516 PolymorphicInstanceCallInstr* call =
1535 new (Z) PolymorphicInstanceCallInstr(instr, *targets, 1517 new (Z) PolymorphicInstanceCallInstr(instr, targets,
1536 /* call_with_checks = */ false, 1518 /* call_with_checks = */ false,
1537 /* complete = */ false); 1519 /* complete = */ false);
1538 instr->ReplaceWith(call, current_iterator()); 1520 instr->ReplaceWith(call, current_iterator());
1539 return; 1521 return;
1540 } 1522 }
1541 } 1523 }
1542 1524
1543 // If there is only one target we can make this into a deopting class check, 1525 // If there is only one target we can make this into a deopting class check,
1544 // followed by a call instruction that does not check the class of the 1526 // followed by a call instruction that does not check the class of the
1545 // receiver. This enables a lot of optimizations because after the class 1527 // receiver. This enables a lot of optimizations because after the class
(...skipping 11 matching lines...) Expand all
1557 // Type propagation has not run yet, we cannot eliminate the check. 1539 // Type propagation has not run yet, we cannot eliminate the check.
1558 // TODO(erikcorry): The receiver check should use the off-heap targets 1540 // TODO(erikcorry): The receiver check should use the off-heap targets
1559 // array, not the IC array. 1541 // array, not the IC array.
1560 AddReceiverCheck(instr); 1542 AddReceiverCheck(instr);
1561 // Call can still deoptimize, do not detach environment from instr. 1543 // Call can still deoptimize, do not detach environment from instr.
1562 call_with_checks = false; 1544 call_with_checks = false;
1563 } else { 1545 } else {
1564 call_with_checks = true; 1546 call_with_checks = true;
1565 } 1547 }
1566 PolymorphicInstanceCallInstr* call = 1548 PolymorphicInstanceCallInstr* call =
1567 new (Z) PolymorphicInstanceCallInstr(instr, *targets, call_with_checks, 1549 new (Z) PolymorphicInstanceCallInstr(instr, targets, call_with_checks,
1568 /* complete = */ false); 1550 /* complete = */ false);
1569 instr->ReplaceWith(call, current_iterator()); 1551 instr->ReplaceWith(call, current_iterator());
1570 } 1552 }
1571 1553
1572 1554
1573 void JitOptimizer::VisitStaticCall(StaticCallInstr* call) { 1555 void JitOptimizer::VisitStaticCall(StaticCallInstr* call) {
1574 MethodRecognizer::Kind recognized_kind = 1556 MethodRecognizer::Kind recognized_kind =
1575 MethodRecognizer::RecognizeKind(call->function()); 1557 MethodRecognizer::RecognizeKind(call->function());
1576 switch (recognized_kind) { 1558 switch (recognized_kind) {
1577 case MethodRecognizer::kObjectConstructor: 1559 case MethodRecognizer::kObjectConstructor:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1610 kDoubleCid)) { 1592 kDoubleCid)) {
1611 result_cid = kDoubleCid; 1593 result_cid = kDoubleCid;
1612 } else if (ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, 1594 } else if (ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid,
1613 kSmiCid)) { 1595 kSmiCid)) {
1614 result_cid = kSmiCid; 1596 result_cid = kSmiCid;
1615 } 1597 }
1616 if (result_cid != kIllegalCid) { 1598 if (result_cid != kIllegalCid) {
1617 MathMinMaxInstr* min_max = new (Z) MathMinMaxInstr( 1599 MathMinMaxInstr* min_max = new (Z) MathMinMaxInstr(
1618 recognized_kind, new (Z) Value(call->ArgumentAt(0)), 1600 recognized_kind, new (Z) Value(call->ArgumentAt(0)),
1619 new (Z) Value(call->ArgumentAt(1)), call->deopt_id(), result_cid); 1601 new (Z) Value(call->ArgumentAt(1)), call->deopt_id(), result_cid);
1620 const ICData& unary_checks = 1602 const CallTargets* targets = CallTargets::Create(Z, ic_data, 0);
1621 ICData::ZoneHandle(Z, ic_data.AsUnaryClassChecks()); 1603 AddCheckClass(min_max->left()->definition(), *targets,
1622 AddCheckClass(min_max->left()->definition(), unary_checks,
1623 call->deopt_id(), call->env(), call); 1604 call->deopt_id(), call->env(), call);
1624 AddCheckClass(min_max->right()->definition(), unary_checks, 1605 AddCheckClass(min_max->right()->definition(), *targets,
1625 call->deopt_id(), call->env(), call); 1606 call->deopt_id(), call->env(), call);
1626 ReplaceCall(call, min_max); 1607 ReplaceCall(call, min_max);
1627 } 1608 }
1628 } 1609 }
1629 break; 1610 break;
1630 } 1611 }
1631 1612
1632 case MethodRecognizer::kDoubleFromInteger: { 1613 case MethodRecognizer::kDoubleFromInteger: {
1633 if (call->HasICData() && call->ic_data()->NumberOfChecksIs(1)) { 1614 if (call->HasICData() && call->ic_data()->NumberOfChecksIs(1)) {
1634 const ICData& ic_data = *call->ic_data(); 1615 const ICData& ic_data = *call->ic_data();
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1813 // Discard the environment from the original instruction because the store 1794 // Discard the environment from the original instruction because the store
1814 // can't deoptimize. 1795 // can't deoptimize.
1815 instr->RemoveEnvironment(); 1796 instr->RemoveEnvironment();
1816 ReplaceCall(instr, store); 1797 ReplaceCall(instr, store);
1817 return true; 1798 return true;
1818 } 1799 }
1819 1800
1820 1801
1821 } // namespace dart 1802 } // namespace dart
1822 #endif // DART_PRECOMPILED_RUNTIME 1803 #endif // DART_PRECOMPILED_RUNTIME
OLDNEW
« runtime/vm/intermediate_language_ia32.cc ('K') | « runtime/vm/jit_optimizer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698