OLD | NEW |
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/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 "lib/error.h" | 10 #include "lib/error.h" |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 // - Class equality (only if class is not parameterized). | 442 // - Class equality (only if class is not parameterized). |
443 // Inputs: | 443 // Inputs: |
444 // - EAX: object. | 444 // - EAX: object. |
445 // - EDX: instantiator type arguments or raw_null. | 445 // - EDX: instantiator type arguments or raw_null. |
446 // - ECX: instantiator or raw_null. | 446 // - ECX: instantiator or raw_null. |
447 // Clobbers ECX and EDX. | 447 // Clobbers ECX and EDX. |
448 // Returns: | 448 // Returns: |
449 // - true or false in EAX. | 449 // - true or false in EAX. |
450 void FlowGraphCompiler::GenerateInstanceOf(intptr_t deopt_id, | 450 void FlowGraphCompiler::GenerateInstanceOf(intptr_t deopt_id, |
451 intptr_t token_pos, | 451 intptr_t token_pos, |
452 intptr_t try_index, | |
453 const AbstractType& type, | 452 const AbstractType& type, |
454 bool negate_result, | 453 bool negate_result, |
455 LocationSummary* locs) { | 454 LocationSummary* locs) { |
456 ASSERT(type.IsFinalized() && !type.IsMalformed()); | 455 ASSERT(type.IsFinalized() && !type.IsMalformed()); |
457 | 456 |
458 const Immediate raw_null = | 457 const Immediate raw_null = |
459 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 458 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
460 Label is_instance, is_not_instance; | 459 Label is_instance, is_not_instance; |
461 __ pushl(ECX); // Store instantiator on stack. | 460 __ pushl(ECX); // Store instantiator on stack. |
462 __ pushl(EDX); // Store instantiator type arguments. | 461 __ pushl(EDX); // Store instantiator type arguments. |
(...skipping 22 matching lines...) Expand all Loading... |
485 // Generate runtime call. | 484 // Generate runtime call. |
486 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments. | 485 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments. |
487 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator. | 486 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator. |
488 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 487 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
489 __ pushl(EAX); // Push the instance. | 488 __ pushl(EAX); // Push the instance. |
490 __ PushObject(type); // Push the type. | 489 __ PushObject(type); // Push the type. |
491 __ pushl(ECX); // Instantiator. | 490 __ pushl(ECX); // Instantiator. |
492 __ pushl(EDX); // Instantiator type arguments. | 491 __ pushl(EDX); // Instantiator type arguments. |
493 __ LoadObject(EAX, test_cache); | 492 __ LoadObject(EAX, test_cache); |
494 __ pushl(EAX); | 493 __ pushl(EAX); |
495 GenerateCallRuntime(deopt_id, token_pos, try_index, | 494 GenerateCallRuntime(deopt_id, token_pos, kInstanceofRuntimeEntry, locs); |
496 kInstanceofRuntimeEntry, locs); | |
497 // Pop the parameters supplied to the runtime entry. The result of the | 495 // Pop the parameters supplied to the runtime entry. The result of the |
498 // instanceof runtime call will be left as the result of the operation. | 496 // instanceof runtime call will be left as the result of the operation. |
499 __ Drop(5); | 497 __ Drop(5); |
500 if (negate_result) { | 498 if (negate_result) { |
501 __ popl(EDX); | 499 __ popl(EDX); |
502 __ LoadObject(EAX, bool_true()); | 500 __ LoadObject(EAX, bool_true()); |
503 __ cmpl(EDX, EAX); | 501 __ cmpl(EDX, EAX); |
504 __ j(NOT_EQUAL, &done, Assembler::kNearJump); | 502 __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
505 __ LoadObject(EAX, bool_false()); | 503 __ LoadObject(EAX, bool_false()); |
506 } else { | 504 } else { |
(...skipping 20 matching lines...) Expand all Loading... |
527 // Inputs: | 525 // Inputs: |
528 // - EAX: object. | 526 // - EAX: object. |
529 // - EDX: instantiator type arguments or raw_null. | 527 // - EDX: instantiator type arguments or raw_null. |
530 // - ECX: instantiator or raw_null. | 528 // - ECX: instantiator or raw_null. |
531 // Returns: | 529 // Returns: |
532 // - object in EAX for successful assignable check (or throws TypeError). | 530 // - object in EAX for successful assignable check (or throws TypeError). |
533 // Performance notes: positive checks must be quick, negative checks can be slow | 531 // Performance notes: positive checks must be quick, negative checks can be slow |
534 // as they throw an exception. | 532 // as they throw an exception. |
535 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t deopt_id, | 533 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t deopt_id, |
536 intptr_t token_pos, | 534 intptr_t token_pos, |
537 intptr_t try_index, | |
538 const AbstractType& dst_type, | 535 const AbstractType& dst_type, |
539 const String& dst_name, | 536 const String& dst_name, |
540 LocationSummary* locs) { | 537 LocationSummary* locs) { |
541 ASSERT(token_pos >= 0); | 538 ASSERT(token_pos >= 0); |
542 ASSERT(!dst_type.IsNull()); | 539 ASSERT(!dst_type.IsNull()); |
543 ASSERT(dst_type.IsFinalized()); | 540 ASSERT(dst_type.IsFinalized()); |
544 // Assignable check is skipped in FlowGraphBuilder, not here. | 541 // Assignable check is skipped in FlowGraphBuilder, not here. |
545 ASSERT(dst_type.IsMalformed() || | 542 ASSERT(dst_type.IsMalformed() || |
546 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); | 543 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); |
547 __ pushl(ECX); // Store instantiator. | 544 __ pushl(ECX); // Store instantiator. |
548 __ pushl(EDX); // Store instantiator type arguments. | 545 __ pushl(EDX); // Store instantiator type arguments. |
549 // A null object is always assignable and is returned as result. | 546 // A null object is always assignable and is returned as result. |
550 const Immediate raw_null = | 547 const Immediate raw_null = |
551 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 548 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
552 Label is_assignable, runtime_call; | 549 Label is_assignable, runtime_call; |
553 __ cmpl(EAX, raw_null); | 550 __ cmpl(EAX, raw_null); |
554 __ j(EQUAL, &is_assignable); | 551 __ j(EQUAL, &is_assignable); |
555 | 552 |
556 // Generate throw new TypeError() if the type is malformed. | 553 // Generate throw new TypeError() if the type is malformed. |
557 if (dst_type.IsMalformed()) { | 554 if (dst_type.IsMalformed()) { |
558 const Error& error = Error::Handle(dst_type.malformed_error()); | 555 const Error& error = Error::Handle(dst_type.malformed_error()); |
559 const String& error_message = String::ZoneHandle( | 556 const String& error_message = String::ZoneHandle( |
560 Symbols::New(error.ToErrorCString())); | 557 Symbols::New(error.ToErrorCString())); |
561 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 558 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
562 __ pushl(EAX); // Push the source object. | 559 __ pushl(EAX); // Push the source object. |
563 __ PushObject(dst_name); // Push the name of the destination. | 560 __ PushObject(dst_name); // Push the name of the destination. |
564 __ PushObject(error_message); | 561 __ PushObject(error_message); |
565 GenerateCallRuntime(deopt_id, | 562 GenerateCallRuntime(deopt_id, |
566 token_pos, | 563 token_pos, |
567 try_index, | |
568 kMalformedTypeErrorRuntimeEntry, | 564 kMalformedTypeErrorRuntimeEntry, |
569 locs); | 565 locs); |
570 // We should never return here. | 566 // We should never return here. |
571 __ int3(); | 567 __ int3(); |
572 | 568 |
573 __ Bind(&is_assignable); // For a null object. | 569 __ Bind(&is_assignable); // For a null object. |
574 __ popl(EDX); // Remove pushed instantiator type arguments. | 570 __ popl(EDX); // Remove pushed instantiator type arguments. |
575 __ popl(ECX); // Remove pushed instantiator. | 571 __ popl(ECX); // Remove pushed instantiator. |
576 return; | 572 return; |
577 } | 573 } |
578 | 574 |
579 // Generate inline type check, linking to runtime call if not assignable. | 575 // Generate inline type check, linking to runtime call if not assignable. |
580 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); | 576 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); |
581 test_cache = GenerateInlineInstanceof(token_pos, dst_type, | 577 test_cache = GenerateInlineInstanceof(token_pos, dst_type, |
582 &is_assignable, &runtime_call); | 578 &is_assignable, &runtime_call); |
583 | 579 |
584 __ Bind(&runtime_call); | 580 __ Bind(&runtime_call); |
585 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments. | 581 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments. |
586 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator. | 582 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator. |
587 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 583 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
588 __ pushl(EAX); // Push the source object. | 584 __ pushl(EAX); // Push the source object. |
589 __ PushObject(dst_type); // Push the type of the destination. | 585 __ PushObject(dst_type); // Push the type of the destination. |
590 __ pushl(ECX); // Instantiator. | 586 __ pushl(ECX); // Instantiator. |
591 __ pushl(EDX); // Instantiator type arguments. | 587 __ pushl(EDX); // Instantiator type arguments. |
592 __ PushObject(dst_name); // Push the name of the destination. | 588 __ PushObject(dst_name); // Push the name of the destination. |
593 __ LoadObject(EAX, test_cache); | 589 __ LoadObject(EAX, test_cache); |
594 __ pushl(EAX); | 590 __ pushl(EAX); |
595 GenerateCallRuntime(deopt_id, | 591 GenerateCallRuntime(deopt_id, token_pos, kTypeCheckRuntimeEntry, locs); |
596 token_pos, | |
597 try_index, | |
598 kTypeCheckRuntimeEntry, | |
599 locs); | |
600 // Pop the parameters supplied to the runtime entry. The result of the | 592 // Pop the parameters supplied to the runtime entry. The result of the |
601 // type check runtime call is the checked value. | 593 // type check runtime call is the checked value. |
602 __ Drop(6); | 594 __ Drop(6); |
603 __ popl(EAX); | 595 __ popl(EAX); |
604 | 596 |
605 __ Bind(&is_assignable); | 597 __ Bind(&is_assignable); |
606 __ popl(EDX); // Remove pushed instantiator type arguments. | 598 __ popl(EDX); // Remove pushed instantiator type arguments. |
607 __ popl(ECX); // Remove pushed instantiator. | 599 __ popl(ECX); // Remove pushed instantiator. |
608 } | 600 } |
609 | 601 |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
768 } | 760 } |
769 // The calls below have empty stackmaps because we have just dropped the | 761 // The calls below have empty stackmaps because we have just dropped the |
770 // spill slots. | 762 // spill slots. |
771 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder(); | 763 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder(); |
772 if (function.IsClosureFunction()) { | 764 if (function.IsClosureFunction()) { |
773 // We do not use GenerateCallRuntime because of the non-standard (empty) | 765 // We do not use GenerateCallRuntime because of the non-standard (empty) |
774 // stackmap used here. | 766 // stackmap used here. |
775 __ CallRuntime(kClosureArgumentMismatchRuntimeEntry); | 767 __ CallRuntime(kClosureArgumentMismatchRuntimeEntry); |
776 AddCurrentDescriptor(PcDescriptors::kOther, | 768 AddCurrentDescriptor(PcDescriptors::kOther, |
777 Isolate::kNoDeoptId, | 769 Isolate::kNoDeoptId, |
778 0, // No token position. | 770 0); // No token position. |
779 CatchClauseNode::kInvalidTryIndex); | |
780 } else { | 771 } else { |
781 ASSERT(!IsLeaf()); | 772 ASSERT(!IsLeaf()); |
782 // Invoke noSuchMethod function. | 773 // Invoke noSuchMethod function. |
783 const int kNumArgsChecked = 1; | 774 const int kNumArgsChecked = 1; |
784 ICData& ic_data = ICData::ZoneHandle(); | 775 ICData& ic_data = ICData::ZoneHandle(); |
785 ic_data = ICData::New(function, | 776 ic_data = ICData::New(function, |
786 String::Handle(function.name()), | 777 String::Handle(function.name()), |
787 Isolate::kNoDeoptId, | 778 Isolate::kNoDeoptId, |
788 kNumArgsChecked); | 779 kNumArgsChecked); |
789 __ LoadObject(ECX, ic_data); | 780 __ LoadObject(ECX, ic_data); |
(...skipping 13 matching lines...) Expand all Loading... |
803 | 794 |
804 | 795 |
805 if (FLAG_trace_functions) { | 796 if (FLAG_trace_functions) { |
806 __ pushl(EAX); // Preserve result. | 797 __ pushl(EAX); // Preserve result. |
807 __ PushObject(Function::ZoneHandle(function.raw())); | 798 __ PushObject(Function::ZoneHandle(function.raw())); |
808 // We do not use GenerateCallRuntime because of the non-standard (empty) | 799 // We do not use GenerateCallRuntime because of the non-standard (empty) |
809 // stackmap used here. | 800 // stackmap used here. |
810 __ CallRuntime(kTraceFunctionExitRuntimeEntry); | 801 __ CallRuntime(kTraceFunctionExitRuntimeEntry); |
811 AddCurrentDescriptor(PcDescriptors::kOther, | 802 AddCurrentDescriptor(PcDescriptors::kOther, |
812 Isolate::kNoDeoptId, | 803 Isolate::kNoDeoptId, |
813 0, // No token position. | 804 0); // No token position. |
814 CatchClauseNode::kInvalidTryIndex); | |
815 if (is_optimizing()) { | 805 if (is_optimizing()) { |
816 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), | 806 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), |
817 empty_stack_bitmap); | 807 empty_stack_bitmap); |
818 } | 808 } |
819 __ popl(EAX); // Remove argument. | 809 __ popl(EAX); // Remove argument. |
820 __ popl(EAX); // Restore result. | 810 __ popl(EAX); // Restore result. |
821 } | 811 } |
822 __ LeaveFrame(); | 812 __ LeaveFrame(); |
823 __ ret(); | 813 __ ret(); |
824 | 814 |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
941 __ Comment("Check argument count"); | 931 __ Comment("Check argument count"); |
942 // Check that num_fixed <= argc <= num_params. | 932 // Check that num_fixed <= argc <= num_params. |
943 Label argc_in_range; | 933 Label argc_in_range; |
944 // Total number of args is the first Smi in args descriptor array (EDX). | 934 // Total number of args is the first Smi in args descriptor array (EDX). |
945 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); | 935 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); |
946 __ cmpl(EAX, Immediate(Smi::RawValue(parameter_count))); | 936 __ cmpl(EAX, Immediate(Smi::RawValue(parameter_count))); |
947 __ j(EQUAL, &argc_in_range, Assembler::kNearJump); | 937 __ j(EQUAL, &argc_in_range, Assembler::kNearJump); |
948 if (function.IsClosureFunction()) { | 938 if (function.IsClosureFunction()) { |
949 GenerateCallRuntime(Isolate::kNoDeoptId, | 939 GenerateCallRuntime(Isolate::kNoDeoptId, |
950 function.token_pos(), | 940 function.token_pos(), |
951 CatchClauseNode::kInvalidTryIndex, | |
952 kClosureArgumentMismatchRuntimeEntry, | 941 kClosureArgumentMismatchRuntimeEntry, |
953 prologue_locs); | 942 prologue_locs); |
954 } else { | 943 } else { |
955 __ Stop("Wrong number of arguments"); | 944 __ Stop("Wrong number of arguments"); |
956 } | 945 } |
957 __ Bind(&argc_in_range); | 946 __ Bind(&argc_in_range); |
958 } | 947 } |
959 } else { | 948 } else { |
960 CopyParameters(); | 949 CopyParameters(); |
961 } | 950 } |
(...skipping 23 matching lines...) Expand all Loading... |
985 } | 974 } |
986 | 975 |
987 VisitBlocks(); | 976 VisitBlocks(); |
988 | 977 |
989 __ int3(); | 978 __ int3(); |
990 GenerateDeferredCode(); | 979 GenerateDeferredCode(); |
991 // Emit function patching code. This will be swapped with the first 5 bytes | 980 // Emit function patching code. This will be swapped with the first 5 bytes |
992 // at entry point. | 981 // at entry point. |
993 AddCurrentDescriptor(PcDescriptors::kPatchCode, | 982 AddCurrentDescriptor(PcDescriptors::kPatchCode, |
994 Isolate::kNoDeoptId, | 983 Isolate::kNoDeoptId, |
995 0, // No token position. | 984 0); // No token position. |
996 CatchClauseNode::kInvalidTryIndex); | |
997 __ jmp(&StubCode::FixCallersTargetLabel()); | 985 __ jmp(&StubCode::FixCallersTargetLabel()); |
998 } | 986 } |
999 | 987 |
1000 | 988 |
1001 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, | 989 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, |
1002 intptr_t try_index, | |
1003 const ExternalLabel* label, | 990 const ExternalLabel* label, |
1004 PcDescriptors::Kind kind, | 991 PcDescriptors::Kind kind, |
1005 LocationSummary* locs) { | 992 LocationSummary* locs) { |
1006 ASSERT(!IsLeaf()); | 993 ASSERT(!IsLeaf()); |
1007 __ call(label); | 994 __ call(label); |
1008 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos, try_index); | 995 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos); |
1009 RecordSafepoint(locs); | 996 RecordSafepoint(locs); |
1010 } | 997 } |
1011 | 998 |
1012 | 999 |
1013 void FlowGraphCompiler::GenerateCallRuntime(intptr_t deopt_id, | 1000 void FlowGraphCompiler::GenerateCallRuntime(intptr_t deopt_id, |
1014 intptr_t token_pos, | 1001 intptr_t token_pos, |
1015 intptr_t try_index, | |
1016 const RuntimeEntry& entry, | 1002 const RuntimeEntry& entry, |
1017 LocationSummary* locs) { | 1003 LocationSummary* locs) { |
1018 ASSERT(!IsLeaf()); | 1004 ASSERT(!IsLeaf()); |
1019 __ CallRuntime(entry); | 1005 __ CallRuntime(entry); |
1020 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos, try_index); | 1006 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos); |
1021 RecordSafepoint(locs); | 1007 RecordSafepoint(locs); |
1022 } | 1008 } |
1023 | 1009 |
1024 | 1010 |
1025 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, | 1011 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, |
1026 const ICData& ic_data, | 1012 const ICData& ic_data, |
1027 const Array& arguments_descriptor, | 1013 const Array& arguments_descriptor, |
1028 intptr_t argument_count, | 1014 intptr_t argument_count, |
1029 intptr_t deopt_id, | 1015 intptr_t deopt_id, |
1030 intptr_t token_pos, | 1016 intptr_t token_pos, |
1031 intptr_t try_index, | |
1032 LocationSummary* locs) { | 1017 LocationSummary* locs) { |
1033 ASSERT(!IsLeaf()); | 1018 ASSERT(!IsLeaf()); |
1034 __ LoadObject(ECX, ic_data); | 1019 __ LoadObject(ECX, ic_data); |
1035 __ LoadObject(EDX, arguments_descriptor); | 1020 __ LoadObject(EDX, arguments_descriptor); |
1036 | 1021 |
1037 __ call(target_label); | 1022 __ call(target_label); |
1038 AddCurrentDescriptor(PcDescriptors::kIcCall, deopt_id, token_pos, try_index); | 1023 AddCurrentDescriptor(PcDescriptors::kIcCall, deopt_id, token_pos); |
1039 RecordSafepoint(locs); | 1024 RecordSafepoint(locs); |
1040 | 1025 |
1041 __ Drop(argument_count); | 1026 __ Drop(argument_count); |
1042 } | 1027 } |
1043 | 1028 |
1044 | 1029 |
1045 void FlowGraphCompiler::EmitStaticCall(const Function& function, | 1030 void FlowGraphCompiler::EmitStaticCall(const Function& function, |
1046 const Array& arguments_descriptor, | 1031 const Array& arguments_descriptor, |
1047 intptr_t argument_count, | 1032 intptr_t argument_count, |
1048 intptr_t deopt_id, | 1033 intptr_t deopt_id, |
1049 intptr_t token_pos, | 1034 intptr_t token_pos, |
1050 intptr_t try_index, | |
1051 LocationSummary* locs) { | 1035 LocationSummary* locs) { |
1052 ASSERT(!IsLeaf()); | 1036 ASSERT(!IsLeaf()); |
1053 __ LoadObject(ECX, function); | 1037 __ LoadObject(ECX, function); |
1054 __ LoadObject(EDX, arguments_descriptor); | 1038 __ LoadObject(EDX, arguments_descriptor); |
1055 __ call(&StubCode::CallStaticFunctionLabel()); | 1039 __ call(&StubCode::CallStaticFunctionLabel()); |
1056 AddCurrentDescriptor(PcDescriptors::kFuncCall, deopt_id, token_pos, | 1040 AddCurrentDescriptor(PcDescriptors::kFuncCall, deopt_id, token_pos); |
1057 try_index); | |
1058 RecordSafepoint(locs); | 1041 RecordSafepoint(locs); |
1059 if (is_optimizing()) { | 1042 if (is_optimizing()) { |
1060 AddDeoptIndexAtCall(deopt_id, token_pos); | 1043 AddDeoptIndexAtCall(deopt_id, token_pos); |
1061 } | 1044 } |
1062 __ Drop(argument_count); | 1045 __ Drop(argument_count); |
1063 } | 1046 } |
1064 | 1047 |
1065 | 1048 |
1066 // Checks class id of instance against all 'class_ids'. Jump to 'deopt' label | 1049 // Checks class id of instance against all 'class_ids'. Jump to 'deopt' label |
1067 // if no match or instance is Smi. | 1050 // if no match or instance is Smi. |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1315 __ popl(ECX); | 1298 __ popl(ECX); |
1316 __ popl(EAX); | 1299 __ popl(EAX); |
1317 } | 1300 } |
1318 | 1301 |
1319 | 1302 |
1320 #undef __ | 1303 #undef __ |
1321 | 1304 |
1322 } // namespace dart | 1305 } // namespace dart |
1323 | 1306 |
1324 #endif // defined TARGET_ARCH_IA32 | 1307 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |