Mercurial > hg > graal-jvmci-8
comparison src/share/vm/prims/methodHandleWalk.hpp @ 3461:81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
Reviewed-by: never
author | jrose |
---|---|
date | Thu, 23 Jun 2011 17:14:06 -0700 |
parents | f7d55ea6ee56 |
children | c26de9aef2ed |
comparison
equal
deleted
inserted
replaced
3460:e9b51b4bdcc7 | 3461:81d815b05abb |
---|---|
96 | 96 |
97 BasicType bound_arg_type() { assert(is_bound(), ""); return _arg_type; } | 97 BasicType bound_arg_type() { assert(is_bound(), ""); return _arg_type; } |
98 int bound_arg_slot() { assert(is_bound(), ""); return _arg_slot; } | 98 int bound_arg_slot() { assert(is_bound(), ""); return _arg_slot; } |
99 oop bound_arg_oop() { assert(is_bound(), ""); return BoundMethodHandle_argument_oop(); } | 99 oop bound_arg_oop() { assert(is_bound(), ""); return BoundMethodHandle_argument_oop(); } |
100 | 100 |
101 methodHandle last_method() { assert(is_last(), ""); return _last_method; } | |
101 methodOop last_method_oop() { assert(is_last(), ""); return _last_method(); } | 102 methodOop last_method_oop() { assert(is_last(), ""); return _last_method(); } |
102 Bytecodes::Code last_invoke_code() { assert(is_last(), ""); return _last_invoke; } | 103 Bytecodes::Code last_invoke_code() { assert(is_last(), ""); return _last_invoke; } |
103 | 104 |
104 void lose(const char* msg, TRAPS); | 105 void lose(const char* msg, TRAPS); |
105 const char* lose_message() { return _lose_message; } | 106 const char* lose_message() { return _lose_message; } |
179 // If there is a receiver in the current argument list, it is at _outgoing.at(_outgoing.length()-1). | 180 // If there is a receiver in the current argument list, it is at _outgoing.at(_outgoing.length()-1). |
180 // If a value at _outgoing.at(n) is T_LONG or T_DOUBLE, the value at _outgoing.at(n+1) is T_VOID. | 181 // If a value at _outgoing.at(n) is T_LONG or T_DOUBLE, the value at _outgoing.at(n+1) is T_VOID. |
181 GrowableArray<ArgToken> _outgoing; // current outgoing parameter slots | 182 GrowableArray<ArgToken> _outgoing; // current outgoing parameter slots |
182 int _outgoing_argc; // # non-empty outgoing slots | 183 int _outgoing_argc; // # non-empty outgoing slots |
183 | 184 |
185 vmIntrinsics::ID _return_conv; // Return conversion required by raw retypes. | |
186 | |
184 // Replace a value of type old_type at slot (and maybe slot+1) with the new value. | 187 // Replace a value of type old_type at slot (and maybe slot+1) with the new value. |
185 // If old_type != T_VOID, remove the old argument at that point. | 188 // If old_type != T_VOID, remove the old argument at that point. |
186 // If new_type != T_VOID, insert the new argument at that point. | 189 // If new_type != T_VOID, insert the new argument at that point. |
187 // Insert or delete a second empty slot as needed. | 190 // Insert or delete a second empty slot as needed. |
188 void change_argument(BasicType old_type, int slot, const ArgToken& new_arg); | 191 void change_argument(BasicType old_type, int slot, const ArgToken& new_arg); |
217 public: | 220 public: |
218 MethodHandleWalker(Handle root, bool for_invokedynamic, TRAPS) | 221 MethodHandleWalker(Handle root, bool for_invokedynamic, TRAPS) |
219 : _chain(root, THREAD), | 222 : _chain(root, THREAD), |
220 _for_invokedynamic(for_invokedynamic), | 223 _for_invokedynamic(for_invokedynamic), |
221 _outgoing(THREAD, 10), | 224 _outgoing(THREAD, 10), |
222 _outgoing_argc(0) | 225 _outgoing_argc(0), |
226 _return_conv(vmIntrinsics::_none) | |
223 { | 227 { |
224 _local_index = for_invokedynamic ? 0 : 1; | 228 _local_index = for_invokedynamic ? 0 : 1; |
225 } | 229 } |
226 | 230 |
227 MethodHandleChain& chain() { return _chain; } | 231 MethodHandleChain& chain() { return _chain; } |
228 | 232 |
229 bool for_invokedynamic() const { return _for_invokedynamic; } | 233 bool for_invokedynamic() const { return _for_invokedynamic; } |
234 | |
235 vmIntrinsics::ID return_conv() const { return _return_conv; } | |
236 void set_return_conv(vmIntrinsics::ID c) { _return_conv = c; } | |
237 static vmIntrinsics::ID zero_return_conv() { return vmIntrinsics::_min; } | |
230 | 238 |
231 int new_local_index(BasicType bt) { | 239 int new_local_index(BasicType bt) { |
232 //int index = _for_invokedynamic ? _local_index : _local_index - 1; | 240 //int index = _for_invokedynamic ? _local_index : _local_index - 1; |
233 int index = _local_index; | 241 int index = _local_index; |
234 _local_index += type2size[bt]; | 242 _local_index += type2size[bt]; |
241 virtual ArgToken make_parameter(BasicType type, klassOop tk, int argnum, TRAPS) = 0; | 249 virtual ArgToken make_parameter(BasicType type, klassOop tk, int argnum, TRAPS) = 0; |
242 virtual ArgToken make_prim_constant(BasicType type, jvalue* con, TRAPS) = 0; | 250 virtual ArgToken make_prim_constant(BasicType type, jvalue* con, TRAPS) = 0; |
243 virtual ArgToken make_oop_constant(oop con, TRAPS) = 0; | 251 virtual ArgToken make_oop_constant(oop con, TRAPS) = 0; |
244 virtual ArgToken make_conversion(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& src, TRAPS) = 0; | 252 virtual ArgToken make_conversion(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& src, TRAPS) = 0; |
245 virtual ArgToken make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& base, const ArgToken& offset, TRAPS) = 0; | 253 virtual ArgToken make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& base, const ArgToken& offset, TRAPS) = 0; |
246 virtual ArgToken make_invoke(methodOop m, vmIntrinsics::ID iid, Bytecodes::Code op, bool tailcall, int argc, ArgToken* argv, TRAPS) = 0; | 254 virtual ArgToken make_invoke(methodHandle m, vmIntrinsics::ID iid, Bytecodes::Code op, bool tailcall, int argc, ArgToken* argv, TRAPS) = 0; |
247 | 255 |
248 // For make_invoke, the methodOop can be NULL if the intrinsic ID | 256 // For make_invoke, the methodHandle can be NULL if the intrinsic ID |
249 // is something other than vmIntrinsics::_none. | 257 // is something other than vmIntrinsics::_none. |
250 | 258 |
251 // and in case anyone cares to related the previous actions to the chain: | 259 // and in case anyone cares to related the previous actions to the chain: |
252 virtual void set_method_handle(oop mh) { } | 260 virtual void set_method_handle(oop mh) { } |
253 | 261 |
278 private: | 286 private: |
279 int _tag; // Constant pool tag type. | 287 int _tag; // Constant pool tag type. |
280 JavaValue _value; | 288 JavaValue _value; |
281 Handle _handle; | 289 Handle _handle; |
282 Symbol* _sym; | 290 Symbol* _sym; |
291 methodHandle _method; // pre-linkage | |
283 | 292 |
284 public: | 293 public: |
285 // Constructor for oop types. | 294 // Constructor for oop types. |
286 ConstantValue(int tag, Handle con) : _tag(tag), _handle(con) { | 295 ConstantValue(int tag, Handle con) : _tag(tag), _handle(con) { |
287 assert(tag == JVM_CONSTANT_Class || | 296 assert(tag == JVM_CONSTANT_Class || |
326 bool is_primitive() const { return is_java_primitive(_value.get_type()); } | 335 bool is_primitive() const { return is_java_primitive(_value.get_type()); } |
327 jint get_jint() const { return _value.get_jint(); } | 336 jint get_jint() const { return _value.get_jint(); } |
328 jlong get_jlong() const { return _value.get_jlong(); } | 337 jlong get_jlong() const { return _value.get_jlong(); } |
329 jfloat get_jfloat() const { return _value.get_jfloat(); } | 338 jfloat get_jfloat() const { return _value.get_jfloat(); } |
330 jdouble get_jdouble() const { return _value.get_jdouble(); } | 339 jdouble get_jdouble() const { return _value.get_jdouble(); } |
340 | |
341 void set_linkage(methodHandle method) { | |
342 assert(_method.is_null(), ""); | |
343 _method = method; | |
344 } | |
345 bool has_linkage() const { return _method.not_null(); } | |
346 methodHandle linkage() const { return _method; } | |
331 }; | 347 }; |
332 | 348 |
333 // Fake constant pool. | 349 // Fake constant pool. |
334 GrowableArray<ConstantValue*> _constants; | 350 GrowableArray<ConstantValue*> _constants; |
351 | |
352 // Non-BCP classes that appear in associated MethodTypes (require special handling). | |
353 GrowableArray<KlassHandle> _non_bcp_klasses; | |
335 | 354 |
336 // Accumulated compiler state: | 355 // Accumulated compiler state: |
337 GrowableArray<unsigned char> _bytecode; | 356 GrowableArray<unsigned char> _bytecode; |
338 | 357 |
339 int _cur_stack; | 358 int _cur_stack; |
366 ConstantValue* cv = new ConstantValue(tag, con); | 385 ConstantValue* cv = new ConstantValue(tag, con); |
367 con->increment_refcount(); | 386 con->increment_refcount(); |
368 return _constants.append(cv); | 387 return _constants.append(cv); |
369 } | 388 } |
370 | 389 |
371 int cpool_oop_reference_put(int tag, int first_index, int second_index) { | 390 int cpool_oop_reference_put(int tag, int first_index, int second_index, methodHandle method) { |
372 if (first_index == 0 && second_index == 0) return 0; | 391 if (first_index == 0 && second_index == 0) return 0; |
373 assert(first_index != 0 && second_index != 0, "no zero indexes"); | 392 assert(first_index != 0 && second_index != 0, "no zero indexes"); |
374 ConstantValue* cv = new ConstantValue(tag, first_index, second_index); | 393 ConstantValue* cv = new ConstantValue(tag, first_index, second_index); |
394 if (method.not_null()) cv->set_linkage(method); | |
375 return _constants.append(cv); | 395 return _constants.append(cv); |
376 } | 396 } |
377 | 397 |
378 int cpool_primitive_put(BasicType type, jvalue* con); | 398 int cpool_primitive_put(BasicType type, jvalue* con); |
399 | |
400 bool check_non_bcp_klasses(Handle method_type, TRAPS); | |
401 bool check_non_bcp_klass(klassOop klass, TRAPS); | |
402 void record_non_bcp_klasses(); | |
379 | 403 |
380 int cpool_int_put(jint value) { | 404 int cpool_int_put(jint value) { |
381 jvalue con; con.i = value; | 405 jvalue con; con.i = value; |
382 return cpool_primitive_put(T_INT, &con); | 406 return cpool_primitive_put(T_INT, &con); |
383 } | 407 } |
401 return cpool_symbol_put(JVM_CONSTANT_Utf8, sym); | 425 return cpool_symbol_put(JVM_CONSTANT_Utf8, sym); |
402 } | 426 } |
403 int cpool_klass_put(klassOop klass) { | 427 int cpool_klass_put(klassOop klass) { |
404 return cpool_oop_put(JVM_CONSTANT_Class, klass); | 428 return cpool_oop_put(JVM_CONSTANT_Class, klass); |
405 } | 429 } |
406 int cpool_methodref_put(int class_index, int name_and_type_index) { | 430 int cpool_methodref_put(Bytecodes::Code op, int class_index, int name_and_type_index, methodHandle method) { |
407 return cpool_oop_reference_put(JVM_CONSTANT_Methodref, class_index, name_and_type_index); | 431 int tag = (op == Bytecodes::_invokeinterface ? JVM_CONSTANT_InterfaceMethodref : JVM_CONSTANT_Methodref); |
432 return cpool_oop_reference_put(tag, class_index, name_and_type_index, method); | |
408 } | 433 } |
409 int cpool_name_and_type_put(int name_index, int signature_index) { | 434 int cpool_name_and_type_put(int name_index, int signature_index) { |
410 return cpool_oop_reference_put(JVM_CONSTANT_NameAndType, name_index, signature_index); | 435 return cpool_oop_reference_put(JVM_CONSTANT_NameAndType, name_index, signature_index, methodHandle()); |
411 } | 436 } |
412 | 437 |
413 void emit_bc(Bytecodes::Code op, int index = 0, int args_size = -1); | 438 void emit_bc(Bytecodes::Code op, int index = 0, int args_size = -1); |
414 void emit_load(BasicType bt, int index); | 439 void emit_load(BasicType bt, int index); |
415 void emit_store(BasicType bt, int index); | 440 void emit_store(BasicType bt, int index); |
426 return ArgToken(type, *con); | 451 return ArgToken(type, *con); |
427 } | 452 } |
428 | 453 |
429 virtual ArgToken make_conversion(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& src, TRAPS); | 454 virtual ArgToken make_conversion(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& src, TRAPS); |
430 virtual ArgToken make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& base, const ArgToken& offset, TRAPS); | 455 virtual ArgToken make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& base, const ArgToken& offset, TRAPS); |
431 virtual ArgToken make_invoke(methodOop m, vmIntrinsics::ID iid, Bytecodes::Code op, bool tailcall, int argc, ArgToken* argv, TRAPS); | 456 virtual ArgToken make_invoke(methodHandle m, vmIntrinsics::ID iid, Bytecodes::Code op, bool tailcall, int argc, ArgToken* argv, TRAPS); |
432 | 457 |
433 // Get a real constant pool. | 458 // Get a real constant pool. |
434 constantPoolHandle get_constant_pool(TRAPS) const; | 459 constantPoolHandle get_constant_pool(TRAPS) const; |
435 | 460 |
436 // Get a real methodOop. | 461 // Get a real methodOop. |