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

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

Issue 10831261: Build and use stack maps in the SSA compiler. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 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
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"
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 // - EAX: object. 448 // - EAX: object.
449 // - EDX: instantiator type arguments or raw_null. 449 // - EDX: instantiator type arguments or raw_null.
450 // - ECX: instantiator or raw_null. 450 // - ECX: instantiator or raw_null.
451 // Clobbers ECX and EDX. 451 // Clobbers ECX and EDX.
452 // Returns: 452 // Returns:
453 // - true or false in EAX. 453 // - true or false in EAX.
454 void FlowGraphCompiler::GenerateInstanceOf(intptr_t deopt_id, 454 void FlowGraphCompiler::GenerateInstanceOf(intptr_t deopt_id,
455 intptr_t token_pos, 455 intptr_t token_pos,
456 intptr_t try_index, 456 intptr_t try_index,
457 const AbstractType& type, 457 const AbstractType& type,
458 bool negate_result) { 458 bool negate_result,
459 BitmapBuilder* stack_bitmap) {
459 ASSERT(type.IsFinalized() && !type.IsMalformed()); 460 ASSERT(type.IsFinalized() && !type.IsMalformed());
460 461
461 const Immediate raw_null = 462 const Immediate raw_null =
462 Immediate(reinterpret_cast<intptr_t>(Object::null())); 463 Immediate(reinterpret_cast<intptr_t>(Object::null()));
463 Label is_instance, is_not_instance; 464 Label is_instance, is_not_instance;
464 __ pushl(ECX); // Store instantiator on stack. 465 __ pushl(ECX); // Store instantiator on stack.
465 __ pushl(EDX); // Store instantiator type arguments. 466 __ pushl(EDX); // Store instantiator type arguments.
466 // If type is instantiated and non-parameterized, we can inline code 467 // If type is instantiated and non-parameterized, we can inline code
467 // checking whether the tested instance is a Smi. 468 // checking whether the tested instance is a Smi.
468 if (type.IsInstantiated()) { 469 if (type.IsInstantiated()) {
(...skipping 20 matching lines...) Expand all
489 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments. 490 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments.
490 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator. 491 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator.
491 __ PushObject(Object::ZoneHandle()); // Make room for the result. 492 __ PushObject(Object::ZoneHandle()); // Make room for the result.
492 __ pushl(EAX); // Push the instance. 493 __ pushl(EAX); // Push the instance.
493 __ PushObject(type); // Push the type. 494 __ PushObject(type); // Push the type.
494 __ pushl(ECX); // Instantiator. 495 __ pushl(ECX); // Instantiator.
495 __ pushl(EDX); // Instantiator type arguments. 496 __ pushl(EDX); // Instantiator type arguments.
496 __ LoadObject(EAX, test_cache); 497 __ LoadObject(EAX, test_cache);
497 __ pushl(EAX); 498 __ pushl(EAX);
498 GenerateCallRuntime(deopt_id, token_pos, try_index, 499 GenerateCallRuntime(deopt_id, token_pos, try_index,
499 kInstanceofRuntimeEntry); 500 kInstanceofRuntimeEntry, stack_bitmap);
500 // Pop the parameters supplied to the runtime entry. The result of the 501 // Pop the parameters supplied to the runtime entry. The result of the
501 // instanceof runtime call will be left as the result of the operation. 502 // instanceof runtime call will be left as the result of the operation.
502 __ Drop(5); 503 __ Drop(5);
503 if (negate_result) { 504 if (negate_result) {
504 __ popl(EDX); 505 __ popl(EDX);
505 __ LoadObject(EAX, bool_true()); 506 __ LoadObject(EAX, bool_true());
506 __ cmpl(EDX, EAX); 507 __ cmpl(EDX, EAX);
507 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 508 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
508 __ LoadObject(EAX, bool_false()); 509 __ LoadObject(EAX, bool_false());
509 } else { 510 } else {
(...skipping 22 matching lines...) Expand all
532 // - EDX: instantiator type arguments or raw_null. 533 // - EDX: instantiator type arguments or raw_null.
533 // - ECX: instantiator or raw_null. 534 // - ECX: instantiator or raw_null.
534 // Returns: 535 // Returns:
535 // - object in EAX for successful assignable check (or throws TypeError). 536 // - object in EAX for successful assignable check (or throws TypeError).
536 // Performance notes: positive checks must be quick, negative checks can be slow 537 // Performance notes: positive checks must be quick, negative checks can be slow
537 // as they throw an exception. 538 // as they throw an exception.
538 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t deopt_id, 539 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t deopt_id,
539 intptr_t token_pos, 540 intptr_t token_pos,
540 intptr_t try_index, 541 intptr_t try_index,
541 const AbstractType& dst_type, 542 const AbstractType& dst_type,
542 const String& dst_name) { 543 const String& dst_name,
544 BitmapBuilder* stack_bitmap) {
543 ASSERT(token_pos >= 0); 545 ASSERT(token_pos >= 0);
544 ASSERT(!dst_type.IsNull()); 546 ASSERT(!dst_type.IsNull());
545 ASSERT(dst_type.IsFinalized()); 547 ASSERT(dst_type.IsFinalized());
546 // Assignable check is skipped in FlowGraphBuilder, not here. 548 // Assignable check is skipped in FlowGraphBuilder, not here.
547 ASSERT(dst_type.IsMalformed() || 549 ASSERT(dst_type.IsMalformed() ||
548 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); 550 (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
549 __ pushl(ECX); // Store instantiator. 551 __ pushl(ECX); // Store instantiator.
550 __ pushl(EDX); // Store instantiator type arguments. 552 __ pushl(EDX); // Store instantiator type arguments.
551 // A null object is always assignable and is returned as result. 553 // A null object is always assignable and is returned as result.
552 const Immediate raw_null = 554 const Immediate raw_null =
553 Immediate(reinterpret_cast<intptr_t>(Object::null())); 555 Immediate(reinterpret_cast<intptr_t>(Object::null()));
554 Label is_assignable, runtime_call; 556 Label is_assignable, runtime_call;
555 __ cmpl(EAX, raw_null); 557 __ cmpl(EAX, raw_null);
556 __ j(EQUAL, &is_assignable); 558 __ j(EQUAL, &is_assignable);
557 559
558 // Generate throw new TypeError() if the type is malformed. 560 // Generate throw new TypeError() if the type is malformed.
559 if (dst_type.IsMalformed()) { 561 if (dst_type.IsMalformed()) {
560 const Error& error = Error::Handle(dst_type.malformed_error()); 562 const Error& error = Error::Handle(dst_type.malformed_error());
561 const String& error_message = String::ZoneHandle( 563 const String& error_message = String::ZoneHandle(
562 Symbols::New(error.ToErrorCString())); 564 Symbols::New(error.ToErrorCString()));
563 __ PushObject(Object::ZoneHandle()); // Make room for the result. 565 __ PushObject(Object::ZoneHandle()); // Make room for the result.
564 __ pushl(EAX); // Push the source object. 566 __ pushl(EAX); // Push the source object.
565 __ PushObject(dst_name); // Push the name of the destination. 567 __ PushObject(dst_name); // Push the name of the destination.
566 __ PushObject(error_message); 568 __ PushObject(error_message);
567 GenerateCallRuntime(deopt_id, 569 GenerateCallRuntime(deopt_id,
568 token_pos, 570 token_pos,
569 try_index, 571 try_index,
570 kMalformedTypeErrorRuntimeEntry); 572 kMalformedTypeErrorRuntimeEntry,
573 stack_bitmap);
571 // We should never return here. 574 // We should never return here.
572 __ int3(); 575 __ int3();
573 576
574 __ Bind(&is_assignable); // For a null object. 577 __ Bind(&is_assignable); // For a null object.
575 __ popl(EDX); // Remove pushed instantiator type arguments. 578 __ popl(EDX); // Remove pushed instantiator type arguments.
576 __ popl(ECX); // Remove pushed instantiator. 579 __ popl(ECX); // Remove pushed instantiator.
577 return; 580 return;
578 } 581 }
579 582
580 // Generate inline type check, linking to runtime call if not assignable. 583 // Generate inline type check, linking to runtime call if not assignable.
581 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); 584 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
582 test_cache = GenerateInlineInstanceof(token_pos, dst_type, 585 test_cache = GenerateInlineInstanceof(token_pos, dst_type,
583 &is_assignable, &runtime_call); 586 &is_assignable, &runtime_call);
584 587
585 __ Bind(&runtime_call); 588 __ Bind(&runtime_call);
586 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments. 589 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments.
587 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator. 590 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator.
588 __ PushObject(Object::ZoneHandle()); // Make room for the result. 591 __ PushObject(Object::ZoneHandle()); // Make room for the result.
589 __ pushl(EAX); // Push the source object. 592 __ pushl(EAX); // Push the source object.
590 __ PushObject(dst_type); // Push the type of the destination. 593 __ PushObject(dst_type); // Push the type of the destination.
591 __ pushl(ECX); // Instantiator. 594 __ pushl(ECX); // Instantiator.
592 __ pushl(EDX); // Instantiator type arguments. 595 __ pushl(EDX); // Instantiator type arguments.
593 __ PushObject(dst_name); // Push the name of the destination. 596 __ PushObject(dst_name); // Push the name of the destination.
594 __ LoadObject(EAX, test_cache); 597 __ LoadObject(EAX, test_cache);
595 __ pushl(EAX); 598 __ pushl(EAX);
596 GenerateCallRuntime(deopt_id, 599 GenerateCallRuntime(deopt_id,
597 token_pos, 600 token_pos,
598 try_index, 601 try_index,
599 kTypeCheckRuntimeEntry); 602 kTypeCheckRuntimeEntry,
603 stack_bitmap);
600 // Pop the parameters supplied to the runtime entry. The result of the 604 // Pop the parameters supplied to the runtime entry. The result of the
601 // type check runtime call is the checked value. 605 // type check runtime call is the checked value.
602 __ Drop(6); 606 __ Drop(6);
603 __ popl(EAX); 607 __ popl(EAX);
604 608
605 __ Bind(&is_assignable); 609 __ Bind(&is_assignable);
606 __ popl(EDX); // Remove pushed instantiator type arguments. 610 __ popl(EDX); // Remove pushed instantiator type arguments.
607 __ popl(ECX); // Remove pushed instantiator. 611 __ popl(ECX); // Remove pushed instantiator.
608 } 612 }
609 613
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 if (StackSize() != 0) { 773 if (StackSize() != 0) {
770 // We need to unwind the space we reserved for locals and copied parameters. 774 // We need to unwind the space we reserved for locals and copied parameters.
771 // The NoSuchMethodFunction stub does not expect to see that area on the 775 // The NoSuchMethodFunction stub does not expect to see that area on the
772 // stack. 776 // stack.
773 __ addl(ESP, Immediate(StackSize() * kWordSize)); 777 __ addl(ESP, Immediate(StackSize() * kWordSize));
774 } 778 }
775 if (function.IsClosureFunction()) { 779 if (function.IsClosureFunction()) {
776 GenerateCallRuntime(Isolate::kNoDeoptId, 780 GenerateCallRuntime(Isolate::kNoDeoptId,
777 0, 781 0,
778 CatchClauseNode::kInvalidTryIndex, 782 CatchClauseNode::kInvalidTryIndex,
779 kClosureArgumentMismatchRuntimeEntry); 783 kClosureArgumentMismatchRuntimeEntry,
784 NULL);
Vyacheslav Egorov (Google) 2012/08/13 12:54:46 This NULL looks suspicious to me because we alread
Kevin Millikin (Google) 2012/08/13 15:10:37 Yes, it's an existing problem. We should be able
780 } else { 785 } else {
781 ASSERT(!IsLeaf()); 786 ASSERT(!IsLeaf());
782 // Invoke noSuchMethod function. 787 // Invoke noSuchMethod function.
783 const int kNumArgsChecked = 1; 788 const int kNumArgsChecked = 1;
784 ICData& ic_data = ICData::ZoneHandle(); 789 ICData& ic_data = ICData::ZoneHandle();
785 ic_data = ICData::New(function, 790 ic_data = ICData::New(function,
786 String::Handle(function.name()), 791 String::Handle(function.name()),
787 Isolate::kNoDeoptId, 792 Isolate::kNoDeoptId,
788 kNumArgsChecked); 793 kNumArgsChecked);
789 __ LoadObject(ECX, ic_data); 794 __ LoadObject(ECX, ic_data);
790 // EBP - 4 : PC marker, allows easy identification of RawInstruction obj. 795 // EBP - 4 : PC marker, allows easy identification of RawInstruction obj.
791 // EBP : points to previous frame pointer. 796 // EBP : points to previous frame pointer.
792 // EBP + 4 : points to return address. 797 // EBP + 4 : points to return address.
793 // EBP + 8 : address of last argument (arg n-1). 798 // EBP + 8 : address of last argument (arg n-1).
794 // ESP + 8 + 4*(n-1) : address of first argument (arg 0). 799 // ESP + 8 + 4*(n-1) : address of first argument (arg 0).
795 // ECX : ic-data. 800 // ECX : ic-data.
796 // EDX : arguments descriptor array. 801 // EDX : arguments descriptor array.
797 __ call(&StubCode::CallNoSuchMethodFunctionLabel()); 802 __ call(&StubCode::CallNoSuchMethodFunctionLabel());
798 } 803 }
799 804
800 if (FLAG_trace_functions) { 805 if (FLAG_trace_functions) {
801 __ pushl(EAX); // Preserve result. 806 __ pushl(EAX); // Preserve result.
802 __ PushObject(Function::ZoneHandle(function.raw())); 807 __ PushObject(Function::ZoneHandle(function.raw()));
803 GenerateCallRuntime(Isolate::kNoDeoptId, 808 GenerateCallRuntime(Isolate::kNoDeoptId,
804 0, 809 0,
805 CatchClauseNode::kInvalidTryIndex, 810 CatchClauseNode::kInvalidTryIndex,
806 kTraceFunctionExitRuntimeEntry); 811 kTraceFunctionExitRuntimeEntry,
812 NULL);
Vyacheslav Egorov (Google) 2012/08/13 12:54:46 This NULL looks suspicious to me because we alread
Kevin Millikin (Google) 2012/08/13 15:10:37 Agreed.
807 __ popl(EAX); // Remove argument. 813 __ popl(EAX); // Remove argument.
808 __ popl(EAX); // Restore result. 814 __ popl(EAX); // Restore result.
809 } 815 }
810 __ LeaveFrame(); 816 __ LeaveFrame();
811 __ ret(); 817 __ ret();
812 818
813 __ Bind(&all_arguments_processed); 819 __ Bind(&all_arguments_processed);
814 // Nullify originally passed arguments only after they have been copied and 820 // Nullify originally passed arguments only after they have been copied and
815 // checked, otherwise noSuchMethod would not see their original values. 821 // checked, otherwise noSuchMethod would not see their original values.
816 // This step can be skipped in case we decide that formal parameters are 822 // This step can be skipped in case we decide that formal parameters are
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum 895 // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum
890 // code size. 896 // code size.
891 __ int3(); 897 __ int3();
892 __ jmp(&StubCode::FixCallersTargetLabel()); 898 __ jmp(&StubCode::FixCallersTargetLabel());
893 return; 899 return;
894 } 900 }
895 // Specialized version of entry code from CodeGenerator::GenerateEntryCode. 901 // Specialized version of entry code from CodeGenerator::GenerateEntryCode.
896 const Function& function = parsed_function().function(); 902 const Function& function = parsed_function().function();
897 903
898 const int parameter_count = function.num_fixed_parameters(); 904 const int parameter_count = function.num_fixed_parameters();
899 const int num_copied_params = parsed_function().copied_parameter_count(); 905 const int copied_parameter_count = parsed_function().copied_parameter_count();
900 const int local_count = parsed_function().stack_local_count(); 906 const int local_count = parsed_function().stack_local_count();
901 __ Comment("Enter frame"); 907 __ Comment("Enter frame");
902 if (IsLeaf()) { 908 if (IsLeaf()) {
903 AssemblerMacros::EnterDartLeafFrame(assembler(), (StackSize() * kWordSize)); 909 AssemblerMacros::EnterDartLeafFrame(assembler(), (StackSize() * kWordSize));
904 } else { 910 } else {
905 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize)); 911 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize));
906 } 912 }
907 // We check the number of passed arguments when we have to copy them due to 913 // We check the number of passed arguments when we have to copy them due to
908 // the presence of optional named parameters. 914 // the presence of optional named parameters.
909 // No such checking code is generated if only fixed parameters are declared, 915 // No such checking code is generated if only fixed parameters are declared,
910 // unless we are debug mode or unless we are compiling a closure. 916 // unless we are debug mode or unless we are compiling a closure.
911 if (num_copied_params == 0) { 917 if (copied_parameter_count == 0) {
912 #ifdef DEBUG 918 #ifdef DEBUG
913 const bool check_arguments = true; 919 const bool check_arguments = true;
914 #else 920 #else
915 const bool check_arguments = function.IsClosureFunction(); 921 const bool check_arguments = function.IsClosureFunction();
916 #endif 922 #endif
917 if (check_arguments) { 923 if (check_arguments) {
918 __ Comment("Check argument count"); 924 __ Comment("Check argument count");
919 // Check that num_fixed <= argc <= num_params. 925 // Check that num_fixed <= argc <= num_params.
920 Label argc_in_range; 926 Label argc_in_range;
921 // Total number of args is the first Smi in args descriptor array (EDX). 927 // Total number of args is the first Smi in args descriptor array (EDX).
922 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 928 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
923 __ cmpl(EAX, Immediate(Smi::RawValue(parameter_count))); 929 __ cmpl(EAX, Immediate(Smi::RawValue(parameter_count)));
924 __ j(EQUAL, &argc_in_range, Assembler::kNearJump); 930 __ j(EQUAL, &argc_in_range, Assembler::kNearJump);
925 if (function.IsClosureFunction()) { 931 if (function.IsClosureFunction()) {
926 GenerateCallRuntime(Isolate::kNoDeoptId, 932 GenerateCallRuntime(Isolate::kNoDeoptId,
927 function.token_pos(), 933 function.token_pos(),
928 CatchClauseNode::kInvalidTryIndex, 934 CatchClauseNode::kInvalidTryIndex,
929 kClosureArgumentMismatchRuntimeEntry); 935 kClosureArgumentMismatchRuntimeEntry,
936 NULL);
Vyacheslav Egorov (Google) 2012/08/13 12:54:46 This NULL looks suspicious to me because we alread
Kevin Millikin (Google) 2012/08/13 15:10:37 Agreed.
930 } else { 937 } else {
931 __ Stop("Wrong number of arguments"); 938 __ Stop("Wrong number of arguments");
932 } 939 }
933 __ Bind(&argc_in_range); 940 __ Bind(&argc_in_range);
934 } 941 }
935 } else { 942 } else {
936 CopyParameters(); 943 CopyParameters();
937 } 944 }
938 945
946 // Initialize (non-argument) stack allocated slots to null.
947 //
939 // TODO(vegorov): introduce stack maps and stop initializing all spill slots 948 // TODO(vegorov): introduce stack maps and stop initializing all spill slots
940 // with null. 949 // with null.
941 const intptr_t stack_slot_count = 950 intptr_t uninitialized_slot_count;
942 is_ssa_ ? block_order_[0]->AsGraphEntry()->spill_slot_count() 951 if (is_ssa_) {
943 : local_count; 952 GraphEntryInstr* entry = block_order_[0]->AsGraphEntry();
944 953 uninitialized_slot_count =
954 entry->spill_slot_count() - copied_parameter_count;
955 } else {
956 uninitialized_slot_count = local_count;
957 }
945 const intptr_t slot_base = parsed_function().first_stack_local_index(); 958 const intptr_t slot_base = parsed_function().first_stack_local_index();
946 959
947 // Initialize (non-argument) stack allocated locals to null. 960 if (uninitialized_slot_count > 0) {
948 if (stack_slot_count > 0) {
949 __ Comment("Initialize spill slots"); 961 __ Comment("Initialize spill slots");
950 const Immediate raw_null = 962 const Immediate raw_null =
951 Immediate(reinterpret_cast<intptr_t>(Object::null())); 963 Immediate(reinterpret_cast<intptr_t>(Object::null()));
952 __ movl(EAX, raw_null); 964 __ movl(EAX, raw_null);
953 for (intptr_t i = 0; i < stack_slot_count; ++i) { 965 for (intptr_t i = 0; i < uninitialized_slot_count; ++i) {
954 // Subtract index i (locals lie at lower addresses than EBP). 966 // Subtract index i (locals lie at lower addresses than EBP).
955 __ movl(Address(EBP, (slot_base - i) * kWordSize), EAX); 967 __ movl(Address(EBP, (slot_base - i) * kWordSize), EAX);
956 } 968 }
957 } 969 }
958 970
959 if (FLAG_print_scopes) { 971 if (FLAG_print_scopes) {
960 // Print the function scope (again) after generating the prologue in order 972 // Print the function scope (again) after generating the prologue in order
961 // to see annotations such as allocation indices of locals. 973 // to see annotations such as allocation indices of locals.
962 if (FLAG_print_ast) { 974 if (FLAG_print_ast) {
963 // Second printing. 975 // Second printing.
(...skipping 13 matching lines...) Expand all
977 Isolate::kNoDeoptId, 989 Isolate::kNoDeoptId,
978 0, 990 0,
979 -1); 991 -1);
980 __ jmp(&StubCode::FixCallersTargetLabel()); 992 __ jmp(&StubCode::FixCallersTargetLabel());
981 } 993 }
982 994
983 995
984 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, 996 void FlowGraphCompiler::GenerateCall(intptr_t token_pos,
985 intptr_t try_index, 997 intptr_t try_index,
986 const ExternalLabel* label, 998 const ExternalLabel* label,
987 PcDescriptors::Kind kind) { 999 PcDescriptors::Kind kind,
1000 BitmapBuilder* stack_bitmap) {
988 ASSERT(!IsLeaf()); 1001 ASSERT(!IsLeaf());
989 ASSERT(frame_register_allocator()->IsSpilled()); 1002 ASSERT(frame_register_allocator()->IsSpilled());
990 __ call(label); 1003 __ call(label);
1004 if (is_ssa() && (stack_bitmap != NULL)) {
1005 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), stack_bitmap);
1006 }
991 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos, try_index); 1007 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos, try_index);
992 } 1008 }
993 1009
994 1010
995 void FlowGraphCompiler::GenerateCallRuntime(intptr_t deopt_id, 1011 void FlowGraphCompiler::GenerateCallRuntime(intptr_t deopt_id,
996 intptr_t token_pos, 1012 intptr_t token_pos,
997 intptr_t try_index, 1013 intptr_t try_index,
998 const RuntimeEntry& entry) { 1014 const RuntimeEntry& entry,
1015 BitmapBuilder* stack_bitmap) {
999 ASSERT(!IsLeaf()); 1016 ASSERT(!IsLeaf());
1000 ASSERT(frame_register_allocator()->IsSpilled()); 1017 ASSERT(frame_register_allocator()->IsSpilled());
1001 __ CallRuntime(entry); 1018 __ CallRuntime(entry);
1019 if (is_ssa() && (stack_bitmap != NULL)) {
1020 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), stack_bitmap);
1021 }
1002 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos, try_index); 1022 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos, try_index);
1003 } 1023 }
1004 1024
1005 1025
1006 intptr_t FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, 1026 intptr_t FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label,
1007 const ICData& ic_data, 1027 const ICData& ic_data,
1008 const Array& arguments_descriptor, 1028 const Array& arguments_descriptor,
1009 intptr_t argument_count) { 1029 intptr_t argument_count) {
1010 ASSERT(!IsLeaf()); 1030 ASSERT(!IsLeaf());
1011 __ LoadObject(ECX, ic_data); 1031 __ LoadObject(ECX, ic_data);
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1208 __ popl(ECX); 1228 __ popl(ECX);
1209 __ popl(EAX); 1229 __ popl(EAX);
1210 } 1230 }
1211 1231
1212 1232
1213 #undef __ 1233 #undef __
1214 1234
1215 } // namespace dart 1235 } // namespace dart
1216 1236
1217 #endif // defined TARGET_ARCH_IA32 1237 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698