/hg/release/icedtea7-forest-2.3/hotspot: Fix Zero FTBFS issues
andrew at icedtea.classpath.org
andrew at icedtea.classpath.org
Thu Aug 30 12:27:04 PDT 2012
changeset 2a413d946cb1 in /hg/release/icedtea7-forest-2.3/hotspot
details: http://icedtea.classpath.org/hg/release/icedtea7-forest-2.3/hotspot?cmd=changeset;node=2a413d946cb1
author: andrew
date: Thu Aug 30 20:24:27 2012 +0100
Fix Zero FTBFS issues
diffstat:
src/cpu/zero/vm/assembler_zero.cpp | 8 +
src/cpu/zero/vm/assembler_zero.hpp | 1 +
src/cpu/zero/vm/copy_zero.hpp | 4 +-
src/cpu/zero/vm/cppInterpreter_zero.cpp | 344 ++++++++++++++++++++++++++++++-
src/cpu/zero/vm/frame_zero.inline.hpp | 2 +
src/cpu/zero/vm/methodHandles_zero.cpp | 67 ++++++-
src/cpu/zero/vm/methodHandles_zero.hpp | 8 +
src/cpu/zero/vm/sharedRuntime_zero.cpp | 15 +-
src/share/vm/asm/codeBuffer.cpp | 2 +-
9 files changed, 429 insertions(+), 22 deletions(-)
diffs (truncated from 636 to 500 lines):
diff -r 3e0087ab5e92 -r 2a413d946cb1 src/cpu/zero/vm/assembler_zero.cpp
--- a/src/cpu/zero/vm/assembler_zero.cpp Wed Aug 29 17:57:27 2012 +0100
+++ b/src/cpu/zero/vm/assembler_zero.cpp Thu Aug 30 20:24:27 2012 +0100
@@ -91,3 +91,11 @@
address ShouldNotCallThisEntry() {
return (address) should_not_call;
}
+
+static void zero_null_fn() {
+ return;
+}
+
+address ZeroNullStubEntry(address fn) {
+ return (address) fn;
+}
diff -r 3e0087ab5e92 -r 2a413d946cb1 src/cpu/zero/vm/assembler_zero.hpp
--- a/src/cpu/zero/vm/assembler_zero.hpp Wed Aug 29 17:57:27 2012 +0100
+++ b/src/cpu/zero/vm/assembler_zero.hpp Thu Aug 30 20:24:27 2012 +0100
@@ -65,5 +65,6 @@
address ShouldNotCallThisStub();
address ShouldNotCallThisEntry();
+address ZeroNullStubEntry(address fn);
#endif // CPU_ZERO_VM_ASSEMBLER_ZERO_HPP
diff -r 3e0087ab5e92 -r 2a413d946cb1 src/cpu/zero/vm/copy_zero.hpp
--- a/src/cpu/zero/vm/copy_zero.hpp Wed Aug 29 17:57:27 2012 +0100
+++ b/src/cpu/zero/vm/copy_zero.hpp Thu Aug 30 20:24:27 2012 +0100
@@ -169,7 +169,7 @@
}
static void pd_fill_to_bytes(void* to, size_t count, jubyte value) {
- memset(to, value, count);
+ if ( count > 0 ) memset(to, value, count);
}
static void pd_zero_to_words(HeapWord* tohw, size_t count) {
@@ -177,7 +177,7 @@
}
static void pd_zero_to_bytes(void* to, size_t count) {
- memset(to, 0, count);
+ if ( count > 0 ) memset(to, 0, count);
}
#endif // CPU_ZERO_VM_COPY_ZERO_HPP
diff -r 3e0087ab5e92 -r 2a413d946cb1 src/cpu/zero/vm/cppInterpreter_zero.cpp
--- a/src/cpu/zero/vm/cppInterpreter_zero.cpp Wed Aug 29 17:57:27 2012 +0100
+++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp Thu Aug 30 20:24:27 2012 +0100
@@ -36,6 +36,7 @@
#include "oops/oop.inline.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiThreadState.hpp"
+#include "prims/methodHandles.hpp"
#include "runtime/arguments.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
@@ -65,6 +66,13 @@
CALL_VM_NOCHECK_NOFIX(func) \
fixup_after_potential_safepoint()
+
+#ifdef z_CPPDEBUG
+#define CPPINT_DEBUG( Z_code_ ) Z_code_
+#else
+#define CPPINT_DEBUG( Z_code_ )
+#endif
+
int CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) {
JavaThread *thread = (JavaThread *) THREAD;
@@ -699,6 +707,9 @@
method_handle = adapter;
}
+ CPPINT_DEBUG( tty->print_cr( "Process method_handle sp: 0x%x unwind_sp: 0x%x result_slots: %d.", \
+ stack->sp(), unwind_sp, result_slots ); )
+
// Start processing
process_method_handle(method_handle, THREAD);
if (HAS_PENDING_EXCEPTION)
@@ -718,6 +729,8 @@
}
// Check
+ CPPINT_DEBUG( tty->print_cr( "Exiting method_handle_entry, sp: 0x%x unwind_sp: 0x%x result_slots: %d.", \
+ stack->sp(), unwind_sp, result_slots ); )
assert(stack->sp() == unwind_sp - result_slots, "should be");
// No deoptimized frames on the stack
@@ -725,6 +738,7 @@
}
void CppInterpreter::process_method_handle(oop method_handle, TRAPS) {
+
JavaThread *thread = (JavaThread *) THREAD;
ZeroStack *stack = thread->zero_stack();
intptr_t *vmslots = stack->sp();
@@ -739,6 +753,7 @@
(MethodHandles::EntryKind) (((intptr_t) entry) & 0xffffffff);
methodOop method = NULL;
+ CPPINT_DEBUG( tty->print_cr( "\nEntering %s 0x%x.",MethodHandles::entry_name(entry_kind), (char *)vmslots ); )
switch (entry_kind) {
case MethodHandles::_invokestatic_mh:
direct_to_method = true;
@@ -811,11 +826,15 @@
case MethodHandles::_bound_int_mh:
case MethodHandles::_bound_long_mh:
{
- BasicType arg_type = T_ILLEGAL;
- int arg_mask = -1;
- int arg_slots = -1;
- MethodHandles::get_ek_bound_mh_info(
- entry_kind, arg_type, arg_mask, arg_slots);
+ // BasicType arg_type = T_ILLEGAL;
+ // int arg_mask = -1;
+ // int arg_slots = -1;
+ // MethodHandles::get_ek_bound_mh_info(
+ // entry_kind, arg_type, arg_mask, arg_slots);
+ BasicType arg_type = MethodHandles::ek_bound_mh_arg_type(entry_kind);
+ int arg_mask = 0;
+ int arg_slots = type2size[arg_type];;
+
int arg_slot =
java_lang_invoke_BoundMethodHandle::vmargslot(method_handle);
@@ -961,10 +980,13 @@
java_lang_invoke_AdapterMethodHandle::conversion(method_handle);
int arg2 = MethodHandles::adapter_conversion_vminfo(conv);
- int swap_bytes = 0, rotate = 0;
- MethodHandles::get_ek_adapter_opt_swap_rot_info(
- entry_kind, swap_bytes, rotate);
- int swap_slots = swap_bytes >> LogBytesPerWord;
+ // int swap_bytes = 0, rotate = 0;
+ // MethodHandles::get_ek_adapter_opt_swap_rot_info(
+ // entry_kind, swap_bytes, rotate);
+ int swap_slots = MethodHandles::ek_adapter_opt_swap_slots(entry_kind);
+ int rotate = MethodHandles::ek_adapter_opt_swap_mode(entry_kind);
+ int swap_bytes = swap_slots * Interpreter::stackElementSize;
+ swap_slots = swap_bytes >> LogBytesPerWord;
intptr_t tmp;
switch (rotate) {
@@ -1080,12 +1102,309 @@
}
break;
- default:
- tty->print_cr("unhandled entry_kind %s",
+ case MethodHandles::_adapter_opt_spread_0:
+ case MethodHandles::_adapter_opt_spread_1_ref:
+ case MethodHandles::_adapter_opt_spread_2_ref:
+ case MethodHandles::_adapter_opt_spread_3_ref:
+ case MethodHandles::_adapter_opt_spread_4_ref:
+ case MethodHandles::_adapter_opt_spread_5_ref:
+ case MethodHandles::_adapter_opt_spread_ref:
+ case MethodHandles::_adapter_opt_spread_byte:
+ case MethodHandles::_adapter_opt_spread_char:
+ case MethodHandles::_adapter_opt_spread_short:
+ case MethodHandles::_adapter_opt_spread_int:
+ case MethodHandles::_adapter_opt_spread_long:
+ case MethodHandles::_adapter_opt_spread_float:
+ case MethodHandles::_adapter_opt_spread_double:
+ {
+
+ // spread an array out into a group of arguments
+
+ int arg_slot =
+ java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
+ // Fetch the argument, which we will cast to the required array type.
+ oop arg = VMSLOTS_OBJECT(arg_slot);
+
+ BasicType elem_type =
+ MethodHandles::ek_adapter_opt_spread_type(entry_kind);
+ int elem_slots =
+ type2size[elem_type]; // 1 or 2
+ int array_slots =
+ 1; // array is always a T_OBJECT
+ int length_offset =
+ arrayOopDesc::length_offset_in_bytes();
+ int elem0_offset =
+ arrayOopDesc::base_offset_in_bytes(elem_type);
+ int length_constant =
+ MethodHandles::ek_adapter_opt_spread_count(entry_kind);
+ int array_length = 0;
+ void *array_elem0 = NULL;
+
+ CPPINT_DEBUG( tty->print_cr( \
+ "ENTERING _adapter_opt_spread: %s %d %d 0x%x 0x%x", \
+ type2name(elem_type), arg_slot, length_constant, (char *)arg, stack->sp() ); )
+
+ // If the spread count is -1, the length is "variable" ie controlled
+ // by the array length.
+ // See ek_adapter_opt_spread_count in methodHandles.hpp
+ // If array lenth is 0 or spread count is 0 , we will remove the argslot.
+
+ bool length_can_be_zero = (length_constant == 0);
+ if (length_constant < 0) {
+ // some adapters with variable length must handle the zero case
+ if (!OptimizeMethodHandles ||
+ elem_type != T_OBJECT)
+ length_can_be_zero = true;
+ }
+
+ if (arg == NULL) {
+ CPPINT_DEBUG( tty->print_cr( \
+ "arg NULL implies Array_length == 0, remove slot." ); )
+ // remove arg slot
+ remove_vmslots(arg_slot, 1, THREAD); // doesn't trap
+ vmslots = stack->sp(); // unused, but let the compiler figure that out
+ CPPINT_DEBUG( tty->print_cr( \
+ " >> Would LEAVE _adapter_opt_spread with NPE." ); )
+#ifdef _NOT_DEF_
+ // queue a nullpointer exception for the caller
+ stack->set_sp(calculate_unwind_sp(stack, method_handle));
+ CALL_VM_NOCHECK_NOFIX(
+ throw_exception(
+ thread,
+ vmSymbols::java_lang_NullPointerException()));
+ // NB all oops trashed!
+ assert(HAS_PENDING_EXCEPTION, "should do");
+ return;
+#endif
+ } else { // (arg != NULL)
+ klassOop objKlassOop = arg->klass();
+ klassOop klassOf = java_lang_Class::as_klassOop(
+ java_lang_invoke_AdapterMethodHandle::argument(method_handle));
+
+ if (objKlassOop != klassOf &&
+ !objKlassOop->klass_part()->is_subtype_of(klassOf)) {
+ CPPINT_DEBUG( tty->print_cr( \
+ "CLASS CAST ERROR #1 in _adapter_opt_spread." ); )
+ ResourceMark rm(THREAD);
+ const char* objName = Klass::cast(objKlassOop)->external_name();
+ const char* klassName = Klass::cast(klassOf)->external_name();
+ char* message = SharedRuntime::generate_class_cast_message(
+ objName, klassName);
+
+ stack->set_sp(calculate_unwind_sp(stack, method_handle));
+ CALL_VM_NOCHECK_NOFIX(
+ throw_exception(
+ thread,
+ vmSymbols::java_lang_ClassCastException(), message));
+ // NB all oops trashed!
+ assert(HAS_PENDING_EXCEPTION, "should do");
+ return;
+ }
+
+ // Check the array type.
+
+ klassOop array_klass_oop = NULL;
+ BasicType array_type = java_lang_Class::as_BasicType(
+ java_lang_invoke_AdapterMethodHandle::argument(method_handle),
+ &array_klass_oop);
+ arrayKlassHandle array_klass(THREAD, array_klass_oop);
+
+ assert(array_type == T_OBJECT, "");
+ assert(Klass::cast(array_klass_oop)->oop_is_array(), "");
+ if (!(array_type == T_OBJECT) ||
+ !(Klass::cast(array_klass_oop)->oop_is_array())) {
+ CPPINT_DEBUG( tty->print_cr( \
+ "CLASS CAST ERROR #2 not an array in _adapter_opt_spread." ); )
+ ResourceMark rm(THREAD);
+ const char* objName = Klass::cast(objKlassOop)->external_name();
+ const char* klassName = Klass::cast(klassOf)->external_name();
+ char* message = SharedRuntime::generate_class_cast_message(
+ objName, klassName);
+ stack->set_sp(calculate_unwind_sp(stack, method_handle));
+ CALL_VM_NOCHECK_NOFIX(
+ throw_exception(
+ thread,
+ vmSymbols::java_lang_ClassCastException(), message));
+ // NB all oops trashed!
+ assert(HAS_PENDING_EXCEPTION, "should do");
+ return;
+ }
+
+ klassOop element_klass_oop = NULL;
+ BasicType element_type =
+ java_lang_Class::as_BasicType(array_klass->component_mirror(),
+ &element_klass_oop);
+ KlassHandle element_klass(THREAD, element_klass_oop);
+ if ((elem_type != T_OBJECT) && (elem_type != element_type)) {
+ CPPINT_DEBUG( tty->print_cr( \
+ "CLASS CAST ERROR #3 invalid type %s != %s in _adapter_opt_spread.", \
+ type2name(elem_type), type2name(element_type) ); )
+ ResourceMark rm(THREAD);
+ const char* objName = Klass::cast(objKlassOop)->external_name();
+ const char* klassName = Klass::cast(klassOf)->external_name();
+ char* message = SharedRuntime::generate_class_cast_message(
+ objName, klassName);
+ stack->set_sp(calculate_unwind_sp(stack, method_handle));
+ CALL_VM_NOCHECK_NOFIX(
+ throw_exception(
+ thread,
+ vmSymbols::java_lang_ClassCastException(), message));
+ // NB all oops trashed!
+ assert(HAS_PENDING_EXCEPTION, "should do");
+ return;
+ }
+
+ array_length = arrayOop(arg)->length();
+
+ // Check the required length.
+ if (length_constant > 0) { // must match ?
+ if ( array_length != length_constant ) {
+ CPPINT_DEBUG( tty->print_cr( \
+ "ARRY INDEX ERROR #4 invalid array length in _adapter_opt_spread." ); )
+ //fixme ArrayIndexOutOfBoundsException ?
+ ResourceMark rm(THREAD);
+ const char* objName = Klass::cast(objKlassOop)->external_name();
+ const char* klassName = Klass::cast(klassOf)->external_name();
+ char* message = SharedRuntime::generate_class_cast_message(
+ objName, klassName);
+
+ stack->set_sp(calculate_unwind_sp(stack, method_handle));
+ CALL_VM_NOCHECK_NOFIX(
+ throw_exception(
+ thread,
+ vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message));
+ // NB all oops trashed!
+ assert(HAS_PENDING_EXCEPTION, "should do");
+ return;
+ }
+ // use array_length ?
+ } else { // length_constant == [ -1 or 0 ]
+ if ( (array_length > 0) || length_can_be_zero ) {
+ // use array_length.
+ } else { // array_length 0 and not length_can_be_zero
+ CPPINT_DEBUG( tty->print_cr( \
+ "ARRY INDEX ERROR #5 arry length 0 in _adapter_opt_spread." ); )
+ //fixme ArrayIndexOutOfBoundsException ?
+ ResourceMark rm(THREAD);
+ const char* objName = Klass::cast(objKlassOop)->external_name();
+ const char* klassName = Klass::cast(klassOf)->external_name();
+ char* message = SharedRuntime::generate_class_cast_message(
+ objName, klassName);
+
+ stack->set_sp(calculate_unwind_sp(stack, method_handle));
+ CALL_VM_NOCHECK_NOFIX(
+ throw_exception(
+ thread,
+ vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message));
+ // NB all oops trashed!
+ assert(HAS_PENDING_EXCEPTION, "should do");
+ return;
+ }
+ }
+
+ // Array length checked out. Now insert any required arg slots.
+ // array_length - 1 more slots if array_length > 0
+ // otherwise if array_length == 0 remove arg_slot.
+
+ if ( array_length > 0 ) {
+ int slots = (array_length * elem_slots) - 1;
+ CPPINT_DEBUG( tty->print_cr( \
+ "array_length %d %d slots needed in _adapter_opt_spread.",\
+ array_length, slots); )
+ debug_only(if (elem_slots == 2) \
+ assert ((slots % 2 == 1)," bad slots calc"));
+ if ( slots > 0 ) {
+ intptr_t *unwind_sp =
+ calculate_unwind_sp(stack, method_handle);
+ insert_vmslots(arg_slot, slots, THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ // all oops trashed
+ stack->set_sp(unwind_sp);
+ return;
+ }
+ }
+ vmslots = stack->sp();
+ arg_slot += slots;
+
+ array_elem0 = arrayOop(arg)->base(elem_type);
+
+ // Copy from the array to the new arg slots.
+ // [from native : Beware: Arguments that are shallow
+ // on the stack are deep in the array,
+ // and vice versa. So a downward-growing stack (the usual)
+ // has to be copied elementwise in reverse order
+ // from the source array.]
+
+ void * array_elem = array_elem0;
+ int top_slot = arg_slot;
+
+ debug_only(if (elem_slots == 2) \
+ assert ((((ulong)(char *)&vmslots[top_slot]) % \
+ (u_int)type2aelembytes(elem_type) == 0), \
+ " bad arg alignment"));
+
+ CPPINT_DEBUG( tty->print_cr( \
+ "BEGIN ARRY LOOP %d %d 0x%x 0x%x _adapter_opt_spread.",\
+ array_length, top_slot, &vmslots[top_slot], array_elem ); )
+
+ for (int index = 0; index < array_length; index++) {
+ switch (elem_type) {
+ case T_BYTE:
+ SET_VMSLOTS_INT(*(jint*)array_elem, top_slot);
+ break;
+ case T_CHAR:
+ SET_VMSLOTS_INT(*(jint*)array_elem, top_slot);
+ break;
+ case T_SHORT:
+ SET_VMSLOTS_INT(*(jint*)array_elem, top_slot);
+ break;
+ case T_INT:
+ SET_VMSLOTS_INT(*(jint*)array_elem, top_slot);
+ break;
+ case T_FLOAT:
+ SET_VMSLOTS_FLOAT(*(jfloat*)array_elem,top_slot);
+ break;
+ case T_LONG:
+ SET_VMSLOTS_LONG(*(jlong*)array_elem, top_slot);
+ break;
+ case T_DOUBLE:
+ SET_VMSLOTS_DOUBLE(*(jdouble*)array_elem, top_slot);
+ break;
+ case T_OBJECT:
+ SET_VMSLOTS_OBJECT(*(oopDesc**)array_elem, top_slot);
+ break;
+ default:
+ tty->print_cr("unhandled type %s", type2name(elem_type));
+ ShouldNotReachHere();
+ }
+ array_elem = (void*)((char *)array_elem +
+ type2aelembytes(element_type));
+ top_slot -= elem_slots;
+ }
+ arg_slot++;
+ }
+ }
+ if ((array_length == 0) && (arg != NULL)) {
+ CPPINT_DEBUG( tty->print_cr( \
+ "Array_length == 0, will remove slot." ); )
+ // remove arg slot
+ remove_vmslots(arg_slot, 1, THREAD); // doesn't trap
+ // unused, but let the compiler figure that out
+ vmslots = stack->sp();
+ //
+ }
+ CPPINT_DEBUG( tty->print_cr( \
+ "LEAVING _adapter_opt_spread: %s 0x%x 0x%x \n", \
+ type2name(elem_type), (char *)arg, (char *)stack->sp() ); )
+ }
+ break;
+ default:
+ tty->print_cr("unhandled entry_kind %s",
MethodHandles::entry_name(entry_kind));
- ShouldNotReachHere();
+ ShouldNotReachHere();
}
+
// Continue along the chain
if (direct_to_method) {
if (method == NULL) {
@@ -1138,6 +1457,7 @@
tty->print_cr("dst_rtype = %s", type2name(dst_rtype));
ShouldNotReachHere();
}
+ CPPINT_DEBUG( tty->print_cr( "LEAVING %s\n",MethodHandles::entry_name(entry_kind) ); )
}
// The new slots will be inserted before slot insert_before.
diff -r 3e0087ab5e92 -r 2a413d946cb1 src/cpu/zero/vm/frame_zero.inline.hpp
--- a/src/cpu/zero/vm/frame_zero.inline.hpp Wed Aug 29 17:57:27 2012 +0100
+++ b/src/cpu/zero/vm/frame_zero.inline.hpp Thu Aug 30 20:24:27 2012 +0100
@@ -36,6 +36,8 @@
_deopt_state = unknown;
}
+inline address frame::sender_pc() const { ShouldNotCallThis(); }
+
inline frame::frame(ZeroFrame* zf, intptr_t* sp) {
_zeroframe = zf;
_sp = sp;
diff -r 3e0087ab5e92 -r 2a413d946cb1 src/cpu/zero/vm/methodHandles_zero.cpp
--- a/src/cpu/zero/vm/methodHandles_zero.cpp Wed Aug 29 17:57:27 2012 +0100
+++ b/src/cpu/zero/vm/methodHandles_zero.cpp Thu Aug 30 20:24:27 2012 +0100
@@ -28,6 +28,8 @@
#include "memory/allocation.inline.hpp"
#include "prims/methodHandles.hpp"
+#define __ _masm->
+
int MethodHandles::adapter_conversion_ops_supported_mask() {
return ((1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW)
@@ -38,12 +40,73 @@
|(1<<java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS)
- //|(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG!
+ |(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS)
);
- // FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS.
}
More information about the distro-pkg-dev
mailing list