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

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

Issue 27307005: Change == into an instance call to allow polymorphic inlining of ==. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: rebased, addressed comments Created 7 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/flow_graph_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/ast_printer.h" 8 #include "vm/ast_printer.h"
9 #include "vm/bit_vector.h" 9 #include "vm/bit_vector.h"
10 #include "vm/code_descriptors.h" 10 #include "vm/code_descriptors.h"
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 void TestGraphVisitor::ReturnValue(Value* value) { 664 void TestGraphVisitor::ReturnValue(Value* value) {
665 if (FLAG_enable_type_checks) { 665 if (FLAG_enable_type_checks) {
666 value = Bind(new AssertBooleanInstr(condition_token_pos(), value)); 666 value = Bind(new AssertBooleanInstr(condition_token_pos(), value));
667 } 667 }
668 Value* constant_true = Bind(new ConstantInstr(Bool::True())); 668 Value* constant_true = Bind(new ConstantInstr(Bool::True()));
669 StrictCompareInstr* comp = 669 StrictCompareInstr* comp =
670 new StrictCompareInstr(condition_token_pos(), 670 new StrictCompareInstr(condition_token_pos(),
671 Token::kEQ_STRICT, 671 Token::kEQ_STRICT,
672 value, 672 value,
673 constant_true); 673 constant_true);
674 comp->set_needs_number_check(false);
674 BranchInstr* branch = new BranchInstr(comp); 675 BranchInstr* branch = new BranchInstr(comp);
675 AddInstruction(branch); 676 AddInstruction(branch);
676 CloseFragment(); 677 CloseFragment();
677 678
678 true_successor_addresses_.Add(branch->true_successor_address()); 679 true_successor_addresses_.Add(branch->true_successor_address());
679 false_successor_addresses_.Add(branch->false_successor_address()); 680 false_successor_addresses_.Add(branch->false_successor_address());
680 } 681 }
681 682
682 683
683 void TestGraphVisitor::MergeBranchWithComparison(ComparisonInstr* comp) { 684 void TestGraphVisitor::MergeBranchWithComparison(ComparisonInstr* comp) {
684 BranchInstr* branch; 685 BranchInstr* branch;
685 if (Token::IsStrictEqualityOperator(comp->kind())) { 686 if (Token::IsStrictEqualityOperator(comp->kind())) {
686 branch = new BranchInstr(new StrictCompareInstr(comp->token_pos(), 687 ASSERT(comp->IsStrictCompare());
687 comp->kind(), 688 branch = new BranchInstr(comp);
688 comp->left(),
689 comp->right()));
690 } else if (Token::IsEqualityOperator(comp->kind()) && 689 } else if (Token::IsEqualityOperator(comp->kind()) &&
691 (comp->left()->BindsToConstantNull() || 690 (comp->left()->BindsToConstantNull() ||
692 comp->right()->BindsToConstantNull())) { 691 comp->right()->BindsToConstantNull())) {
693 branch = new BranchInstr(new StrictCompareInstr( 692 branch = new BranchInstr(new StrictCompareInstr(
694 comp->token_pos(), 693 comp->token_pos(),
695 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT, 694 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT,
696 comp->left(), 695 comp->left(),
697 comp->right())); 696 comp->right()));
698 } else { 697 } else {
699 branch = new BranchInstr(comp, FLAG_enable_type_checks); 698 branch = new BranchInstr(comp, FLAG_enable_type_checks);
700 } 699 }
701 AddInstruction(branch); 700 AddInstruction(branch);
702 CloseFragment(); 701 CloseFragment();
703 true_successor_addresses_.Add(branch->true_successor_address()); 702 true_successor_addresses_.Add(branch->true_successor_address());
704 false_successor_addresses_.Add(branch->false_successor_address()); 703 false_successor_addresses_.Add(branch->false_successor_address());
705 } 704 }
706 705
707 706
708 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) { 707 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) {
709 ASSERT(!FLAG_enable_type_checks); 708 ASSERT(!FLAG_enable_type_checks);
710 Value* constant_true = Bind(new ConstantInstr(Bool::True())); 709 Value* constant_true = Bind(new ConstantInstr(Bool::True()));
711 BranchInstr* branch = new BranchInstr( 710 StrictCompareInstr* comp =
712 new StrictCompareInstr(condition_token_pos(), 711 new StrictCompareInstr(condition_token_pos(),
713 Token::kNE_STRICT, 712 Token::kNE_STRICT,
714 neg->value(), 713 neg->value(),
715 constant_true)); 714 constant_true);
715 comp->set_needs_number_check(false);
716 BranchInstr* branch = new BranchInstr(comp);
716 AddInstruction(branch); 717 AddInstruction(branch);
717 CloseFragment(); 718 CloseFragment();
718 true_successor_addresses_.Add(branch->true_successor_address()); 719 true_successor_addresses_.Add(branch->true_successor_address());
719 false_successor_addresses_.Add(branch->false_successor_address()); 720 false_successor_addresses_.Add(branch->false_successor_address());
720 } 721 }
721 722
722 723
723 void TestGraphVisitor::ReturnDefinition(Definition* definition) { 724 void TestGraphVisitor::ReturnDefinition(Definition* definition) {
724 ComparisonInstr* comp = definition->AsComparison(); 725 ComparisonInstr* comp = definition->AsComparison();
725 if (comp != NULL) { 726 if (comp != NULL) {
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 Library::PrivateCoreLibName(Symbols::_as()), 1360 Library::PrivateCoreLibName(Symbols::_as()),
1360 node->kind(), 1361 node->kind(),
1361 arguments, 1362 arguments,
1362 Object::null_array(), // No argument names. 1363 Object::null_array(), // No argument names.
1363 kNumArgsChecked, 1364 kNumArgsChecked,
1364 owner()->ic_data_array()); 1365 owner()->ic_data_array());
1365 ReturnDefinition(call); 1366 ReturnDefinition(call);
1366 } 1367 }
1367 1368
1368 1369
1370 StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare(AstNode* left,
1371 AstNode* right,
1372 Token::Kind kind,
1373 intptr_t token_pos) {
1374 ValueGraphVisitor for_left_value(owner(), temp_index());
1375 left->Visit(&for_left_value);
1376 Append(for_left_value);
1377 ValueGraphVisitor for_right_value(owner(), temp_index());
1378 right->Visit(&for_right_value);
1379 Append(for_right_value);
1380 StrictCompareInstr* comp = new StrictCompareInstr(token_pos,
1381 kind,
1382 for_left_value.value(),
1383 for_right_value.value());
1384 return comp;
1385 }
1386
1387
1369 // <Expression> :: Comparison { kind: Token::Kind 1388 // <Expression> :: Comparison { kind: Token::Kind
1370 // left: <Expression> 1389 // left: <Expression>
1371 // right: <Expression> } 1390 // right: <Expression> }
1372 // TODO(srdjan): Implement new equality. 1391 // TODO(srdjan): Implement new equality.
1373 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { 1392 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
1374 if (Token::IsTypeTestOperator(node->kind())) { 1393 if (Token::IsTypeTestOperator(node->kind())) {
1375 BuildTypeTest(node); 1394 BuildTypeTest(node);
1376 return; 1395 return;
1377 } 1396 }
1378 if (Token::IsTypeCastOperator(node->kind())) { 1397 if (Token::IsTypeCastOperator(node->kind())) {
1379 BuildTypeCast(node); 1398 BuildTypeCast(node);
1380 return; 1399 return;
1381 } 1400 }
1401
1382 if ((node->kind() == Token::kEQ_STRICT) || 1402 if ((node->kind() == Token::kEQ_STRICT) ||
1383 (node->kind() == Token::kNE_STRICT)) { 1403 (node->kind() == Token::kNE_STRICT)) {
1384 ValueGraphVisitor for_left_value(owner(), temp_index()); 1404 ReturnDefinition(BuildStrictCompare(node->left(), node->right(),
1385 node->left()->Visit(&for_left_value); 1405 node->kind(), node->token_pos()));
1386 Append(for_left_value);
1387 ValueGraphVisitor for_right_value(owner(), temp_index());
1388 node->right()->Visit(&for_right_value);
1389 Append(for_right_value);
1390 StrictCompareInstr* comp = new StrictCompareInstr(node->token_pos(),
1391 node->kind(),
1392 for_left_value.value(),
1393 for_right_value.value());
1394 ReturnDefinition(comp);
1395 return; 1406 return;
1396 } 1407 }
1397 1408
1398 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { 1409 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) {
1410 // Eagerly fold null-comparisons.
1411 LiteralNode* left_lit = node->left()->AsLiteralNode();
1412 LiteralNode* right_lit = node->right()->AsLiteralNode();
1413 if (((left_lit != NULL) && left_lit->literal().IsNull()) ||
1414 ((right_lit != NULL) && right_lit->literal().IsNull())) {
1415 Token::Kind kind =
1416 (node->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT;
1417 StrictCompareInstr* compare =
1418 BuildStrictCompare(node->left(), node->right(),
1419 kind, node->token_pos());
1420 ReturnDefinition(compare);
1421 return;
1422 }
1423
1424 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1425 new ZoneGrowableArray<PushArgumentInstr*>(2);
1426
1399 ValueGraphVisitor for_left_value(owner(), temp_index()); 1427 ValueGraphVisitor for_left_value(owner(), temp_index());
1400 node->left()->Visit(&for_left_value); 1428 node->left()->Visit(&for_left_value);
1401 Append(for_left_value); 1429 Append(for_left_value);
1430 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1431 arguments->Add(push_left);
1432
1402 ValueGraphVisitor for_right_value(owner(), temp_index()); 1433 ValueGraphVisitor for_right_value(owner(), temp_index());
1403 node->right()->Visit(&for_right_value); 1434 node->right()->Visit(&for_right_value);
1404 Append(for_right_value); 1435 Append(for_right_value);
1436 PushArgumentInstr* push_right = PushArgument(for_right_value.value());
1437 arguments->Add(push_right);
1438
1439 Definition* result =
1440 new InstanceCallInstr(node->token_pos(),
1441 Symbols::EqualOperator(),
1442 Token::kEQ, // Result is negated later for kNE.
1443 arguments,
1444 Object::null_array(),
1445 2,
1446 owner()->ic_data_array());
1405 if (FLAG_enable_type_checks) { 1447 if (FLAG_enable_type_checks) {
1406 EqualityCompareInstr* comp = new EqualityCompareInstr( 1448 Value* value = Bind(result);
1407 node->token_pos(), 1449 result = new AssertBooleanInstr(node->token_pos(), value);
1408 Token::kEQ,
1409 for_left_value.value(),
1410 for_right_value.value(),
1411 owner()->ic_data_array());
1412 if (node->kind() == Token::kEQ) {
1413 ReturnDefinition(comp);
1414 } else {
1415 Value* eq_result = Bind(comp);
1416 eq_result = Bind(new AssertBooleanInstr(node->token_pos(), eq_result));
1417 ReturnDefinition(new BooleanNegateInstr(eq_result));
1418 }
1419 } else {
1420 EqualityCompareInstr* comp = new EqualityCompareInstr(
1421 node->token_pos(),
1422 node->kind(),
1423 for_left_value.value(),
1424 for_right_value.value(),
1425 owner()->ic_data_array());
1426 ReturnDefinition(comp);
1427 } 1450 }
1451
1452 if (node->kind() == Token::kNE) {
1453 Value* value = Bind(result);
1454 result = new BooleanNegateInstr(value);
1455 }
1456 ReturnDefinition(result);
1428 return; 1457 return;
1429 } 1458 }
1430 1459
1431 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1460 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1432 new ZoneGrowableArray<PushArgumentInstr*>(2); 1461 new ZoneGrowableArray<PushArgumentInstr*>(2);
1433 1462
1434 ValueGraphVisitor for_left_value(owner(), temp_index()); 1463 ValueGraphVisitor for_left_value(owner(), temp_index());
1435 node->left()->Visit(&for_left_value); 1464 node->left()->Visit(&for_left_value);
1436 Append(for_left_value); 1465 Append(for_left_value);
1437 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1466 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
(...skipping 1480 matching lines...) Expand 10 before | Expand all | Expand 10 after
2918 true); // Test only. 2947 true); // Test only.
2919 return new LoadLocalInstr(*receiver_var); 2948 return new LoadLocalInstr(*receiver_var);
2920 } 2949 }
2921 2950
2922 2951
2923 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { 2952 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
2924 const Function& function = owner()->parsed_function()->function(); 2953 const Function& function = owner()->parsed_function()->function();
2925 if (!function.IsClosureFunction()) { 2954 if (!function.IsClosureFunction()) {
2926 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function); 2955 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
2927 switch (kind) { 2956 switch (kind) {
2957 case MethodRecognizer::kObjectEquals: {
2958 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
2959 LocalVariable* other_var =
2960 node->scope()->LookupVariable(Symbols::Other(),
2961 true); // Test only.
2962 Value* other = Bind(new LoadLocalInstr(*other_var));
2963 StrictCompareInstr* compare =
2964 new StrictCompareInstr(node->token_pos(),
2965 Token::kEQ_STRICT,
2966 receiver,
2967 other);
2968 // Receiver is not a number because numbers override equality.
2969 compare->set_needs_number_check(false);
2970 return ReturnDefinition(compare);
2971 }
2928 case MethodRecognizer::kStringBaseLength: 2972 case MethodRecognizer::kStringBaseLength:
2929 case MethodRecognizer::kStringBaseIsEmpty: { 2973 case MethodRecognizer::kStringBaseIsEmpty: {
2930 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 2974 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
2931 // Treat length loads as mutable (i.e. affected by side effects) to 2975 // Treat length loads as mutable (i.e. affected by side effects) to
2932 // avoid hoisting them since we can't hoist the preceding class-check. 2976 // avoid hoisting them since we can't hoist the preceding class-check.
2933 // This is because of externalization of strings that affects their 2977 // This is because of externalization of strings that affects their
2934 // class-id. 2978 // class-id.
2935 const bool is_immutable = false; 2979 const bool is_immutable = false;
2936 LoadFieldInstr* load = new LoadFieldInstr( 2980 LoadFieldInstr* load = new LoadFieldInstr(
2937 receiver, 2981 receiver,
(...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after
3858 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 3902 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
3859 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 3903 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
3860 OS::SNPrint(chars, len, kFormat, function_name, reason); 3904 OS::SNPrint(chars, len, kFormat, function_name, reason);
3861 const Error& error = Error::Handle( 3905 const Error& error = Error::Handle(
3862 LanguageError::New(String::Handle(String::New(chars)))); 3906 LanguageError::New(String::Handle(String::New(chars))));
3863 Isolate::Current()->long_jump_base()->Jump(1, error); 3907 Isolate::Current()->long_jump_base()->Jump(1, error);
3864 } 3908 }
3865 3909
3866 3910
3867 } // namespace dart 3911 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698