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

Side by Side Diff: runtime/vm/stub_code_ia32.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/parser.cc ('k') | runtime/vm/stub_code_x64.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" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/assembler_macros.h" 9 #include "vm/assembler_macros.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 18 matching lines...) Expand all
29 // Input parameters: 29 // Input parameters:
30 // ESP : points to return address. 30 // ESP : points to return address.
31 // ESP + 4 : address of last argument in argument array. 31 // ESP + 4 : address of last argument in argument array.
32 // ESP + 4*EDX : address of first argument in argument array. 32 // ESP + 4*EDX : address of first argument in argument array.
33 // ESP + 4*EDX + 4 : address of return value. 33 // ESP + 4*EDX + 4 : address of return value.
34 // ECX : address of the runtime function to call. 34 // ECX : address of the runtime function to call.
35 // EDX : number of arguments to the call. 35 // EDX : number of arguments to the call.
36 // Must preserve callee saved registers EDI and EBX. 36 // Must preserve callee saved registers EDI and EBX.
37 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { 37 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
38 const intptr_t isolate_offset = NativeArguments::isolate_offset(); 38 const intptr_t isolate_offset = NativeArguments::isolate_offset();
39 const intptr_t argc_offset = NativeArguments::argc_offset(); 39 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
40 const intptr_t argv_offset = NativeArguments::argv_offset(); 40 const intptr_t argv_offset = NativeArguments::argv_offset();
41 const intptr_t retval_offset = NativeArguments::retval_offset(); 41 const intptr_t retval_offset = NativeArguments::retval_offset();
42 42
43 __ EnterFrame(0); 43 __ EnterFrame(0);
44 44
45 // Load current Isolate pointer from Context structure into EAX. 45 // Load current Isolate pointer from Context structure into EAX.
46 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); 46 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset()));
47 47
48 // Save exit frame information to enable stack walking as we are about 48 // Save exit frame information to enable stack walking as we are about
49 // to transition to Dart VM C++ code. 49 // to transition to Dart VM C++ code.
50 __ movl(Address(EAX, Isolate::top_exit_frame_info_offset()), ESP); 50 __ movl(Address(EAX, Isolate::top_exit_frame_info_offset()), ESP);
51 51
52 // Save current Context pointer into Isolate structure. 52 // Save current Context pointer into Isolate structure.
53 __ movl(Address(EAX, Isolate::top_context_offset()), CTX); 53 __ movl(Address(EAX, Isolate::top_context_offset()), CTX);
54 54
55 // Cache Isolate pointer into CTX while executing runtime code. 55 // Cache Isolate pointer into CTX while executing runtime code.
56 __ movl(CTX, EAX); 56 __ movl(CTX, EAX);
57 57
58 // Reserve space for arguments and align frame before entering C++ world. 58 // Reserve space for arguments and align frame before entering C++ world.
59 __ AddImmediate(ESP, Immediate(-sizeof(NativeArguments))); 59 __ AddImmediate(ESP, Immediate(-sizeof(NativeArguments)));
60 if (OS::ActivationFrameAlignment() > 0) { 60 if (OS::ActivationFrameAlignment() > 0) {
61 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); 61 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
62 } 62 }
63 63
64 // Pass NativeArguments structure by value and call runtime. 64 // Pass NativeArguments structure by value and call runtime.
65 __ movl(Address(ESP, isolate_offset), CTX); // Set isolate in NativeArgs. 65 __ movl(Address(ESP, isolate_offset), CTX); // Set isolate in NativeArgs.
66 __ movl(Address(ESP, argc_offset), EDX); // Set argc in NativeArguments. 66 // There are no runtime calls to closures, so we do not need to set the tag
67 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
68 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments.
67 __ leal(EAX, Address(EBP, EDX, TIMES_4, 1 * kWordSize)); // Compute argv. 69 __ leal(EAX, Address(EBP, EDX, TIMES_4, 1 * kWordSize)); // Compute argv.
68 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. 70 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments.
69 __ addl(EAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument. 71 __ addl(EAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument.
70 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. 72 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments.
71 __ call(ECX); 73 __ call(ECX);
72 74
73 // Reset exit frame information in Isolate structure. 75 // Reset exit frame information in Isolate structure.
74 __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); 76 __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
75 77
76 // Load Context pointer from Isolate structure into ECX. 78 // Load Context pointer from Isolate structure into ECX.
(...skipping 29 matching lines...) Expand all
106 __ CallRuntime(kPrintStopMessageRuntimeEntry); 108 __ CallRuntime(kPrintStopMessageRuntimeEntry);
107 __ LeaveCallRuntimeFrame(); 109 __ LeaveCallRuntimeFrame();
108 __ ret(); 110 __ ret();
109 } 111 }
110 112
111 113
112 // Input parameters: 114 // Input parameters:
113 // ESP : points to return address. 115 // ESP : points to return address.
114 // ESP + 4 : address of return value. 116 // ESP + 4 : address of return value.
115 // EAX : address of first argument in argument array. 117 // EAX : address of first argument in argument array.
116 // EAX - 4*EDX + 4 : address of last argument in argument array.
117 // ECX : address of the native function to call. 118 // ECX : address of the native function to call.
118 // EDX : number of arguments to the call. 119 // EDX : argc_tag including number of arguments and function kind.
119 // Uses EDI. 120 // Uses EDI.
120 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { 121 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
121 const intptr_t native_args_struct_offset = kWordSize; 122 const intptr_t native_args_struct_offset = kWordSize;
122 const intptr_t isolate_offset = 123 const intptr_t isolate_offset =
123 NativeArguments::isolate_offset() + native_args_struct_offset; 124 NativeArguments::isolate_offset() + native_args_struct_offset;
124 const intptr_t argc_offset = 125 const intptr_t argc_tag_offset =
125 NativeArguments::argc_offset() + native_args_struct_offset; 126 NativeArguments::argc_tag_offset() + native_args_struct_offset;
126 const intptr_t argv_offset = 127 const intptr_t argv_offset =
127 NativeArguments::argv_offset() + native_args_struct_offset; 128 NativeArguments::argv_offset() + native_args_struct_offset;
128 const intptr_t retval_offset = 129 const intptr_t retval_offset =
129 NativeArguments::retval_offset() + native_args_struct_offset; 130 NativeArguments::retval_offset() + native_args_struct_offset;
130 131
131 __ EnterFrame(0); 132 __ EnterFrame(0);
132 133
133 // Load current Isolate pointer from Context structure into EDI. 134 // Load current Isolate pointer from Context structure into EDI.
134 __ movl(EDI, FieldAddress(CTX, Context::isolate_offset())); 135 __ movl(EDI, FieldAddress(CTX, Context::isolate_offset()));
135 136
(...skipping 10 matching lines...) Expand all
146 // Reserve space for the native arguments structure, the outgoing parameter 147 // Reserve space for the native arguments structure, the outgoing parameter
147 // (pointer to the native arguments structure) and align frame before 148 // (pointer to the native arguments structure) and align frame before
148 // entering the C++ world. 149 // entering the C++ world.
149 __ AddImmediate(ESP, Immediate(-sizeof(NativeArguments) - kWordSize)); 150 __ AddImmediate(ESP, Immediate(-sizeof(NativeArguments) - kWordSize));
150 if (OS::ActivationFrameAlignment() > 0) { 151 if (OS::ActivationFrameAlignment() > 0) {
151 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); 152 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
152 } 153 }
153 154
154 // Pass NativeArguments structure by value and call native function. 155 // Pass NativeArguments structure by value and call native function.
155 __ movl(Address(ESP, isolate_offset), CTX); // Set isolate in NativeArgs. 156 __ movl(Address(ESP, isolate_offset), CTX); // Set isolate in NativeArgs.
156 __ movl(Address(ESP, argc_offset), EDX); // Set argc in NativeArguments. 157 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments.
157 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. 158 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments.
158 __ leal(EAX, Address(EBP, 2 * kWordSize)); // Compute return value addr. 159 __ leal(EAX, Address(EBP, 2 * kWordSize)); // Compute return value addr.
159 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. 160 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments.
160 __ leal(EAX, Address(ESP, kWordSize)); // Pointer to the NativeArguments. 161 __ leal(EAX, Address(ESP, kWordSize)); // Pointer to the NativeArguments.
161 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments. 162 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments.
162 __ call(ECX); 163 __ call(ECX);
163 164
164 // Reset exit frame information in Isolate structure. 165 // Reset exit frame information in Isolate structure.
165 __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); 166 __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
166 167
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 __ popl(EAX); // Pop element type argument. 728 __ popl(EAX); // Pop element type argument.
728 __ popl(EDX); // Pop array length argument. 729 __ popl(EDX); // Pop array length argument.
729 __ popl(EAX); // Pop return value from return slot. 730 __ popl(EAX); // Pop return value from return slot.
730 __ LeaveFrame(); 731 __ LeaveFrame();
731 __ ret(); 732 __ ret();
732 } 733 }
733 734
734 735
735 // Input parameters: 736 // Input parameters:
736 // EDX: Arguments descriptor array (num_args is first Smi element, closure 737 // EDX: Arguments descriptor array (num_args is first Smi element, closure
737 // object is not included in num_args). 738 // object is included in num_args and is first argument).
738 // Note: The closure object is pushed before the first argument to the function 739 // Note: The closure object is the first argument to the function being
739 // being called, the stub accesses the closure from this location directly 740 // called, the stub accesses the closure from this location directly
740 // when setting up the context and resolving the entry point. 741 // when trying to resolve the call.
741 // Uses EDI. 742 // Uses EDI.
742 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) { 743 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) {
743 const Immediate raw_null = 744 const Immediate raw_null =
744 Immediate(reinterpret_cast<intptr_t>(Object::null())); 745 Immediate(reinterpret_cast<intptr_t>(Object::null()));
745 746
746 // Total number of args is the first Smi in args descriptor array (EDX). 747 // Total number of args is the first Smi in args descriptor array (EDX).
747 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); // Load num_args. 748 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); // Load num_args.
748 // Load closure object in EDI. 749 // Load closure object in EDI.
749 __ movl(EDI, Address(ESP, EAX, TIMES_2, kWordSize)); // EAX is a Smi. 750 __ movl(EDI, Address(ESP, EAX, TIMES_2, 0)); // EAX is a Smi.
750 751
751 // Verify that EDI is a closure by checking its class. 752 // Verify that EDI is a closure by checking its class.
752 Label not_closure; 753 Label not_closure;
753 __ cmpl(EDI, raw_null); 754 __ cmpl(EDI, raw_null);
754 // Not a closure, but null object. 755 // Not a closure, but null object.
755 __ j(EQUAL, &not_closure, Assembler::kNearJump); 756 __ j(EQUAL, &not_closure, Assembler::kNearJump);
756 __ testl(EDI, Immediate(kSmiTagMask)); 757 __ testl(EDI, Immediate(kSmiTagMask));
757 __ j(ZERO, &not_closure, Assembler::kNearJump); // Not a closure, but a smi. 758 __ j(ZERO, &not_closure, Assembler::kNearJump); // Not a closure, but a smi.
758 // Verify that the class of the object is a closure class by checking that 759 // Verify that the class of the object is a closure class by checking that
759 // class.signature_function() is not null. 760 // class.signature_function() is not null.
(...skipping 13 matching lines...) Expand all
773 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); 774 __ movl(EAX, FieldAddress(ECX, Function::code_offset()));
774 __ cmpl(EAX, raw_null); 775 __ cmpl(EAX, raw_null);
775 Label function_compiled; 776 Label function_compiled;
776 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); 777 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump);
777 778
778 // Create a stub frame as we are pushing some objects on the stack before 779 // Create a stub frame as we are pushing some objects on the stack before
779 // calling into the runtime. 780 // calling into the runtime.
780 AssemblerMacros::EnterStubFrame(assembler); 781 AssemblerMacros::EnterStubFrame(assembler);
781 782
782 __ pushl(EDX); // Preserve arguments descriptor array. 783 __ pushl(EDX); // Preserve arguments descriptor array.
783 __ pushl(ECX); 784 __ pushl(ECX); // Preserve read-only function object argument.
784 __ CallRuntime(kCompileFunctionRuntimeEntry); 785 __ CallRuntime(kCompileFunctionRuntimeEntry);
785 __ popl(ECX); // Restore read-only function object argument in ECX. 786 __ popl(ECX); // Restore read-only function object argument in ECX.
786 __ popl(EDX); // Restore arguments descriptor array. 787 __ popl(EDX); // Restore arguments descriptor array.
787 // Restore EAX. 788 // Restore EAX.
788 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); 789 __ movl(EAX, FieldAddress(ECX, Function::code_offset()));
789 790
790 // Remove the stub frame as we are about to jump to the closure function. 791 // Remove the stub frame as we are about to jump to the closure function.
791 __ LeaveFrame(); 792 __ LeaveFrame();
792 793
793 __ Bind(&function_compiled); 794 __ Bind(&function_compiled);
794 // EAX: Code. 795 // EAX: Code.
795 // ECX: Function. 796 // ECX: Function.
796 // EDX: Arguments descriptor array (num_args is first Smi element). 797 // EDX: Arguments descriptor array (num_args is first Smi element).
797 798
798 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); 799 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset()));
799 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 800 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
800 __ jmp(ECX); 801 __ jmp(ECX);
801 802
802 __ Bind(&not_closure); 803 __ Bind(&not_closure);
803 // Call runtime to report that a closure call was attempted on a non-closure 804 // Call runtime to report that a closure call was attempted on a non-closure
804 // object, passing the non-closure object and its arguments array. 805 // object, passing the non-closure object and its arguments array.
805 // EDI: non-closure object. 806 // EDI: non-closure object.
806 // EDX: arguments descriptor array (num_args is first Smi element, closure 807 // EDX: arguments descriptor array (num_args is first Smi element, closure
807 // object is not included in num_args). 808 // object is included in num_args).
808 809
809 // Create a stub frame as we are pushing some objects on the stack before 810 // Create a stub frame as we are pushing some objects on the stack before
810 // calling into the runtime. 811 // calling into the runtime.
811 AssemblerMacros::EnterStubFrame(assembler); 812 AssemblerMacros::EnterStubFrame(assembler);
812 813
813 __ pushl(raw_null); // Setup space on stack for result from error reporting. 814 __ pushl(raw_null); // Setup space on stack for result from error reporting.
814 __ pushl(EDI); // Non-closure object. 815 __ pushl(EDI); // Non-closure object.
815 // Total number of args is the first Smi in args descriptor array (EDX). 816 // Total number of args is the first Smi in args descriptor array (EDX).
816 __ movl(EDI, FieldAddress(EDX, Array::data_offset())); // Load num_args. 817 __ movl(EDI, FieldAddress(EDX, Array::data_offset())); // Load num_args.
817 __ SmiUntag(EDI); 818 __ SmiUntag(EDI);
819 __ subl(EDI, Immediate(1)); // Arguments array length, minus the closure.
818 // See stack layout below explaining "wordSize * 5" offset. 820 // See stack layout below explaining "wordSize * 5" offset.
819 PushArgumentsArray(assembler, (kWordSize * 5)); 821 PushArgumentsArray(assembler, (kWordSize * 5));
820 822
821 // Stack: 823 // Stack:
822 // TOS + 0: Argument array. 824 // TOS + 0: Argument array.
823 // TOS + 1: Non-closure object. 825 // TOS + 1: Non-closure object.
824 // TOS + 2: Place for result from reporting the error. 826 // TOS + 2: Place for result from reporting the error.
825 // TOS + 3: PC marker => RawInstruction object. 827 // TOS + 3: PC marker => RawInstruction object.
826 // TOS + 4: Saved EBP of previous frame. <== EBP 828 // TOS + 4: Saved EBP of previous frame. <== EBP
827 // TOS + 5: Dart code return address 829 // TOS + 5: Dart code return address
(...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after
2064 __ Drop(4); 2066 __ Drop(4);
2065 __ LeaveFrame(); 2067 __ LeaveFrame();
2066 2068
2067 __ jmp(&compute_result, Assembler::kNearJump); 2069 __ jmp(&compute_result, Assembler::kNearJump);
2068 } 2070 }
2069 2071
2070 2072
2071 } // namespace dart 2073 } // namespace dart
2072 2074
2073 #endif // defined TARGET_ARCH_IA32 2075 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/parser.cc ('k') | runtime/vm/stub_code_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698