Mercurial > people > rkennke > hotspot-comp-zero > hotspot > .hg > patches
changeset 1:cef23de210a4
Bunch of fixes to get Zero to build.
author | Roman Kennke <rkennke@redhat.com> |
---|---|
date | Mon, 30 Jul 2012 13:57:49 +0200 |
parents | a9efa2633708 |
children | 264be8bc2c98 |
files | hotspot.patch psgc-bind-procs.patch series zero-makefile.patch zero-new-math.patch zero-segfault.patch |
diffstat | 6 files changed, 940 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot.patch Mon Jul 30 13:57:49 2012 +0200 @@ -0,0 +1,742 @@ +--- old/make/linux/platform_zero.in 2012-07-26 11:59:59.762620781 -0400 ++++ new/make/linux/platform_zero.in 2012-07-26 11:59:59.527600874 -0400 +@@ -14,4 +14,4 @@ + + gnu_dis_arch = zero + +-sysdefs = -DLINUX -D_GNU_SOURCE -DCC_INTERP -DZERO -D@ZERO_ARCHDEF@ -DZERO_LIBARCH=\"@ZERO_LIBARCH@\" ++sysdefs = -DLINUX -D_GNU_SOURCE -DCC_INTERP -DZERO -DTARGET_ARCH_NYI_6939861=1 -D@ZERO_ARCHDEF@ -DZERO_LIBARCH=\"@ZERO_LIBARCH@\" +--- old/src/cpu/zero/vm/assembler_zero.cpp 2012-07-26 12:00:00.277664407 -0400 ++++ new/src/cpu/zero/vm/assembler_zero.cpp 2012-07-26 12:00:00.120651108 -0400 +@@ -91,3 +91,11 @@ + address ShouldNotCallThisEntry() { + return (address) should_not_call; + } ++ ++static void zero_null_fn() { ++ return; ++} ++ ++address ZeroNullStubEntry(address fn) { ++ return (address) fn; ++} +--- old/src/cpu/zero/vm/assembler_zero.hpp 2012-07-26 12:00:00.664697192 -0400 ++++ new/src/cpu/zero/vm/assembler_zero.hpp 2012-07-26 12:00:00.536686349 -0400 +@@ -65,5 +65,6 @@ + + address ShouldNotCallThisStub(); + address ShouldNotCallThisEntry(); ++address ZeroNullStubEntry(address fn); + + #endif // CPU_ZERO_VM_ASSEMBLER_ZERO_HPP +--- old/src/cpu/zero/vm/copy_zero.hpp 2012-07-26 12:00:01.529770463 -0400 ++++ new/src/cpu/zero/vm/copy_zero.hpp 2012-07-26 12:00:01.017727097 -0400 +@@ -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 +--- old/src/cpu/zero/vm/cppInterpreter_zero.cpp 2012-07-26 12:00:01.934804777 -0400 ++++ new/src/cpu/zero/vm/cppInterpreter_zero.cpp 2012-07-26 12:00:01.806793934 -0400 +@@ -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,14 @@ + CALL_VM_NOCHECK_NOFIX(func) \ + fixup_after_potential_safepoint() + ++ ++#ifdef DEBUG ++#define CPPINT_DEBUG( Z_code_ ) Z_code_ ++CPPINT_DEBUG ( static const char *FFng_Zero_Flag = "CPPINT_DEBUG_ON\n"; ) ++#else ++#define CPPINT_DEBUG( Z_code_ ) ++#endif ++ + int CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) { + JavaThread *thread = (JavaThread *) THREAD; + +@@ -699,6 +708,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 +730,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 +739,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 +754,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 +827,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 +981,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 +1103,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 +1458,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. +--- old/src/cpu/zero/vm/frame_zero.inline.hpp 2012-07-26 12:00:02.430846787 -0400 ++++ new/src/cpu/zero/vm/frame_zero.inline.hpp 2012-07-26 12:00:02.295835354 -0400 +@@ -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; +--- old/src/cpu/zero/vm/methodHandles_zero.cpp 2012-07-26 12:00:02.828880511 -0400 ++++ new/src/cpu/zero/vm/methodHandles_zero.cpp 2012-07-26 12:00:02.695869244 -0400 +@@ -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. + } + + void MethodHandles::generate_method_handle_stub(MacroAssembler* masm, + MethodHandles::EntryKind ek) { + init_entry(ek, (MethodHandleEntry *) ek); + } ++void MethodHandles::RicochetFrame::generate_ricochet_blob(MacroAssembler* _masm, ++ // output params: ++ int* bounce_offset, ++ int* exception_offset, ++ int* frame_size_in_words) { ++ (*frame_size_in_words) = 0; ++ address start = __ pc(); ++ (*bounce_offset) = __ pc() - start; ++ (*exception_offset) = __ pc() - start; ++} ++ ++frame MethodHandles::ricochet_frame_sender(const frame& fr, RegisterMap *map) { ++ //RicochetFrame* f = RicochetFrame::from_frame(fr); ++ // Cf. is_interpreted_frame path of frame::sender ++ // intptr_t* younger_sp = fr.sp(); ++ // intptr_t* sp = fr.sender_sp(); ++ // return frame(sp, younger_sp, this_frame_adjusted_stack); ++ ShouldNotCallThis(); ++} ++ ++void MethodHandles::ricochet_frame_oops_do(const frame& fr, OopClosure* blk, const RegisterMap* reg_map) { ++ // ResourceMark rm; ++ // RicochetFrame* f = RicochetFrame::from_frame(fr); ++ ++ // pick up the argument type descriptor: ++ // Thread* thread = Thread::current(); ++ // process fixed part ++ // blk->do_oop((oop*)f->saved_target_addr()); ++ // blk->do_oop((oop*)f->saved_args_layout_addr()); ++ ++ // process variable arguments: ++ // if (cookie.is_null()) return; // no arguments to describe ++ ++ // the cookie is actually the invokeExact method for my target ++ // his argument signature is what I'm interested in ++ // assert(cookie->is_method(), ""); ++ // methodHandle invoker(thread, methodOop(cookie())); ++ // assert(invoker->name() == vmSymbols::invokeExact_name(), "must be this kind of method"); ++ // assert(!invoker->is_static(), "must have MH argument"); ++ // int slot_count = invoker->size_of_parameters(); ++ // assert(slot_count >= 1, "must include 'this'"); ++ // intptr_t* base = f->saved_args_base(); ++ // intptr_t* retval = NULL; ++ // if (f->has_return_value_slot()) ++ // retval = f->return_value_slot_addr(); ++ // int slot_num = slot_count - 1; ++ // intptr_t* loc = &base[slot_num]; ++ //blk->do_oop((oop*) loc); // original target, which is irrelevant ++ // int arg_num = 0; ++ // for (SignatureStream ss(invoker->signature()); !ss.is_done(); ss.next()) { ++ // if (ss.at_return_type()) continue; ++ // BasicType ptype = ss.type(); ++ // if (ptype == T_ARRAY) ptype = T_OBJECT; // fold all refs to T_OBJECT ++ // assert(ptype >= T_BOOLEAN && ptype <= T_OBJECT, "not array or void"); ++ // slot_num -= type2size[ptype]; ++ // loc = &base[slot_num]; ++ // bool is_oop = (ptype == T_OBJECT && loc != retval); ++ // if (is_oop) blk->do_oop((oop*)loc); ++ // arg_num += 1; ++ // } ++ // assert(slot_num == 0, "must have processed all the arguments"); ++} +--- old/src/cpu/zero/vm/methodHandles_zero.hpp 2012-07-26 12:00:03.229914480 -0400 ++++ new/src/cpu/zero/vm/methodHandles_zero.hpp 2012-07-26 12:00:03.114904738 -0400 +@@ -29,3 +29,26 @@ + adapter_code_size = 0 + }; + ++class RicochetFrame : public ResourceObj { ++ friend class MethodHandles; ++ private: ++ /* ++ RF field x86 SPARC ++ sender_pc *(rsp+0) I7-0x8 ++ sender_link rbp I6+BIAS ++ exact_sender_sp rsi/r13 I5_savedSP ++ conversion *(rcx+&amh_conv) L5_conv ++ saved_args_base rax L4_sab (cf. Gargs = G4) ++ saved_args_layout #NULL L3_sal ++ saved_target *(rcx+&mh_vmtgt) L2_stgt ++ continuation #STUB_CON L1_cont ++ */ ++ public: ++ ++static void generate_ricochet_blob(MacroAssembler* _masm, ++ // output params: ++ int* bounce_offset, ++ int* exception_offset, ++ int* frame_size_in_words); ++ ++}; +--- old/src/cpu/zero/vm/sharedRuntime_zero.cpp 2012-07-26 12:00:03.623947857 -0400 ++++ new/src/cpu/zero/vm/sharedRuntime_zero.cpp 2012-07-26 12:00:03.509938200 -0400 +@@ -35,6 +35,7 @@ + #include "runtime/sharedRuntime.hpp" + #include "runtime/vframeArray.hpp" + #include "vmreg_zero.inline.hpp" ++ + #ifdef COMPILER1 + #include "c1/c1_Runtime1.hpp" + #endif +@@ -47,6 +48,12 @@ + #endif + + ++ ++static address zero_null_code_stub() { ++ address start = ShouldNotCallThisStub(); ++ return start; ++} ++ + int SharedRuntime::java_calling_convention(const BasicType *sig_bt, + VMRegPair *regs, + int total_args_passed, +@@ -63,9 +70,9 @@ + AdapterFingerPrint *fingerprint) { + return AdapterHandlerLibrary::new_entry( + fingerprint, +- ShouldNotCallThisStub(), +- ShouldNotCallThisStub(), +- ShouldNotCallThisStub()); ++ ZeroNullStubEntry( CAST_FROM_FN_PTR(address,zero_null_code_stub) ), ++ ZeroNullStubEntry( CAST_FROM_FN_PTR(address,zero_null_code_stub) ), ++ ZeroNullStubEntry( CAST_FROM_FN_PTR(address,zero_null_code_stub) )); + } + + nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, +@@ -96,19 +103,20 @@ + ShouldNotCallThis(); + } + ++JRT_LEAF(void, zero_stub()) ++ ShouldNotCallThis(); ++JRT_END ++ + static RuntimeStub* generate_empty_runtime_stub(const char* name) { +- CodeBuffer buffer(name, 0, 0); +- return RuntimeStub::new_runtime_stub(name, &buffer, 0, 0, NULL, false); ++ return CAST_FROM_FN_PTR(RuntimeStub*,zero_stub); + } + + static SafepointBlob* generate_empty_safepoint_blob() { +- CodeBuffer buffer("handler_blob", 0, 0); +- return SafepointBlob::create(&buffer, NULL, 0); ++ return CAST_FROM_FN_PTR(SafepointBlob*,zero_stub); + } + + static DeoptimizationBlob* generate_empty_deopt_blob() { +- CodeBuffer buffer("handler_blob", 0, 0); +- return DeoptimizationBlob::create(&buffer, NULL, 0, 0, 0, 0); ++ return CAST_FROM_FN_PTR(DeoptimizationBlob*,zero_stub); + } + + +@@ -124,6 +132,7 @@ + return generate_empty_runtime_stub("resolve_blob"); + } + ++ + int SharedRuntime::c_calling_convention(const BasicType *sig_bt, + VMRegPair *regs, + int total_args_passed) { +--- old/src/share/vm/runtime/sharedRuntime.cpp 2012-07-26 12:00:04.113989373 -0400 ++++ new/src/share/vm/runtime/sharedRuntime.cpp 2012-07-26 12:00:03.921973101 -0400 +@@ -120,6 +120,7 @@ + //----------------------------generate_ricochet_blob--------------------------- + void SharedRuntime::generate_ricochet_blob() { + if (!EnableInvokeDynamic) return; // leave it as a null ++ ZERO_ONLY( return; ) + + // allocate space for the code + ResourceMark rm; +--- old/src/share/vm/runtime/vmStructs.cpp 2012-07-26 12:00:04.610031384 -0400 ++++ new/src/share/vm/runtime/vmStructs.cpp 2012-07-26 12:00:04.484020710 -0400 +@@ -836,10 +836,10 @@ + /* CodeBlobs (NOTE: incomplete, but only a little) */ \ + /***************************************************/ \ + \ +- X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _sender_pc, address)) \ +- X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _exact_sender_sp, intptr_t*)) \ +- X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _sender_link, intptr_t*)) \ +- X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _saved_args_base, intptr_t*)) \ ++ NOT_ZERO(X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _sender_pc, address))) \ ++ NOT_ZERO(X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _exact_sender_sp, intptr_t*))) \ ++ NOT_ZERO(X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _sender_link, intptr_t*))) \ ++ NOT_ZERO(X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _saved_args_base, intptr_t*))) \ + \ + static_field(SharedRuntime, _ricochet_blob, RicochetBlob*) \ + \ +@@ -2495,7 +2495,7 @@ + /* frame */ \ + /**********************/ \ + \ +- X86_ONLY(declare_constant(frame::entry_frame_call_wrapper_offset)) \ ++ NOT_ZERO(X86_ONLY(declare_constant(frame::entry_frame_call_wrapper_offset))) \ + declare_constant(frame::pc_return_offset) \ + \ + /*************/ \ +--- old/src/share/vm/shark/sharkCompiler.cpp 2012-07-26 12:00:05.105073316 -0400 ++++ new/src/share/vm/shark/sharkCompiler.cpp 2012-07-26 12:00:04.971061965 -0400 +@@ -319,7 +319,8 @@ + // finish with the exception of the VM thread, so we can consider + // ourself the owner of the execution engine lock even though we + // can't actually acquire it at this time. +- assert(Thread::current()->is_VM_thread(), "must be called by VM thread"); ++ assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode"); ++//assert(Thread::current()->is_VM_thread(), "must be called by VM thread"); + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); + + SharkEntry *entry = (SharkEntry *) code; +--- old/src/share/vm/utilities/macros.hpp 2012-07-26 12:00:05.529109235 -0400 ++++ new/src/share/vm/utilities/macros.hpp 2012-07-26 12:00:05.388097290 -0400 +@@ -177,6 +177,22 @@ + #define NOT_WIN64(code) code + #endif + ++#if defined(ZERO) ++#define ZERO_ONLY(code) code ++#define NOT_ZERO(code) ++#else ++#define ZERO_ONLY(code) ++#define NOT_ZERO(code) code ++#endif ++ ++#if defined(SHARK) ++#define SHARK_ONLY(code) code ++#define NOT_SHARK(code) ++#else ++#define SHARK_ONLY(code) ++#define NOT_SHARK(code) code ++#endif ++ + #if defined(IA32) || defined(AMD64) + #define X86 + #define X86_ONLY(code) code
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/psgc-bind-procs.patch Mon Jul 30 13:57:49 2012 +0200 @@ -0,0 +1,117 @@ +# HG changeset patch +# Parent 144e4e0a3b16431210ba8c49030e33129803e7ef +diff --git a/src/os/linux/vm/os_linux.cpp b/src/os/linux/vm/os_linux.cpp +--- a/src/os/linux/vm/os_linux.cpp ++++ b/src/os/linux/vm/os_linux.cpp +@@ -4356,14 +4356,108 @@ + } + } + ++// TODO: This is almost 100% copied from os_solaris.cpp, ++// it can and should be extracted into a shared method. ++static bool assign_distribution(uint* id_array, ++ uint id_length, ++ uint* distribution, ++ uint distribution_length) { ++ // Quick check to see if we won't succeed. ++ if (id_length < distribution_length) { ++ return false; ++ } ++ // Assign processor ids to the distribution. ++ // Try to shuffle processors to distribute work across boards, ++ // assuming 4 processors per board. ++ const uint processors_per_board = ProcessDistributionStride; ++ // Find the maximum processor id. ++ uint max_id = 0; ++ for (uint m = 0; m < id_length; m += 1) { ++ max_id = MAX2(max_id, id_array[m]); ++ } ++ // The next id, to limit loops. ++ const uint limit_id = max_id + 1; ++ // Make up markers for available processors. ++ bool* available_id = NEW_C_HEAP_ARRAY(bool, limit_id, mtInternal); ++ for (uint c = 0; c < limit_id; c += 1) { ++ available_id[c] = false; ++ } ++ for (uint a = 0; a < id_length; a += 1) { ++ available_id[id_array[a]] = true; ++ } ++ // Step by "boards", then by "slot", copying to "assigned". ++ // NEEDS_CLEANUP: The assignment of processors should be stateful, ++ // remembering which processors have been assigned by ++ // previous calls, etc., so as to distribute several ++ // independent calls of this method. What we'd like is ++ // It would be nice to have an API that let us ask ++ // how many processes are bound to a processor, ++ // but we don't have that, either. ++ // In the short term, "board" is static so that ++ // subsequent distributions don't all start at board 0. ++ static uint board = 0; ++ uint assigned = 0; ++ // Until we've found enough processors .... ++ while (assigned < distribution_length) { ++ // ... find the next available processor in the board. ++ for (uint slot = 0; slot < processors_per_board; slot += 1) { ++ uint try_id = board * processors_per_board + slot; ++ if ((try_id < limit_id) && (available_id[try_id] == true)) { ++ distribution[assigned] = try_id; ++ available_id[try_id] = false; ++ assigned += 1; ++ break; ++ } ++ } ++ board += 1; ++ if (board * processors_per_board + 0 >= limit_id) { ++ board = 0; ++ } ++ } ++ if (available_id != NULL) { ++ FREE_C_HEAP_ARRAY(bool, available_id, mtInternal); ++ } ++ return true; ++} ++ + bool os::distribute_processes(uint length, uint* distribution) { +- // Not yet implemented. ++ ++ cpu_set_t cpu_set; ++ ++ int result = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpu_set); ++ ++ if (result == 0) { ++ ++ uint cpu_ids_length; ++ uint *cpu_ids; ++ uint cpu_ids_found = 0; ++ ++ cpu_ids_length = CPU_COUNT(&cpu_set); ++ ++ cpu_ids = NEW_C_HEAP_ARRAY(uint, cpu_ids_length, mtInternal); ++ ++ for (uint i = 0; i < CPU_SETSIZE && cpu_ids_found < cpu_ids_length; i++) { ++ if (CPU_ISSET(i, &cpu_set)) { ++ cpu_ids[cpu_ids_found] = i; ++ cpu_ids_found++; ++ } ++ } ++ bool result = assign_distribution(cpu_ids, cpu_ids_length, distribution, length); ++ ++ FREE_C_HEAP_ARRAY(uint, cpu_ids, mtInternal); ++ ++ return result; ++ } + return false; + } + + bool os::bind_to_processor(uint processor_id) { +- // Not yet implemented. +- return false; ++ cpu_set_t cpu_set; ++ CPU_ZERO(&cpu_set); ++ CPU_SET(processor_id, &cpu_set); ++ pthread_t current_thread = pthread_self(); ++ int result = pthread_setaffinity_np(current_thread, sizeof(cpu_set), &cpu_set); ++ return result; + } + + ///
--- a/series Tue Jul 24 10:09:03 2012 +0200 +++ b/series Mon Jul 30 13:57:49 2012 +0200 @@ -1,1 +1,6 @@ linux_thread_name.patch +hotspot.patch +zero-makefile.patch +zero-segfault.patch +zero-new-math.patch +psgc-bind-procs.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zero-makefile.patch Mon Jul 30 13:57:49 2012 +0200 @@ -0,0 +1,36 @@ +# HG changeset patch +# Parent db2aaabd9e401399bd8e426afb67608e87d352cd +diff --git a/make/Makefile b/make/Makefile +--- a/make/Makefile ++++ b/make/Makefile +@@ -402,14 +402,30 @@ + ifeq ($(JVM_VARIANT_ZEROSHARK), true) + $(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX) + $(install-file) ++ $(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo): $(SHARK_DIR)/%.debuginfo ++ $(install-file) ++ $(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(SHARK_DIR)/%.diz ++ $(install-file) + $(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX) + $(install-file) ++ $(EXPORT_SERVER_DIR)/%.debuginfo: $(SHARK_DIR)/%.debuginfo ++ $(install-file) ++ $(EXPORT_SERVER_DIR)/%.diz: $(SHARK_DIR)/%.diz ++ $(install-file) + endif + ifeq ($(JVM_VARIANT_ZERO), true) + $(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX) + $(install-file) ++ $(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(ZERO_DIR)/%.debuginfo ++ $(install-file) ++ $(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(ZERO_DIR)/%.diz ++ $(install-file) + $(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX) + $(install-file) ++ $(EXPORT_SERVER_DIR)/%.debuginfo: $(ZERO_DIR)/%.debuginfo ++ $(install-file) ++ $(EXPORT_SERVER_DIR)/%.diz: $(ZERO_DIR)/%.diz ++ $(install-file) + endif + endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zero-new-math.patch Mon Jul 30 13:57:49 2012 +0200 @@ -0,0 +1,26 @@ +# HG changeset patch +# Parent dbe08e8d5dca671e570718f04b0e6f6be5afc02d +diff --git a/src/cpu/zero/vm/cppInterpreter_zero.cpp b/src/cpu/zero/vm/cppInterpreter_zero.cpp +--- a/src/cpu/zero/vm/cppInterpreter_zero.cpp ++++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp +@@ -1714,6 +1714,8 @@ + case Interpreter::java_lang_math_log: + case Interpreter::java_lang_math_log10: + case Interpreter::java_lang_math_sqrt: ++ case Interpreter::java_lang_math_pow: ++ case Interpreter::java_lang_math_exp: + entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind); + break; + +diff --git a/src/share/vm/interpreter/cppInterpreter.cpp b/src/share/vm/interpreter/cppInterpreter.cpp +--- a/src/share/vm/interpreter/cppInterpreter.cpp ++++ b/src/share/vm/interpreter/cppInterpreter.cpp +@@ -125,6 +125,8 @@ + method_entry(java_lang_math_sqrt ); + method_entry(java_lang_math_log ); + method_entry(java_lang_math_log10 ); ++ method_entry(java_lang_math_pow ); ++ method_entry(java_lang_math_exp ); + method_entry(java_lang_ref_reference_get); + Interpreter::_native_entry_begin = Interpreter::code()->code_end(); + method_entry(native);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zero-segfault.patch Mon Jul 30 13:57:49 2012 +0200 @@ -0,0 +1,14 @@ +# HG changeset patch +# Parent bbe0f6e46610f23cf483e928e5d30558364e03c3 +diff --git a/src/share/vm/asm/codeBuffer.cpp b/src/share/vm/asm/codeBuffer.cpp +--- a/src/share/vm/asm/codeBuffer.cpp ++++ b/src/share/vm/asm/codeBuffer.cpp +@@ -674,7 +674,7 @@ + } + } + +- if (dest->blob() == NULL) { ++ if (dest->blob() == NULL && dest_filled != 0x0) { + // Destination is a final resting place, not just another buffer. + // Normalize uninitialized bytes in the final padding. + Copy::fill_to_bytes(dest_filled, dest_end - dest_filled,