--- a/indy.compiler.patch Wed Jul 08 16:45:11 2009 +0200
+++ b/indy.compiler.patch Mon Jul 13 17:54:18 2009 +0200
@@ -1,32 +1,25 @@ diff --git a/src/cpu/x86/vm/frame_x86.cp
diff --git a/src/cpu/x86/vm/frame_x86.cpp b/src/cpu/x86/vm/frame_x86.cpp
--- a/src/cpu/x86/vm/frame_x86.cpp
+++ b/src/cpu/x86/vm/frame_x86.cpp
-@@ -307,6 +307,13 @@
- }
- #endif // CC_INTERP
-
-+static bool is_method_handle_return(address sender_pc) {
-+ u1* pc = (u1*) sender_pc;
-+ if (pc[0] == (u1)Assembler::REX)
-+ pc++;
-+ return (pc[0] == 0x8B && pc[1] == (0xC0 | rsp->encoding() << 3 | rbp->encoding()));
-+}
-+
- frame frame::sender_for_entry_frame(RegisterMap* map) const {
- assert(map != NULL, "map must be set");
- // Java frame called from C; skip all C frames and return top C
-@@ -331,6 +338,10 @@
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
++ * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -331,6 +331,10 @@
// This is the sp before any possible extension (adapter/locals).
intptr_t* unextended_sp = interpreter_frame_sender_sp();
+ address sender_pc = this->sender_pc();
-+ if (is_method_handle_return(sender_pc))
++ if (nmethod::is_method_handle_return(sender_pc))
+ unextended_sp = (intptr_t*) at(link_offset);
+
// The interpreter and compiler(s) always save EBP/RBP in a known
// location on entry. We must record where that location is
// so this if EBP/RBP was live on callout from c2 we can find
-@@ -353,7 +364,7 @@
+@@ -353,7 +357,7 @@
#endif // AMD64
}
#endif /* COMPILER2 */
@@ -35,7 +28,7 @@ diff --git a/src/cpu/x86/vm/frame_x86.cp
}
-@@ -376,6 +387,14 @@
+@@ -376,6 +380,14 @@
intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
@@ -44,13 +37,13 @@ diff --git a/src/cpu/x86/vm/frame_x86.cp
+ // the saved_fp will in fact be a saved value of the unextended SP.
+ // The simplest way to tell whether we are returning to such a call
+ // site is as follows:
-+ if (is_method_handle_return(sender_pc))
++ if (nmethod::is_method_handle_return(sender_pc))
+ unextended_sp = saved_fp;
+
if (map->update_map()) {
// Tell GC to use argument oopmaps for some runtime stubs that need it.
// For C1, the runtime stub might not have oop maps, so set this flag
-@@ -400,7 +419,7 @@
+@@ -400,7 +412,7 @@
}
assert(sender_sp != sp(), "must have changed");
@@ -59,6 +52,54 @@ diff --git a/src/cpu/x86/vm/frame_x86.cp
}
frame frame::sender(RegisterMap* map) const {
+diff --git a/src/cpu/x86/vm/runtime_x86_32.cpp b/src/cpu/x86/vm/runtime_x86_32.cpp
+--- a/src/cpu/x86/vm/runtime_x86_32.cpp
++++ b/src/cpu/x86/vm/runtime_x86_32.cpp
+@@ -43,11 +43,11 @@
+ // This code is entered with a jmp.
+ //
+ // Arguments:
+-// rax,: exception oop
++// rax: exception oop
+ // rdx: exception pc
+ //
+ // Results:
+-// rax,: exception oop
++// rax: exception oop
+ // rdx: exception pc in caller or ???
+ // destination: exception handler of caller
+ //
+@@ -113,17 +113,17 @@
+ __ addptr(rsp, return_off * wordSize); // Epilog!
+ __ pop(rdx); // Exception pc
+
++ // rax: exception handler for given <exception oop/exception pc>
+
+- // rax,: exception handler for given <exception oop/exception pc>
++ // Restore SP from BP if the exception PC is a MethodHandle call.
++ __ cmpl(Address(rcx, JavaThread::is_method_handle_exception_offset()), 0);
++ __ cmovptr(Assembler::notEqual, rsp, rbp);
+
+ // We have a handler in rax, (could be deopt blob)
+ // rdx - throwing pc, deopt blob will need it.
+
+ __ push(rax);
+
+- // rcx contains handler address
+-
+- __ get_thread(rcx); // TLS
+ // Get the exception
+ __ movptr(rax, Address(rcx, JavaThread::exception_oop_offset()));
+ // Get the exception pc in case we are deoptimized
+@@ -137,7 +137,7 @@
+
+ __ pop(rcx);
+
+- // rax,: exception oop
++ // rax: exception oop
+ // rcx: exception handler
+ // rdx: exception pc
+ __ jmp (rcx);
diff --git a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
--- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
+++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
@@ -631,6 +672,61 @@ diff --git a/src/share/vm/classfile/vmSy
template(java_dyn_Linkage, "java/dyn/Linkage") \
template(java_dyn_CallSite, "java/dyn/CallSite") \
template(java_dyn_MethodHandle, "java/dyn/MethodHandle") \
+diff --git a/src/share/vm/code/nmethod.cpp b/src/share/vm/code/nmethod.cpp
+--- a/src/share/vm/code/nmethod.cpp
++++ b/src/share/vm/code/nmethod.cpp
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
++ * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -1876,6 +1876,24 @@
+
+
+ // -----------------------------------------------------------------------------
++// MethodHandle
++
++bool nmethod::is_method_handle_return(address return_pc) {
++ u1* pc = (u1*) return_pc;
++ // FIXME This should query a data structure.
++#if defined(X86)
++ if (pc[0] == (u1) Assembler::REX)
++ pc++;
++ return (pc[0] == 0x8B && pc[1] == (0xC0 | rsp->encoding() << 3 | rbp->encoding()));
++#elif defined(AMD64)
++#error Unimplemented
++#elif defined(SPARC)
++#error Unimplemented
++#endif
++}
++
++
++// -----------------------------------------------------------------------------
+ // Verification
+
+ void nmethod::verify() {
+diff --git a/src/share/vm/code/nmethod.hpp b/src/share/vm/code/nmethod.hpp
+--- a/src/share/vm/code/nmethod.hpp
++++ b/src/share/vm/code/nmethod.hpp
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
++ * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -504,6 +504,9 @@
+ address get_original_pc(const frame* fr) { return *orig_pc_addr(fr); }
+ void set_original_pc(const frame* fr, address pc) { *orig_pc_addr(fr) = pc; }
+
++ // MethodHandle
++ static bool is_method_handle_return(address return_pc);
++
+ // jvmti support:
+ void post_compiled_method_load_event();
+
diff --git a/src/share/vm/compiler/methodLiveness.cpp b/src/share/vm/compiler/methodLiveness.cpp
--- a/src/share/vm/compiler/methodLiveness.cpp
+++ b/src/share/vm/compiler/methodLiveness.cpp
@@ -1070,6 +1166,26 @@ diff --git a/src/share/vm/opto/matcher.c
// Compute the max stack slot killed by any call. These will not be
// available for debug info, and will be used to adjust FIRST_STACK_mask
// after all call sites have been visited.
+diff --git a/src/share/vm/opto/runtime.cpp b/src/share/vm/opto/runtime.cpp
+--- a/src/share/vm/opto/runtime.cpp
++++ b/src/share/vm/opto/runtime.cpp
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
++ * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -856,6 +856,9 @@
+ thread->set_exception_pc(pc);
+ thread->set_exception_handler_pc(handler_address);
+ thread->set_exception_stack_size(0);
++
++ // Check if the exception PC is a MethodHandle call.
++ thread->set_is_method_handle_exception(nmethod::is_method_handle_return(pc));
+ }
+
+ // Restore correct return pc. Was saved above.
diff --git a/src/share/vm/opto/type.cpp b/src/share/vm/opto/type.cpp
--- a/src/share/vm/opto/type.cpp
+++ b/src/share/vm/opto/type.cpp
@@ -1119,3 +1235,43 @@ diff --git a/src/share/vm/runtime/thread
}
// See : bugid 4211085.
+diff --git a/src/share/vm/runtime/thread.hpp b/src/share/vm/runtime/thread.hpp
+--- a/src/share/vm/runtime/thread.hpp
++++ b/src/share/vm/runtime/thread.hpp
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
++ * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -746,6 +746,7 @@
+ volatile address _exception_pc; // PC where exception happened
+ volatile address _exception_handler_pc; // PC for handler of exception
+ volatile int _exception_stack_size; // Size of frame where exception happened
++ volatile int _is_method_handle_exception; // True if the current exception PC is at a MethodHandle call.
+
+ // support for compilation
+ bool _is_compiling; // is true if a compilation is active inthis thread (one compilation per thread possible)
+@@ -1087,11 +1088,13 @@
+ int exception_stack_size() const { return _exception_stack_size; }
+ address exception_pc() const { return _exception_pc; }
+ address exception_handler_pc() const { return _exception_handler_pc; }
++ int is_method_handle_exception() const { return _is_method_handle_exception; }
+
+ void set_exception_oop(oop o) { _exception_oop = o; }
+ void set_exception_pc(address a) { _exception_pc = a; }
+ void set_exception_handler_pc(address a) { _exception_handler_pc = a; }
+ void set_exception_stack_size(int size) { _exception_stack_size = size; }
++ void set_is_method_handle_exception(int value) { _is_method_handle_exception = value; }
+
+ // Stack overflow support
+ inline size_t stack_available(address cur_sp);
+@@ -1165,6 +1168,7 @@
+ static ByteSize exception_pc_offset() { return byte_offset_of(JavaThread, _exception_pc ); }
+ static ByteSize exception_handler_pc_offset() { return byte_offset_of(JavaThread, _exception_handler_pc); }
+ static ByteSize exception_stack_size_offset() { return byte_offset_of(JavaThread, _exception_stack_size); }
++ static ByteSize is_method_handle_exception_offset() { return byte_offset_of(JavaThread, _is_method_handle_exception); }
+ static ByteSize stack_guard_state_offset() { return byte_offset_of(JavaThread, _stack_guard_state ); }
+ static ByteSize suspend_flags_offset() { return byte_offset_of(JavaThread, _suspend_flags ); }
+