40 } |
40 } |
41 |
41 |
42 void InterpreterRuntime::SignatureHandlerGenerator::pass_long() { |
42 void InterpreterRuntime::SignatureHandlerGenerator::pass_long() { |
43 Argument jni_arg(jni_offset(), false); |
43 Argument jni_arg(jni_offset(), false); |
44 Register Rtmp = O0; |
44 Register Rtmp = O0; |
45 |
|
46 #ifdef ASSERT |
|
47 if (TaggedStackInterpreter) { |
|
48 // check at least one tag is okay |
|
49 Label ok; |
|
50 __ ld_ptr(Llocals, Interpreter::local_tag_offset_in_bytes(offset() + 1), Rtmp); |
|
51 __ cmp(Rtmp, G0); |
|
52 __ brx(Assembler::equal, false, Assembler::pt, ok); |
|
53 __ delayed()->nop(); |
|
54 __ stop("Native object has bad tag value"); |
|
55 __ bind(ok); |
|
56 } |
|
57 #endif // ASSERT |
|
58 |
45 |
59 #ifdef _LP64 |
46 #ifdef _LP64 |
60 __ ldx(Llocals, Interpreter::local_offset_in_bytes(offset() + 1), Rtmp); |
47 __ ldx(Llocals, Interpreter::local_offset_in_bytes(offset() + 1), Rtmp); |
61 __ store_long_argument(Rtmp, jni_arg); |
48 __ store_long_argument(Rtmp, jni_arg); |
62 #else |
49 #else |
105 // the handle for a receiver will never be null |
92 // the handle for a receiver will never be null |
106 bool do_NULL_check = offset() != 0 || is_static(); |
93 bool do_NULL_check = offset() != 0 || is_static(); |
107 |
94 |
108 Address h_arg = Address(Llocals, Interpreter::local_offset_in_bytes(offset())); |
95 Address h_arg = Address(Llocals, Interpreter::local_offset_in_bytes(offset())); |
109 __ ld_ptr(h_arg, Rtmp1); |
96 __ ld_ptr(h_arg, Rtmp1); |
110 #ifdef ASSERT |
|
111 if (TaggedStackInterpreter) { |
|
112 // check we have the obj and not the tag |
|
113 Label ok; |
|
114 __ mov(frame::TagReference, Rtmp3); |
|
115 __ cmp(Rtmp1, Rtmp3); |
|
116 __ brx(Assembler::notEqual, true, Assembler::pt, ok); |
|
117 __ delayed()->nop(); |
|
118 __ stop("Native object passed tag by mistake"); |
|
119 __ bind(ok); |
|
120 } |
|
121 #endif // ASSERT |
|
122 if (!do_NULL_check) { |
97 if (!do_NULL_check) { |
123 __ add(h_arg.base(), h_arg.disp(), Rtmp2); |
98 __ add(h_arg.base(), h_arg.disp(), Rtmp2); |
124 } else { |
99 } else { |
125 if (Rtmp1 == Rtmp2) |
100 if (Rtmp1 == Rtmp2) |
126 __ tst(Rtmp1); |
101 __ tst(Rtmp1); |
166 float_sig = 1, |
141 float_sig = 1, |
167 double_sig = 2, |
142 double_sig = 2, |
168 long_sig = 3 |
143 long_sig = 3 |
169 }; |
144 }; |
170 |
145 |
171 #ifdef ASSERT |
|
172 void verify_tag(frame::Tag t) { |
|
173 assert(!TaggedStackInterpreter || |
|
174 *(intptr_t*)(_from+Interpreter::local_tag_offset_in_bytes(0)) == t, "wrong tag"); |
|
175 } |
|
176 #endif // ASSERT |
|
177 |
|
178 virtual void pass_int() { |
146 virtual void pass_int() { |
179 *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); |
147 *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); |
180 debug_only(verify_tag(frame::TagValue)); |
148 _from -= Interpreter::stackElementSize; |
181 _from -= Interpreter::stackElementSize(); |
|
182 add_signature( non_float ); |
149 add_signature( non_float ); |
183 } |
150 } |
184 |
151 |
185 virtual void pass_object() { |
152 virtual void pass_object() { |
186 // pass address of from |
153 // pass address of from |
187 intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0)); |
154 intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0)); |
188 *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr; |
155 *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr; |
189 debug_only(verify_tag(frame::TagReference)); |
156 _from -= Interpreter::stackElementSize; |
190 _from -= Interpreter::stackElementSize(); |
|
191 add_signature( non_float ); |
157 add_signature( non_float ); |
192 } |
158 } |
193 |
159 |
194 #ifdef _LP64 |
160 #ifdef _LP64 |
195 virtual void pass_float() { |
161 virtual void pass_float() { |
196 *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); |
162 *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); |
197 debug_only(verify_tag(frame::TagValue)); |
163 _from -= Interpreter::stackElementSize; |
198 _from -= Interpreter::stackElementSize(); |
|
199 add_signature( float_sig ); |
164 add_signature( float_sig ); |
200 } |
165 } |
201 |
166 |
202 virtual void pass_double() { |
167 virtual void pass_double() { |
203 *_to++ = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); |
168 *_to++ = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); |
204 debug_only(verify_tag(frame::TagValue)); |
169 _from -= 2*Interpreter::stackElementSize; |
205 _from -= 2*Interpreter::stackElementSize(); |
|
206 add_signature( double_sig ); |
170 add_signature( double_sig ); |
207 } |
171 } |
208 |
172 |
209 virtual void pass_long() { |
173 virtual void pass_long() { |
210 _to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); |
174 _to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); |
211 debug_only(verify_tag(frame::TagValue)); |
|
212 _to += 1; |
175 _to += 1; |
213 _from -= 2*Interpreter::stackElementSize(); |
176 _from -= 2*Interpreter::stackElementSize; |
214 add_signature( long_sig ); |
177 add_signature( long_sig ); |
215 } |
178 } |
216 #else |
179 #else |
217 // pass_double() is pass_long() and pass_float() only _LP64 |
180 // pass_double() is pass_long() and pass_float() only _LP64 |
218 virtual void pass_long() { |
181 virtual void pass_long() { |
219 _to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); |
182 _to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); |
220 _to[1] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0)); |
183 _to[1] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0)); |
221 debug_only(verify_tag(frame::TagValue)); |
|
222 _to += 2; |
184 _to += 2; |
223 _from -= 2*Interpreter::stackElementSize(); |
185 _from -= 2*Interpreter::stackElementSize; |
224 add_signature( non_float ); |
186 add_signature( non_float ); |
225 } |
187 } |
226 #endif // _LP64 |
188 #endif // _LP64 |
227 |
189 |
228 virtual void add_signature( intptr_t sig_type ) { |
190 virtual void add_signature( intptr_t sig_type ) { |