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

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

Issue 9395016: First part of new ICData infrastructure: use a wrapper object instead of an array. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object_test.cc ('k') | runtime/vm/raw_object.h » ('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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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/opt_code_generator.h" 8 #include "vm/opt_code_generator.h"
9 9
10 #include "vm/assembler_macros.h" 10 #include "vm/assembler_macros.h"
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 317
318 318
319 static const ZoneGrowableArray<const Class*>* 319 static const ZoneGrowableArray<const Class*>*
320 CollectedClassesAtNode(AstNode* node) { 320 CollectedClassesAtNode(AstNode* node) {
321 ZoneGrowableArray<const Class*>* result = 321 ZoneGrowableArray<const Class*>* result =
322 new ZoneGrowableArray<const Class*>(); 322 new ZoneGrowableArray<const Class*>();
323 const ICData& ic_data = node->ICDataAtId(node->id()); 323 const ICData& ic_data = node->ICDataAtId(node->id());
324 if (ic_data.NumberOfChecks() == 0) { 324 if (ic_data.NumberOfChecks() == 0) {
325 return result; 325 return result;
326 } 326 }
327 ASSERT(ic_data.NumberOfArgumentsChecked() == 1); 327 ASSERT(ic_data.num_args_tested() == 1);
328 Function& target = Function::Handle(); 328 Function& target = Function::Handle();
329 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { 329 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
330 Class& cls = Class::ZoneHandle(); 330 Class& cls = Class::ZoneHandle();
331 ic_data.GetOneClassCheckAt(i, &cls, &target); 331 ic_data.GetOneClassCheckAt(i, &cls, &target);
332 result->Add(&cls); 332 result->Add(&cls);
333 } 333 }
334 return result; 334 return result;
335 } 335 }
336 336
337 337
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 static bool AtIdNodeHasClassAt(AstNode* node, 630 static bool AtIdNodeHasClassAt(AstNode* node,
631 intptr_t id, 631 intptr_t id,
632 const Class& cls, 632 const Class& cls,
633 intptr_t arg_index) { 633 intptr_t arg_index) {
634 ASSERT(node != NULL); 634 ASSERT(node != NULL);
635 ASSERT(!cls.IsNull()); 635 ASSERT(!cls.IsNull());
636 const ICData& ic_data = node->ICDataAtId(id); 636 const ICData& ic_data = node->ICDataAtId(id);
637 if (ic_data.NumberOfChecks() == 0) { 637 if (ic_data.NumberOfChecks() == 0) {
638 return false; 638 return false;
639 } 639 }
640 ASSERT(ic_data.NumberOfArgumentsChecked() > arg_index); 640 ASSERT(ic_data.num_args_tested() > arg_index);
641 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { 641 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
642 GrowableArray<const Class*> classes; 642 GrowableArray<const Class*> classes;
643 Function& target = Function::Handle(); 643 Function& target = Function::Handle();
644 ic_data.GetCheckAt(i, &classes, &target); 644 ic_data.GetCheckAt(i, &classes, &target);
645 if (classes.is_empty()) { 645 if (classes.is_empty()) {
646 return false; 646 return false;
647 } 647 }
648 if (classes[arg_index]->raw() != cls.raw()) { 648 if (classes[arg_index]->raw() != cls.raw()) {
649 return false; 649 return false;
650 } 650 }
651 } 651 }
652 return true; 652 return true;
653 } 653 }
654 654
655 655
656 // IC data may have only one check, and it has to contain the two classes in 656 // IC data may have only one check, and it has to contain the two classes in
657 // specified order. 657 // specified order.
658 static bool AtIdNodeHasTwoClasses(AstNode* node, 658 static bool AtIdNodeHasTwoClasses(AstNode* node,
659 intptr_t id, 659 intptr_t id,
660 const Class& cls0, 660 const Class& cls0,
661 const Class& cls1) { 661 const Class& cls1) {
662 ASSERT(node != NULL); 662 ASSERT(node != NULL);
663 ASSERT(!cls0.IsNull() && !cls1.IsNull()); 663 ASSERT(!cls0.IsNull() && !cls1.IsNull());
664 const ICData& ic_data = node->ICDataAtId(id); 664 const ICData& ic_data = node->ICDataAtId(id);
665 ASSERT(ic_data.NumberOfArgumentsChecked() == 2); 665 ASSERT(ic_data.num_args_tested() == 2);
666 if (ic_data.NumberOfChecks() != 1) { 666 if (ic_data.NumberOfChecks() != 1) {
667 return false; 667 return false;
668 } 668 }
669 Function& target = Function::Handle(); 669 Function& target = Function::Handle();
670 GrowableArray<const Class*> classes; 670 GrowableArray<const Class*> classes;
671 ic_data.GetCheckAt(0, &classes, &target); 671 ic_data.GetCheckAt(0, &classes, &target);
672 if ((cls0.raw() == classes[0]->raw()) && (cls1.raw() == classes[1]->raw())) { 672 if ((cls0.raw() == classes[0]->raw()) && (cls1.raw() == classes[1]->raw())) {
673 return true; 673 return true;
674 } 674 }
675 return false; 675 return false;
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 node->token_index(), 789 node->token_index(),
790 number_of_arguments, 790 number_of_arguments,
791 no_optional_argument_names); 791 no_optional_argument_names);
792 __ Bind(&done); 792 __ Bind(&done);
793 } 793 }
794 794
795 795
796 // Implement Token::kSUB and Token::kBIT_NOT. 796 // Implement Token::kSUB and Token::kBIT_NOT.
797 void OptimizingCodeGenerator::GenerateSmiUnaryOp(UnaryOpNode* node) { 797 void OptimizingCodeGenerator::GenerateSmiUnaryOp(UnaryOpNode* node) {
798 const ICData& ic_data = node->ICDataAtId(node->id()); 798 const ICData& ic_data = node->ICDataAtId(node->id());
799 ASSERT(ic_data.NumberOfArgumentsChecked() == 1); 799 ASSERT(ic_data.num_args_tested() == 1);
800 DeoptReasonId deopt_reason_id = ic_data.NumberOfChecks() == 0 ? 800 DeoptReasonId deopt_reason_id = ic_data.NumberOfChecks() == 0 ?
801 kDeoptNoTypeFeedback : kDeoptUnaryOp; 801 kDeoptNoTypeFeedback : kDeoptUnaryOp;
802 DeoptimizationBlob* deopt_blob = 802 DeoptimizationBlob* deopt_blob =
803 AddDeoptimizationBlob(node, EAX, deopt_reason_id); 803 AddDeoptimizationBlob(node, EAX, deopt_reason_id);
804 CodeGenInfo info(node->operand()); 804 CodeGenInfo info(node->operand());
805 VisitLoadOne(node->operand(), EAX); 805 VisitLoadOne(node->operand(), EAX);
806 if (ic_data.NumberOfChecks() == 0) { 806 if (ic_data.NumberOfChecks() == 0) {
807 // No type feedback. 807 // No type feedback.
808 __ jmp(deopt_blob->label()); 808 __ jmp(deopt_blob->label());
809 return; 809 return;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 if ((kind == Token::kADD) || 893 if ((kind == Token::kADD) ||
894 (kind == Token::kSUB) || 894 (kind == Token::kSUB) ||
895 (kind == Token::kMUL) || 895 (kind == Token::kMUL) ||
896 (kind == Token::kTRUNCDIV) || 896 (kind == Token::kTRUNCDIV) ||
897 (kind == Token::kBIT_AND) || 897 (kind == Token::kBIT_AND) ||
898 (kind == Token::kBIT_OR) || 898 (kind == Token::kBIT_OR) ||
899 (kind == Token::kBIT_XOR)) { 899 (kind == Token::kBIT_XOR)) {
900 TraceOpt(node, kOptMessage); 900 TraceOpt(node, kOptMessage);
901 // Check if both arguments are expected to be Smi. 901 // Check if both arguments are expected to be Smi.
902 const ICData& ic_data = node->ICDataAtId(node->id()); 902 const ICData& ic_data = node->ICDataAtId(node->id());
903 ASSERT(ic_data.NumberOfArgumentsChecked() == 2); 903 ASSERT(ic_data.num_args_tested() == 2);
904 ASSERT(ic_data.NumberOfChecks() > 0); 904 ASSERT(ic_data.NumberOfChecks() > 0);
905 Function& target = Function::Handle(); 905 Function& target = Function::Handle();
906 GrowableArray<const Class*> classes; 906 GrowableArray<const Class*> classes;
907 ic_data.GetCheckAt(0, &classes, &target); 907 ic_data.GetCheckAt(0, &classes, &target);
908 ASSERT(ic_data.NumberOfChecks() == 1); 908 ASSERT(ic_data.NumberOfChecks() == 1);
909 ASSERT((classes[0]->raw() == smi_class_.raw()) && 909 ASSERT((classes[0]->raw() == smi_class_.raw()) &&
910 (classes[1]->raw() == smi_class_.raw())); 910 (classes[1]->raw() == smi_class_.raw()));
911 CodeGenInfo left_info(node->left()); 911 CodeGenInfo left_info(node->left());
912 CodeGenInfo right_info(node->right()); 912 CodeGenInfo right_info(node->right());
913 VisitLoadTwo(node->left(), node->right(), EAX, EDX); 913 VisitLoadTwo(node->left(), node->right(), EAX, EDX);
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
1351 1351
1352 const ICData& ic_data = node->ICDataAtId(node->id()); 1352 const ICData& ic_data = node->ICDataAtId(node->id());
1353 if (ic_data.NumberOfChecks() == 0) { 1353 if (ic_data.NumberOfChecks() == 0) {
1354 VisitLoadTwo(node->left(), node->right(), EAX, EDX); 1354 VisitLoadTwo(node->left(), node->right(), EAX, EDX);
1355 DeoptimizationBlob* deopt_blob = 1355 DeoptimizationBlob* deopt_blob =
1356 AddDeoptimizationBlob(node, EAX, EDX, kDeoptNoTypeFeedback); 1356 AddDeoptimizationBlob(node, EAX, EDX, kDeoptNoTypeFeedback);
1357 __ jmp(deopt_blob->label()); 1357 __ jmp(deopt_blob->label());
1358 return; 1358 return;
1359 } 1359 }
1360 1360
1361 ASSERT(ic_data.NumberOfArgumentsChecked() == 2); 1361 ASSERT(ic_data.num_args_tested() == 2);
1362 1362
1363 if (AtIdNodeHasTwoClasses(node, node->id(), smi_class_, smi_class_)) { 1363 if (AtIdNodeHasTwoClasses(node, node->id(), smi_class_, smi_class_)) {
1364 GenerateSmiBinaryOp(node); 1364 GenerateSmiBinaryOp(node);
1365 return; 1365 return;
1366 } 1366 }
1367 1367
1368 if (AtIdNodeHasClassAt(node, node->id(), double_class_, 0)) { 1368 if (AtIdNodeHasClassAt(node, node->id(), double_class_, 0)) {
1369 const bool receiver_can_be_smi = false; 1369 const bool receiver_can_be_smi = false;
1370 GenerateDoubleBinaryOp(node, receiver_can_be_smi); 1370 GenerateDoubleBinaryOp(node, receiver_can_be_smi);
1371 return; 1371 return;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 1460
1461 1461
1462 // Debugging helper method, used in assert only. 1462 // Debugging helper method, used in assert only.
1463 static bool HaveSameClassesInICData(const ICData& a, const ICData& b) { 1463 static bool HaveSameClassesInICData(const ICData& a, const ICData& b) {
1464 if (a.NumberOfChecks() != b.NumberOfChecks()) { 1464 if (a.NumberOfChecks() != b.NumberOfChecks()) {
1465 return false; 1465 return false;
1466 } 1466 }
1467 if (a.NumberOfChecks() == 0) { 1467 if (a.NumberOfChecks() == 0) {
1468 return true; 1468 return true;
1469 } 1469 }
1470 if (a.NumberOfArgumentsChecked() != b.NumberOfArgumentsChecked()) { 1470 if (a.num_args_tested() != b.num_args_tested()) {
1471 return false; 1471 return false;
1472 } 1472 }
1473 // Only one-argument checks implemented. 1473 // Only one-argument checks implemented.
1474 ASSERT(a.NumberOfArgumentsChecked() == 1); 1474 ASSERT(a.num_args_tested() == 1);
1475 Function& a_target = Function::Handle(); 1475 Function& a_target = Function::Handle();
1476 Function& b_target = Function::Handle(); 1476 Function& b_target = Function::Handle();
1477 Class& a_class = Class::Handle(); 1477 Class& a_class = Class::Handle();
1478 Class& b_class = Class::Handle(); 1478 Class& b_class = Class::Handle();
1479 for (intptr_t i = 0; i < a.NumberOfChecks(); i++) { 1479 for (intptr_t i = 0; i < a.NumberOfChecks(); i++) {
1480 a.GetOneClassCheckAt(i, &a_class, &a_target); 1480 a.GetOneClassCheckAt(i, &a_class, &a_target);
1481 bool found = false; 1481 bool found = false;
1482 for (intptr_t n = 0; n < b.NumberOfChecks(); n++) { 1482 for (intptr_t n = 0; n < b.NumberOfChecks(); n++) {
1483 b.GetOneClassCheckAt(n, &b_class, &b_target); 1483 b.GetOneClassCheckAt(n, &b_class, &b_target);
1484 if ((a_class.raw() == b_class.raw())) { 1484 if ((a_class.raw() == b_class.raw())) {
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
1828 Register recv_reg, 1828 Register recv_reg,
1829 Register value_reg) { 1829 Register value_reg) {
1830 // EBX is used as temporary register for class. 1830 // EBX is used as temporary register for class.
1831 ASSERT((recv_reg != EBX) && (value_reg != EBX)); 1831 ASSERT((recv_reg != EBX) && (value_reg != EBX));
1832 GrowableArray<Class*> classes; 1832 GrowableArray<Class*> classes;
1833 GrowableArray<Function*> targets; 1833 GrowableArray<Function*> targets;
1834 bool unique_target = true; 1834 bool unique_target = true;
1835 { 1835 {
1836 const ICData& ic_data = node->ICDataAtId(id); 1836 const ICData& ic_data = node->ICDataAtId(id);
1837 ASSERT(ic_data.NumberOfChecks() > 0); 1837 ASSERT(ic_data.NumberOfChecks() > 0);
1838 ASSERT(ic_data.NumberOfArgumentsChecked() == 1); 1838 ASSERT(ic_data.num_args_tested() == 1);
1839 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { 1839 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
1840 Class& cls = Class::ZoneHandle(); 1840 Class& cls = Class::ZoneHandle();
1841 Function& target = Function::ZoneHandle(); 1841 Function& target = Function::ZoneHandle();
1842 ic_data.GetOneClassCheckAt(i, &cls, &target); 1842 ic_data.GetOneClassCheckAt(i, &cls, &target);
1843 classes.Add(&cls); 1843 classes.Add(&cls);
1844 targets.Add(&target); 1844 targets.Add(&target);
1845 } 1845 }
1846 for (intptr_t i = 1; i < targets.length(); i++) { 1846 for (intptr_t i = 1; i < targets.length(); i++) {
1847 if (targets[i - 1]->raw() != targets[i]->raw()) { 1847 if (targets[i - 1]->raw() != targets[i]->raw()) {
1848 unique_target = false; 1848 unique_target = false;
(...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after
2752 // provided. 2752 // provided.
2753 // TODO(srdjan): Recompilation framework should recognize active IC calls 2753 // TODO(srdjan): Recompilation framework should recognize active IC calls
2754 // in optimized code and mark them for reoptimization since type feedback was 2754 // in optimized code and mark them for reoptimization since type feedback was
2755 // collected in the meantime. 2755 // collected in the meantime.
2756 void OptimizingCodeGenerator::GenerateInlineCacheCall( 2756 void OptimizingCodeGenerator::GenerateInlineCacheCall(
2757 intptr_t node_id, 2757 intptr_t node_id,
2758 intptr_t token_index, 2758 intptr_t token_index,
2759 const ICData& ic_data, 2759 const ICData& ic_data,
2760 intptr_t num_args, 2760 intptr_t num_args,
2761 const Array& optional_arguments_names) { 2761 const Array& optional_arguments_names) {
2762 __ LoadObject(ECX, Array::ZoneHandle(ic_data.data())); 2762 __ LoadObject(ECX, ic_data);
2763 __ LoadObject(EDX, ArgumentsDescriptor(num_args, optional_arguments_names)); 2763 __ LoadObject(EDX, ArgumentsDescriptor(num_args, optional_arguments_names));
2764 ExternalLabel target_label( 2764 ExternalLabel target_label(
2765 "InlineCache", StubCode::OneArgCheckInlineCacheEntryPoint()); 2765 "InlineCache", StubCode::OneArgCheckInlineCacheEntryPoint());
2766 2766
2767 __ call(&target_label); 2767 __ call(&target_label);
2768 AddCurrentDescriptor(PcDescriptors::kIcCall, 2768 AddCurrentDescriptor(PcDescriptors::kIcCall,
2769 node_id, 2769 node_id,
2770 token_index); 2770 token_index);
2771 __ addl(ESP, Immediate(num_args * kWordSize)); 2771 __ addl(ESP, Immediate(num_args * kWordSize));
2772 } 2772 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2812 } 2812 }
2813 // Do not add a target that has not been compiled yet. 2813 // Do not add a target that has not been compiled yet.
2814 if (!null_target.IsNull() && null_target.HasCode()) { 2814 if (!null_target.IsNull() && null_target.HasCode()) {
2815 ASSERT(null_target.IsZoneHandle()); 2815 ASSERT(null_target.IsZoneHandle());
2816 classes->Add(&Class::ZoneHandle(Object::null_class())); 2816 classes->Add(&Class::ZoneHandle(Object::null_class()));
2817 targets->Add(&null_target); 2817 targets->Add(&null_target);
2818 } 2818 }
2819 } 2819 }
2820 2820
2821 2821
2822 // Use ICData in 'node' to issues checks and calls. 2822 // Use IC data in 'node' to issues checks and calls.
2823 // IC data can contain one or more argument checks. 2823 // IC data can contain one or more argument checks.
2824 void OptimizingCodeGenerator::GenerateCheckedInstanceCalls( 2824 void OptimizingCodeGenerator::GenerateCheckedInstanceCalls(
2825 AstNode* node, 2825 AstNode* node,
2826 AstNode* receiver, 2826 AstNode* receiver,
2827 intptr_t node_id, 2827 intptr_t node_id,
2828 intptr_t token_index, 2828 intptr_t token_index,
2829 intptr_t num_args, 2829 intptr_t num_args,
2830 const Array& optional_arguments_names) { 2830 const Array& optional_arguments_names) {
2831 ASSERT(node != NULL); 2831 ASSERT(node != NULL);
2832 ASSERT(receiver != NULL); 2832 ASSERT(receiver != NULL);
2833 ASSERT(num_args > 0); 2833 ASSERT(num_args > 0);
2834 const ICData& ic_data = node->ICDataAtId(node_id); 2834 const ICData& ic_data = node->ICDataAtId(node_id);
2835 if (ic_data.NumberOfChecks() == 0) { 2835 if (ic_data.NumberOfChecks() == 0) {
2836 // No type feedback means node was never executed. However that can be 2836 // No type feedback means node was never executed. However that can be
2837 // a common case especially in case of large switch statements. 2837 // a common case especially in case of large switch statements.
2838 // Use a special inline cache call which can help us decide when to 2838 // Use a special inline cache call which can help us decide when to
2839 // re-optimize this optiumized function. 2839 // re-optimize this optiumized function.
2840 GenerateInlineCacheCall( 2840 GenerateInlineCacheCall(
2841 node_id, token_index, ic_data, num_args, optional_arguments_names); 2841 node_id, token_index, ic_data, num_args, optional_arguments_names);
2842 return; 2842 return;
2843 } 2843 }
2844 2844
2845 Function& target_for_null = Function::ZoneHandle(); 2845 Function& target_for_null = Function::ZoneHandle();
2846 ObjectStore* object_store = Isolate::Current()->object_store(); 2846 ObjectStore* object_store = Isolate::Current()->object_store();
2847 int num_optional_args = 2847 int num_optional_args =
2848 optional_arguments_names.IsNull() ? 0 : optional_arguments_names.Length(); 2848 optional_arguments_names.IsNull() ? 0 : optional_arguments_names.Length();
2849 target_for_null = Resolver::ResolveDynamicForReceiverClass( 2849 target_for_null = Resolver::ResolveDynamicForReceiverClass(
2850 Class::Handle(object_store->object_class()), 2850 Class::Handle(object_store->object_class()),
2851 String::Handle(ic_data.FunctionName()), 2851 String::Handle(ic_data.target_name()),
2852 num_args, 2852 num_args,
2853 num_optional_args); 2853 num_optional_args);
2854 GrowableArray<const Class*> classes; 2854 GrowableArray<const Class*> classes;
2855 GrowableArray<const Function*> targets; 2855 GrowableArray<const Function*> targets;
2856 // Make Smi class the first one, if it is in the list. 2856 // Make Smi class the first one, if it is in the list.
2857 NormalizeClassChecks(ic_data, target_for_null, &classes, &targets); 2857 NormalizeClassChecks(ic_data, target_for_null, &classes, &targets);
2858 ASSERT(!classes.is_empty()); 2858 ASSERT(!classes.is_empty());
2859 ASSERT(classes.length() == targets.length()); 2859 ASSERT(classes.length() == targets.length());
2860 intptr_t start_ix = 0; 2860 intptr_t start_ix = 0;
2861 2861
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
3125 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 3125 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
3126 __ LoadObject(EAX, Bool::ZoneHandle(Bool::False())); 3126 __ LoadObject(EAX, Bool::ZoneHandle(Bool::False()));
3127 __ Bind(&done); 3127 __ Bind(&done);
3128 HandleResult(node, EAX); 3128 HandleResult(node, EAX);
3129 return; 3129 return;
3130 } 3130 }
3131 3131
3132 if ((node->kind() == Token::kSUB) || (node->kind() == Token::kBIT_NOT)) { 3132 if ((node->kind() == Token::kSUB) || (node->kind() == Token::kBIT_NOT)) {
3133 if (AtIdNodeHasClassAt(node, node->id(), smi_class_, 0)) { 3133 if (AtIdNodeHasClassAt(node, node->id(), smi_class_, 0)) {
3134 const ICData& ic_data = node->ICDataAtId(node->id()); 3134 const ICData& ic_data = node->ICDataAtId(node->id());
3135 ASSERT(ic_data.NumberOfArgumentsChecked() == 1); 3135 ASSERT(ic_data.num_args_tested() == 1);
3136 GenerateSmiUnaryOp(node); 3136 GenerateSmiUnaryOp(node);
3137 return; 3137 return;
3138 } 3138 }
3139 } 3139 }
3140 if (node->kind() == Token::kSUB) { 3140 if (node->kind() == Token::kSUB) {
3141 if (AtIdNodeHasClassAt(node, node->id(), double_class_, 0)) { 3141 if (AtIdNodeHasClassAt(node, node->id(), double_class_, 0)) {
3142 const ICData& ic_data = node->ICDataAtId(node->id()); 3142 const ICData& ic_data = node->ICDataAtId(node->id());
3143 ASSERT(ic_data.NumberOfArgumentsChecked() == 1); 3143 ASSERT(ic_data.num_args_tested() == 1);
3144 GenerateDoubleUnaryOp(node); 3144 GenerateDoubleUnaryOp(node);
3145 return; 3145 return;
3146 } 3146 }
3147 } 3147 }
3148 // TODO(srdjan): Implement unary kSUB (negate) Mint. 3148 // TODO(srdjan): Implement unary kSUB (negate) Mint.
3149 CodeGenerator::VisitUnaryOpNode(node); 3149 CodeGenerator::VisitUnaryOpNode(node);
3150 } 3150 }
3151 3151
3152 3152
3153 } // namespace dart 3153 } // namespace dart
3154 3154
3155 #endif // defined TARGET_ARCH_IA32 3155 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/object_test.cc ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698