61 #define __ _masm-> |
73 #define __ _masm-> |
62 |
74 |
63 |
75 |
64 //---------------------------------------------------------------------------------------------------- |
76 //---------------------------------------------------------------------------------------------------- |
65 |
77 |
|
78 #ifndef _LP64 |
|
79 address TemplateInterpreterGenerator::generate_slow_signature_handler() { |
|
80 address entry = __ pc(); |
|
81 Argument argv(0, true); |
|
82 |
|
83 // We are in the jni transition frame. Save the last_java_frame corresponding to the |
|
84 // outer interpreter frame |
|
85 // |
|
86 __ set_last_Java_frame(FP, noreg); |
|
87 // make sure the interpreter frame we've pushed has a valid return pc |
|
88 __ mov(O7, I7); |
|
89 __ mov(Lmethod, G3_scratch); |
|
90 __ mov(Llocals, G4_scratch); |
|
91 __ save_frame(0); |
|
92 __ mov(G2_thread, L7_thread_cache); |
|
93 __ add(argv.address_in_frame(), O3); |
|
94 __ mov(G2_thread, O0); |
|
95 __ mov(G3_scratch, O1); |
|
96 __ call(CAST_FROM_FN_PTR(address, InterpreterRuntime::slow_signature_handler), relocInfo::runtime_call_type); |
|
97 __ delayed()->mov(G4_scratch, O2); |
|
98 __ mov(L7_thread_cache, G2_thread); |
|
99 __ reset_last_Java_frame(); |
|
100 |
|
101 // load the register arguments (the C code packed them as varargs) |
|
102 for (Argument ldarg = argv.successor(); ldarg.is_register(); ldarg = ldarg.successor()) { |
|
103 __ ld_ptr(ldarg.address_in_frame(), ldarg.as_register()); |
|
104 } |
|
105 __ ret(); |
|
106 __ delayed()-> |
|
107 restore(O0, 0, Lscratch); // caller's Lscratch gets the result handler |
|
108 return entry; |
|
109 } |
|
110 |
|
111 |
|
112 #else |
|
113 // LP64 passes floating point arguments in F1, F3, F5, etc. instead of |
|
114 // O0, O1, O2 etc.. |
|
115 // Doubles are passed in D0, D2, D4 |
|
116 // We store the signature of the first 16 arguments in the first argument |
|
117 // slot because it will be overwritten prior to calling the native |
|
118 // function, with the pointer to the JNIEnv. |
|
119 // If LP64 there can be up to 16 floating point arguments in registers |
|
120 // or 6 integer registers. |
|
121 address TemplateInterpreterGenerator::generate_slow_signature_handler() { |
|
122 |
|
123 enum { |
|
124 non_float = 0, |
|
125 float_sig = 1, |
|
126 double_sig = 2, |
|
127 sig_mask = 3 |
|
128 }; |
|
129 |
|
130 address entry = __ pc(); |
|
131 Argument argv(0, true); |
|
132 |
|
133 // We are in the jni transition frame. Save the last_java_frame corresponding to the |
|
134 // outer interpreter frame |
|
135 // |
|
136 __ set_last_Java_frame(FP, noreg); |
|
137 // make sure the interpreter frame we've pushed has a valid return pc |
|
138 __ mov(O7, I7); |
|
139 __ mov(Lmethod, G3_scratch); |
|
140 __ mov(Llocals, G4_scratch); |
|
141 __ save_frame(0); |
|
142 __ mov(G2_thread, L7_thread_cache); |
|
143 __ add(argv.address_in_frame(), O3); |
|
144 __ mov(G2_thread, O0); |
|
145 __ mov(G3_scratch, O1); |
|
146 __ call(CAST_FROM_FN_PTR(address, InterpreterRuntime::slow_signature_handler), relocInfo::runtime_call_type); |
|
147 __ delayed()->mov(G4_scratch, O2); |
|
148 __ mov(L7_thread_cache, G2_thread); |
|
149 __ reset_last_Java_frame(); |
|
150 |
|
151 |
|
152 // load the register arguments (the C code packed them as varargs) |
|
153 Address Sig = argv.address_in_frame(); // Argument 0 holds the signature |
|
154 __ ld_ptr( Sig, G3_scratch ); // Get register argument signature word into G3_scratch |
|
155 __ mov( G3_scratch, G4_scratch); |
|
156 __ srl( G4_scratch, 2, G4_scratch); // Skip Arg 0 |
|
157 Label done; |
|
158 for (Argument ldarg = argv.successor(); ldarg.is_float_register(); ldarg = ldarg.successor()) { |
|
159 Label NonFloatArg; |
|
160 Label LoadFloatArg; |
|
161 Label LoadDoubleArg; |
|
162 Label NextArg; |
|
163 Address a = ldarg.address_in_frame(); |
|
164 __ andcc(G4_scratch, sig_mask, G3_scratch); |
|
165 __ br(Assembler::zero, false, Assembler::pt, NonFloatArg); |
|
166 __ delayed()->nop(); |
|
167 |
|
168 __ cmp(G3_scratch, float_sig ); |
|
169 __ br(Assembler::equal, false, Assembler::pt, LoadFloatArg); |
|
170 __ delayed()->nop(); |
|
171 |
|
172 __ cmp(G3_scratch, double_sig ); |
|
173 __ br(Assembler::equal, false, Assembler::pt, LoadDoubleArg); |
|
174 __ delayed()->nop(); |
|
175 |
|
176 __ bind(NonFloatArg); |
|
177 // There are only 6 integer register arguments! |
|
178 if ( ldarg.is_register() ) |
|
179 __ ld_ptr(ldarg.address_in_frame(), ldarg.as_register()); |
|
180 else { |
|
181 // Optimization, see if there are any more args and get out prior to checking |
|
182 // all 16 float registers. My guess is that this is rare. |
|
183 // If is_register is false, then we are done the first six integer args. |
|
184 __ br_null_short(G4_scratch, Assembler::pt, done); |
|
185 } |
|
186 __ ba(NextArg); |
|
187 __ delayed()->srl( G4_scratch, 2, G4_scratch ); |
|
188 |
|
189 __ bind(LoadFloatArg); |
|
190 __ ldf( FloatRegisterImpl::S, a, ldarg.as_float_register(), 4); |
|
191 __ ba(NextArg); |
|
192 __ delayed()->srl( G4_scratch, 2, G4_scratch ); |
|
193 |
|
194 __ bind(LoadDoubleArg); |
|
195 __ ldf( FloatRegisterImpl::D, a, ldarg.as_double_register() ); |
|
196 __ ba(NextArg); |
|
197 __ delayed()->srl( G4_scratch, 2, G4_scratch ); |
|
198 |
|
199 __ bind(NextArg); |
|
200 |
|
201 } |
|
202 |
|
203 __ bind(done); |
|
204 __ ret(); |
|
205 __ delayed()-> |
|
206 restore(O0, 0, Lscratch); // caller's Lscratch gets the result handler |
|
207 return entry; |
|
208 } |
|
209 #endif |
|
210 |
|
211 void TemplateInterpreterGenerator::generate_counter_overflow(Label& Lcontinue) { |
|
212 |
|
213 // Generate code to initiate compilation on the counter overflow. |
|
214 |
|
215 // InterpreterRuntime::frequency_counter_overflow takes two arguments, |
|
216 // the first indicates if the counter overflow occurs at a backwards branch (NULL bcp) |
|
217 // and the second is only used when the first is true. We pass zero for both. |
|
218 // The call returns the address of the verified entry point for the method or NULL |
|
219 // if the compilation did not complete (either went background or bailed out). |
|
220 __ set((int)false, O2); |
|
221 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), O2, O2, true); |
|
222 // returns verified_entry_point or NULL |
|
223 // we ignore it in any case |
|
224 __ ba_short(Lcontinue); |
|
225 |
|
226 } |
|
227 |
|
228 |
|
229 // End of helpers |
|
230 |
|
231 // Various method entries |
|
232 |
|
233 // Abstract method entry |
|
234 // Attempt to execute abstract method. Throw exception |
|
235 // |
|
236 address TemplateInterpreterGenerator::generate_abstract_entry(void) { |
|
237 address entry = __ pc(); |
|
238 // abstract method entry |
|
239 // throw exception |
|
240 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError)); |
|
241 // the call_VM checks for exception, so we should never return here. |
|
242 __ should_not_reach_here(); |
|
243 return entry; |
|
244 |
|
245 } |
66 |
246 |
67 void TemplateInterpreterGenerator::save_native_result(void) { |
247 void TemplateInterpreterGenerator::save_native_result(void) { |
68 // result potentially in O0/O1: save it across calls |
248 // result potentially in O0/O1: save it across calls |
69 const Address& l_tmp = InterpreterMacroAssembler::l_tmp; |
249 const Address& l_tmp = InterpreterMacroAssembler::l_tmp; |
70 |
250 |
909 |
1089 |
910 // Not supported |
1090 // Not supported |
911 address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) { |
1091 address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) { |
912 return NULL; |
1092 return NULL; |
913 } |
1093 } |
|
1094 |
|
1095 // TODO: rather than touching all pages, check against stack_overflow_limit and bang yellow page to |
|
1096 // generate exception |
|
1097 void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) { |
|
1098 // Quick & dirty stack overflow checking: bang the stack & handle trap. |
|
1099 // Note that we do the banging after the frame is setup, since the exception |
|
1100 // handling code expects to find a valid interpreter frame on the stack. |
|
1101 // Doing the banging earlier fails if the caller frame is not an interpreter |
|
1102 // frame. |
|
1103 // (Also, the exception throwing code expects to unlock any synchronized |
|
1104 // method receiever, so do the banging after locking the receiver.) |
|
1105 |
|
1106 // Bang each page in the shadow zone. We can't assume it's been done for |
|
1107 // an interpreter frame with greater than a page of locals, so each page |
|
1108 // needs to be checked. Only true for non-native. |
|
1109 if (UseStackBanging) { |
|
1110 const int page_size = os::vm_page_size(); |
|
1111 const int n_shadow_pages = ((int)JavaThread::stack_shadow_zone_size()) / page_size; |
|
1112 const int start_page = native_call ? n_shadow_pages : 1; |
|
1113 for (int pages = start_page; pages <= n_shadow_pages; pages++) { |
|
1114 __ bang_stack_with_offset(pages*page_size); |
|
1115 } |
|
1116 } |
|
1117 } |
|
1118 |
914 // |
1119 // |
915 // Interpreter stub for calling a native method. (asm interpreter) |
1120 // Interpreter stub for calling a native method. (asm interpreter) |
916 // This sets up a somewhat different looking stack for calling the native method |
1121 // This sets up a somewhat different looking stack for calling the native method |
917 // than the typical interpreter frame setup. |
1122 // than the typical interpreter frame setup. |
918 // |
1123 // |