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

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

Issue 10873027: Use the location summary to represent safepoint information. (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
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.h ('k') | runtime/vm/flow_graph_compiler_x64.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"
(...skipping 29 matching lines...) Expand all
40 const intptr_t offset = assem->CodeSize(); 40 const intptr_t offset = assem->CodeSize();
41 __ Bind(&L); 41 __ Bind(&L);
42 __ popl(EAX); 42 __ popl(EAX);
43 __ subl(EAX, 43 __ subl(EAX,
44 Immediate(offset - AssemblerMacros::kOffsetOfSavedPCfromEntrypoint)); 44 Immediate(offset - AssemblerMacros::kOffsetOfSavedPCfromEntrypoint));
45 __ movl(Address(EBP, -kWordSize), EAX); 45 __ movl(Address(EBP, -kWordSize), EAX);
46 __ popl(EAX); 46 __ popl(EAX);
47 } 47 }
48 __ call(&StubCode::DeoptimizeLabel()); 48 __ call(&StubCode::DeoptimizeLabel());
49 const intptr_t deopt_info_index = stub_ix; 49 const intptr_t deopt_info_index = stub_ix;
50 compiler->pc_descriptors_list()-> AddDeoptInfo( 50 compiler->pc_descriptors_list()->AddDeoptInfo(
51 compiler->assembler()->CodeSize(), 51 compiler->assembler()->CodeSize(),
52 deopt_id_, 52 deopt_id_,
53 reason_, 53 reason_,
54 deopt_info_index); 54 deopt_info_index);
55 #undef __ 55 #undef __
56 } 56 }
57 57
58 58
59 #define __ assembler()-> 59 #define __ assembler()->
60 60
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 // - EDX: instantiator type arguments or raw_null. 443 // - EDX: instantiator type arguments or raw_null.
444 // - ECX: instantiator or raw_null. 444 // - ECX: instantiator or raw_null.
445 // Clobbers ECX and EDX. 445 // Clobbers ECX and EDX.
446 // Returns: 446 // Returns:
447 // - true or false in EAX. 447 // - true or false in EAX.
448 void FlowGraphCompiler::GenerateInstanceOf(intptr_t deopt_id, 448 void FlowGraphCompiler::GenerateInstanceOf(intptr_t deopt_id,
449 intptr_t token_pos, 449 intptr_t token_pos,
450 intptr_t try_index, 450 intptr_t try_index,
451 const AbstractType& type, 451 const AbstractType& type,
452 bool negate_result, 452 bool negate_result,
453 BitmapBuilder* stack_bitmap) { 453 LocationSummary* locs) {
454 ASSERT(type.IsFinalized() && !type.IsMalformed()); 454 ASSERT(type.IsFinalized() && !type.IsMalformed());
455 455
456 const Immediate raw_null = 456 const Immediate raw_null =
457 Immediate(reinterpret_cast<intptr_t>(Object::null())); 457 Immediate(reinterpret_cast<intptr_t>(Object::null()));
458 Label is_instance, is_not_instance; 458 Label is_instance, is_not_instance;
459 __ pushl(ECX); // Store instantiator on stack. 459 __ pushl(ECX); // Store instantiator on stack.
460 __ pushl(EDX); // Store instantiator type arguments. 460 __ pushl(EDX); // Store instantiator type arguments.
461 // If type is instantiated and non-parameterized, we can inline code 461 // If type is instantiated and non-parameterized, we can inline code
462 // checking whether the tested instance is a Smi. 462 // checking whether the tested instance is a Smi.
463 if (type.IsInstantiated()) { 463 if (type.IsInstantiated()) {
(...skipping 20 matching lines...) Expand all
484 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments. 484 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments.
485 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator. 485 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator.
486 __ PushObject(Object::ZoneHandle()); // Make room for the result. 486 __ PushObject(Object::ZoneHandle()); // Make room for the result.
487 __ pushl(EAX); // Push the instance. 487 __ pushl(EAX); // Push the instance.
488 __ PushObject(type); // Push the type. 488 __ PushObject(type); // Push the type.
489 __ pushl(ECX); // Instantiator. 489 __ pushl(ECX); // Instantiator.
490 __ pushl(EDX); // Instantiator type arguments. 490 __ pushl(EDX); // Instantiator type arguments.
491 __ LoadObject(EAX, test_cache); 491 __ LoadObject(EAX, test_cache);
492 __ pushl(EAX); 492 __ pushl(EAX);
493 GenerateCallRuntime(deopt_id, token_pos, try_index, 493 GenerateCallRuntime(deopt_id, token_pos, try_index,
494 kInstanceofRuntimeEntry, stack_bitmap); 494 kInstanceofRuntimeEntry, locs);
495 // 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
496 // 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.
497 __ Drop(5); 497 __ Drop(5);
498 if (negate_result) { 498 if (negate_result) {
499 __ popl(EDX); 499 __ popl(EDX);
500 __ LoadObject(EAX, bool_true()); 500 __ LoadObject(EAX, bool_true());
501 __ cmpl(EDX, EAX); 501 __ cmpl(EDX, EAX);
502 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 502 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
503 __ LoadObject(EAX, bool_false()); 503 __ LoadObject(EAX, bool_false());
504 } else { 504 } else {
(...skipping 23 matching lines...) Expand all
528 // - ECX: instantiator or raw_null. 528 // - ECX: instantiator or raw_null.
529 // Returns: 529 // Returns:
530 // - object in EAX for successful assignable check (or throws TypeError). 530 // - object in EAX for successful assignable check (or throws TypeError).
531 // 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
532 // as they throw an exception. 532 // as they throw an exception.
533 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t deopt_id, 533 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t deopt_id,
534 intptr_t token_pos, 534 intptr_t token_pos,
535 intptr_t try_index, 535 intptr_t try_index,
536 const AbstractType& dst_type, 536 const AbstractType& dst_type,
537 const String& dst_name, 537 const String& dst_name,
538 BitmapBuilder* stack_bitmap) { 538 LocationSummary* locs) {
539 ASSERT(token_pos >= 0); 539 ASSERT(token_pos >= 0);
540 ASSERT(!dst_type.IsNull()); 540 ASSERT(!dst_type.IsNull());
541 ASSERT(dst_type.IsFinalized()); 541 ASSERT(dst_type.IsFinalized());
542 // Assignable check is skipped in FlowGraphBuilder, not here. 542 // Assignable check is skipped in FlowGraphBuilder, not here.
543 ASSERT(dst_type.IsMalformed() || 543 ASSERT(dst_type.IsMalformed() ||
544 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); 544 (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
545 __ pushl(ECX); // Store instantiator. 545 __ pushl(ECX); // Store instantiator.
546 __ pushl(EDX); // Store instantiator type arguments. 546 __ pushl(EDX); // Store instantiator type arguments.
547 // A null object is always assignable and is returned as result. 547 // A null object is always assignable and is returned as result.
548 const Immediate raw_null = 548 const Immediate raw_null =
549 Immediate(reinterpret_cast<intptr_t>(Object::null())); 549 Immediate(reinterpret_cast<intptr_t>(Object::null()));
550 Label is_assignable, runtime_call; 550 Label is_assignable, runtime_call;
551 __ cmpl(EAX, raw_null); 551 __ cmpl(EAX, raw_null);
552 __ j(EQUAL, &is_assignable); 552 __ j(EQUAL, &is_assignable);
553 553
554 // Generate throw new TypeError() if the type is malformed. 554 // Generate throw new TypeError() if the type is malformed.
555 if (dst_type.IsMalformed()) { 555 if (dst_type.IsMalformed()) {
556 const Error& error = Error::Handle(dst_type.malformed_error()); 556 const Error& error = Error::Handle(dst_type.malformed_error());
557 const String& error_message = String::ZoneHandle( 557 const String& error_message = String::ZoneHandle(
558 Symbols::New(error.ToErrorCString())); 558 Symbols::New(error.ToErrorCString()));
559 __ PushObject(Object::ZoneHandle()); // Make room for the result. 559 __ PushObject(Object::ZoneHandle()); // Make room for the result.
560 __ pushl(EAX); // Push the source object. 560 __ pushl(EAX); // Push the source object.
561 __ PushObject(dst_name); // Push the name of the destination. 561 __ PushObject(dst_name); // Push the name of the destination.
562 __ PushObject(error_message); 562 __ PushObject(error_message);
563 GenerateCallRuntime(deopt_id, 563 GenerateCallRuntime(deopt_id,
564 token_pos, 564 token_pos,
565 try_index, 565 try_index,
566 kMalformedTypeErrorRuntimeEntry, 566 kMalformedTypeErrorRuntimeEntry,
567 stack_bitmap); 567 locs);
568 // We should never return here. 568 // We should never return here.
569 __ int3(); 569 __ int3();
570 570
571 __ Bind(&is_assignable); // For a null object. 571 __ Bind(&is_assignable); // For a null object.
572 __ popl(EDX); // Remove pushed instantiator type arguments. 572 __ popl(EDX); // Remove pushed instantiator type arguments.
573 __ popl(ECX); // Remove pushed instantiator. 573 __ popl(ECX); // Remove pushed instantiator.
574 return; 574 return;
575 } 575 }
576 576
577 // Generate inline type check, linking to runtime call if not assignable. 577 // Generate inline type check, linking to runtime call if not assignable.
578 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); 578 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
579 test_cache = GenerateInlineInstanceof(token_pos, dst_type, 579 test_cache = GenerateInlineInstanceof(token_pos, dst_type,
580 &is_assignable, &runtime_call); 580 &is_assignable, &runtime_call);
581 581
582 __ Bind(&runtime_call); 582 __ Bind(&runtime_call);
583 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments. 583 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments.
584 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator. 584 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator.
585 __ PushObject(Object::ZoneHandle()); // Make room for the result. 585 __ PushObject(Object::ZoneHandle()); // Make room for the result.
586 __ pushl(EAX); // Push the source object. 586 __ pushl(EAX); // Push the source object.
587 __ PushObject(dst_type); // Push the type of the destination. 587 __ PushObject(dst_type); // Push the type of the destination.
588 __ pushl(ECX); // Instantiator. 588 __ pushl(ECX); // Instantiator.
589 __ pushl(EDX); // Instantiator type arguments. 589 __ pushl(EDX); // Instantiator type arguments.
590 __ PushObject(dst_name); // Push the name of the destination. 590 __ PushObject(dst_name); // Push the name of the destination.
591 __ LoadObject(EAX, test_cache); 591 __ LoadObject(EAX, test_cache);
592 __ pushl(EAX); 592 __ pushl(EAX);
593 GenerateCallRuntime(deopt_id, 593 GenerateCallRuntime(deopt_id,
594 token_pos, 594 token_pos,
595 try_index, 595 try_index,
596 kTypeCheckRuntimeEntry, 596 kTypeCheckRuntimeEntry,
597 stack_bitmap); 597 locs);
598 // Pop the parameters supplied to the runtime entry. The result of the 598 // Pop the parameters supplied to the runtime entry. The result of the
599 // type check runtime call is the checked value. 599 // type check runtime call is the checked value.
600 __ Drop(6); 600 __ Drop(6);
601 __ popl(EAX); 601 __ popl(EAX);
602 602
603 __ Bind(&is_assignable); 603 __ Bind(&is_assignable);
604 __ popl(EDX); // Remove pushed instantiator type arguments. 604 __ popl(EDX); // Remove pushed instantiator type arguments.
605 __ popl(ECX); // Remove pushed instantiator. 605 __ popl(ECX); // Remove pushed instantiator.
606 } 606 }
607 607
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 if (StackSize() != 0) { 761 if (StackSize() != 0) {
762 // We need to unwind the space we reserved for locals and copied parameters. 762 // We need to unwind the space we reserved for locals and copied parameters.
763 // The NoSuchMethodFunction stub does not expect to see that area on the 763 // The NoSuchMethodFunction stub does not expect to see that area on the
764 // stack. 764 // stack.
765 __ addl(ESP, Immediate(StackSize() * kWordSize)); 765 __ addl(ESP, Immediate(StackSize() * kWordSize));
766 } 766 }
767 // The calls below have empty stackmaps because we have just dropped the 767 // The calls below have empty stackmaps because we have just dropped the
768 // spill slots. 768 // spill slots.
769 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder(); 769 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
770 if (function.IsClosureFunction()) { 770 if (function.IsClosureFunction()) {
771 GenerateCallRuntime(Isolate::kNoDeoptId, 771 // We do not use GenerateCallRuntime because of the non-standard (empty)
772 0, 772 // stackmap used here.
773 CatchClauseNode::kInvalidTryIndex, 773 __ CallRuntime(kClosureArgumentMismatchRuntimeEntry);
774 kClosureArgumentMismatchRuntimeEntry, 774 AddCurrentDescriptor(PcDescriptors::kOther,
775 empty_stack_bitmap); 775 Isolate::kNoDeoptId,
776 0, // No token position.
777 CatchClauseNode::kInvalidTryIndex);
776 } else { 778 } else {
777 ASSERT(!IsLeaf()); 779 ASSERT(!IsLeaf());
778 // Invoke noSuchMethod function. 780 // Invoke noSuchMethod function.
779 const int kNumArgsChecked = 1; 781 const int kNumArgsChecked = 1;
780 ICData& ic_data = ICData::ZoneHandle(); 782 ICData& ic_data = ICData::ZoneHandle();
781 ic_data = ICData::New(function, 783 ic_data = ICData::New(function,
782 String::Handle(function.name()), 784 String::Handle(function.name()),
783 Isolate::kNoDeoptId, 785 Isolate::kNoDeoptId,
784 kNumArgsChecked); 786 kNumArgsChecked);
785 __ LoadObject(ECX, ic_data); 787 __ LoadObject(ECX, ic_data);
786 // EBP - 4 : PC marker, allows easy identification of RawInstruction obj. 788 // EBP - 4 : PC marker, allows easy identification of RawInstruction obj.
787 // EBP : points to previous frame pointer. 789 // EBP : points to previous frame pointer.
788 // EBP + 4 : points to return address. 790 // EBP + 4 : points to return address.
789 // EBP + 8 : address of last argument (arg n-1). 791 // EBP + 8 : address of last argument (arg n-1).
790 // ESP + 8 + 4*(n-1) : address of first argument (arg 0). 792 // ESP + 8 + 4*(n-1) : address of first argument (arg 0).
791 // ECX : ic-data. 793 // ECX : ic-data.
792 // EDX : arguments descriptor array. 794 // EDX : arguments descriptor array.
793 __ call(&StubCode::CallNoSuchMethodFunctionLabel()); 795 __ call(&StubCode::CallNoSuchMethodFunctionLabel());
796 }
797 if (is_optimizing()) {
798 stackmap_table_builder_->AddEntry(assembler()->CodeSize(),
799 empty_stack_bitmap);
800 }
801
802
803 if (FLAG_trace_functions) {
804 __ pushl(EAX); // Preserve result.
805 __ PushObject(Function::ZoneHandle(function.raw()));
806 // We do not use GenerateCallRuntime because of the non-standard (empty)
807 // stackmap used here.
808 __ CallRuntime(kTraceFunctionExitRuntimeEntry);
809 AddCurrentDescriptor(PcDescriptors::kOther,
810 Isolate::kNoDeoptId,
811 0, // No token position.
812 CatchClauseNode::kInvalidTryIndex);
794 if (is_optimizing()) { 813 if (is_optimizing()) {
795 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), 814 stackmap_table_builder_->AddEntry(assembler()->CodeSize(),
796 empty_stack_bitmap); 815 empty_stack_bitmap);
797 } 816 }
798 }
799
800 if (FLAG_trace_functions) {
801 __ pushl(EAX); // Preserve result.
802 __ PushObject(Function::ZoneHandle(function.raw()));
803 GenerateCallRuntime(Isolate::kNoDeoptId,
804 0,
805 CatchClauseNode::kInvalidTryIndex,
806 kTraceFunctionExitRuntimeEntry,
807 empty_stack_bitmap);
808 __ popl(EAX); // Remove argument. 817 __ popl(EAX); // Remove argument.
809 __ popl(EAX); // Restore result. 818 __ popl(EAX); // Restore result.
810 } 819 }
811 __ LeaveFrame(); 820 __ LeaveFrame();
812 __ ret(); 821 __ ret();
813 822
814 __ Bind(&all_arguments_processed); 823 __ Bind(&all_arguments_processed);
815 // Nullify originally passed arguments only after they have been copied and 824 // Nullify originally passed arguments only after they have been copied and
816 // checked, otherwise noSuchMethod would not see their original values. 825 // checked, otherwise noSuchMethod would not see their original values.
817 // This step can be skipped in case we decide that formal parameters are 826 // This step can be skipped in case we decide that formal parameters are
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 const int local_count = parsed_function().stack_local_count(); 910 const int local_count = parsed_function().stack_local_count();
902 __ Comment("Enter frame"); 911 __ Comment("Enter frame");
903 if (IsLeaf()) { 912 if (IsLeaf()) {
904 AssemblerMacros::EnterDartLeafFrame(assembler(), (StackSize() * kWordSize)); 913 AssemblerMacros::EnterDartLeafFrame(assembler(), (StackSize() * kWordSize));
905 } else { 914 } else {
906 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize)); 915 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize));
907 } 916 }
908 917
909 // For optimized code, keep a bitmap of the frame in order to build 918 // For optimized code, keep a bitmap of the frame in order to build
910 // stackmaps for GC safepoints in the prologue. 919 // stackmaps for GC safepoints in the prologue.
911 BitmapBuilder* stack_bitmap = NULL; 920 LocationSummary* prologue_locs = NULL;
912 if (is_optimizing()) { 921 if (is_optimizing()) {
913 // Spill slots are allocated but not initialized. 922 // Spill slots are allocated but not initialized.
914 stack_bitmap = new BitmapBuilder(); 923 prologue_locs = new LocationSummary(0, 0, LocationSummary::kCall);
915 stack_bitmap->SetLength(StackSize()); 924 prologue_locs->stack_bitmap()->SetLength(StackSize());
916 } 925 }
917 926
918 // We check the number of passed arguments when we have to copy them due to 927 // We check the number of passed arguments when we have to copy them due to
919 // the presence of optional named parameters. 928 // the presence of optional named parameters.
920 // No such checking code is generated if only fixed parameters are declared, 929 // No such checking code is generated if only fixed parameters are declared,
921 // unless we are debug mode or unless we are compiling a closure. 930 // unless we are debug mode or unless we are compiling a closure.
922 if (copied_parameter_count == 0) { 931 if (copied_parameter_count == 0) {
923 #ifdef DEBUG 932 #ifdef DEBUG
924 const bool check_arguments = true; 933 const bool check_arguments = true;
925 #else 934 #else
926 const bool check_arguments = function.IsClosureFunction(); 935 const bool check_arguments = function.IsClosureFunction();
927 #endif 936 #endif
928 if (check_arguments) { 937 if (check_arguments) {
929 __ Comment("Check argument count"); 938 __ Comment("Check argument count");
930 // Check that num_fixed <= argc <= num_params. 939 // Check that num_fixed <= argc <= num_params.
931 Label argc_in_range; 940 Label argc_in_range;
932 // Total number of args is the first Smi in args descriptor array (EDX). 941 // Total number of args is the first Smi in args descriptor array (EDX).
933 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 942 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
934 __ cmpl(EAX, Immediate(Smi::RawValue(parameter_count))); 943 __ cmpl(EAX, Immediate(Smi::RawValue(parameter_count)));
935 __ j(EQUAL, &argc_in_range, Assembler::kNearJump); 944 __ j(EQUAL, &argc_in_range, Assembler::kNearJump);
936 if (function.IsClosureFunction()) { 945 if (function.IsClosureFunction()) {
937 GenerateCallRuntime(Isolate::kNoDeoptId, 946 GenerateCallRuntime(Isolate::kNoDeoptId,
938 function.token_pos(), 947 function.token_pos(),
939 CatchClauseNode::kInvalidTryIndex, 948 CatchClauseNode::kInvalidTryIndex,
940 kClosureArgumentMismatchRuntimeEntry, 949 kClosureArgumentMismatchRuntimeEntry,
941 stack_bitmap); 950 prologue_locs);
942 } else { 951 } else {
943 __ Stop("Wrong number of arguments"); 952 __ Stop("Wrong number of arguments");
944 } 953 }
945 __ Bind(&argc_in_range); 954 __ Bind(&argc_in_range);
946 } 955 }
947 } else { 956 } else {
948 CopyParameters(); 957 CopyParameters();
949 } 958 }
950 959
951 // In unoptimized code, initialize (non-argument) stack allocated slots to 960 // In unoptimized code, initialize (non-argument) stack allocated slots to
(...skipping 19 matching lines...) Expand all
971 } 980 }
972 AstPrinter::PrintFunctionScope(parsed_function()); 981 AstPrinter::PrintFunctionScope(parsed_function());
973 } 982 }
974 983
975 VisitBlocks(); 984 VisitBlocks();
976 985
977 __ int3(); 986 __ int3();
978 GenerateDeferredCode(); 987 GenerateDeferredCode();
979 // Emit function patching code. This will be swapped with the first 5 bytes 988 // Emit function patching code. This will be swapped with the first 5 bytes
980 // at entry point. 989 // at entry point.
981 pc_descriptors_list()->AddDescriptor(PcDescriptors::kPatchCode, 990 AddCurrentDescriptor(PcDescriptors::kPatchCode,
982 assembler()->CodeSize(), 991 Isolate::kNoDeoptId,
983 Isolate::kNoDeoptId, 992 0, // No token position.
984 0, 993 CatchClauseNode::kInvalidTryIndex);
985 -1);
986 __ jmp(&StubCode::FixCallersTargetLabel()); 994 __ jmp(&StubCode::FixCallersTargetLabel());
987 } 995 }
988 996
989 997
990 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, 998 void FlowGraphCompiler::GenerateCall(intptr_t token_pos,
991 intptr_t try_index, 999 intptr_t try_index,
992 const ExternalLabel* label, 1000 const ExternalLabel* label,
993 PcDescriptors::Kind kind, 1001 PcDescriptors::Kind kind,
994 BitmapBuilder* stack_bitmap) { 1002 LocationSummary* locs) {
995 ASSERT(!IsLeaf()); 1003 ASSERT(!IsLeaf());
996 __ call(label); 1004 __ call(label);
997 if (is_optimizing() && (stack_bitmap != NULL)) {
998 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), stack_bitmap);
999 }
1000 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos, try_index); 1005 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos, try_index);
1006 RecordSafepoint(locs);
1001 } 1007 }
1002 1008
1003 1009
1004 void FlowGraphCompiler::GenerateCallRuntime(intptr_t deopt_id, 1010 void FlowGraphCompiler::GenerateCallRuntime(intptr_t deopt_id,
1005 intptr_t token_pos, 1011 intptr_t token_pos,
1006 intptr_t try_index, 1012 intptr_t try_index,
1007 const RuntimeEntry& entry, 1013 const RuntimeEntry& entry,
1008 BitmapBuilder* stack_bitmap) { 1014 LocationSummary* locs) {
1009 ASSERT(!IsLeaf()); 1015 ASSERT(!IsLeaf());
1010 ASSERT(!is_optimizing() || (stack_bitmap != NULL));
1011 __ CallRuntime(entry); 1016 __ CallRuntime(entry);
1012 if (is_optimizing()) {
1013 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), stack_bitmap);
1014 }
1015 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos, try_index); 1017 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos, try_index);
1018 RecordSafepoint(locs);
1016 } 1019 }
1017 1020
1018 1021
1019 intptr_t FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, 1022 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label,
1020 const ICData& ic_data, 1023 const ICData& ic_data,
1021 const Array& arguments_descriptor, 1024 const Array& arguments_descriptor,
1022 intptr_t argument_count) { 1025 intptr_t argument_count,
1026 intptr_t deopt_id,
1027 intptr_t token_pos,
1028 intptr_t try_index,
1029 LocationSummary* locs) {
1023 ASSERT(!IsLeaf()); 1030 ASSERT(!IsLeaf());
1024 __ LoadObject(ECX, ic_data); 1031 __ LoadObject(ECX, ic_data);
1025 __ LoadObject(EDX, arguments_descriptor); 1032 __ LoadObject(EDX, arguments_descriptor);
1026 1033
1027 __ call(target_label); 1034 __ call(target_label);
1028 const intptr_t descr_offset = assembler()->CodeSize(); 1035 AddCurrentDescriptor(PcDescriptors::kIcCall, deopt_id, token_pos, try_index);
1036 RecordSafepoint(locs);
1037
1029 __ Drop(argument_count); 1038 __ Drop(argument_count);
1030 return descr_offset;
1031 } 1039 }
1032 1040
1033 1041
1034 intptr_t FlowGraphCompiler::EmitStaticCall(const Function& function, 1042 void FlowGraphCompiler::EmitStaticCall(const Function& function,
1035 const Array& arguments_descriptor, 1043 const Array& arguments_descriptor,
1036 intptr_t argument_count) { 1044 intptr_t argument_count,
1045 intptr_t deopt_id,
1046 intptr_t token_pos,
1047 intptr_t try_index,
1048 LocationSummary* locs) {
1037 ASSERT(!IsLeaf()); 1049 ASSERT(!IsLeaf());
1038 __ LoadObject(ECX, function); 1050 __ LoadObject(ECX, function);
1039 __ LoadObject(EDX, arguments_descriptor); 1051 __ LoadObject(EDX, arguments_descriptor);
1040 __ call(&StubCode::CallStaticFunctionLabel()); 1052 __ call(&StubCode::CallStaticFunctionLabel());
1041 const intptr_t descr_offset = assembler()->CodeSize(); 1053 AddCurrentDescriptor(PcDescriptors::kFuncCall, deopt_id, token_pos,
1054 try_index);
1055 RecordSafepoint(locs);
1042 __ Drop(argument_count); 1056 __ Drop(argument_count);
1043 return descr_offset;
1044 } 1057 }
1045 1058
1046 1059
1047 // Checks class id of instance against all 'class_ids'. Jump to 'deopt' label 1060 // Checks class id of instance against all 'class_ids'. Jump to 'deopt' label
1048 // if no match or instance is Smi. 1061 // if no match or instance is Smi.
1049 void FlowGraphCompiler::EmitClassChecksNoSmi(const ICData& ic_data, 1062 void FlowGraphCompiler::EmitClassChecksNoSmi(const ICData& ic_data,
1050 Register instance_reg, 1063 Register instance_reg,
1051 Register temp_reg, 1064 Register temp_reg,
1052 Label* deopt) { 1065 Label* deopt) {
1053 Label ok; 1066 Label ok;
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1221 __ popl(ECX); 1234 __ popl(ECX);
1222 __ popl(EAX); 1235 __ popl(EAX);
1223 } 1236 }
1224 1237
1225 1238
1226 #undef __ 1239 #undef __
1227 1240
1228 } // namespace dart 1241 } // namespace dart
1229 1242
1230 #endif // defined TARGET_ARCH_IA32 1243 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.h ('k') | runtime/vm/flow_graph_compiler_x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698