Tue, 17 May 2011 19:15:34 -0700
Merge
src/share/vm/prims/methodHandles.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Tue May 17 15:43:46 2011 -0700 1.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Tue May 17 19:15:34 2011 -0700 1.3 @@ -1028,7 +1028,12 @@ 1.4 if (AddressOps.equal(val, value)) { 1.5 if (!printed) { 1.6 printed = true; 1.7 - blob.printOn(out); 1.8 + try { 1.9 + blob.printOn(out); 1.10 + } catch (Exception e) { 1.11 + out.println("Exception printing blob at " + base); 1.12 + e.printStackTrace(); 1.13 + } 1.14 } 1.15 out.println("found at " + base + "\n"); 1.16 }
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/code/AdapterBlob.java Tue May 17 19:15:34 2011 -0700 2.3 @@ -0,0 +1,58 @@ 2.4 +/* 2.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + * 2.26 + */ 2.27 + 2.28 +package sun.jvm.hotspot.code; 2.29 + 2.30 +import java.util.*; 2.31 +import sun.jvm.hotspot.debugger.*; 2.32 +import sun.jvm.hotspot.runtime.*; 2.33 +import sun.jvm.hotspot.types.*; 2.34 + 2.35 +public class AdapterBlob extends CodeBlob { 2.36 + static { 2.37 + VM.registerVMInitializedObserver(new Observer() { 2.38 + public void update(Observable o, Object data) { 2.39 + initialize(VM.getVM().getTypeDataBase()); 2.40 + } 2.41 + }); 2.42 + } 2.43 + 2.44 + private static void initialize(TypeDataBase db) { 2.45 + // Type type = db.lookupType("AdapterBlob"); 2.46 + 2.47 + // // FIXME: add any needed fields 2.48 + } 2.49 + 2.50 + public AdapterBlob(Address addr) { 2.51 + super(addr); 2.52 + } 2.53 + 2.54 + public boolean isAdapterBlob() { 2.55 + return true; 2.56 + } 2.57 + 2.58 + public String getName() { 2.59 + return "AdapterBlob: " + super.getName(); 2.60 + } 2.61 +}
3.1 --- a/agent/src/share/classes/sun/jvm/hotspot/code/CodeBlob.java Tue May 17 15:43:46 2011 -0700 3.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/code/CodeBlob.java Tue May 17 19:15:34 2011 -0700 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. 3.6 + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -93,6 +93,8 @@ 3.11 public boolean isUncommonTrapStub() { return false; } 3.12 public boolean isExceptionStub() { return false; } 3.13 public boolean isSafepointStub() { return false; } 3.14 + public boolean isRicochetBlob() { return false; } 3.15 + public boolean isAdapterBlob() { return false; } 3.16 3.17 // Fine grain nmethod support: isNmethod() == isJavaMethod() || isNativeMethod() || isOSRMethod() 3.18 public boolean isJavaMethod() { return false; }
4.1 --- a/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java Tue May 17 15:43:46 2011 -0700 4.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java Tue May 17 19:15:34 2011 -0700 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -57,6 +57,8 @@ 4.11 virtualConstructor.addMapping("BufferBlob", BufferBlob.class); 4.12 virtualConstructor.addMapping("nmethod", NMethod.class); 4.13 virtualConstructor.addMapping("RuntimeStub", RuntimeStub.class); 4.14 + virtualConstructor.addMapping("RicochetBlob", RicochetBlob.class); 4.15 + virtualConstructor.addMapping("AdapterBlob", AdapterBlob.class); 4.16 virtualConstructor.addMapping("SafepointBlob", SafepointBlob.class); 4.17 virtualConstructor.addMapping("DeoptimizationBlob", DeoptimizationBlob.class); 4.18 if (VM.getVM().isServerCompiler()) {
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/code/RicochetBlob.java Tue May 17 19:15:34 2011 -0700 5.3 @@ -0,0 +1,56 @@ 5.4 +/* 5.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.7 + * 5.8 + * This code is free software; you can redistribute it and/or modify it 5.9 + * under the terms of the GNU General Public License version 2 only, as 5.10 + * published by the Free Software Foundation. 5.11 + * 5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 5.15 + * version 2 for more details (a copy is included in the LICENSE file that 5.16 + * accompanied this code). 5.17 + * 5.18 + * You should have received a copy of the GNU General Public License version 5.19 + * 2 along with this work; if not, write to the Free Software Foundation, 5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 5.21 + * 5.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 5.23 + * or visit www.oracle.com if you need additional information or have any 5.24 + * questions. 5.25 + * 5.26 + */ 5.27 + 5.28 +package sun.jvm.hotspot.code; 5.29 + 5.30 +import java.util.*; 5.31 +import sun.jvm.hotspot.debugger.*; 5.32 +import sun.jvm.hotspot.runtime.*; 5.33 +import sun.jvm.hotspot.types.*; 5.34 + 5.35 +/** RicochetBlob (currently only used by Compiler 2) */ 5.36 + 5.37 +public class RicochetBlob extends SingletonBlob { 5.38 + static { 5.39 + VM.registerVMInitializedObserver(new Observer() { 5.40 + public void update(Observable o, Object data) { 5.41 + initialize(VM.getVM().getTypeDataBase()); 5.42 + } 5.43 + }); 5.44 + } 5.45 + 5.46 + private static void initialize(TypeDataBase db) { 5.47 + // Type type = db.lookupType("RicochetBlob"); 5.48 + 5.49 + // FIXME: add any needed fields 5.50 + } 5.51 + 5.52 + public RicochetBlob(Address addr) { 5.53 + super(addr); 5.54 + } 5.55 + 5.56 + public boolean isRicochetBlob() { 5.57 + return true; 5.58 + } 5.59 +}
6.1 --- a/src/cpu/x86/vm/methodHandles_x86.cpp Tue May 17 15:43:46 2011 -0700 6.2 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp Tue May 17 19:15:34 2011 -0700 6.3 @@ -389,7 +389,7 @@ 6.4 } 6.5 } 6.6 6.7 -#ifndef PRODUCT 6.8 +#ifdef ASSERT 6.9 void MethodHandles::RicochetFrame::verify_offsets() { 6.10 // Check compatibility of this struct with the more generally used offsets of class frame: 6.11 int ebp_off = sender_link_offset_in_bytes(); // offset from struct base to local rbp value
7.1 --- a/src/share/vm/ci/ciMethodHandle.cpp Tue May 17 15:43:46 2011 -0700 7.2 +++ b/src/share/vm/ci/ciMethodHandle.cpp Tue May 17 19:15:34 2011 -0700 7.3 @@ -43,7 +43,7 @@ 7.4 methodHandle callee(_callee->get_methodOop()); 7.5 // We catch all exceptions here that could happen in the method 7.6 // handle compiler and stop the VM. 7.7 - MethodHandleCompiler mhc(h, callee, _profile->count(), is_invokedynamic, THREAD); 7.8 + MethodHandleCompiler mhc(h, callee->name(), callee->signature(), _profile->count(), is_invokedynamic, THREAD); 7.9 if (!HAS_PENDING_EXCEPTION) { 7.10 methodHandle m = mhc.compile(THREAD); 7.11 if (!HAS_PENDING_EXCEPTION) {
8.1 --- a/src/share/vm/interpreter/bytecodeTracer.cpp Tue May 17 15:43:46 2011 -0700 8.2 +++ b/src/share/vm/interpreter/bytecodeTracer.cpp Tue May 17 19:15:34 2011 -0700 8.3 @@ -203,11 +203,14 @@ 8.4 if (value == NULL) { 8.5 st->print_cr(" NULL"); 8.6 } else if (java_lang_String::is_instance(value)) { 8.7 - EXCEPTION_MARK; 8.8 - Handle h_value (THREAD, value); 8.9 - Symbol* sym = java_lang_String::as_symbol(h_value, CATCH); 8.10 - print_symbol(sym, st); 8.11 - sym->decrement_refcount(); 8.12 + char buf[40]; 8.13 + int len = java_lang_String::utf8_length(value); 8.14 + java_lang_String::as_utf8_string(value, buf, sizeof(buf)); 8.15 + if (len >= (int)sizeof(buf)) { 8.16 + st->print_cr(" %s...[%d]", buf, len); 8.17 + } else { 8.18 + st->print_cr(" %s", buf); 8.19 + } 8.20 } else { 8.21 st->print_cr(" " PTR_FORMAT, (intptr_t) value); 8.22 }
9.1 --- a/src/share/vm/opto/idealGraphPrinter.cpp Tue May 17 15:43:46 2011 -0700 9.2 +++ b/src/share/vm/opto/idealGraphPrinter.cpp Tue May 17 19:15:34 2011 -0700 9.3 @@ -615,6 +615,7 @@ 9.4 } 9.5 } 9.6 9.7 +#ifdef ASSERT 9.8 if (node->debug_orig() != NULL) { 9.9 stringStream dorigStream; 9.10 Node* dorig = node->debug_orig(); 9.11 @@ -629,6 +630,7 @@ 9.12 } 9.13 print_prop("debug_orig", dorigStream.as_string()); 9.14 } 9.15 +#endif 9.16 9.17 if (_chaitin && _chaitin != (PhaseChaitin *)0xdeadbeef) { 9.18 buffer[0] = 0;
10.1 --- a/src/share/vm/prims/methodHandleWalk.cpp Tue May 17 15:43:46 2011 -0700 10.2 +++ b/src/share/vm/prims/methodHandleWalk.cpp Tue May 17 19:15:34 2011 -0700 10.3 @@ -265,7 +265,7 @@ 10.4 assert(dest == arg_state->_type, ""); 10.5 ArgToken arg = arg_state->_arg; 10.6 ArgToken new_arg = make_conversion(T_OBJECT, dest_klass, Bytecodes::_checkcast, arg, CHECK_(empty)); 10.7 - assert(arg.token_type() >= tt_symbolic || arg.index() == new_arg.index(), "should be the same index"); 10.8 + assert(!arg.has_index() || arg.index() == new_arg.index(), "should be the same index"); 10.9 debug_only(dest_klass = (klassOop)badOop); 10.10 break; 10.11 } 10.12 @@ -443,8 +443,10 @@ 10.13 ret = make_conversion(T_OBJECT, rklass, Bytecodes::_checkcast, ret, CHECK_(empty)); 10.14 } 10.15 } 10.16 - int ret_slot = arg_slot + (retain_original_args ? coll_slots : 0); 10.17 - change_argument(T_VOID, ret_slot, rtype, ret); 10.18 + if (rtype != T_VOID) { 10.19 + int ret_slot = arg_slot + (retain_original_args ? coll_slots : 0); 10.20 + change_argument(T_VOID, ret_slot, rtype, ret); 10.21 + } 10.22 break; 10.23 } 10.24 10.25 @@ -690,9 +692,8 @@ 10.26 // ----------------------------------------------------------------------------- 10.27 // MethodHandleCompiler 10.28 10.29 -MethodHandleCompiler::MethodHandleCompiler(Handle root, methodHandle callee, int invoke_count, bool is_invokedynamic, TRAPS) 10.30 +MethodHandleCompiler::MethodHandleCompiler(Handle root, Symbol* name, Symbol* signature, int invoke_count, bool is_invokedynamic, TRAPS) 10.31 : MethodHandleWalker(root, is_invokedynamic, THREAD), 10.32 - _callee(callee), 10.33 _invoke_count(invoke_count), 10.34 _thread(THREAD), 10.35 _bytecode(THREAD, 50), 10.36 @@ -706,8 +707,8 @@ 10.37 (void) _constants.append(NULL); 10.38 10.39 // Set name and signature index. 10.40 - _name_index = cpool_symbol_put(_callee->name()); 10.41 - _signature_index = cpool_symbol_put(_callee->signature()); 10.42 + _name_index = cpool_symbol_put(name); 10.43 + _signature_index = cpool_symbol_put(signature); 10.44 10.45 // Get return type klass. 10.46 Handle first_mtype(THREAD, chain().method_type_oop()); 10.47 @@ -715,7 +716,8 @@ 10.48 _rtype = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(first_mtype()), &_rklass); 10.49 if (_rtype == T_ARRAY) _rtype = T_OBJECT; 10.50 10.51 - int params = _callee->size_of_parameters(); // Incoming arguments plus receiver. 10.52 + ArgumentSizeComputer args(signature); 10.53 + int params = args.size() + 1; // Incoming arguments plus receiver. 10.54 _num_params = for_invokedynamic() ? params - 1 : params; // XXX Check if callee is static? 10.55 } 10.56 10.57 @@ -733,7 +735,7 @@ 10.58 } 10.59 10.60 10.61 -void MethodHandleCompiler::emit_bc(Bytecodes::Code op, int index) { 10.62 +void MethodHandleCompiler::emit_bc(Bytecodes::Code op, int index, int args_size) { 10.63 Bytecodes::check(op); // Are we legal? 10.64 10.65 switch (op) { 10.66 @@ -809,6 +811,14 @@ 10.67 case Bytecodes::_d2i: 10.68 case Bytecodes::_d2l: 10.69 case Bytecodes::_d2f: 10.70 + case Bytecodes::_iaload: 10.71 + case Bytecodes::_laload: 10.72 + case Bytecodes::_faload: 10.73 + case Bytecodes::_daload: 10.74 + case Bytecodes::_aaload: 10.75 + case Bytecodes::_baload: 10.76 + case Bytecodes::_caload: 10.77 + case Bytecodes::_saload: 10.78 case Bytecodes::_ireturn: 10.79 case Bytecodes::_lreturn: 10.80 case Bytecodes::_freturn: 10.81 @@ -822,9 +832,14 @@ 10.82 // bi 10.83 case Bytecodes::_ldc: 10.84 assert(Bytecodes::format_bits(op, false) == (Bytecodes::_fmt_b|Bytecodes::_fmt_has_k), "wrong bytecode format"); 10.85 - assert((char) index == index, "index does not fit in 8-bit"); 10.86 - _bytecode.push(op); 10.87 - _bytecode.push(index); 10.88 + if (index == (index & 0xff)) { 10.89 + _bytecode.push(op); 10.90 + _bytecode.push(index); 10.91 + } else { 10.92 + _bytecode.push(Bytecodes::_ldc_w); 10.93 + _bytecode.push(index >> 8); 10.94 + _bytecode.push(index); 10.95 + } 10.96 break; 10.97 10.98 case Bytecodes::_iload: 10.99 @@ -838,9 +853,16 @@ 10.100 case Bytecodes::_dstore: 10.101 case Bytecodes::_astore: 10.102 assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_bi, "wrong bytecode format"); 10.103 - assert((char) index == index, "index does not fit in 8-bit"); 10.104 - _bytecode.push(op); 10.105 - _bytecode.push(index); 10.106 + if (index == (index & 0xff)) { 10.107 + _bytecode.push(op); 10.108 + _bytecode.push(index); 10.109 + } else { 10.110 + // doesn't fit in a u2 10.111 + _bytecode.push(Bytecodes::_wide); 10.112 + _bytecode.push(op); 10.113 + _bytecode.push(index >> 8); 10.114 + _bytecode.push(index); 10.115 + } 10.116 break; 10.117 10.118 // bkk 10.119 @@ -848,7 +870,7 @@ 10.120 case Bytecodes::_ldc2_w: 10.121 case Bytecodes::_checkcast: 10.122 assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_bkk, "wrong bytecode format"); 10.123 - assert((short) index == index, "index does not fit in 16-bit"); 10.124 + assert((unsigned short) index == index, "index does not fit in 16-bit"); 10.125 _bytecode.push(op); 10.126 _bytecode.push(index >> 8); 10.127 _bytecode.push(index); 10.128 @@ -859,12 +881,23 @@ 10.129 case Bytecodes::_invokespecial: 10.130 case Bytecodes::_invokevirtual: 10.131 assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_bJJ, "wrong bytecode format"); 10.132 - assert((short) index == index, "index does not fit in 16-bit"); 10.133 + assert((unsigned short) index == index, "index does not fit in 16-bit"); 10.134 _bytecode.push(op); 10.135 _bytecode.push(index >> 8); 10.136 _bytecode.push(index); 10.137 break; 10.138 10.139 + case Bytecodes::_invokeinterface: 10.140 + assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_bJJ, "wrong bytecode format"); 10.141 + assert((unsigned short) index == index, "index does not fit in 16-bit"); 10.142 + assert(args_size > 0, "valid args_size"); 10.143 + _bytecode.push(op); 10.144 + _bytecode.push(index >> 8); 10.145 + _bytecode.push(index); 10.146 + _bytecode.push(args_size); 10.147 + _bytecode.push(0); 10.148 + break; 10.149 + 10.150 default: 10.151 ShouldNotReachHere(); 10.152 } 10.153 @@ -983,7 +1016,8 @@ 10.154 const ArgToken& src, TRAPS) { 10.155 10.156 BasicType srctype = src.basic_type(); 10.157 - int index = src.index(); 10.158 + TokenType tt = src.token_type(); 10.159 + int index = -1; 10.160 10.161 switch (op) { 10.162 case Bytecodes::_i2l: 10.163 @@ -1004,18 +1038,31 @@ 10.164 case Bytecodes::_d2i: 10.165 case Bytecodes::_d2l: 10.166 case Bytecodes::_d2f: 10.167 - emit_load(srctype, index); 10.168 + if (tt == tt_constant) { 10.169 + emit_load_constant(src); 10.170 + } else { 10.171 + emit_load(srctype, src.index()); 10.172 + } 10.173 stack_pop(srctype); // pop the src type 10.174 emit_bc(op); 10.175 stack_push(type); // push the dest value 10.176 - if (srctype != type) 10.177 + if (tt != tt_constant) 10.178 + index = src.index(); 10.179 + if (srctype != type || index == -1) 10.180 index = new_local_index(type); 10.181 emit_store(type, index); 10.182 break; 10.183 10.184 case Bytecodes::_checkcast: 10.185 - emit_load(srctype, index); 10.186 + if (tt == tt_constant) { 10.187 + emit_load_constant(src); 10.188 + } else { 10.189 + emit_load(srctype, src.index()); 10.190 + index = src.index(); 10.191 + } 10.192 emit_bc(op, cpool_klass_put(tk)); 10.193 + if (index == -1) 10.194 + index = new_local_index(type); 10.195 emit_store(srctype, index); 10.196 break; 10.197 10.198 @@ -1058,6 +1105,11 @@ 10.199 Symbol* name = m->name(); 10.200 Symbol* signature = m->signature(); 10.201 10.202 + // Count the number of arguments, not the size 10.203 + ArgumentCount asc(signature); 10.204 + assert(argc == asc.size() + ((op == Bytecodes::_invokestatic || op == Bytecodes::_invokedynamic) ? 0 : 1), 10.205 + "argc mismatch"); 10.206 + 10.207 if (tailcall) { 10.208 // Actually, in order to make these methods more recognizable, 10.209 // let's put them in holder class MethodHandle. That way stack 10.210 @@ -1106,9 +1158,13 @@ 10.211 case Bytecodes::_invokevirtual: 10.212 emit_bc(op, methodref_index); 10.213 break; 10.214 - case Bytecodes::_invokeinterface: 10.215 - Unimplemented(); 10.216 + 10.217 + case Bytecodes::_invokeinterface: { 10.218 + ArgumentSizeComputer asc(signature); 10.219 + emit_bc(op, methodref_index, asc.size() + 1); 10.220 break; 10.221 + } 10.222 + 10.223 default: 10.224 ShouldNotReachHere(); 10.225 } 10.226 @@ -1117,6 +1173,7 @@ 10.227 // Otherwise, make a recursive call to some helper routine. 10.228 BasicType rbt = m->result_type(); 10.229 if (rbt == T_ARRAY) rbt = T_OBJECT; 10.230 + stack_push(rbt); // The return value is already pushed onto the stack. 10.231 ArgToken ret; 10.232 if (tailcall) { 10.233 if (rbt != _rtype) { 10.234 @@ -1171,7 +1228,6 @@ 10.235 ret = ArgToken(); // Dummy return value. 10.236 } 10.237 else { 10.238 - stack_push(rbt); // The return value is already pushed onto the stack. 10.239 int index = new_local_index(rbt); 10.240 switch (rbt) { 10.241 case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT: 10.242 @@ -1196,8 +1252,32 @@ 10.243 const MethodHandleWalker::ArgToken& base, 10.244 const MethodHandleWalker::ArgToken& offset, 10.245 TRAPS) { 10.246 - Unimplemented(); 10.247 - return ArgToken(); 10.248 + switch (base.token_type()) { 10.249 + case tt_parameter: 10.250 + case tt_temporary: 10.251 + emit_load(base.basic_type(), base.index()); 10.252 + break; 10.253 + case tt_constant: 10.254 + emit_load_constant(base); 10.255 + break; 10.256 + default: 10.257 + ShouldNotReachHere(); 10.258 + } 10.259 + switch (offset.token_type()) { 10.260 + case tt_parameter: 10.261 + case tt_temporary: 10.262 + emit_load(offset.basic_type(), offset.index()); 10.263 + break; 10.264 + case tt_constant: 10.265 + emit_load_constant(offset); 10.266 + break; 10.267 + default: 10.268 + ShouldNotReachHere(); 10.269 + } 10.270 + emit_bc(op); 10.271 + int index = new_local_index(type); 10.272 + emit_store(type, index); 10.273 + return ArgToken(tt_temporary, type, index); 10.274 } 10.275 10.276 10.277 @@ -1372,12 +1452,10 @@ 10.278 return s; 10.279 } 10.280 ArgToken token(const char* str) { 10.281 - jvalue string_con; 10.282 - string_con.j = (intptr_t) str; 10.283 - return ArgToken(tt_symbolic, T_LONG, string_con); 10.284 + return ArgToken(str); 10.285 } 10.286 const char* string(ArgToken token) { 10.287 - return (const char*) (intptr_t) token.get_jlong(); 10.288 + return token.str(); 10.289 } 10.290 void start_params() { 10.291 _param_state <<= 1;
11.1 --- a/src/share/vm/prims/methodHandleWalk.hpp Tue May 17 15:43:46 2011 -0700 11.2 +++ b/src/share/vm/prims/methodHandleWalk.hpp Tue May 17 19:15:34 2011 -0700 11.3 @@ -126,26 +126,34 @@ 11.4 Handle _handle; 11.5 11.6 public: 11.7 - ArgToken(TokenType tt = tt_illegal) : _tt(tt) {} 11.8 - ArgToken(TokenType tt, BasicType bt, jvalue value) : _tt(tt), _bt(bt), _value(value) {} 11.9 + ArgToken(TokenType tt = tt_illegal) : _tt(tt) { 11.10 + assert(tt == tt_illegal || tt == tt_void, "invalid token type"); 11.11 + } 11.12 11.13 ArgToken(TokenType tt, BasicType bt, int index) : _tt(tt), _bt(bt) { 11.14 + assert(_tt == tt_parameter || _tt == tt_temporary, "must have index"); 11.15 _value.i = index; 11.16 } 11.17 11.18 - ArgToken(TokenType tt, BasicType bt, Handle value) : _tt(tt), _bt(bt) { 11.19 - _handle = value; 11.20 + ArgToken(BasicType bt, jvalue value) : _tt(tt_constant), _bt(bt), _value(value) {} 11.21 + ArgToken(BasicType bt, Handle value) : _tt(tt_constant), _bt(bt), _handle(value) {} 11.22 + 11.23 + 11.24 + ArgToken(const char* str) : _tt(tt_symbolic), _bt(T_LONG) { 11.25 + _value.j = (intptr_t)str; 11.26 } 11.27 11.28 TokenType token_type() const { return _tt; } 11.29 BasicType basic_type() const { return _bt; } 11.30 - int index() const { return _value.i; } 11.31 - Handle object() const { return _handle; } 11.32 + bool has_index() const { return _tt == tt_parameter || _tt == tt_temporary; } 11.33 + int index() const { assert(has_index(), "must have index");; return _value.i; } 11.34 + Handle object() const { assert(_tt == tt_constant, "value type"); return _handle; } 11.35 + const char* str() const { assert(_tt == tt_symbolic, "string type"); return (const char*)_value.j; } 11.36 11.37 - jint get_jint() const { return _value.i; } 11.38 - jlong get_jlong() const { return _value.j; } 11.39 - jfloat get_jfloat() const { return _value.f; } 11.40 - jdouble get_jdouble() const { return _value.d; } 11.41 + jint get_jint() const { assert(_tt == tt_constant, "value types"); return _value.i; } 11.42 + jlong get_jlong() const { assert(_tt == tt_constant, "value types"); return _value.j; } 11.43 + jfloat get_jfloat() const { assert(_tt == tt_constant, "value types"); return _value.f; } 11.44 + jdouble get_jdouble() const { assert(_tt == tt_constant, "value types"); return _value.d; } 11.45 }; 11.46 11.47 // Abstract interpretation state: 11.48 @@ -256,7 +264,6 @@ 11.49 // The IR happens to be JVM bytecodes. 11.50 class MethodHandleCompiler : public MethodHandleWalker { 11.51 private: 11.52 - methodHandle _callee; 11.53 int _invoke_count; // count the original call site has been executed 11.54 KlassHandle _rklass; // Return type for casting. 11.55 BasicType _rtype; 11.56 @@ -404,7 +411,7 @@ 11.57 return cpool_oop_reference_put(JVM_CONSTANT_NameAndType, name_index, signature_index); 11.58 } 11.59 11.60 - void emit_bc(Bytecodes::Code op, int index = 0); 11.61 + void emit_bc(Bytecodes::Code op, int index = 0, int args_size = -1); 11.62 void emit_load(BasicType bt, int index); 11.63 void emit_store(BasicType bt, int index); 11.64 void emit_load_constant(ArgToken arg); 11.65 @@ -414,10 +421,10 @@ 11.66 } 11.67 virtual ArgToken make_oop_constant(oop con, TRAPS) { 11.68 Handle h(THREAD, con); 11.69 - return ArgToken(tt_constant, T_OBJECT, h); 11.70 + return ArgToken(T_OBJECT, h); 11.71 } 11.72 virtual ArgToken make_prim_constant(BasicType type, jvalue* con, TRAPS) { 11.73 - return ArgToken(tt_constant, type, *con); 11.74 + return ArgToken(type, *con); 11.75 } 11.76 11.77 virtual ArgToken make_conversion(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& src, TRAPS); 11.78 @@ -431,7 +438,7 @@ 11.79 methodHandle get_method_oop(TRAPS) const; 11.80 11.81 public: 11.82 - MethodHandleCompiler(Handle root, methodHandle callee, int invoke_count, bool for_invokedynamic, TRAPS); 11.83 + MethodHandleCompiler(Handle root, Symbol* name, Symbol* signature, int invoke_count, bool for_invokedynamic, TRAPS); 11.84 11.85 // Compile the given MH chain into bytecode. 11.86 methodHandle compile(TRAPS);
12.1 --- a/src/share/vm/prims/methodHandles.cpp Tue May 17 15:43:46 2011 -0700 12.2 +++ b/src/share/vm/prims/methodHandles.cpp Tue May 17 19:15:34 2011 -0700 12.3 @@ -25,9 +25,11 @@ 12.4 #include "precompiled.hpp" 12.5 #include "classfile/symbolTable.hpp" 12.6 #include "interpreter/interpreter.hpp" 12.7 +#include "interpreter/oopMapCache.hpp" 12.8 #include "memory/allocation.inline.hpp" 12.9 #include "memory/oopFactory.hpp" 12.10 #include "prims/methodHandles.hpp" 12.11 +#include "prims/methodHandleWalk.hpp" 12.12 #include "runtime/javaCalls.hpp" 12.13 #include "runtime/reflection.hpp" 12.14 #include "runtime/signature.hpp" 12.15 @@ -2599,6 +2601,50 @@ 12.16 } 12.17 } 12.18 12.19 +#ifdef ASSERT 12.20 + 12.21 +extern "C" 12.22 +void print_method_handle(oop mh); 12.23 + 12.24 +static void stress_method_handle_walk_impl(Handle mh, TRAPS) { 12.25 + if (StressMethodHandleWalk) { 12.26 + // Exercise the MethodHandleWalk code in various ways and validate 12.27 + // the resulting method oop. Some of these produce output so they 12.28 + // are guarded under Verbose. 12.29 + ResourceMark rm; 12.30 + HandleMark hm; 12.31 + if (Verbose) { 12.32 + print_method_handle(mh()); 12.33 + } 12.34 + TempNewSymbol name = SymbolTable::new_symbol("invoke", CHECK); 12.35 + Handle mt = java_lang_invoke_MethodHandle::type(mh()); 12.36 + TempNewSymbol signature = java_lang_invoke_MethodType::as_signature(mt(), true, CHECK); 12.37 + MethodHandleCompiler mhc(mh, name, signature, 10000, false, CHECK); 12.38 + methodHandle m = mhc.compile(CHECK); 12.39 + if (Verbose) { 12.40 + m->print_codes(); 12.41 + } 12.42 + InterpreterOopMap mask; 12.43 + OopMapCache::compute_one_oop_map(m, m->code_size() - 1, &mask); 12.44 + } 12.45 +} 12.46 + 12.47 +static void stress_method_handle_walk(Handle mh, TRAPS) { 12.48 + stress_method_handle_walk_impl(mh, THREAD); 12.49 + if (HAS_PENDING_EXCEPTION) { 12.50 + oop ex = PENDING_EXCEPTION; 12.51 + CLEAR_PENDING_EXCEPTION; 12.52 + tty->print("StressMethodHandleWalk: "); 12.53 + java_lang_Throwable::print(ex, tty); 12.54 + tty->cr(); 12.55 + } 12.56 +} 12.57 +#else 12.58 + 12.59 +static void stress_method_handle_walk(Handle mh, TRAPS) {} 12.60 + 12.61 +#endif 12.62 + 12.63 // 12.64 // Here are the native methods on sun.invoke.MethodHandleImpl. 12.65 // They are the private interface between this JVM and the HotSpot-specific 12.66 @@ -2666,6 +2712,7 @@ 12.67 } 12.68 12.69 MethodHandles::init_DirectMethodHandle(mh, m, (do_dispatch != JNI_FALSE), CHECK); 12.70 + stress_method_handle_walk(mh, CHECK); 12.71 } 12.72 JVM_END 12.73 12.74 @@ -2694,11 +2741,11 @@ 12.75 receiver_limit, 12.76 decode_flags, 12.77 CHECK); 12.78 - return; 12.79 + } else { 12.80 + // Build a BMH on top of a DMH or another BMH: 12.81 + MethodHandles::init_BoundMethodHandle(mh, target, argnum, CHECK); 12.82 } 12.83 - 12.84 - // Build a BMH on top of a DMH or another BMH: 12.85 - MethodHandles::init_BoundMethodHandle(mh, target, argnum, CHECK); 12.86 + stress_method_handle_walk(mh, CHECK); 12.87 } 12.88 JVM_END 12.89 12.90 @@ -2716,6 +2763,7 @@ 12.91 assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); 12.92 12.93 MethodHandles::init_AdapterMethodHandle(mh, target, argnum, CHECK); 12.94 + stress_method_handle_walk(mh, CHECK); 12.95 } 12.96 JVM_END 12.97
13.1 --- a/src/share/vm/runtime/globals.hpp Tue May 17 15:43:46 2011 -0700 13.2 +++ b/src/share/vm/runtime/globals.hpp Tue May 17 19:15:34 2011 -0700 13.3 @@ -3724,6 +3724,9 @@ 13.4 diagnostic(bool, OptimizeMethodHandles, true, \ 13.5 "when constructing method handles, try to improve them") \ 13.6 \ 13.7 + develop(bool, StressMethodHandleWalk, false, \ 13.8 + "Process all method handles with MethodHandleWalk") \ 13.9 + \ 13.10 diagnostic(bool, UseRicochetFrames, true, \ 13.11 "use ricochet stack frames for method handle combination, " \ 13.12 "if the platform supports them") \
14.1 --- a/src/share/vm/runtime/thread.cpp Tue May 17 15:43:46 2011 -0700 14.2 +++ b/src/share/vm/runtime/thread.cpp Tue May 17 19:15:34 2011 -0700 14.3 @@ -2861,6 +2861,7 @@ 14.4 } 14.5 14.6 14.7 +#ifdef ASSERT 14.8 // Print or validate the layout of stack frames 14.9 void JavaThread::print_frame_layout(int depth, bool validate_only) { 14.10 ResourceMark rm; 14.11 @@ -2878,7 +2879,7 @@ 14.12 values.print(); 14.13 } 14.14 } 14.15 - 14.16 +#endif 14.17 14.18 void JavaThread::trace_stack_from(vframe* start_vf) { 14.19 ResourceMark rm;
15.1 --- a/src/share/vm/runtime/vmStructs.cpp Tue May 17 15:43:46 2011 -0700 15.2 +++ b/src/share/vm/runtime/vmStructs.cpp Tue May 17 19:15:34 2011 -0700 15.3 @@ -783,6 +783,7 @@ 15.4 nonstatic_field(nmethod, _osr_link, nmethod*) \ 15.5 nonstatic_field(nmethod, _scavenge_root_link, nmethod*) \ 15.6 nonstatic_field(nmethod, _scavenge_root_state, jbyte) \ 15.7 + nonstatic_field(nmethod, _state, unsigned char) \ 15.8 nonstatic_field(nmethod, _exception_offset, int) \ 15.9 nonstatic_field(nmethod, _deoptimize_offset, int) \ 15.10 nonstatic_field(nmethod, _orig_pc_offset, int) \ 15.11 @@ -800,6 +801,8 @@ 15.12 nonstatic_field(nmethod, _osr_entry_point, address) \ 15.13 nonstatic_field(nmethod, _lock_count, jint) \ 15.14 nonstatic_field(nmethod, _stack_traversal_mark, long) \ 15.15 + nonstatic_field(nmethod, _compile_id, int) \ 15.16 + nonstatic_field(nmethod, _marked_for_deoptimization, bool) \ 15.17 \ 15.18 /********************************/ \ 15.19 /* JavaCalls (NOTE: incomplete) */ \ 15.20 @@ -1310,11 +1313,13 @@ 15.21 \ 15.22 declare_toplevel_type(CodeBlob) \ 15.23 declare_type(BufferBlob, CodeBlob) \ 15.24 - declare_type(nmethod, CodeBlob) \ 15.25 + declare_type(AdapterBlob, BufferBlob) \ 15.26 + declare_type(nmethod, CodeBlob) \ 15.27 declare_type(RuntimeStub, CodeBlob) \ 15.28 declare_type(SingletonBlob, CodeBlob) \ 15.29 declare_type(SafepointBlob, SingletonBlob) \ 15.30 declare_type(DeoptimizationBlob, SingletonBlob) \ 15.31 + declare_type(RicochetBlob, SingletonBlob) \ 15.32 declare_c2_type(ExceptionBlob, SingletonBlob) \ 15.33 declare_c2_type(UncommonTrapBlob, CodeBlob) \ 15.34 \