Mercurial > hg > truffle
comparison src/cpu/sparc/vm/templateInterpreter_sparc.cpp @ 13010:bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
Reviewed-by: jrose, roland
author | twisti |
---|---|
date | Thu, 24 Oct 2013 16:23:07 -0700 |
parents | ca0165daa6ec |
children | 096c224171c4 8cdf3f43f63e |
comparison
equal
deleted
inserted
replaced
12968:97d400662426 | 13010:bd3237e0e18d |
---|---|
151 __ should_not_reach_here(); | 151 __ should_not_reach_here(); |
152 return entry; | 152 return entry; |
153 } | 153 } |
154 | 154 |
155 | 155 |
156 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) { | 156 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) { |
157 TosState incoming_state = state; | |
158 | |
159 Label cont; | |
160 address compiled_entry = __ pc(); | |
161 | |
162 address entry = __ pc(); | 157 address entry = __ pc(); |
158 | |
163 #if !defined(_LP64) && defined(COMPILER2) | 159 #if !defined(_LP64) && defined(COMPILER2) |
164 // All return values are where we want them, except for Longs. C2 returns | 160 // All return values are where we want them, except for Longs. C2 returns |
165 // longs in G1 in the 32-bit build whereas the interpreter wants them in O0/O1. | 161 // longs in G1 in the 32-bit build whereas the interpreter wants them in O0/O1. |
166 // Since the interpreter will return longs in G1 and O0/O1 in the 32bit | 162 // Since the interpreter will return longs in G1 and O0/O1 in the 32bit |
167 // build even if we are returning from interpreted we just do a little | 163 // build even if we are returning from interpreted we just do a little |
168 // stupid shuffing. | 164 // stupid shuffing. |
169 // Note: I tried to make c2 return longs in O0/O1 and G1 so we wouldn't have to | 165 // Note: I tried to make c2 return longs in O0/O1 and G1 so we wouldn't have to |
170 // do this here. Unfortunately if we did a rethrow we'd see an machepilog node | 166 // do this here. Unfortunately if we did a rethrow we'd see an machepilog node |
171 // first which would move g1 -> O0/O1 and destroy the exception we were throwing. | 167 // first which would move g1 -> O0/O1 and destroy the exception we were throwing. |
172 | 168 |
173 if (incoming_state == ltos) { | 169 if (state == ltos) { |
174 __ srl (G1, 0, O1); | 170 __ srl (G1, 0, O1); |
175 __ srlx(G1, 32, O0); | 171 __ srlx(G1, 32, O0); |
176 } | 172 } |
177 #endif // !_LP64 && COMPILER2 | 173 #endif // !_LP64 && COMPILER2 |
178 | |
179 __ bind(cont); | |
180 | 174 |
181 // The callee returns with the stack possibly adjusted by adapter transition | 175 // The callee returns with the stack possibly adjusted by adapter transition |
182 // We remove that possible adjustment here. | 176 // We remove that possible adjustment here. |
183 // All interpreter local registers are untouched. Any result is passed back | 177 // All interpreter local registers are untouched. Any result is passed back |
184 // in the O0/O1 or float registers. Before continuing, the arguments must be | 178 // in the O0/O1 or float registers. Before continuing, the arguments must be |
185 // popped from the java expression stack; i.e., Lesp must be adjusted. | 179 // popped from the java expression stack; i.e., Lesp must be adjusted. |
186 | 180 |
187 __ mov(Llast_SP, SP); // Remove any adapter added stack space. | 181 __ mov(Llast_SP, SP); // Remove any adapter added stack space. |
188 | 182 |
189 Label L_got_cache, L_giant_index; | |
190 const Register cache = G3_scratch; | 183 const Register cache = G3_scratch; |
191 const Register size = G1_scratch; | 184 const Register index = G1_scratch; |
192 if (EnableInvokeDynamic) { | 185 __ get_cache_and_index_at_bcp(cache, index, 1, index_size); |
193 __ ldub(Address(Lbcp, 0), G1_scratch); // Load current bytecode. | 186 |
194 __ cmp_and_br_short(G1_scratch, Bytecodes::_invokedynamic, Assembler::equal, Assembler::pn, L_giant_index); | 187 const Register flags = cache; |
195 } | 188 __ ld_ptr(cache, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset(), flags); |
196 __ get_cache_and_index_at_bcp(cache, G1_scratch, 1); | 189 const Register parameter_size = flags; |
197 __ bind(L_got_cache); | 190 __ and3(flags, ConstantPoolCacheEntry::parameter_size_mask, parameter_size); // argument size in words |
198 __ ld_ptr(cache, ConstantPoolCache::base_offset() + | 191 __ sll(parameter_size, Interpreter::logStackElementSize, parameter_size); // each argument size in bytes |
199 ConstantPoolCacheEntry::flags_offset(), size); | 192 __ add(Lesp, parameter_size, Lesp); // pop arguments |
200 __ and3(size, 0xFF, size); // argument size in words | |
201 __ sll(size, Interpreter::logStackElementSize, size); // each argument size in bytes | |
202 __ add(Lesp, size, Lesp); // pop arguments | |
203 __ dispatch_next(state, step); | 193 __ dispatch_next(state, step); |
204 | |
205 // out of the main line of code... | |
206 if (EnableInvokeDynamic) { | |
207 __ bind(L_giant_index); | |
208 __ get_cache_and_index_at_bcp(cache, G1_scratch, 1, sizeof(u4)); | |
209 __ ba_short(L_got_cache); | |
210 } | |
211 | 194 |
212 return entry; | 195 return entry; |
213 } | 196 } |
214 | 197 |
215 | 198 |