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

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

Powered by Google App Engine
This is Rietveld 408576698