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

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

Issue 11360116: Pass closure object as first implicit argument to closure functions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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.cc ('k') | runtime/vm/flow_graph_inliner.cc » ('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_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 609 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 Definition* defn = instr->AsDefinition(); 620 Definition* defn = instr->AsDefinition();
621 if ((defn != NULL) && defn->is_used()) { 621 if ((defn != NULL) && defn->is_used()) {
622 __ pushq(defn->locs()->out().reg()); 622 __ pushq(defn->locs()->out().reg());
623 } 623 }
624 } 624 }
625 625
626 626
627 void FlowGraphCompiler::CopyParameters() { 627 void FlowGraphCompiler::CopyParameters() {
628 __ Comment("Copy parameters"); 628 __ Comment("Copy parameters");
629 const Function& function = parsed_function().function(); 629 const Function& function = parsed_function().function();
630 const bool is_native_instance_closure =
631 function.is_native() && function.IsImplicitInstanceClosureFunction();
632 LocalScope* scope = parsed_function().node_sequence()->scope(); 630 LocalScope* scope = parsed_function().node_sequence()->scope();
633 const int num_fixed_params = function.num_fixed_parameters(); 631 const int num_fixed_params = function.num_fixed_parameters();
634 const int num_opt_pos_params = function.NumOptionalPositionalParameters(); 632 const int num_opt_pos_params = function.NumOptionalPositionalParameters();
635 int num_opt_named_params = function.NumOptionalNamedParameters(); 633 const int num_opt_named_params = function.NumOptionalNamedParameters();
636 const int num_params = 634 const int num_params =
637 num_fixed_params + num_opt_pos_params + num_opt_named_params; 635 num_fixed_params + num_opt_pos_params + num_opt_named_params;
638 int implicit_this_param_pos = is_native_instance_closure ? -1 : 0; 636 ASSERT(function.NumParameters() == num_params);
639 ASSERT(parsed_function().first_parameter_index() == 637 ASSERT(parsed_function().first_parameter_index() ==
640 ParsedFunction::kFirstLocalSlotIndex + implicit_this_param_pos); 638 ParsedFunction::kFirstLocalSlotIndex);
641 639
642 // Check that min_num_pos_args <= num_pos_args <= max_num_pos_args, 640 // Check that min_num_pos_args <= num_pos_args <= max_num_pos_args,
643 // where num_pos_args is the number of positional arguments passed in. 641 // where num_pos_args is the number of positional arguments passed in.
644 const int min_num_pos_args = num_fixed_params; 642 const int min_num_pos_args = num_fixed_params;
645 const int max_num_pos_args = num_fixed_params + num_opt_pos_params; 643 const int max_num_pos_args = num_fixed_params + num_opt_pos_params;
646 644
647 // Number of positional args is the second Smi in descriptor array (R10). 645 // Number of positional args is the second Smi in descriptor array (R10).
648 __ movq(RCX, FieldAddress(R10, Array::data_offset() + (1 * kWordSize))); 646 __ movq(RCX, FieldAddress(R10, Array::data_offset() + (1 * kWordSize)));
649 // Check that min_num_pos_args <= num_pos_args. 647 // Check that min_num_pos_args <= num_pos_args.
650 Label wrong_num_arguments; 648 Label wrong_num_arguments;
(...skipping 10 matching lines...) Expand all
661 // Total number of args is the first Smi in args descriptor array (R10). 659 // Total number of args is the first Smi in args descriptor array (R10).
662 __ movq(RBX, FieldAddress(R10, Array::data_offset())); 660 __ movq(RBX, FieldAddress(R10, Array::data_offset()));
663 // Since RBX and RCX are Smi, use TIMES_4 instead of TIMES_8. 661 // Since RBX and RCX are Smi, use TIMES_4 instead of TIMES_8.
664 // Let RBX point to the last passed positional argument, i.e. to 662 // Let RBX point to the last passed positional argument, i.e. to
665 // fp[1 + num_args - (num_pos_args - 1)]. 663 // fp[1 + num_args - (num_pos_args - 1)].
666 __ subq(RBX, RCX); 664 __ subq(RBX, RCX);
667 __ leaq(RBX, Address(RBP, RBX, TIMES_4, 2 * kWordSize)); 665 __ leaq(RBX, Address(RBP, RBX, TIMES_4, 2 * kWordSize));
668 666
669 // Let RDI point to the last copied positional argument, i.e. to 667 // Let RDI point to the last copied positional argument, i.e. to
670 // fp[ParsedFunction::kFirstLocalSlotIndex - (num_pos_args - 1)]. 668 // fp[ParsedFunction::kFirstLocalSlotIndex - (num_pos_args - 1)].
671 const int index = 669 const int index = ParsedFunction::kFirstLocalSlotIndex + 1;
672 ParsedFunction::kFirstLocalSlotIndex + 1 + implicit_this_param_pos;
673 // First copy captured receiver if function is an implicit native closure.
674 if (is_native_instance_closure) {
675 __ movq(RAX, FieldAddress(CTX, Context::variable_offset(0)));
676 __ movq(Address(RBP, (index * kWordSize)), RAX);
677 }
678 __ SmiUntag(RCX); 670 __ SmiUntag(RCX);
679 __ movq(RAX, RCX); 671 __ movq(RAX, RCX);
680 __ negq(RAX); 672 __ negq(RAX);
681 // -num_pos_args is in RAX. 673 // -num_pos_args is in RAX.
682 // (ParsedFunction::kFirstLocalSlotIndex + 1 + implicit_this_param_pos) 674 // (ParsedFunction::kFirstLocalSlotIndex + 1) is in index.
683 // is in index.
684 __ leaq(RDI, Address(RBP, RAX, TIMES_8, (index * kWordSize))); 675 __ leaq(RDI, Address(RBP, RAX, TIMES_8, (index * kWordSize)));
685 Label loop, loop_condition; 676 Label loop, loop_condition;
686 __ jmp(&loop_condition, Assembler::kNearJump); 677 __ jmp(&loop_condition, Assembler::kNearJump);
687 // We do not use the final allocation index of the variable here, i.e. 678 // We do not use the final allocation index of the variable here, i.e.
688 // scope->VariableAt(i)->index(), because captured variables still need 679 // scope->VariableAt(i)->index(), because captured variables still need
689 // to be copied to the context that is not yet allocated. 680 // to be copied to the context that is not yet allocated.
690 const Address argument_addr(RBX, RCX, TIMES_8, 0); 681 const Address argument_addr(RBX, RCX, TIMES_8, 0);
691 const Address copy_addr(RDI, RCX, TIMES_8, 0); 682 const Address copy_addr(RDI, RCX, TIMES_8, 0);
692 __ Bind(&loop); 683 __ Bind(&loop);
693 __ movq(RAX, argument_addr); 684 __ movq(RAX, argument_addr);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 // Load RAX with default argument. 740 // Load RAX with default argument.
750 const Object& value = Object::ZoneHandle( 741 const Object& value = Object::ZoneHandle(
751 parsed_function().default_parameter_values().At( 742 parsed_function().default_parameter_values().At(
752 param_pos - num_fixed_params)); 743 param_pos - num_fixed_params));
753 __ LoadObject(RAX, value); 744 __ LoadObject(RAX, value);
754 __ Bind(&assign_optional_parameter); 745 __ Bind(&assign_optional_parameter);
755 // Assign RAX to fp[ParsedFunction::kFirstLocalSlotIndex - param_pos]. 746 // Assign RAX to fp[ParsedFunction::kFirstLocalSlotIndex - param_pos].
756 // We do not use the final allocation index of the variable here, i.e. 747 // We do not use the final allocation index of the variable here, i.e.
757 // scope->VariableAt(i)->index(), because captured variables still need 748 // scope->VariableAt(i)->index(), because captured variables still need
758 // to be copied to the context that is not yet allocated. 749 // to be copied to the context that is not yet allocated.
759 intptr_t computed_param_pos = (ParsedFunction::kFirstLocalSlotIndex - 750 const intptr_t computed_param_pos =
760 param_pos + implicit_this_param_pos); 751 ParsedFunction::kFirstLocalSlotIndex - param_pos;
761 const Address param_addr(RBP, (computed_param_pos * kWordSize)); 752 const Address param_addr(RBP, (computed_param_pos * kWordSize));
762 __ movq(param_addr, RAX); 753 __ movq(param_addr, RAX);
763 __ Bind(&next_parameter); 754 __ Bind(&next_parameter);
764 } 755 }
765 delete[] opt_param; 756 delete[] opt_param;
766 delete[] opt_param_position; 757 delete[] opt_param_position;
767 // Check that RDI now points to the null terminator in the array descriptor. 758 // Check that RDI now points to the null terminator in the array descriptor.
768 __ cmpq(Address(RDI, 0), raw_null); 759 __ cmpq(Address(RDI, 0), raw_null);
769 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); 760 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump);
770 } else if (num_opt_pos_params > 0) { 761 } else {
762 ASSERT(num_opt_pos_params > 0);
771 // Number of positional args is the second Smi in descriptor array (R10). 763 // Number of positional args is the second Smi in descriptor array (R10).
772 __ movq(RCX, FieldAddress(R10, Array::data_offset() + (1 * kWordSize))); 764 __ movq(RCX, FieldAddress(R10, Array::data_offset() + (1 * kWordSize)));
773 __ SmiUntag(RCX); 765 __ SmiUntag(RCX);
774 for (int i = 0; i < num_opt_pos_params; i++) { 766 for (int i = 0; i < num_opt_pos_params; i++) {
775 Label next_parameter; 767 Label next_parameter;
776 // Handle this optional positonal parameter only if k or fewer positional 768 // Handle this optional positonal parameter only if k or fewer positional
777 // arguments have been passed, where k is param_pos, the position of this 769 // arguments have been passed, where k is param_pos, the position of this
778 // optional parameter in the formal parameter list. 770 // optional parameter in the formal parameter list.
779 const int param_pos = num_fixed_params + i; 771 const int param_pos = num_fixed_params + i;
780 __ cmpq(RCX, Immediate(param_pos)); 772 __ cmpq(RCX, Immediate(param_pos));
781 __ j(GREATER, &next_parameter, Assembler::kNearJump); 773 __ j(GREATER, &next_parameter, Assembler::kNearJump);
782 // Load RAX with default argument. 774 // Load RAX with default argument.
783 const Object& value = Object::ZoneHandle( 775 const Object& value = Object::ZoneHandle(
784 parsed_function().default_parameter_values().At(i)); 776 parsed_function().default_parameter_values().At(i));
785 __ LoadObject(RAX, value); 777 __ LoadObject(RAX, value);
786 // Assign RAX to fp[ParsedFunction::kFirstLocalSlotIndex - param_pos]. 778 // Assign RAX to fp[ParsedFunction::kFirstLocalSlotIndex - param_pos].
787 // We do not use the final allocation index of the variable here, i.e. 779 // We do not use the final allocation index of the variable here, i.e.
788 // scope->VariableAt(i)->index(), because captured variables still need 780 // scope->VariableAt(i)->index(), because captured variables still need
789 // to be copied to the context that is not yet allocated. 781 // to be copied to the context that is not yet allocated.
790 intptr_t computed_param_pos = (ParsedFunction::kFirstLocalSlotIndex - 782 const intptr_t computed_param_pos =
791 param_pos + implicit_this_param_pos); 783 ParsedFunction::kFirstLocalSlotIndex - param_pos;
792 const Address param_addr(RBP, (computed_param_pos * kWordSize)); 784 const Address param_addr(RBP, (computed_param_pos * kWordSize));
793 __ movq(param_addr, RAX); 785 __ movq(param_addr, RAX);
794 __ Bind(&next_parameter); 786 __ Bind(&next_parameter);
795 } 787 }
796 // Total number of args is the first Smi in args descriptor array (R10). 788 // Total number of args is the first Smi in args descriptor array (R10).
797 __ movq(RBX, FieldAddress(R10, Array::data_offset())); 789 __ movq(RBX, FieldAddress(R10, Array::data_offset()));
798 __ SmiUntag(RBX); 790 __ SmiUntag(RBX);
799 // Check that RCX equals RBX, i.e. no named arguments passed. 791 // Check that RCX equals RBX, i.e. no named arguments passed.
800 __ cmpq(RCX, RBX); 792 __ cmpq(RCX, RBX);
801 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); 793 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump);
802 } else {
803 ASSERT(is_native_instance_closure);
804 __ jmp(&all_arguments_processed, Assembler::kNearJump);
805 } 794 }
806 795
807 __ Bind(&wrong_num_arguments); 796 __ Bind(&wrong_num_arguments);
808 if (StackSize() != 0) { 797 if (StackSize() != 0) {
809 // We need to unwind the space we reserved for locals and copied parameters. 798 // We need to unwind the space we reserved for locals and copied parameters.
810 // The NoSuchMethodFunction stub does not expect to see that area on the 799 // The NoSuchMethodFunction stub does not expect to see that area on the
811 // stack. 800 // stack.
812 __ addq(RSP, Immediate(StackSize() * kWordSize)); 801 __ addq(RSP, Immediate(StackSize() * kWordSize));
813 } 802 }
814 // The calls immediately below have empty stackmaps because we have just 803 // The calls immediately below have empty stackmaps because we have just
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
1366 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { 1355 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) {
1367 __ Exchange(mem1, mem2); 1356 __ Exchange(mem1, mem2);
1368 } 1357 }
1369 1358
1370 1359
1371 #undef __ 1360 #undef __
1372 1361
1373 } // namespace dart 1362 } // namespace dart
1374 1363
1375 #endif // defined TARGET_ARCH_X64 1364 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.cc ('k') | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698