src/share/vm/prims/methodHandleWalk.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/share/vm/prims/methodHandleWalk.hpp	Wed May 25 13:43:18 2011
--- new/src/share/vm/prims/methodHandleWalk.hpp	Wed May 25 13:43:18 2011

*** 54,63 **** --- 54,67 ---- int DirectMethodHandle_vmindex() { return java_lang_invoke_DirectMethodHandle::vmindex(method_handle_oop()); } oop BoundMethodHandle_argument_oop() { return java_lang_invoke_BoundMethodHandle::argument(method_handle_oop()); } int BoundMethodHandle_vmargslot() { return java_lang_invoke_BoundMethodHandle::vmargslot(method_handle_oop()); } int AdapterMethodHandle_conversion() { return java_lang_invoke_AdapterMethodHandle::conversion(method_handle_oop()); } + #ifdef ASSERT + void print_impl(TRAPS); + #endif + public: MethodHandleChain(Handle root, TRAPS) : _root(root) { set_method_handle(root, THREAD); }
*** 97,106 **** --- 101,118 ---- methodOop last_method_oop() { assert(is_last(), ""); return _last_method(); } Bytecodes::Code last_invoke_code() { assert(is_last(), ""); return _last_invoke; } void lose(const char* msg, TRAPS); const char* lose_message() { return _lose_message; } + + #ifdef ASSERT + // Print a symbolic description of a method handle chain, including + // the signature for each method. The signatures are printed in + // slot order to make it easier to understand. + void print(); + static void print(Handle mh); + #endif }; // Structure walker for method handles. // Does abstract interpretation on top of low-level parsing.
*** 124,212 **** --- 136,208 ---- BasicType _bt; jvalue _value; Handle _handle; public: ! ArgToken(TokenType tt = tt_illegal) : _tt(tt), _bt(tt == tt_void ? T_VOID : T_ILLEGAL) { assert(tt == tt_illegal || tt == tt_void, "invalid token type"); } ArgToken(TokenType tt, BasicType bt, int index) : _tt(tt), _bt(bt) { assert(_tt == tt_parameter || _tt == tt_temporary, "must have index"); _value.i = index; } ! ArgToken(BasicType bt, jvalue value) : _tt(tt_constant), _bt(bt), _value(value) { assert(_bt != T_OBJECT, "wrong constructor"); } ! ArgToken(BasicType bt, Handle value) : _tt(tt_constant), _bt(bt), _handle(value) {} ! ArgToken(Handle handle) : _tt(tt_constant), _bt(T_OBJECT), _handle(handle) {} ! ArgToken(const char* str) : _tt(tt_symbolic), _bt(T_LONG) { ! ArgToken(const char* str, BasicType type) : _tt(tt_symbolic), _bt(type) { _value.j = (intptr_t)str; } TokenType token_type() const { return _tt; } BasicType basic_type() const { return _bt; } bool has_index() const { return _tt == tt_parameter || _tt == tt_temporary; } int index() const { assert(has_index(), "must have index");; return _value.i; } ! Handle object() const { assert(_bt == T_OBJECT, "wrong accessor"); assert(_tt == tt_constant, "value type"); return _handle; } ! const char* str() const { assert(_tt == tt_symbolic, "string type"); return (const char*)(intptr_t)_value.j; } ! jint get_jint() const { assert(_bt == T_INT || is_subword_type(_bt), "wrong accessor"); assert(_tt == tt_constant, "value types"); return _value.i; } ! jlong get_jlong() const { assert(_bt == T_LONG, "wrong accessor"); assert(_tt == tt_constant, "value types"); return _value.j; } ! jfloat get_jfloat() const { assert(_bt == T_FLOAT, "wrong accessor"); assert(_tt == tt_constant, "value types"); return _value.f; } ! jdouble get_jdouble() const { assert(_bt == T_DOUBLE, "wrong accessor"); assert(_tt == tt_constant, "value types"); return _value.d; } }; // Abstract interpretation state: struct SlotState { BasicType _type; ArgToken _arg; SlotState() : _type(), _arg() {} }; static SlotState make_state(BasicType type, ArgToken arg) { SlotState ss; ss._type = type; ss._arg = arg; return ss; } private: MethodHandleChain _chain; bool _for_invokedynamic; int _local_index; // This array is kept in an unusual order, indexed by low-level "slot number". // TOS is always _outgoing.at(0), so simple pushes and pops shift the whole _outgoing array. // If there is a receiver in the current argument list, it is at _outgoing.at(_outgoing.length()-1). // If a value at _outgoing.at(n) is T_LONG or T_DOUBLE, the value at _outgoing.at(n+1) is T_VOID. ! GrowableArray<SlotState> _outgoing; // current outgoing parameter slots ! GrowableArray<ArgToken> _outgoing; // current outgoing parameter slots int _outgoing_argc; // # non-empty outgoing slots // Replace a value of type old_type at slot (and maybe slot+1) with the new value. // If old_type != T_VOID, remove the old argument at that point. // If new_type != T_VOID, insert the new argument at that point. // Insert or delete a second empty slot as needed. - void change_argument(BasicType old_type, int slot, BasicType new_type, const ArgToken& new_arg); + void change_argument(BasicType old_type, int slot, BasicType type, const ArgToken& new_arg) { + assert(type == new_arg.basic_type(), "must agree"); + change_argument(old_type, slot, new_arg); + } // Raw retype conversions for OP_RAW_RETYPE. void retype_raw_conversion(BasicType src, BasicType dst, bool for_return, int slot, TRAPS); void retype_raw_argument_type(BasicType src, BasicType dst, int slot, TRAPS) { retype_raw_conversion(src, dst, false, slot, CHECK); } void retype_raw_return_type( BasicType src, BasicType dst, TRAPS) { retype_raw_conversion(src, dst, true, -1, CHECK); } ! SlotState* slot_state(int slot) { if (slot < 0 || slot >= _outgoing.length()) return NULL; return _outgoing.adr_at(slot); ! BasicType arg_type(int slot) { + return _outgoing.at(slot).basic_type(); } ! BasicType slot_type(int slot) { ! SlotState* ss = slot_state(slot); if (ss == NULL) return T_ILLEGAL; return ss->_type; ! bool has_argument(int slot) { ! return arg_type(slot) < T_VOID; } bool slot_has_argument(int slot) { return slot_type(slot) < T_VOID; } #ifdef ASSERT int argument_count_slow(); #endif
*** 213,222 **** --- 209,220 ---- // Return a bytecode for converting src to dest, if one exists. Bytecodes::Code conversion_code(BasicType src, BasicType dest); void walk_incoming_state(TRAPS); + void verify_args_and_signature(TRAPS) NOT_DEBUG_RETURN; + public: MethodHandleWalker(Handle root, bool for_invokedynamic, TRAPS) : _chain(root, THREAD), _for_invokedynamic(for_invokedynamic), _outgoing(THREAD, 10),
*** 419,429 **** --- 417,427 ---- virtual ArgToken make_parameter(BasicType type, klassOop tk, int argnum, TRAPS) { return ArgToken(tt_parameter, type, argnum); } virtual ArgToken make_oop_constant(oop con, TRAPS) { Handle h(THREAD, con); - return ArgToken(T_OBJECT, h); } virtual ArgToken make_prim_constant(BasicType type, jvalue* con, TRAPS) { return ArgToken(type, *con); }

src/share/vm/prims/methodHandleWalk.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File