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.