Merge

Tue, 17 May 2011 19:15:34 -0700

author
never
date
Tue, 17 May 2011 19:15:34 -0700
changeset 2921
b79e8b4ecd76
parent 2919
2848194272f4
parent 2920
a80577f854f9
child 2922
1be2f0c40a34
child 2927
2b27ef5c2173

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                                                                            \

mercurial