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

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

Issue 10477020: Move inlined type checking code to new compiler ia32. Sharing more and more code between ia32/x64 (… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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/flow_graph_compiler_ia32.h ('k') | runtime/vm/flow_graph_compiler_shared.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) 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"
11 #include "vm/ast_printer.h" 11 #include "vm/ast_printer.h"
12 #include "vm/compiler_stats.h" 12 #include "vm/compiler_stats.h"
13 #include "vm/il_printer.h" 13 #include "vm/il_printer.h"
14 #include "vm/locations.h" 14 #include "vm/locations.h"
15 #include "vm/object_store.h"
15 #include "vm/stub_code.h" 16 #include "vm/stub_code.h"
16 17
17 namespace dart { 18 namespace dart {
18 19
19 DECLARE_FLAG(bool, code_comments); 20 DECLARE_FLAG(bool, code_comments);
20 DECLARE_FLAG(bool, compiler_stats); 21 DECLARE_FLAG(bool, compiler_stats);
21 DECLARE_FLAG(bool, enable_type_checks); 22 DECLARE_FLAG(bool, enable_type_checks);
22 DECLARE_FLAG(bool, print_ast); 23 DECLARE_FLAG(bool, print_ast);
23 DECLARE_FLAG(bool, print_scopes); 24 DECLARE_FLAG(bool, print_scopes);
24 DECLARE_FLAG(bool, trace_functions); 25 DECLARE_FLAG(bool, trace_functions);
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 403
403 void FlowGraphCompiler::GenerateCall(intptr_t token_index, 404 void FlowGraphCompiler::GenerateCall(intptr_t token_index,
404 intptr_t try_index, 405 intptr_t try_index,
405 const ExternalLabel* label, 406 const ExternalLabel* label,
406 PcDescriptors::Kind kind) { 407 PcDescriptors::Kind kind) {
407 __ call(label); 408 __ call(label);
408 AddCurrentDescriptor(kind, AstNode::kNoId, token_index, try_index); 409 AddCurrentDescriptor(kind, AstNode::kNoId, token_index, try_index);
409 } 410 }
410 411
411 412
413 // Fall through if bool_register contains null.
414 void FlowGraphCompiler::GenerateBoolToJump(Register bool_register,
415 Label* is_true,
416 Label* is_false) {
417 const Immediate raw_null =
418 Immediate(reinterpret_cast<intptr_t>(Object::null()));
419 Label fall_through;
420 __ cmpl(bool_register, raw_null);
421 __ j(EQUAL, &fall_through, Assembler::kNearJump);
422 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
423 __ CompareObject(bool_register, bool_true);
424 __ j(EQUAL, is_true);
425 __ jmp(is_false);
426 __ Bind(&fall_through);
427 }
428
429
430 // Clobbers ECX.
431 RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
432 TypeTestStubKind test_kind,
433 Register instance_reg,
434 Register type_arguments_reg,
435 Register temp_reg,
436 Label* is_instance_lbl,
437 Label* is_not_instance_lbl) {
438 const SubtypeTestCache& type_test_cache =
439 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
440 const Immediate raw_null =
441 Immediate(reinterpret_cast<intptr_t>(Object::null()));
442 __ LoadObject(temp_reg, type_test_cache);
443 __ pushl(temp_reg); // Subtype test cache.
444 __ pushl(instance_reg); // Instance.
445 if (test_kind == kTestTypeOneArg) {
446 ASSERT(type_arguments_reg == kNoRegister);
447 __ pushl(raw_null);
448 __ call(&StubCode::Subtype1TestCacheLabel());
449 } else if (test_kind == kTestTypeTwoArgs) {
450 ASSERT(type_arguments_reg == kNoRegister);
451 __ pushl(raw_null);
452 __ call(&StubCode::Subtype2TestCacheLabel());
453 } else if (test_kind == kTestTypeThreeArgs) {
454 __ pushl(type_arguments_reg);
455 __ call(&StubCode::Subtype3TestCacheLabel());
456 } else {
457 UNREACHABLE();
458 }
459 // Result is in ECX: null -> not found, otherwise Bool::True or Bool::False.
460 ASSERT(instance_reg != ECX);
461 ASSERT(temp_reg != ECX);
462 __ popl(instance_reg); // Discard.
463 __ popl(instance_reg); // Restore receiver.
464 __ popl(temp_reg); // Discard.
465 GenerateBoolToJump(ECX, is_instance_lbl, is_not_instance_lbl);
466 return type_test_cache.raw();
467 }
468
469
470 // Jumps to labels 'is_instance' or 'is_not_instance' respectively, if
471 // type test is conclusive, otherwise fallthrough if a type test could not
472 // be completed.
473 // EAX: instance (must survive), clobbers ECX, EDI
474 RawSubtypeTestCache*
475 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
476 intptr_t cid,
477 intptr_t token_index,
478 const AbstractType& type,
479 Label* is_instance_lbl,
480 Label* is_not_instance_lbl) {
481 ASSERT(type.IsInstantiated());
482 const Class& type_class = Class::ZoneHandle(type.type_class());
483 ASSERT(type_class.HasTypeArguments());
484 const Register kInstanceReg = EAX;
485 // A Smi object cannot be the instance of a parameterized class.
486 __ testl(kInstanceReg, Immediate(kSmiTagMask));
487 __ j(ZERO, is_not_instance_lbl);
488 const AbstractTypeArguments& type_arguments =
489 AbstractTypeArguments::ZoneHandle(type.arguments());
490 const bool is_raw_type = type_arguments.IsNull() ||
491 type_arguments.IsRaw(type_arguments.Length());
492 if (is_raw_type) {
493 const Register kClassIdReg = ECX;
494 // Dynamic type argument, check only classes.
495 __ LoadClassId(kClassIdReg, kInstanceReg);
496 if (!type_class.is_interface()) {
497 __ cmpl(kClassIdReg, Immediate(type_class.id()));
498 __ j(EQUAL, is_instance_lbl);
499 }
500 if (type.IsListInterface()) {
501 GenerateListTypeCheck(kClassIdReg, is_instance_lbl);
502 }
503 return GenerateSubtype1TestCacheLookup(
504 cid, token_index, type_class, is_instance_lbl, is_not_instance_lbl);
505 }
506 // If one type argument only, check if type argument is Object or Dynamic.
507 if (type_arguments.Length() == 1) {
508 const AbstractType& tp_argument = AbstractType::ZoneHandle(
509 type_arguments.TypeAt(0));
510 ASSERT(!tp_argument.IsMalformed());
511 if (tp_argument.IsType()) {
512 ASSERT(tp_argument.HasResolvedTypeClass());
513 // Check if type argument is dynamic or Object.
514 const Type& object_type =
515 Type::Handle(Isolate::Current()->object_store()->object_type());
516 Error& malformed_error = Error::Handle();
517 if (object_type.IsSubtypeOf(tp_argument, &malformed_error)) {
518 // Instance class test only necessary.
519 return GenerateSubtype1TestCacheLookup(
520 cid, token_index, type_class, is_instance_lbl, is_not_instance_lbl);
521 }
522 }
523 }
524 // Regular subtype test cache involving instance's type arguments.
525 const Register kTypeArgumentsReg = kNoRegister;
526 const Register kTempReg = EDI;
527 return GenerateCallSubtypeTestStub(kTestTypeTwoArgs,
528 kInstanceReg,
529 kTypeArgumentsReg,
530 kTempReg,
531 is_instance_lbl,
532 is_not_instance_lbl);
533 }
534
535
536 void FlowGraphCompiler::CheckClassIds(Register class_id_reg,
537 const GrowableArray<intptr_t>& class_ids,
538 Label* is_equal_lbl,
539 Label* is_not_equal_lbl) {
540 for (intptr_t i = 0; i < class_ids.length(); i++) {
541 __ cmpl(class_id_reg, Immediate(class_ids[i]));
542 __ j(EQUAL, is_equal_lbl);
543 }
544 __ jmp(is_not_equal_lbl);
545 }
546
547
548 // Testing against an instantiated type with no arguments, without
549 // SubtypeTestCache.
550 // EAX: instance to test against (preserved). Clobbers ECX, EDI.
551 void FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
552 intptr_t cid,
553 intptr_t token_index,
554 const AbstractType& type,
555 Label* is_instance_lbl,
556 Label* is_not_instance_lbl) {
557 ASSERT(type.IsInstantiated());
558 const Class& type_class = Class::Handle(type.type_class());
559 ASSERT(!type_class.HasTypeArguments());
560
561 const Register kInstanceReg = EAX;
562 Label compare_classes;
563 __ testl(kInstanceReg, Immediate(kSmiTagMask));
564 __ j(NOT_ZERO, &compare_classes, Assembler::kNearJump);
565 // Instance is Smi, check directly.
566 const Class& smi_class = Class::Handle(Smi::Class());
567 // TODO(regis): We should introduce a SmiType.
568 Error& malformed_error = Error::Handle();
569 if (smi_class.IsSubtypeOf(TypeArguments::Handle(),
570 type_class,
571 TypeArguments::Handle(),
572 &malformed_error)) {
573 __ jmp(is_instance_lbl);
574 } else {
575 __ jmp(is_not_instance_lbl);
576 }
577 // Compare if the classes are equal.
578 __ Bind(&compare_classes);
579 const Register kClassIdReg = ECX;
580 __ LoadClassId(kClassIdReg, kInstanceReg);
581 // If type is an interface, we can skip the class equality check.
582 if (!type_class.is_interface()) {
583 __ cmpl(kClassIdReg, Immediate(type_class.id()));
584 __ j(EQUAL, is_instance_lbl);
585 }
586 // (see ClassFinalizer::ResolveInterfaces for list of restricted interfaces).
587 // Bool interface can be implemented only by core class Bool.
588 if (type.IsBoolInterface()) {
589 __ cmpl(kClassIdReg, Immediate(kBool));
590 __ j(EQUAL, is_instance_lbl);
591 __ jmp(is_not_instance_lbl);
592 return;
593 }
594 if (type.IsFunctionInterface()) {
595 // Check if instance is a closure.
596 const Immediate raw_null =
597 Immediate(reinterpret_cast<intptr_t>(Object::null()));
598 __ LoadClassById(EDI, kClassIdReg);
599 __ movl(EDI, FieldAddress(EDI, Class::signature_function_offset()));
600 __ cmpl(EDI, raw_null);
601 __ j(NOT_EQUAL, is_instance_lbl);
602 __ jmp(is_not_instance_lbl);
603 return;
604 }
605 // Custom checking for numbers (Smi, Mint, Bigint and Double).
606 // Note that instance is not Smi(checked above).
607 if (type.IsSubtypeOf(
608 Type::Handle(Type::NumberInterface()), &malformed_error)) {
609 GenerateNumberTypeCheck(
610 kClassIdReg, type, is_instance_lbl, is_not_instance_lbl);
611 return;
612 }
613 if (type.IsStringInterface()) {
614 GenerateStringTypeCheck(kClassIdReg, is_instance_lbl, is_not_instance_lbl);
615 return;
616 }
617 }
618
619
620 // Generates inlined check if 'type' is a type parameter or type itsef
621 // EAX: instance (preserved). Clobbers EDX, EDI, ECX.
622 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
623 intptr_t cid,
624 intptr_t token_index,
625 const AbstractType& type,
626 Label* is_instance_lbl,
627 Label* is_not_instance_lbl) {
628 ASSERT(!type.IsInstantiated());
629 // Skip check if destination is a dynamic type.
630 const Immediate raw_null =
631 Immediate(reinterpret_cast<intptr_t>(Object::null()));
632 if (type.IsTypeParameter()) {
633 // Load instantiator (or null) and instantiator type arguments on stack.
634 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments.
635 // EDX: instantiator type arguments.
636 // Check if type argument is Dynamic.
637 __ cmpl(EDX, raw_null);
638 __ j(EQUAL, is_instance_lbl);
639 // Can handle only type arguments that are instances of TypeArguments.
640 // (runtime checks canonicalize type arguments).
641 Label fall_through;
642 __ CompareClassId(EDX, kTypeArguments, EDI);
643 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
644
645 __ movl(EDI,
646 FieldAddress(EDX, TypeArguments::type_at_offset(type.Index())));
647 // EDI: concrete type of type.
648 // Check if type argument is dynamic.
649 __ CompareObject(EDI, Type::ZoneHandle(Type::DynamicType()));
650 __ j(EQUAL, is_instance_lbl);
651 __ cmpl(EDI, raw_null);
652 __ j(EQUAL, is_instance_lbl);
653 const Type& object_type =
654 Type::ZoneHandle(Isolate::Current()->object_store()->object_type());
655 __ CompareObject(EDI, object_type);
656 __ j(EQUAL, is_instance_lbl);
657
658 // For Smi check quickly against int and num interfaces.
659 Label not_smi;
660 __ testl(EAX, Immediate(kSmiTagMask)); // Value is Smi?
661 __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
662 __ CompareObject(EDI, Type::ZoneHandle(Type::IntInterface()));
663 __ j(EQUAL, is_instance_lbl);
664 __ CompareObject(EDI, Type::ZoneHandle(Type::NumberInterface()));
665 __ j(EQUAL, is_instance_lbl);
666 // Smi must be handled in runtime.
667 __ jmp(&fall_through);
668
669 __ Bind(&not_smi);
670 // EDX: instantiator type arguments.
671 // EAX: instance.
672 const Register kInstanceReg = EAX;
673 const Register kTypeArgumentsReg = EDX;
674 const Register kTempReg = EDI;
675 const SubtypeTestCache& type_test_cache =
676 SubtypeTestCache::ZoneHandle(
677 GenerateCallSubtypeTestStub(kTestTypeThreeArgs,
678 kInstanceReg,
679 kTypeArgumentsReg,
680 kTempReg,
681 is_instance_lbl,
682 is_not_instance_lbl));
683 __ Bind(&fall_through);
684 return type_test_cache.raw();
685 }
686 if (type.IsType()) {
687 const Register kInstanceReg = EAX;
688 const Register kTypeArgumentsReg = EDX;
689 __ testl(kInstanceReg, Immediate(kSmiTagMask)); // Is instance Smi?
690 __ j(ZERO, is_not_instance_lbl);
691 __ movl(kTypeArgumentsReg, Address(ESP, 0)); // Instantiator type args.
692 // Uninstantiated type class is known at compile time, but the type
693 // arguments are determined at runtime by the instantiator.
694 const Register kTempReg = EDI;
695 return GenerateCallSubtypeTestStub(kTestTypeThreeArgs,
696 kInstanceReg,
697 kTypeArgumentsReg,
698 kTempReg,
699 is_instance_lbl,
700 is_not_instance_lbl);
701 }
702 return SubtypeTestCache::null();
703 }
704
705
706 // Uses SubtypeTestCache to store instance class and result.
707 // EAX: instance to test. Clobbers EDI, ECX.
708 // Immediate class test already done.
709 // TODO(srdjan): Implement a quicker subtype check, as type test
710 // arrays can grow too high, but they may be useful when optimizing
711 // code (type-feedback).
712 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
713 intptr_t cid,
714 intptr_t token_index,
715 const Class& type_class,
716 Label* is_instance_lbl,
717 Label* is_not_instance_lbl) {
718 const Register kInstanceReg = EAX;
719 __ LoadClass(ECX, kInstanceReg, EDI);
720 // ECX: instance class.
721 // Check immediate superclass equality.
722 __ movl(EDI, FieldAddress(ECX, Class::super_type_offset()));
723 __ movl(EDI, FieldAddress(EDI, Type::type_class_offset()));
724 __ CompareObject(EDI, type_class);
725 __ j(EQUAL, is_instance_lbl);
726
727 const Register kTypeArgumentsReg = kNoRegister;
728 const Register kTempReg = EDI;
729 return GenerateCallSubtypeTestStub(kTestTypeOneArg,
730 kInstanceReg,
731 kTypeArgumentsReg,
732 kTempReg,
733 is_instance_lbl,
734 is_not_instance_lbl);
735 }
736
737
738 // Inputs:
739 // - EAX: instance to test against (preserved).
740 // - EDX: optional instantiator type arguments (preserved).
741 // Returns:
742 // - preserved instance in EAX and optional instantiator type arguments in EDX.
743 // Note that this inlined code must be followed by the runtime_call code, as it
744 // may fall through to it. Otherwise, this inline code will jump to the label
745 // is_instance or to the label is_not_instance.
746 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
747 intptr_t cid,
748 intptr_t token_index,
749 const AbstractType& type,
750 Label* is_instance_lbl,
751 Label* is_not_instance_lbl) {
752 if (type.IsInstantiated()) {
753 const Class& type_class = Class::ZoneHandle(type.type_class());
754 // A Smi object cannot be the instance of a parameterized class.
755 // A class equality check is only applicable with a dst type of a
756 // non-parameterized class or with a raw dst type of a parameterized class.
757 if (type_class.HasTypeArguments()) {
758 return GenerateInstantiatedTypeWithArgumentsTest(cid,
759 token_index,
760 type,
761 is_instance_lbl,
762 is_not_instance_lbl);
763 // Fall through to runtime call.
764 } else {
765 GenerateInstantiatedTypeNoArgumentsTest(cid,
766 token_index,
767 type,
768 is_instance_lbl,
769 is_not_instance_lbl);
770 // If test non-conclusive so far, try the inlined type-test cache.
771 // 'type' is known at compile time.
772 return GenerateSubtype1TestCacheLookup(
773 cid, token_index, type_class,
774 is_instance_lbl, is_not_instance_lbl);
775 }
776 } else {
777 return GenerateUninstantiatedTypeTest(cid,
778 token_index,
779 type,
780 is_instance_lbl,
781 is_not_instance_lbl);
782 }
783 return SubtypeTestCache::null();
784 }
785
786
412 // If instanceof type test cannot be performed successfully at compile time and 787 // If instanceof type test cannot be performed successfully at compile time and
413 // therefore eliminated, optimize it by adding inlined tests for: 788 // therefore eliminated, optimize it by adding inlined tests for:
414 // - NULL -> return false. 789 // - NULL -> return false.
415 // - Smi -> compile time subtype check (only if dst class is not parameterized). 790 // - Smi -> compile time subtype check (only if dst class is not parameterized).
416 // - Class equality (only if class is not parameterized). 791 // - Class equality (only if class is not parameterized).
417 // Inputs: 792 // Inputs:
418 // - EAX: object. 793 // - EAX: object.
419 // - EDX: instantiator type arguments or raw_null. 794 // - EDX: instantiator type arguments or raw_null.
420 // - ECX: instantiator or raw_null. 795 // - ECX: instantiator or raw_null.
421 // Returns: 796 // Returns:
(...skipping 21 matching lines...) Expand all
443 // instantiated). 818 // instantiated).
444 // We can only inline this null check if the type is instantiated at compile 819 // We can only inline this null check if the type is instantiated at compile
445 // time, since an uninstantiated type at compile time could be Object or 820 // time, since an uninstantiated type at compile time could be Object or
446 // Dynamic at run time. 821 // Dynamic at run time.
447 __ cmpl(EAX, raw_null); 822 __ cmpl(EAX, raw_null);
448 __ j(EQUAL, &is_not_instance); 823 __ j(EQUAL, &is_not_instance);
449 } 824 }
450 // TODO(srdjan): Enable inlined checks. 825 // TODO(srdjan): Enable inlined checks.
451 // Generate inline instanceof test. 826 // Generate inline instanceof test.
452 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); 827 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
453 // test_cache = GenerateInlineInstanceof(cid, token_index, type, 828 test_cache = GenerateInlineInstanceof(cid, token_index, type,
454 // &is_instance, &is_not_instance); 829 &is_instance, &is_not_instance);
455 830
456 // Generate runtime call. 831 // Generate runtime call.
457 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments. 832 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments.
458 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator. 833 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator.
459 __ PushObject(Object::ZoneHandle()); // Make room for the result. 834 __ PushObject(Object::ZoneHandle()); // Make room for the result.
460 __ pushl(Immediate(Smi::RawValue(token_index))); // Source location. 835 __ pushl(Immediate(Smi::RawValue(token_index))); // Source location.
461 __ pushl(Immediate(Smi::RawValue(cid))); // Computation id. 836 __ pushl(Immediate(Smi::RawValue(cid))); // Computation id.
462 __ pushl(EAX); // Push the instance. 837 __ pushl(EAX); // Push the instance.
463 __ PushObject(type); // Push the type. 838 __ PushObject(type); // Push the type.
464 __ pushl(ECX); // TODO(srdjan): Pass instantiator instead of null. 839 __ pushl(ECX); // TODO(srdjan): Pass instantiator instead of null.
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 // We should never return here. 919 // We should never return here.
545 __ int3(); 920 __ int3();
546 921
547 __ Bind(&is_assignable); // For a null object. 922 __ Bind(&is_assignable); // For a null object.
548 return; 923 return;
549 } 924 }
550 925
551 // TODO(srdjan): Enable subtype test cache. 926 // TODO(srdjan): Enable subtype test cache.
552 // Generate inline type check, linking to runtime call if not assignable. 927 // Generate inline type check, linking to runtime call if not assignable.
553 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); 928 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
554 // test_cache = GenerateInlineInstanceof(cid, token_index, dst_type, 929 test_cache = GenerateInlineInstanceof(cid, token_index, dst_type,
555 // &is_assignable, &runtime_call); 930 &is_assignable, &runtime_call);
556 931
557 __ Bind(&runtime_call); 932 __ Bind(&runtime_call);
558 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments. 933 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments.
559 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator. 934 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator.
560 __ PushObject(Object::ZoneHandle()); // Make room for the result. 935 __ PushObject(Object::ZoneHandle()); // Make room for the result.
561 __ pushl(Immediate(Smi::RawValue(token_index))); // Source location. 936 __ pushl(Immediate(Smi::RawValue(token_index))); // Source location.
562 __ pushl(Immediate(Smi::RawValue(cid))); // Computation id. 937 __ pushl(Immediate(Smi::RawValue(cid))); // Computation id.
563 __ pushl(EAX); // Push the source object. 938 __ pushl(EAX); // Push the source object.
564 __ PushObject(dst_type); // Push the type of the destination. 939 __ PushObject(dst_type); // Push the type of the destination.
565 __ pushl(ECX); // Instantiator. 940 __ pushl(ECX); // Instantiator.
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 } 1017 }
643 } 1018 }
644 } 1019 }
645 } 1020 }
646 1021
647 #undef __ 1022 #undef __
648 1023
649 } // namespace dart 1024 } // namespace dart
650 1025
651 #endif // defined TARGET_ARCH_IA32 1026 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.h ('k') | runtime/vm/flow_graph_compiler_shared.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698