Mercurial > people > rkennke > hotspot-comp-zero > hotspot > .hg > patches
changeset 4:df468965b6f6 default tip
Merged zero with upstream changes, fixes jtreg tests.
author | Roman Kennke <rkennke@redhat.com> |
---|---|
date | Wed, 10 Oct 2012 12:14:29 +0200 |
parents | 9b527bc96254 |
children | |
files | hotspot-zero.patch hotspot.patch mergejdk8.patch series zero-makefile.patch zero-meth.patch zero-new-math.patch zero-segfault.patch |
diffstat | 8 files changed, 1420 insertions(+), 2516 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot-zero.patch Wed Oct 10 12:14:29 2012 +0200 @@ -0,0 +1,1419 @@ +# HG changeset patch +# Parent 7482c7f6081469eedf7d27de17aa5385a4a5006c + +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 + +diff --git a/src/cpu/zero/vm/copy_zero.hpp b/src/cpu/zero/vm/copy_zero.hpp +--- a/src/cpu/zero/vm/copy_zero.hpp ++++ b/src/cpu/zero/vm/copy_zero.hpp +@@ -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 --git a/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp b/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp +--- a/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp ++++ b/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp +@@ -31,12 +31,17 @@ + return _masm; + } + +- protected: +- address generate_entry(address entry_point) { +- ZeroEntry *entry = (ZeroEntry *) assembler()->pc(); +- assembler()->advance(sizeof(ZeroEntry)); ++ public: ++ static address generate_entry_impl(MacroAssembler* masm, address entry_point) { ++ ZeroEntry *entry = (ZeroEntry *) masm->pc(); ++ masm->advance(sizeof(ZeroEntry)); + entry->set_entry_point(entry_point); + return (address) entry; + } + ++ protected: ++ address generate_entry(address entry_point) { ++ return generate_entry_impl(assembler(), entry_point); ++ } ++ + #endif // CPU_ZERO_VM_CPPINTERPRETERGENERATOR_ZERO_HPP +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 +@@ -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" +@@ -180,25 +181,6 @@ + method, istate->osr_entry(), istate->osr_buf(), THREAD); + return; + } +- else if (istate->msg() == BytecodeInterpreter::call_method_handle) { +- oop method_handle = istate->callee(); +- +- // Trim back the stack to put the parameters at the top +- stack->set_sp(istate->stack() + 1); +- +- // Make the call +- process_method_handle(method_handle, THREAD); +- fixup_after_potential_safepoint(); +- +- // Convert the result +- istate->set_stack(stack->sp() - 1); +- +- // Restore the stack +- stack->set_sp(istate->stack_limit() + 1); +- +- // Resume the interpreter +- istate->set_msg(BytecodeInterpreter::method_resume); +- } + else { + ShouldNotReachHere(); + } +@@ -535,35 +517,35 @@ + if (entry->is_volatile()) { + switch (entry->flag_state()) { + case ctos: +- SET_LOCALS_INT(object->char_field_acquire(entry->f2()), 0); ++ SET_LOCALS_INT(object->char_field_acquire(entry->f2_as_index()), 0); + break; + + case btos: +- SET_LOCALS_INT(object->byte_field_acquire(entry->f2()), 0); ++ SET_LOCALS_INT(object->byte_field_acquire(entry->f2_as_index()), 0); + break; + + case stos: +- SET_LOCALS_INT(object->short_field_acquire(entry->f2()), 0); ++ SET_LOCALS_INT(object->short_field_acquire(entry->f2_as_index()), 0); + break; + + case itos: +- SET_LOCALS_INT(object->int_field_acquire(entry->f2()), 0); ++ SET_LOCALS_INT(object->int_field_acquire(entry->f2_as_index()), 0); + break; + + case ltos: +- SET_LOCALS_LONG(object->long_field_acquire(entry->f2()), 0); ++ SET_LOCALS_LONG(object->long_field_acquire(entry->f2_as_index()), 0); + break; + + case ftos: +- SET_LOCALS_FLOAT(object->float_field_acquire(entry->f2()), 0); ++ SET_LOCALS_FLOAT(object->float_field_acquire(entry->f2_as_index()), 0); + break; + + case dtos: +- SET_LOCALS_DOUBLE(object->double_field_acquire(entry->f2()), 0); ++ SET_LOCALS_DOUBLE(object->double_field_acquire(entry->f2_as_index()), 0); + break; + + case atos: +- SET_LOCALS_OBJECT(object->obj_field_acquire(entry->f2()), 0); ++ SET_LOCALS_OBJECT(object->obj_field_acquire(entry->f2_as_index()), 0); + break; + + default: +@@ -573,35 +555,35 @@ + else { + switch (entry->flag_state()) { + case ctos: +- SET_LOCALS_INT(object->char_field(entry->f2()), 0); ++ SET_LOCALS_INT(object->char_field(entry->f2_as_index()), 0); + break; + + case btos: +- SET_LOCALS_INT(object->byte_field(entry->f2()), 0); ++ SET_LOCALS_INT(object->byte_field(entry->f2_as_index()), 0); + break; + + case stos: +- SET_LOCALS_INT(object->short_field(entry->f2()), 0); ++ SET_LOCALS_INT(object->short_field(entry->f2_as_index()), 0); + break; + + case itos: +- SET_LOCALS_INT(object->int_field(entry->f2()), 0); ++ SET_LOCALS_INT(object->int_field(entry->f2_as_index()), 0); + break; + + case ltos: +- SET_LOCALS_LONG(object->long_field(entry->f2()), 0); ++ SET_LOCALS_LONG(object->long_field(entry->f2_as_index()), 0); + break; + + case ftos: +- SET_LOCALS_FLOAT(object->float_field(entry->f2()), 0); ++ SET_LOCALS_FLOAT(object->float_field(entry->f2_as_index()), 0); + break; + + case dtos: +- SET_LOCALS_DOUBLE(object->double_field(entry->f2()), 0); ++ SET_LOCALS_DOUBLE(object->double_field(entry->f2_as_index()), 0); + break; + + case atos: +- SET_LOCALS_OBJECT(object->obj_field(entry->f2()), 0); ++ SET_LOCALS_OBJECT(object->obj_field(entry->f2_as_index()), 0); + break; + + default: +@@ -629,516 +611,6 @@ + return 0; + } + +-int CppInterpreter::method_handle_entry(Method* method, +- intptr_t UNUSED, TRAPS) { +- JavaThread *thread = (JavaThread *) THREAD; +- ZeroStack *stack = thread->zero_stack(); +- int argument_slots = method->size_of_parameters(); +- int result_slots = type2size[result_type_of(method)]; +- intptr_t *vmslots = stack->sp(); +- intptr_t *unwind_sp = vmslots + argument_slots; +- +- // Find the MethodType +- address p = (address) method; +- for (jint* pc = method->method_type_offsets_chain(); (*pc) != -1; pc++) { +- p = *(address*)(p + (*pc)); +- } +- oop method_type = (oop) p; +- +- // The MethodHandle is in the slot after the arguments +- int num_vmslots = argument_slots - 1; +- oop method_handle = VMSLOTS_OBJECT(num_vmslots); +- +- // InvokeGeneric requires some extra shuffling +- oop mhtype = java_lang_invoke_MethodHandle::type(method_handle); +- bool is_exact = mhtype == method_type; +- if (!is_exact) { +- if (true || // FIXME +- method->intrinsic_id() == vmIntrinsics::_invokeExact) { +- CALL_VM_NOCHECK_NOFIX( +- SharedRuntime::throw_WrongMethodTypeException( +- thread, method_type, mhtype)); +- // NB all oops trashed! +- assert(HAS_PENDING_EXCEPTION, "should do"); +- stack->set_sp(unwind_sp); +- return 0; +- } +- assert(method->intrinsic_id() == vmIntrinsics::_invokeGeneric, "should be"); +- +- // Load up an adapter from the calling type +- // NB the x86 code for this (in methodHandles_x86.cpp, search for +- // "genericInvoker") is really really odd. I'm hoping it's trying +- // to accomodate odd VM/class library combinations I can ignore. +- oop adapter = NULL; //FIXME: load the adapter from the CP cache +- IF (adapter == NULL) { +- CALL_VM_NOCHECK_NOFIX( +- SharedRuntime::throw_WrongMethodTypeException( +- thread, method_type, mhtype)); +- // NB all oops trashed! +- assert(HAS_PENDING_EXCEPTION, "should do"); +- stack->set_sp(unwind_sp); +- return 0; +- } +- +- // Adapters are shared among form-families of method-type. The +- // type being called is passed as a trusted first argument so that +- // the adapter knows the actual types of its arguments and return +- // values. +- insert_vmslots(num_vmslots + 1, 1, THREAD); +- if (HAS_PENDING_EXCEPTION) { +- // NB all oops trashed! +- stack->set_sp(unwind_sp); +- return 0; +- } +- +- vmslots = stack->sp(); +- num_vmslots++; +- SET_VMSLOTS_OBJECT(method_type, num_vmslots); +- +- method_handle = adapter; +- } +- +- // Start processing +- process_method_handle(method_handle, THREAD); +- if (HAS_PENDING_EXCEPTION) +- result_slots = 0; +- +- // If this is an invokeExact then the eventual callee will not +- // have unwound the method handle argument so we have to do it. +- // If a result is being returned the it will be above the method +- // handle argument we're unwinding. +- if (is_exact) { +- intptr_t result[2]; +- for (int i = 0; i < result_slots; i++) +- result[i] = stack->pop(); +- stack->pop(); +- for (int i = result_slots - 1; i >= 0; i--) +- stack->push(result[i]); +- } +- +- // Check +- assert(stack->sp() == unwind_sp - result_slots, "should be"); +- +- // No deoptimized frames on the stack +- return 0; +-} +- +-void CppInterpreter::process_method_handle(oop method_handle, TRAPS) { +- JavaThread *thread = (JavaThread *) THREAD; +- ZeroStack *stack = thread->zero_stack(); +- intptr_t *vmslots = stack->sp(); +- +- bool direct_to_method = false; +- BasicType src_rtype = T_ILLEGAL; +- BasicType dst_rtype = T_ILLEGAL; +- +- MethodHandleEntry *entry = +- java_lang_invoke_MethodHandle::vmentry(method_handle); +- MethodHandles::EntryKind entry_kind = +- (MethodHandles::EntryKind) (((intptr_t) entry) & 0xffffffff); +- +- Method* method = NULL; +- switch (entry_kind) { +- case MethodHandles::_invokestatic_mh: +- direct_to_method = true; +- break; +- +- case MethodHandles::_invokespecial_mh: +- case MethodHandles::_invokevirtual_mh: +- case MethodHandles::_invokeinterface_mh: +- { +- oop receiver = +- VMSLOTS_OBJECT( +- java_lang_invoke_MethodHandle::vmslots(method_handle) - 1); +- if (receiver == NULL) { +- 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; +- } +- if (entry_kind != MethodHandles::_invokespecial_mh) { +- intptr_t index = java_lang_invoke_DirectMethodHandle::vmindex(method_handle); +- InstanceKlass* rcvrKlass = +- (InstanceKlass *) receiver->klass(); +- if (entry_kind == MethodHandles::_invokevirtual_mh) { +- method = (Method*) rcvrKlass->start_of_vtable()[index]; +- } +- else { +- oop iclass = java_lang_invoke_MethodHandle::next_target(method_handle); +- itableOffsetEntry* ki = +- (itableOffsetEntry *) rcvrKlass->start_of_itable(); +- int i, length = rcvrKlass->itable_length(); +- for (i = 0; i < length; i++, ki++ ) { +- if (ki->interface_klass() == iclass) +- break; +- } +- if (i == length) { +- stack->set_sp(calculate_unwind_sp(stack, method_handle)); +- CALL_VM_NOCHECK_NOFIX( +- throw_exception( +- thread, vmSymbols::java_lang_IncompatibleClassChangeError())); +- // NB all oops trashed! +- assert(HAS_PENDING_EXCEPTION, "should do"); +- return; +- } +- itableMethodEntry* im = ki->first_method_entry(receiver->klass()); +- method = im[index].method(); +- if (method == NULL) { +- stack->set_sp(calculate_unwind_sp(stack, method_handle)); +- CALL_VM_NOCHECK_NOFIX( +- throw_exception( +- thread, vmSymbols::java_lang_AbstractMethodError())); +- // NB all oops trashed! +- assert(HAS_PENDING_EXCEPTION, "should do"); +- return; +- } +- } +- } +- } +- direct_to_method = true; +- break; +- +- case MethodHandles::_bound_ref_direct_mh: +- case MethodHandles::_bound_int_direct_mh: +- case MethodHandles::_bound_long_direct_mh: +- direct_to_method = true; +- // fall through +- case MethodHandles::_bound_ref_mh: +- 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); +- int arg_slot = +- java_lang_invoke_BoundMethodHandle::vmargslot(method_handle); +- +- // Create the new slot(s) +- intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle); +- insert_vmslots(arg_slot, arg_slots, THREAD); +- if (HAS_PENDING_EXCEPTION) { +- // all oops trashed +- stack->set_sp(unwind_sp); +- return; +- } +- vmslots = stack->sp(); +- +- // Store bound argument into new stack slot +- oop arg = java_lang_invoke_BoundMethodHandle::argument(method_handle); +- if (arg_type == T_OBJECT) { +- assert(arg_slots == 1, "should be"); +- SET_VMSLOTS_OBJECT(arg, arg_slot); +- } +- else { +- jvalue arg_value; +- arg_type = java_lang_boxing_object::get_value(arg, &arg_value); +- switch (arg_type) { +- case T_BOOLEAN: +- SET_VMSLOTS_INT(arg_value.z, arg_slot); +- break; +- case T_CHAR: +- SET_VMSLOTS_INT(arg_value.c, arg_slot); +- break; +- case T_BYTE: +- SET_VMSLOTS_INT(arg_value.b, arg_slot); +- break; +- case T_SHORT: +- SET_VMSLOTS_INT(arg_value.s, arg_slot); +- break; +- case T_INT: +- SET_VMSLOTS_INT(arg_value.i, arg_slot); +- break; +- case T_FLOAT: +- SET_VMSLOTS_FLOAT(arg_value.f, arg_slot); +- break; +- case T_LONG: +- SET_VMSLOTS_LONG(arg_value.j, arg_slot + 1); +- break; +- case T_DOUBLE: +- SET_VMSLOTS_DOUBLE(arg_value.d, arg_slot + 1); +- break; +- default: +- tty->print_cr("unhandled type %s", type2name(arg_type)); +- ShouldNotReachHere(); +- } +- } +- } +- break; +- +- case MethodHandles::_adapter_retype_only: +- case MethodHandles::_adapter_retype_raw: +- src_rtype = result_type_of_handle( +- java_lang_invoke_MethodHandle::next_target(method_handle)); +- dst_rtype = result_type_of_handle(method_handle); +- break; +- +- case MethodHandles::_adapter_check_cast: +- { +- int arg_slot = +- java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); +- oop arg = VMSLOTS_OBJECT(arg_slot); +- if (arg != NULL) { +- Klass* objKlassOop = arg->klass(); +- Klass* klassOf = java_lang_Class::as_Klass( +- java_lang_invoke_AdapterMethodHandle::argument(method_handle)); +- +- if (objKlassOop != klassOf && +- !objKlassOop->is_subtype_of(klassOf)) { +- 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; +- } +- } +- } +- break; +- +- case MethodHandles::_adapter_dup_args: +- { +- int arg_slot = +- java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); +- int conv = +- java_lang_invoke_AdapterMethodHandle::conversion(method_handle); +- int num_slots = -MethodHandles::adapter_conversion_stack_move(conv); +- assert(num_slots > 0, "should be"); +- +- // Create the new slot(s) +- intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle); +- stack->overflow_check(num_slots, THREAD); +- if (HAS_PENDING_EXCEPTION) { +- // all oops trashed +- stack->set_sp(unwind_sp); +- return; +- } +- +- // Duplicate the arguments +- for (int i = num_slots - 1; i >= 0; i--) +- stack->push(*VMSLOTS_SLOT(arg_slot + i)); +- +- vmslots = stack->sp(); // unused, but let the compiler figure that out +- } +- break; +- +- case MethodHandles::_adapter_drop_args: +- { +- int arg_slot = +- java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); +- int conv = +- java_lang_invoke_AdapterMethodHandle::conversion(method_handle); +- int num_slots = MethodHandles::adapter_conversion_stack_move(conv); +- assert(num_slots > 0, "should be"); +- +- remove_vmslots(arg_slot, num_slots, THREAD); // doesn't trap +- vmslots = stack->sp(); // unused, but let the compiler figure that out +- } +- break; +- +- case MethodHandles::_adapter_opt_swap_1: +- case MethodHandles::_adapter_opt_swap_2: +- case MethodHandles::_adapter_opt_rot_1_up: +- case MethodHandles::_adapter_opt_rot_1_down: +- case MethodHandles::_adapter_opt_rot_2_up: +- case MethodHandles::_adapter_opt_rot_2_down: +- { +- int arg1 = +- java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); +- int conv = +- 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; +- +- intptr_t tmp; +- switch (rotate) { +- case 0: // swap +- for (int i = 0; i < swap_slots; i++) { +- tmp = *VMSLOTS_SLOT(arg1 + i); +- SET_VMSLOTS_SLOT(VMSLOTS_SLOT(arg2 + i), arg1 + i); +- SET_VMSLOTS_SLOT(&tmp, arg2 + i); +- } +- break; +- +- case 1: // up +- assert(arg1 - swap_slots > arg2, "should be"); +- +- tmp = *VMSLOTS_SLOT(arg1); +- for (int i = arg1 - swap_slots; i >= arg2; i--) +- SET_VMSLOTS_SLOT(VMSLOTS_SLOT(i), i + swap_slots); +- SET_VMSLOTS_SLOT(&tmp, arg2); +- +- break; +- +- case -1: // down +- assert(arg2 - swap_slots > arg1, "should be"); +- +- tmp = *VMSLOTS_SLOT(arg1); +- for (int i = arg1 + swap_slots; i <= arg2; i++) +- SET_VMSLOTS_SLOT(VMSLOTS_SLOT(i), i - swap_slots); +- SET_VMSLOTS_SLOT(&tmp, arg2); +- break; +- +- default: +- ShouldNotReachHere(); +- } +- } +- break; +- +- case MethodHandles::_adapter_opt_i2l: +- { +- int arg_slot = +- java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); +- int arg = VMSLOTS_INT(arg_slot); +- intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle); +- insert_vmslots(arg_slot, 1, THREAD); +- if (HAS_PENDING_EXCEPTION) { +- // all oops trashed +- stack->set_sp(unwind_sp); +- return; +- } +- vmslots = stack->sp(); +- arg_slot++; +- SET_VMSLOTS_LONG(arg, arg_slot); +- } +- break; +- +- case MethodHandles::_adapter_opt_unboxi: +- case MethodHandles::_adapter_opt_unboxl: +- { +- int arg_slot = +- java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); +- oop arg = VMSLOTS_OBJECT(arg_slot); +- jvalue arg_value; +- if (arg == NULL) { +- // 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; +- } +- BasicType arg_type = java_lang_boxing_object::get_value(arg, &arg_value); +- if (arg_type == T_LONG || arg_type == T_DOUBLE) { +- intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle); +- insert_vmslots(arg_slot, 1, THREAD); +- if (HAS_PENDING_EXCEPTION) { +- // all oops trashed +- stack->set_sp(unwind_sp); +- return; +- } +- vmslots = stack->sp(); +- arg_slot++; +- } +- switch (arg_type) { +- case T_BOOLEAN: +- SET_VMSLOTS_INT(arg_value.z, arg_slot); +- break; +- case T_CHAR: +- SET_VMSLOTS_INT(arg_value.c, arg_slot); +- break; +- case T_BYTE: +- SET_VMSLOTS_INT(arg_value.b, arg_slot); +- break; +- case T_SHORT: +- SET_VMSLOTS_INT(arg_value.s, arg_slot); +- break; +- case T_INT: +- SET_VMSLOTS_INT(arg_value.i, arg_slot); +- break; +- case T_FLOAT: +- SET_VMSLOTS_FLOAT(arg_value.f, arg_slot); +- break; +- case T_LONG: +- SET_VMSLOTS_LONG(arg_value.j, arg_slot); +- break; +- case T_DOUBLE: +- SET_VMSLOTS_DOUBLE(arg_value.d, arg_slot); +- break; +- default: +- tty->print_cr("unhandled type %s", type2name(arg_type)); +- ShouldNotReachHere(); +- } +- } +- break; +- +- default: +- tty->print_cr("unhandled entry_kind %s", +- MethodHandles::entry_name(entry_kind)); +- ShouldNotReachHere(); +- } +- +- // Continue along the chain +- if (direct_to_method) { +- if (method == NULL) { +- method = +- (Method*) java_lang_invoke_MethodHandle::vmtarget(method_handle); +- } +- address entry_point = method->from_interpreted_entry(); +- Interpreter::invoke_method(method, entry_point, THREAD); +- } +- else { +- process_method_handle( +- java_lang_invoke_MethodHandle::next_target(method_handle), THREAD); +- } +- // NB all oops now trashed +- +- // Adapt the result type, if necessary +- if (src_rtype != dst_rtype && !HAS_PENDING_EXCEPTION) { +- switch (dst_rtype) { +- case T_VOID: +- for (int i = 0; i < type2size[src_rtype]; i++) +- stack->pop(); +- return; +- +- case T_INT: +- switch (src_rtype) { +- case T_VOID: +- stack->overflow_check(1, CHECK); +- stack->push(0); +- return; +- +- case T_BOOLEAN: +- case T_CHAR: +- case T_BYTE: +- case T_SHORT: +- return; +- } +- // INT results sometimes need narrowing +- case T_BOOLEAN: +- case T_CHAR: +- case T_BYTE: +- case T_SHORT: +- switch (src_rtype) { +- case T_INT: +- return; +- } +- } +- +- tty->print_cr("unhandled conversion:"); +- tty->print_cr("src_rtype = %s", type2name(src_rtype)); +- tty->print_cr("dst_rtype = %s", type2name(dst_rtype)); +- ShouldNotReachHere(); +- } +-} +- + // The new slots will be inserted before slot insert_before. + // Slots < insert_before will have the same slot number after the insert. + // Slots >= insert_before will become old_slot + num_slots. +@@ -1380,10 +852,6 @@ + entry_point = ((InterpreterGenerator*) this)->generate_abstract_entry(); + break; + +- case Interpreter::method_handle: +- entry_point = ((InterpreterGenerator*) this)->generate_method_handle_entry(); +- break; +- + case Interpreter::java_lang_math_sin: + case Interpreter::java_lang_math_cos: + case Interpreter::java_lang_math_tan: +@@ -1391,6 +859,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/cpu/zero/vm/cppInterpreter_zero.hpp b/src/cpu/zero/vm/cppInterpreter_zero.hpp +--- a/src/cpu/zero/vm/cppInterpreter_zero.hpp ++++ b/src/cpu/zero/vm/cppInterpreter_zero.hpp +@@ -36,7 +36,6 @@ + static int native_entry(Method* method, intptr_t UNUSED, TRAPS); + static int accessor_entry(Method* method, intptr_t UNUSED, TRAPS); + static int empty_entry(Method* method, intptr_t UNUSED, TRAPS); +- static int method_handle_entry(Method* method, intptr_t UNUSED, TRAPS); + + public: + // Main loop of normal_entry +@@ -44,7 +43,6 @@ + + private: + // Helpers for method_handle_entry +- static void process_method_handle(oop method_handle, TRAPS); + static void insert_vmslots(int insert_before, int num_slots, TRAPS); + static void remove_vmslots(int first_slot, int num_slots, TRAPS); + static BasicType result_type_of_handle(oop method_handle); +diff --git a/src/cpu/zero/vm/frame_zero.cpp b/src/cpu/zero/vm/frame_zero.cpp +--- a/src/cpu/zero/vm/frame_zero.cpp ++++ b/src/cpu/zero/vm/frame_zero.cpp +@@ -351,7 +351,7 @@ + switch (offset) { + case pc_off: + strncpy(fieldbuf, "pc", buflen); +- if (method()->is_oop()) { ++ if (method()->is_method()) { + nmethod *code = method()->code(); + if (code && code->pc_desc_at(pc())) { + SimpleScopeDesc ssd(code, pc()); +@@ -367,7 +367,7 @@ + + case method_off: + strncpy(fieldbuf, "method", buflen); +- if (method()->is_oop()) { ++ if (method()->is_method()) { + method()->name_and_sig_as_C_string(valuebuf, buflen); + } + return; +@@ -378,7 +378,7 @@ + } + + // Variable part +- if (method()->is_oop()) { ++ if (method()->is_method()) { + identify_vp_word(frame_index, addr_of_word(offset), + addr_of_word(header_words + 1), + unextended_sp() + method()->max_stack(), +diff --git a/src/cpu/zero/vm/frame_zero.inline.hpp b/src/cpu/zero/vm/frame_zero.inline.hpp +--- a/src/cpu/zero/vm/frame_zero.inline.hpp ++++ b/src/cpu/zero/vm/frame_zero.inline.hpp +@@ -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 --git a/src/cpu/zero/vm/icBuffer_zero.cpp b/src/cpu/zero/vm/icBuffer_zero.cpp +--- a/src/cpu/zero/vm/icBuffer_zero.cpp ++++ b/src/cpu/zero/vm/icBuffer_zero.cpp +@@ -40,7 +40,7 @@ + } + + void InlineCacheBuffer::assemble_ic_buffer_code(address code_begin, +- Metadata* cached_oop, ++ void* cached_oop, + address entry_point) { + // NB ic_stub_code_size() must return the size of the code we generate + ShouldNotCallThis(); +@@ -51,7 +51,6 @@ + ShouldNotCallThis(); + } + +-Metadata* InlineCacheBuffer::ic_buffer_cached_oop(address code_begin) { +- // NB ic_stub_code_size() must return the size of the code we generate ++void* InlineCacheBuffer::ic_buffer_cached_value(address code_begin) { + ShouldNotCallThis(); + } +diff --git a/src/cpu/zero/vm/methodHandles_zero.cpp b/src/cpu/zero/vm/methodHandles_zero.cpp +--- a/src/cpu/zero/vm/methodHandles_zero.cpp ++++ b/src/cpu/zero/vm/methodHandles_zero.cpp +@@ -24,26 +24,159 @@ + */ + + #include "precompiled.hpp" ++#include "interpreter/interpreterGenerator.hpp" + #include "interpreter/interpreter.hpp" + #include "memory/allocation.inline.hpp" + #include "prims/methodHandles.hpp" + +-int MethodHandles::adapter_conversion_ops_supported_mask() { +- return ((1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY) +- |(1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW) +- |(1<<java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST) +- |(1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM) +- |(1<<java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM) +- |(1<<java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS) +- |(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! +- ); +- // FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS. ++void MethodHandles::invoke_target(Method* method, TRAPS) { ++ ++ JavaThread *thread = (JavaThread *) THREAD; ++ ZeroStack *stack = thread->zero_stack(); ++ InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); ++ interpreterState istate = frame->interpreter_state(); ++ ++ // Trim back the stack to put the parameters at the top ++ stack->set_sp(istate->stack() + 1); ++ ++ Interpreter::invoke_method(method, method->from_interpreted_entry(), THREAD); ++ ++ // Convert the result ++ istate->set_stack(stack->sp() - 1); ++ + } + +-void MethodHandles::generate_method_handle_stub(MacroAssembler* masm, +- MethodHandles::EntryKind ek) { +- init_entry(ek, (MethodHandleEntry *) ek); ++oop MethodHandles::popFromStack(TRAPS) { ++ ++ JavaThread *thread = (JavaThread *) THREAD; ++ InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); ++ interpreterState istate = frame->interpreter_state(); ++ intptr_t* topOfStack = istate->stack(); ++ ++ oop top = STACK_OBJECT(-1); ++ MORE_STACK(-1); ++ istate->set_stack(topOfStack); ++ ++ return top; ++ + } ++ ++int MethodHandles::method_handle_entry_invokeBasic(Method* method, intptr_t UNUSED, TRAPS) { ++ ++ JavaThread *thread = (JavaThread *) THREAD; ++ InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); ++ interpreterState istate = frame->interpreter_state(); ++ intptr_t* topOfStack = istate->stack(); ++ ++ // 'this' is a MethodHandle. We resolve the target method by accessing this.form.vmentry.vmtarget. ++ int numArgs = method->size_of_parameters(); ++ oop lform1 = java_lang_invoke_MethodHandle::form(STACK_OBJECT(-numArgs)); // this.form ++ oop vmEntry1 = java_lang_invoke_LambdaForm::vmentry(lform1); ++ Method* vmtarget = (Method*) java_lang_invoke_MemberName::vmtarget(vmEntry1); ++ ++ invoke_target(vmtarget, THREAD); ++ ++ // No deoptimized frames on the stack ++ return 0; ++} ++ ++int MethodHandles::method_handle_entry_linkToStaticOrSpecial(Method* method, intptr_t UNUSED, TRAPS) { ++ ++ // Pop appendix argument from stack. This is a MemberName which we resolve to the ++ // target method. ++ oop vmentry = popFromStack(THREAD); ++ ++ Method* vmtarget = (Method*) java_lang_invoke_MemberName::vmtarget(vmentry); ++ ++ invoke_target(vmtarget, THREAD); ++ ++ return 0; ++} ++ ++int MethodHandles::method_handle_entry_linkToInterface(Method* method, intptr_t UNUSED, TRAPS) { ++ JavaThread *thread = (JavaThread *) THREAD; ++ InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); ++ interpreterState istate = frame->interpreter_state(); ++ ++ // Pop appendix argument from stack. This is a MemberName which we resolve to the ++ // target method. ++ oop vmentry = popFromStack(THREAD); ++ intptr_t* topOfStack = istate->stack(); ++ ++ // Resolve target method by looking up in the receiver object's itable. ++ Klass* clazz = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(vmentry)); ++ intptr_t vmindex = java_lang_invoke_MemberName::vmindex(vmentry); ++ Method* target = (Method*) java_lang_invoke_MemberName::vmtarget(vmentry); ++ ++ int numArgs = target->size_of_parameters(); ++ oop recv = STACK_OBJECT(-numArgs); ++ ++ InstanceKlass* klass_part = InstanceKlass::cast(recv->klass()); ++ itableOffsetEntry* ki = (itableOffsetEntry*) klass_part->start_of_itable(); ++ int i; ++ for ( i = 0 ; i < klass_part->itable_length() ; i++, ki++ ) { ++ if (ki->interface_klass() == clazz) break; ++ } ++ ++ itableMethodEntry* im = ki->first_method_entry(recv->klass()); ++ Method* vmtarget = im[vmindex].method(); ++ ++ invoke_target(vmtarget, THREAD); ++ ++ return 0; ++} ++ ++int MethodHandles::method_handle_entry_linkToVirtual(Method* method, intptr_t UNUSED, TRAPS) { ++ JavaThread *thread = (JavaThread *) THREAD; ++ ++ InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); ++ interpreterState istate = frame->interpreter_state(); ++ ++ // Pop appendix argument from stack. This is a MemberName which we resolve to the ++ // target method. ++ oop vmentry = popFromStack(THREAD); ++ intptr_t* topOfStack = istate->stack(); ++ ++ // Resolve target method by looking up in the receiver object's vtable. ++ intptr_t vmindex = java_lang_invoke_MemberName::vmindex(vmentry); ++ Method* target = (Method*) java_lang_invoke_MemberName::vmtarget(vmentry); ++ int numArgs = target->size_of_parameters(); ++ oop recv = STACK_OBJECT(-numArgs); ++ Klass* clazz = recv->klass(); ++ Klass* klass_part = InstanceKlass::cast(clazz); ++ klassVtable* vtable = klass_part->vtable(); ++ Method* vmtarget = vtable->method_at(vmindex); ++ ++ invoke_target(vmtarget, THREAD); ++ ++ return 0; ++} ++ ++int MethodHandles::method_handle_entry_invalid(Method* method, intptr_t UNUSED, TRAPS) { ++ ShouldNotReachHere(); ++ return 0; ++} ++ ++address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* masm, ++ vmIntrinsics::ID iid) { ++ switch (iid) { ++ case vmIntrinsics::_invokeGeneric: ++ case vmIntrinsics::_compiledLambdaForm: ++ // Perhaps surprisingly, the symbolic references visible to Java are not directly used. ++ // They are linked to Java-generated adapters via MethodHandleNatives.linkMethod. ++ // They all allow an appendix argument. ++ return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_invalid); ++ case vmIntrinsics::_invokeBasic: ++ return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_invokeBasic); ++ case vmIntrinsics::_linkToStatic: ++ case vmIntrinsics::_linkToSpecial: ++ return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_linkToStaticOrSpecial); ++ case vmIntrinsics::_linkToInterface: ++ return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_linkToInterface); ++ case vmIntrinsics::_linkToVirtual: ++ return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_linkToVirtual); ++ default: ++ ShouldNotReachHere(); ++ return NULL; ++ } ++} +diff --git a/src/cpu/zero/vm/methodHandles_zero.hpp b/src/cpu/zero/vm/methodHandles_zero.hpp +--- a/src/cpu/zero/vm/methodHandles_zero.hpp ++++ b/src/cpu/zero/vm/methodHandles_zero.hpp +@@ -26,6 +26,14 @@ + + // Adapters + enum /* platform_dependent_constants */ { +- adapter_code_size = 0 ++ adapter_code_size = sizeof(ZeroEntry) * (Interpreter::method_handle_invoke_LAST - Interpreter::method_handle_invoke_FIRST + 1) + }; + ++private: ++ static oop popFromStack(TRAPS); ++ static void invoke_target(Method* method, TRAPS); ++ static int method_handle_entry_invokeBasic(Method* method, intptr_t UNUSED, TRAPS); ++ static int method_handle_entry_linkToStaticOrSpecial(Method* method, intptr_t UNUSED, TRAPS); ++ static int method_handle_entry_linkToVirtual(Method* method, intptr_t UNUSED, TRAPS); ++ static int method_handle_entry_linkToInterface(Method* method, intptr_t UNUSED, TRAPS); ++ static int method_handle_entry_invalid(Method* method, intptr_t UNUSED, TRAPS); +diff --git a/src/cpu/zero/vm/register_zero.hpp b/src/cpu/zero/vm/register_zero.hpp +--- a/src/cpu/zero/vm/register_zero.hpp ++++ b/src/cpu/zero/vm/register_zero.hpp +@@ -114,5 +114,8 @@ + }; + + CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1)); ++#ifndef DONT_USE_REGISTER_DEFINES ++#define noreg ((Register)(noreg_RegisterEnumValue)) ++#endif + + #endif // CPU_ZERO_VM_REGISTER_ZERO_HPP +diff --git a/src/cpu/zero/vm/relocInfo_zero.cpp b/src/cpu/zero/vm/relocInfo_zero.cpp +--- a/src/cpu/zero/vm/relocInfo_zero.cpp ++++ b/src/cpu/zero/vm/relocInfo_zero.cpp +@@ -77,3 +77,7 @@ + CodeBuffer* dst) { + ShouldNotCallThis(); + } ++ ++void metadata_Relocation::pd_fix_value(address x) { ++ ShouldNotCallThis(); ++} +diff --git a/src/cpu/zero/vm/sharedRuntime_zero.cpp b/src/cpu/zero/vm/sharedRuntime_zero.cpp +--- a/src/cpu/zero/vm/sharedRuntime_zero.cpp ++++ b/src/cpu/zero/vm/sharedRuntime_zero.cpp +@@ -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,16 +70,14 @@ + AdapterFingerPrint *fingerprint) { + return AdapterHandlerLibrary::new_entry( + fingerprint, +- ShouldNotCallThisStub(), +- ShouldNotCallThisStub(), +- ShouldNotCallThisStub()); ++ CAST_FROM_FN_PTR(address,zero_null_code_stub), ++ CAST_FROM_FN_PTR(address,zero_null_code_stub), ++ CAST_FROM_FN_PTR(address,zero_null_code_stub)); + } + + nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, + methodHandle method, + int compile_id, +- int total_args_passed, +- int max_arg, + BasicType *sig_bt, + VMRegPair *regs, + BasicType ret_type) { +@@ -96,19 +101,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); + } + + +@@ -116,7 +122,7 @@ + _deopt_blob = generate_empty_deopt_blob(); + } + +-SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause_return) { ++SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_type) { + return generate_empty_safepoint_blob(); + } + +@@ -124,6 +130,7 @@ + return generate_empty_runtime_stub("resolve_blob"); + } + ++ + int SharedRuntime::c_calling_convention(const BasicType *sig_bt, + VMRegPair *regs, + int total_args_passed) { +diff --git a/src/cpu/zero/vm/stubRoutines_zero.hpp b/src/cpu/zero/vm/stubRoutines_zero.hpp +--- a/src/cpu/zero/vm/stubRoutines_zero.hpp ++++ b/src/cpu/zero/vm/stubRoutines_zero.hpp +@@ -40,8 +40,8 @@ + } + + enum platform_dependent_constants { +- code_size1 = 0, // The assembler will fail with a guarantee +- code_size2 = 0 // if these are too small. Simply increase ++ code_size1 = 1, // The assembler will fail with a guarantee ++ code_size2 = 1 // if these are too small. Simply increase + }; // them if that happens. + + enum method_handles_platform_dependent_constants { +diff --git a/src/share/vm/asm/assembler.cpp b/src/share/vm/asm/assembler.cpp +--- a/src/share/vm/asm/assembler.cpp ++++ b/src/share/vm/asm/assembler.cpp +@@ -59,6 +59,7 @@ + _code_section = cs; + _code_begin = cs->start(); + _code_limit = cs->limit(); ++ assert(_code_limit > _code_begin, "no empty code buffer"); + _code_pos = cs->end(); + _oop_recorder= code->oop_recorder(); + DEBUG_ONLY( _short_branch_delta = 0; ) +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 +@@ -758,7 +758,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, +diff --git a/src/share/vm/interpreter/bytecodeInterpreter.cpp b/src/share/vm/interpreter/bytecodeInterpreter.cpp +--- a/src/share/vm/interpreter/bytecodeInterpreter.cpp ++++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp +@@ -235,10 +235,6 @@ + #endif + #endif + +-// JavaStack Implementation +-#define MORE_STACK(count) \ +- (topOfStack -= ((count) * Interpreter::stackElementWords)) +- + + #define UPDATE_PC(opsize) {pc += opsize; } + /* +@@ -575,7 +571,7 @@ + + /* 0xE0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, + /* 0xE4 */ &&opc_default, &&opc_fast_aldc, &&opc_fast_aldc_w, &&opc_return_register_finalizer, +-/* 0xE8 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, ++/* 0xE8 */ &&opc_invokehandle,&&opc_default, &&opc_default, &&opc_default, + /* 0xEC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, + + /* 0xF0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, +@@ -1773,7 +1769,7 @@ + + oop obj; + if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) { +- Klass* k = (Klass*) cache->f1(); ++ Klass* k = cache->f1_as_klass(); + obj = k->java_mirror(); + MORE_STACK(1); // Assume single slot push + } else { +@@ -1885,7 +1881,7 @@ + --count; + } + if ((Bytecodes::Code)opcode == Bytecodes::_putstatic) { +- Klass* k = (Klass*) cache->f1(); ++ Klass* k = cache->f1_as_klass(); + obj = k->java_mirror(); + } else { + --count; +@@ -2190,6 +2186,7 @@ + } + + CASE(_invokedynamic): { ++ + if (!EnableInvokeDynamic) { + // We should not encounter this bytecode if !EnableInvokeDynamic. + // The verifier will stop it. However, if we get past the verifier, +@@ -2199,30 +2196,69 @@ + ShouldNotReachHere(); + } + +- int index = Bytes::get_native_u4(pc+1); ++ u4 index = Bytes::get_native_u4(pc+1); ++ ConstantPoolCacheEntry* cache = cp->constant_pool()->invokedynamic_cp_cache_entry_at(index); + + // We are resolved if the resolved_references field contains a non-null object (CallSite, etc.) + // This kind of CP cache entry does not need to match the flags byte, because + // there is a 1-1 relation between bytecode type and CP entry type. +- ConstantPool* constants = METHOD->constants(); +- oop result = constants->resolved_references()->obj_at(index); +- if (result == NULL) { ++ if (! cache->is_resolved((Bytecodes::Code) opcode)) { + CALL_VM(InterpreterRuntime::resolve_invokedynamic(THREAD), + handle_exception); +- result = THREAD->vm_result(); ++ cache = cp->constant_pool()->invokedynamic_cp_cache_entry_at(index); + } + +- VERIFY_OOP(result); +- oop method_handle = java_lang_invoke_CallSite::target(result); +- CHECK_NULL(method_handle); +- +- istate->set_msg(call_method_handle); +- istate->set_callee((Method*) method_handle); ++ Method* method = cache->f1_as_method(); ++ VERIFY_OOP(method); ++ ++ if (cache->has_appendix()) { ++ ConstantPool* constants = METHOD->constants(); ++ SET_STACK_OBJECT(cache->appendix_if_resolved(constants), 0); ++ MORE_STACK(1); ++ } ++ ++ istate->set_msg(call_method); ++ istate->set_callee(method); ++ istate->set_callee_entry_point(method->from_interpreted_entry()); + istate->set_bcp_advance(5); + + UPDATE_PC_AND_RETURN(0); // I'll be back... + } + ++ CASE(_invokehandle): { ++ ++ if (!EnableInvokeDynamic) { ++ ShouldNotReachHere(); ++ } ++ ++ u2 index = Bytes::get_native_u2(pc+1); ++ ConstantPoolCacheEntry* cache = cp->entry_at(index); ++ ++ if (! cache->is_resolved((Bytecodes::Code) opcode)) { ++ CALL_VM(InterpreterRuntime::resolve_invokehandle(THREAD), ++ handle_exception); ++ cache = cp->entry_at(index); ++ } ++ ++ /* ***************** */ ++ Method* method = cache->f1_as_method(); ++ ++ VERIFY_OOP(method); ++ ++ if (cache->has_appendix()) { ++ ConstantPool* constants = METHOD->constants(); ++ SET_STACK_OBJECT(cache->appendix_if_resolved(constants), 0); ++ MORE_STACK(1); ++ } ++ ++ istate->set_msg(call_method); ++ istate->set_callee(method); ++ istate->set_callee_entry_point(method->from_interpreted_entry()); ++ istate->set_bcp_advance(3); ++ ++ UPDATE_PC_AND_RETURN(0); // I'll be back... ++ } ++ + CASE(_invokeinterface): { + u2 index = Bytes::get_native_u2(pc+1); + +diff --git a/src/share/vm/interpreter/bytecodeInterpreter.hpp b/src/share/vm/interpreter/bytecodeInterpreter.hpp +--- a/src/share/vm/interpreter/bytecodeInterpreter.hpp ++++ b/src/share/vm/interpreter/bytecodeInterpreter.hpp +@@ -50,6 +50,10 @@ + + #ifdef CC_INTERP + ++// JavaStack Implementation ++#define MORE_STACK(count) \ ++ (topOfStack -= ((count) * Interpreter::stackElementWords)) ++ + // CVM definitions find hotspot equivalents... + + union VMJavaVal64 { +@@ -107,7 +111,6 @@ + rethrow_exception, // unwinding and throwing exception + // requests to frame manager from C++ interpreter + call_method, // request for new frame from interpreter, manager responds with method_entry +- call_method_handle, // like the above, except the callee is a method handle + return_from_method, // request from interpreter to unwind, manager responds with method_continue + more_monitors, // need a new monitor + throwing_exception, // unwind stack and rethrow +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 +@@ -117,7 +117,6 @@ + method_entry(empty); + method_entry(accessor); + method_entry(abstract); +- method_entry(method_handle); + method_entry(java_lang_math_sin ); + method_entry(java_lang_math_cos ); + method_entry(java_lang_math_tan ); +@@ -125,6 +124,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); +diff --git a/src/share/vm/interpreter/interpreter.cpp b/src/share/vm/interpreter/interpreter.cpp +--- a/src/share/vm/interpreter/interpreter.cpp ++++ b/src/share/vm/interpreter/interpreter.cpp +@@ -252,7 +252,7 @@ + void AbstractInterpreter::set_entry_for_kind(AbstractInterpreter::MethodKind kind, address entry) { + assert(kind >= method_handle_invoke_FIRST && + kind <= method_handle_invoke_LAST, "late initialization only for MH entry points"); +- assert(_entry_table[kind] == _entry_table[abstract], "previous value must be AME entry"); ++ assert(_entry_table[kind] == NULL || _entry_table[kind] == _entry_table[abstract], "previous value must be AME entry or NULL"); + _entry_table[kind] = entry; + } + +diff --git a/src/share/vm/interpreter/interpreterRuntime.cpp b/src/share/vm/interpreter/interpreterRuntime.cpp +--- a/src/share/vm/interpreter/interpreterRuntime.cpp ++++ b/src/share/vm/interpreter/interpreterRuntime.cpp +@@ -732,7 +732,6 @@ + LinkResolver::resolve_invoke(info, Handle(), pool, + get_index_u2_cpcache(thread, bytecode), bytecode, CHECK); + } // end JvmtiHideSingleStepping +- + cache_entry(thread)->set_method_handle( + pool, + info.resolved_method(), +diff --git a/src/share/vm/runtime/vmStructs.cpp b/src/share/vm/runtime/vmStructs.cpp +--- a/src/share/vm/runtime/vmStructs.cpp ++++ b/src/share/vm/runtime/vmStructs.cpp +@@ -2436,7 +2436,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) \ + \ + /*************/ \ +diff --git a/src/share/vm/shark/sharkCompiler.cpp b/src/share/vm/shark/sharkCompiler.cpp +--- a/src/share/vm/shark/sharkCompiler.cpp ++++ b/src/share/vm/shark/sharkCompiler.cpp +@@ -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; +diff --git a/src/share/vm/utilities/macros.hpp b/src/share/vm/utilities/macros.hpp +--- a/src/share/vm/utilities/macros.hpp ++++ b/src/share/vm/utilities/macros.hpp +@@ -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
--- a/hotspot.patch Fri Oct 05 19:46:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,714 +0,0 @@ -diff --git a/make/linux/platform_zero.in b/make/linux/platform_zero.in ---- a/make/linux/platform_zero.in -+++ b/make/linux/platform_zero.in -@@ -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@\" -diff --git a/src/cpu/zero/vm/assembler_zero.cpp b/src/cpu/zero/vm/assembler_zero.cpp ---- a/src/cpu/zero/vm/assembler_zero.cpp -+++ b/src/cpu/zero/vm/assembler_zero.cpp -@@ -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 --git a/src/cpu/zero/vm/assembler_zero.hpp b/src/cpu/zero/vm/assembler_zero.hpp ---- a/src/cpu/zero/vm/assembler_zero.hpp -+++ b/src/cpu/zero/vm/assembler_zero.hpp -@@ -65,5 +65,6 @@ - - address ShouldNotCallThisStub(); - address ShouldNotCallThisEntry(); -+address ZeroNullStubEntry(address fn); - - #endif // CPU_ZERO_VM_ASSEMBLER_ZERO_HPP -diff --git a/src/cpu/zero/vm/copy_zero.hpp b/src/cpu/zero/vm/copy_zero.hpp ---- a/src/cpu/zero/vm/copy_zero.hpp -+++ b/src/cpu/zero/vm/copy_zero.hpp -@@ -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 --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 -@@ -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,7 @@ - CALL_VM_NOCHECK_NOFIX(func) \ - fixup_after_potential_safepoint() - -+ - int CppInterpreter::normal_entry(Method* method, intptr_t UNUSED, TRAPS) { - JavaThread *thread = (JavaThread *) THREAD; - -@@ -698,6 +700,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) -@@ -717,6 +722,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 -@@ -724,6 +731,7 @@ - } - - void CppInterpreter::process_method_handle(oop method_handle, TRAPS) { -+ - JavaThread *thread = (JavaThread *) THREAD; - ZeroStack *stack = thread->zero_stack(); - intptr_t *vmslots = stack->sp(); -@@ -810,11 +818,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); - -@@ -960,10 +972,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) { -@@ -1079,12 +1094,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) { -@@ -1137,6 +1449,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 --git a/src/cpu/zero/vm/frame_zero.inline.hpp b/src/cpu/zero/vm/frame_zero.inline.hpp ---- a/src/cpu/zero/vm/frame_zero.inline.hpp -+++ b/src/cpu/zero/vm/frame_zero.inline.hpp -@@ -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 --git a/src/cpu/zero/vm/methodHandles_zero.cpp b/src/cpu/zero/vm/methodHandles_zero.cpp ---- a/src/cpu/zero/vm/methodHandles_zero.cpp -+++ b/src/cpu/zero/vm/methodHandles_zero.cpp -@@ -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"); -+} -diff --git a/src/cpu/zero/vm/methodHandles_zero.hpp b/src/cpu/zero/vm/methodHandles_zero.hpp ---- a/src/cpu/zero/vm/methodHandles_zero.hpp -+++ b/src/cpu/zero/vm/methodHandles_zero.hpp -@@ -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); -+ -+}; -diff --git a/src/cpu/zero/vm/sharedRuntime_zero.cpp b/src/cpu/zero/vm/sharedRuntime_zero.cpp ---- a/src/cpu/zero/vm/sharedRuntime_zero.cpp -+++ b/src/cpu/zero/vm/sharedRuntime_zero.cpp -@@ -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) { -diff --git a/src/share/vm/runtime/vmStructs.cpp b/src/share/vm/runtime/vmStructs.cpp ---- a/src/share/vm/runtime/vmStructs.cpp -+++ b/src/share/vm/runtime/vmStructs.cpp -@@ -2436,7 +2436,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) \ - \ - /*************/ \ -diff --git a/src/share/vm/shark/sharkCompiler.cpp b/src/share/vm/shark/sharkCompiler.cpp ---- a/src/share/vm/shark/sharkCompiler.cpp -+++ b/src/share/vm/shark/sharkCompiler.cpp -@@ -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; -diff --git a/src/share/vm/utilities/macros.hpp b/src/share/vm/utilities/macros.hpp ---- a/src/share/vm/utilities/macros.hpp -+++ b/src/share/vm/utilities/macros.hpp -@@ -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
--- a/mergejdk8.patch Fri Oct 05 19:46:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,290 +0,0 @@ -# HG changeset patch -# Parent 9fcf1fcc04b46911fe160042b7a3d6a670488777 -diff --git a/src/cpu/zero/vm/frame_zero.cpp b/src/cpu/zero/vm/frame_zero.cpp ---- a/src/cpu/zero/vm/frame_zero.cpp -+++ b/src/cpu/zero/vm/frame_zero.cpp -@@ -351,7 +351,7 @@ - switch (offset) { - case pc_off: - strncpy(fieldbuf, "pc", buflen); -- if (method()->is_oop()) { -+ if (method()->is_method()) { - nmethod *code = method()->code(); - if (code && code->pc_desc_at(pc())) { - SimpleScopeDesc ssd(code, pc()); -@@ -367,7 +367,7 @@ - - case method_off: - strncpy(fieldbuf, "method", buflen); -- if (method()->is_oop()) { -+ if (method()->is_method()) { - method()->name_and_sig_as_C_string(valuebuf, buflen); - } - return; -@@ -378,7 +378,7 @@ - } - - // Variable part -- if (method()->is_oop()) { -+ if (method()->is_method()) { - identify_vp_word(frame_index, addr_of_word(offset), - addr_of_word(header_words + 1), - unextended_sp() + method()->max_stack(), -diff --git a/src/cpu/zero/vm/icBuffer_zero.cpp b/src/cpu/zero/vm/icBuffer_zero.cpp ---- a/src/cpu/zero/vm/icBuffer_zero.cpp -+++ b/src/cpu/zero/vm/icBuffer_zero.cpp -@@ -40,7 +40,7 @@ - } - - void InlineCacheBuffer::assemble_ic_buffer_code(address code_begin, -- Metadata* cached_oop, -+ void* cached_oop, - address entry_point) { - // NB ic_stub_code_size() must return the size of the code we generate - ShouldNotCallThis(); -@@ -51,7 +51,6 @@ - ShouldNotCallThis(); - } - --Metadata* InlineCacheBuffer::ic_buffer_cached_oop(address code_begin) { -- // NB ic_stub_code_size() must return the size of the code we generate -+void* InlineCacheBuffer::ic_buffer_cached_value(address code_begin) { - ShouldNotCallThis(); - } -diff --git a/src/cpu/zero/vm/methodHandles_zero.cpp b/src/cpu/zero/vm/methodHandles_zero.cpp ---- a/src/cpu/zero/vm/methodHandles_zero.cpp -+++ b/src/cpu/zero/vm/methodHandles_zero.cpp -@@ -42,7 +42,7 @@ - (*exception_offset) = __ pc() - start; - } - --void MethodHandles::invoke_target(methodOop method, TRAPS) { -+void MethodHandles::invoke_target(Method* method, TRAPS) { - - JavaThread *thread = (JavaThread *) THREAD; - ZeroStack *stack = thread->zero_stack(); -@@ -74,7 +74,7 @@ - - } - --int MethodHandles::method_handle_entry_invokeBasic(methodOop method, intptr_t UNUSED, TRAPS) { -+int MethodHandles::method_handle_entry_invokeBasic(Method* method, intptr_t UNUSED, TRAPS) { - - JavaThread *thread = (JavaThread *) THREAD; - InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); -@@ -85,7 +85,7 @@ - int numArgs = method->size_of_parameters(); - oop lform1 = java_lang_invoke_MethodHandle::form(STACK_OBJECT(-numArgs)); // this.form - oop vmEntry1 = java_lang_invoke_LambdaForm::vmentry(lform1); -- methodOop vmtarget = (methodOop) java_lang_invoke_MemberName::vmtarget(vmEntry1); -+ Method* vmtarget = (Method*) java_lang_invoke_MemberName::vmtarget(vmEntry1); - - invoke_target(vmtarget, THREAD); - -@@ -93,20 +93,20 @@ - return 0; - } - --int MethodHandles::method_handle_entry_linkToStaticOrSpecial(methodOop method, intptr_t UNUSED, TRAPS) { -+int MethodHandles::method_handle_entry_linkToStaticOrSpecial(Method* method, intptr_t UNUSED, TRAPS) { - - // Pop appendix argument from stack. This is a MemberName which we resolve to the - // target method. - oop vmentry = popFromStack(THREAD); - -- methodOop vmtarget = (methodOop) java_lang_invoke_MemberName::vmtarget(vmentry); -+ Method* vmtarget = (Method*) java_lang_invoke_MemberName::vmtarget(vmentry); - - invoke_target(vmtarget, THREAD); - - return 0; - } - --int MethodHandles::method_handle_entry_linkToInterface(methodOop method, intptr_t UNUSED, TRAPS) { -+int MethodHandles::method_handle_entry_linkToInterface(Method* method, intptr_t UNUSED, TRAPS) { - JavaThread *thread = (JavaThread *) THREAD; - InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); - interpreterState istate = frame->interpreter_state(); -@@ -117,14 +117,14 @@ - oop vmentry = popFromStack(THREAD); - - // Resolve target method by looking up in the receiver object's itable. -- klassOop clazz = java_lang_Class::as_klassOop(java_lang_invoke_MemberName::clazz(vmentry)); -+ Klass* clazz = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(vmentry)); - intptr_t vmindex = java_lang_invoke_MemberName::vmindex(vmentry); -- methodOop target = (methodOop) java_lang_invoke_MemberName::vmtarget(vmentry); -+ Method* target = (Method*) java_lang_invoke_MemberName::vmtarget(vmentry); - - int numArgs = target->size_of_parameters(); - oop recv = STACK_OBJECT(-numArgs); - -- instanceKlass* klass_part = (instanceKlass*) recv->klass()->klass_part(); -+ InstanceKlass* klass_part = InstanceKlass::cast(recv->klass()); - itableOffsetEntry* ki = (itableOffsetEntry*) klass_part->start_of_itable(); - int i; - for ( i = 0 ; i < klass_part->itable_length() ; i++, ki++ ) { -@@ -132,14 +132,14 @@ - } - - itableMethodEntry* im = ki->first_method_entry(recv->klass()); -- methodOop vmtarget = im[vmindex].method(); -+ Method* vmtarget = im[vmindex].method(); - - invoke_target(vmtarget, THREAD); - - return 0; - } - --int MethodHandles::method_handle_entry_linkToVirtual(methodOop method, intptr_t UNUSED, TRAPS) { -+int MethodHandles::method_handle_entry_linkToVirtual(Method* method, intptr_t UNUSED, TRAPS) { - JavaThread *thread = (JavaThread *) THREAD; - - InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); -@@ -152,20 +152,20 @@ - - // Resolve target method by looking up in the receiver object's vtable. - intptr_t vmindex = java_lang_invoke_MemberName::vmindex(vmentry); -- methodOop target = (methodOop) java_lang_invoke_MemberName::vmtarget(vmentry); -+ Method* target = (Method*) java_lang_invoke_MemberName::vmtarget(vmentry); - int numArgs = target->size_of_parameters(); - oop recv = STACK_OBJECT(-numArgs); -- klassOop clazz = recv->klass(); -- Klass* klass_part = clazz->klass_part(); -+ Klass* clazz = recv->klass(); -+ Klass* klass_part = InstanceKlass::cast(clazz); - klassVtable* vtable = klass_part->vtable(); -- methodOop vmtarget = vtable->method_at(vmindex); -+ Method* vmtarget = vtable->method_at(vmindex); - - invoke_target(vmtarget, THREAD); - - return 0; - } - --int MethodHandles::method_handle_entry_invalid(methodOop method, intptr_t UNUSED, TRAPS) { -+int MethodHandles::method_handle_entry_invalid(Method* method, intptr_t UNUSED, TRAPS) { - ShouldNotReachHere(); - return 0; - } -diff --git a/src/cpu/zero/vm/methodHandles_zero.hpp b/src/cpu/zero/vm/methodHandles_zero.hpp ---- a/src/cpu/zero/vm/methodHandles_zero.hpp -+++ b/src/cpu/zero/vm/methodHandles_zero.hpp -@@ -55,9 +55,9 @@ - - private: - static oop popFromStack(TRAPS); -- static void invoke_target(methodOop method, TRAPS); -- static int method_handle_entry_invokeBasic(methodOop method, intptr_t UNUSED, TRAPS); -- static int method_handle_entry_linkToStaticOrSpecial(methodOop method, intptr_t UNUSED, TRAPS); -- static int method_handle_entry_linkToVirtual(methodOop method, intptr_t UNUSED, TRAPS); -- static int method_handle_entry_linkToInterface(methodOop method, intptr_t UNUSED, TRAPS); -- static int method_handle_entry_invalid(methodOop method, intptr_t UNUSED, TRAPS); -+ static void invoke_target(Method* method, TRAPS); -+ static int method_handle_entry_invokeBasic(Method* method, intptr_t UNUSED, TRAPS); -+ static int method_handle_entry_linkToStaticOrSpecial(Method* method, intptr_t UNUSED, TRAPS); -+ static int method_handle_entry_linkToVirtual(Method* method, intptr_t UNUSED, TRAPS); -+ static int method_handle_entry_linkToInterface(Method* method, intptr_t UNUSED, TRAPS); -+ static int method_handle_entry_invalid(Method* method, intptr_t UNUSED, TRAPS); -diff --git a/src/cpu/zero/vm/relocInfo_zero.cpp b/src/cpu/zero/vm/relocInfo_zero.cpp ---- a/src/cpu/zero/vm/relocInfo_zero.cpp -+++ b/src/cpu/zero/vm/relocInfo_zero.cpp -@@ -77,3 +77,7 @@ - CodeBuffer* dst) { - ShouldNotCallThis(); - } -+ -+void metadata_Relocation::pd_fix_value(address x) { -+ ShouldNotCallThis(); -+} -diff --git a/src/cpu/zero/vm/sharedRuntime_zero.cpp b/src/cpu/zero/vm/sharedRuntime_zero.cpp ---- a/src/cpu/zero/vm/sharedRuntime_zero.cpp -+++ b/src/cpu/zero/vm/sharedRuntime_zero.cpp -@@ -78,8 +78,6 @@ - nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, - methodHandle method, - int compile_id, -- int total_args_passed, -- int max_arg, - BasicType *sig_bt, - VMRegPair *regs, - BasicType ret_type) { -@@ -124,7 +122,7 @@ - _deopt_blob = generate_empty_deopt_blob(); - } - --SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause_return) { -+SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_type) { - return generate_empty_safepoint_blob(); - } - -diff --git a/src/share/vm/interpreter/bytecodeInterpreter.cpp b/src/share/vm/interpreter/bytecodeInterpreter.cpp ---- a/src/share/vm/interpreter/bytecodeInterpreter.cpp -+++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp -@@ -1769,7 +1769,7 @@ - - oop obj; - if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) { -- Klass* k = (Klass*) cache->f1(); -+ Klass* k = cache->f1_as_klass(); - obj = k->java_mirror(); - MORE_STACK(1); // Assume single slot push - } else { -@@ -1881,7 +1881,7 @@ - --count; - } - if ((Bytecodes::Code)opcode == Bytecodes::_putstatic) { -- Klass* k = (Klass*) cache->f1(); -+ Klass* k = cache->f1_as_klass(); - obj = k->java_mirror(); - } else { - --count; -@@ -2197,6 +2197,7 @@ - } - - int index = Bytes::get_native_u4(pc+1); -+ ConstantPoolCacheEntry* cache = cp->entry_at(index); - - // We are resolved if the resolved_references field contains a non-null object (CallSite, etc.) - // This kind of CP cache entry does not need to match the flags byte, because -@@ -2209,16 +2210,16 @@ - result = THREAD->vm_result(); - } - -- methodOop method = cache->f2_as_vfinal_method(); -+ Method* method = cache->f2_as_vfinal_method(); - VERIFY_OOP(method); - - if (cache->has_appendix()) { -- SET_STACK_OBJECT(cache->f1_appendix(), 0); -+ SET_STACK_OBJECT(cache->appendix_if_resolved(constants), 0); - MORE_STACK(1); - } - - istate->set_msg(call_method); -- istate->set_callee((methodOop) method); -+ istate->set_callee(method); - istate->set_callee_entry_point(method->from_interpreted_entry()); - istate->set_bcp_advance(5); - -@@ -2234,18 +2235,19 @@ - u2 index = Bytes::get_native_u2(pc+1); - - ConstantPoolCacheEntry* cache = cp->entry_at(index); -+ ConstantPool* constants = METHOD->constants(); - - if (! cache->is_resolved((Bytecodes::Code) opcode)) { - CALL_VM(InterpreterRuntime::resolve_invokehandle(THREAD), - handle_exception); - cache = cp->entry_at(index); - } -- methodOop method = cache->f2_as_vfinal_method(); -+ Method* method = cache->f2_as_vfinal_method(); - - VERIFY_OOP(method); - - if (cache->has_appendix()) { -- SET_STACK_OBJECT(cache->f1_appendix(), 0); -+ SET_STACK_OBJECT(cache->appendix_if_resolved(constants), 0); - MORE_STACK(1); - } -
--- a/series Fri Oct 05 19:46:11 2012 +0200 +++ b/series Wed Oct 10 12:14:29 2012 +0200 @@ -1,8 +1,3 @@ linux_thread_name.patch -hotspot.patch -zero-makefile.patch -zero-segfault.patch -zero-new-math.patch -zero-meth.patch +hotspot-zero.patch psgc-bind-procs.patch -mergejdk8.patch
--- a/zero-makefile.patch Fri Oct 05 19:46:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -# 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 -
--- a/zero-meth.patch Fri Oct 05 19:46:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1430 +0,0 @@ -# HG changeset patch -# Parent fbf3e1b8b4e973d91214d98d76a1903963a93c1b - -diff --git a/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp b/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp ---- a/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp -+++ b/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp -@@ -31,12 +31,17 @@ - return _masm; - } - -- protected: -- address generate_entry(address entry_point) { -- ZeroEntry *entry = (ZeroEntry *) assembler()->pc(); -- assembler()->advance(sizeof(ZeroEntry)); -+ public: -+ static address generate_entry_impl(MacroAssembler* masm, address entry_point) { -+ ZeroEntry *entry = (ZeroEntry *) masm->pc(); -+ masm->advance(sizeof(ZeroEntry)); - entry->set_entry_point(entry_point); - return (address) entry; - } - -+ protected: -+ address generate_entry(address entry_point) { -+ return generate_entry_impl(assembler(), entry_point); -+ } -+ - #endif // CPU_ZERO_VM_CPPINTERPRETERGENERATOR_ZERO_HPP -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 -@@ -182,25 +182,6 @@ - method, istate->osr_entry(), istate->osr_buf(), THREAD); - return; - } -- else if (istate->msg() == BytecodeInterpreter::call_method_handle) { -- oop method_handle = istate->callee(); -- -- // Trim back the stack to put the parameters at the top -- stack->set_sp(istate->stack() + 1); -- -- // Make the call -- process_method_handle(method_handle, THREAD); -- fixup_after_potential_safepoint(); -- -- // Convert the result -- istate->set_stack(stack->sp() - 1); -- -- // Restore the stack -- stack->set_sp(istate->stack_limit() + 1); -- -- // Resume the interpreter -- istate->set_msg(BytecodeInterpreter::method_resume); -- } - else { - ShouldNotReachHere(); - } -@@ -537,35 +518,35 @@ - if (entry->is_volatile()) { - switch (entry->flag_state()) { - case ctos: -- SET_LOCALS_INT(object->char_field_acquire(entry->f2()), 0); -+ SET_LOCALS_INT(object->char_field_acquire(entry->f2_as_index()), 0); - break; - - case btos: -- SET_LOCALS_INT(object->byte_field_acquire(entry->f2()), 0); -+ SET_LOCALS_INT(object->byte_field_acquire(entry->f2_as_index()), 0); - break; - - case stos: -- SET_LOCALS_INT(object->short_field_acquire(entry->f2()), 0); -+ SET_LOCALS_INT(object->short_field_acquire(entry->f2_as_index()), 0); - break; - - case itos: -- SET_LOCALS_INT(object->int_field_acquire(entry->f2()), 0); -+ SET_LOCALS_INT(object->int_field_acquire(entry->f2_as_index()), 0); - break; - - case ltos: -- SET_LOCALS_LONG(object->long_field_acquire(entry->f2()), 0); -+ SET_LOCALS_LONG(object->long_field_acquire(entry->f2_as_index()), 0); - break; - - case ftos: -- SET_LOCALS_FLOAT(object->float_field_acquire(entry->f2()), 0); -+ SET_LOCALS_FLOAT(object->float_field_acquire(entry->f2_as_index()), 0); - break; - - case dtos: -- SET_LOCALS_DOUBLE(object->double_field_acquire(entry->f2()), 0); -+ SET_LOCALS_DOUBLE(object->double_field_acquire(entry->f2_as_index()), 0); - break; - - case atos: -- SET_LOCALS_OBJECT(object->obj_field_acquire(entry->f2()), 0); -+ SET_LOCALS_OBJECT(object->obj_field_acquire(entry->f2_as_index()), 0); - break; - - default: -@@ -575,35 +556,35 @@ - else { - switch (entry->flag_state()) { - case ctos: -- SET_LOCALS_INT(object->char_field(entry->f2()), 0); -+ SET_LOCALS_INT(object->char_field(entry->f2_as_index()), 0); - break; - - case btos: -- SET_LOCALS_INT(object->byte_field(entry->f2()), 0); -+ SET_LOCALS_INT(object->byte_field(entry->f2_as_index()), 0); - break; - - case stos: -- SET_LOCALS_INT(object->short_field(entry->f2()), 0); -+ SET_LOCALS_INT(object->short_field(entry->f2_as_index()), 0); - break; - - case itos: -- SET_LOCALS_INT(object->int_field(entry->f2()), 0); -+ SET_LOCALS_INT(object->int_field(entry->f2_as_index()), 0); - break; - - case ltos: -- SET_LOCALS_LONG(object->long_field(entry->f2()), 0); -+ SET_LOCALS_LONG(object->long_field(entry->f2_as_index()), 0); - break; - - case ftos: -- SET_LOCALS_FLOAT(object->float_field(entry->f2()), 0); -+ SET_LOCALS_FLOAT(object->float_field(entry->f2_as_index()), 0); - break; - - case dtos: -- SET_LOCALS_DOUBLE(object->double_field(entry->f2()), 0); -+ SET_LOCALS_DOUBLE(object->double_field(entry->f2_as_index()), 0); - break; - - case atos: -- SET_LOCALS_OBJECT(object->obj_field(entry->f2()), 0); -+ SET_LOCALS_OBJECT(object->obj_field(entry->f2_as_index()), 0); - break; - - default: -@@ -631,827 +612,6 @@ - return 0; - } - --int CppInterpreter::method_handle_entry(Method* method, -- intptr_t UNUSED, TRAPS) { -- JavaThread *thread = (JavaThread *) THREAD; -- ZeroStack *stack = thread->zero_stack(); -- int argument_slots = method->size_of_parameters(); -- int result_slots = type2size[result_type_of(method)]; -- intptr_t *vmslots = stack->sp(); -- intptr_t *unwind_sp = vmslots + argument_slots; -- -- // Find the MethodType -- address p = (address) method; -- for (jint* pc = method->method_type_offsets_chain(); (*pc) != -1; pc++) { -- p = *(address*)(p + (*pc)); -- } -- oop method_type = (oop) p; -- -- // The MethodHandle is in the slot after the arguments -- int num_vmslots = argument_slots - 1; -- oop method_handle = VMSLOTS_OBJECT(num_vmslots); -- -- // InvokeGeneric requires some extra shuffling -- oop mhtype = java_lang_invoke_MethodHandle::type(method_handle); -- bool is_exact = mhtype == method_type; -- if (!is_exact) { -- if (true || // FIXME -- method->intrinsic_id() == vmIntrinsics::_invokeExact) { -- CALL_VM_NOCHECK_NOFIX( -- SharedRuntime::throw_WrongMethodTypeException( -- thread, method_type, mhtype)); -- // NB all oops trashed! -- assert(HAS_PENDING_EXCEPTION, "should do"); -- stack->set_sp(unwind_sp); -- return 0; -- } -- assert(method->intrinsic_id() == vmIntrinsics::_invokeGeneric, "should be"); -- -- // Load up an adapter from the calling type -- // NB the x86 code for this (in methodHandles_x86.cpp, search for -- // "genericInvoker") is really really odd. I'm hoping it's trying -- // to accomodate odd VM/class library combinations I can ignore. -- oop adapter = NULL; //FIXME: load the adapter from the CP cache -- IF (adapter == NULL) { -- CALL_VM_NOCHECK_NOFIX( -- SharedRuntime::throw_WrongMethodTypeException( -- thread, method_type, mhtype)); -- // NB all oops trashed! -- assert(HAS_PENDING_EXCEPTION, "should do"); -- stack->set_sp(unwind_sp); -- return 0; -- } -- -- // Adapters are shared among form-families of method-type. The -- // type being called is passed as a trusted first argument so that -- // the adapter knows the actual types of its arguments and return -- // values. -- insert_vmslots(num_vmslots + 1, 1, THREAD); -- if (HAS_PENDING_EXCEPTION) { -- // NB all oops trashed! -- stack->set_sp(unwind_sp); -- return 0; -- } -- -- vmslots = stack->sp(); -- num_vmslots++; -- SET_VMSLOTS_OBJECT(method_type, num_vmslots); -- -- 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) -- result_slots = 0; -- -- // If this is an invokeExact then the eventual callee will not -- // have unwound the method handle argument so we have to do it. -- // If a result is being returned the it will be above the method -- // handle argument we're unwinding. -- if (is_exact) { -- intptr_t result[2]; -- for (int i = 0; i < result_slots; i++) -- result[i] = stack->pop(); -- stack->pop(); -- for (int i = result_slots - 1; i >= 0; i--) -- stack->push(result[i]); -- } -- -- // 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 -- return 0; --} -- --void CppInterpreter::process_method_handle(oop method_handle, TRAPS) { -- -- JavaThread *thread = (JavaThread *) THREAD; -- ZeroStack *stack = thread->zero_stack(); -- intptr_t *vmslots = stack->sp(); -- -- bool direct_to_method = false; -- BasicType src_rtype = T_ILLEGAL; -- BasicType dst_rtype = T_ILLEGAL; -- -- MethodHandleEntry *entry = -- java_lang_invoke_MethodHandle::vmentry(method_handle); -- MethodHandles::EntryKind entry_kind = -- (MethodHandles::EntryKind) (((intptr_t) entry) & 0xffffffff); -- -- Method* method = NULL; -- switch (entry_kind) { -- case MethodHandles::_invokestatic_mh: -- direct_to_method = true; -- break; -- -- case MethodHandles::_invokespecial_mh: -- case MethodHandles::_invokevirtual_mh: -- case MethodHandles::_invokeinterface_mh: -- { -- oop receiver = -- VMSLOTS_OBJECT( -- java_lang_invoke_MethodHandle::vmslots(method_handle) - 1); -- if (receiver == NULL) { -- 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; -- } -- if (entry_kind != MethodHandles::_invokespecial_mh) { -- intptr_t index = java_lang_invoke_DirectMethodHandle::vmindex(method_handle); -- InstanceKlass* rcvrKlass = -- (InstanceKlass *) receiver->klass(); -- if (entry_kind == MethodHandles::_invokevirtual_mh) { -- method = (Method*) rcvrKlass->start_of_vtable()[index]; -- } -- else { -- oop iclass = java_lang_invoke_MethodHandle::next_target(method_handle); -- itableOffsetEntry* ki = -- (itableOffsetEntry *) rcvrKlass->start_of_itable(); -- int i, length = rcvrKlass->itable_length(); -- for (i = 0; i < length; i++, ki++ ) { -- if (ki->interface_klass() == iclass) -- break; -- } -- if (i == length) { -- stack->set_sp(calculate_unwind_sp(stack, method_handle)); -- CALL_VM_NOCHECK_NOFIX( -- throw_exception( -- thread, vmSymbols::java_lang_IncompatibleClassChangeError())); -- // NB all oops trashed! -- assert(HAS_PENDING_EXCEPTION, "should do"); -- return; -- } -- itableMethodEntry* im = ki->first_method_entry(receiver->klass()); -- method = im[index].method(); -- if (method == NULL) { -- stack->set_sp(calculate_unwind_sp(stack, method_handle)); -- CALL_VM_NOCHECK_NOFIX( -- throw_exception( -- thread, vmSymbols::java_lang_AbstractMethodError())); -- // NB all oops trashed! -- assert(HAS_PENDING_EXCEPTION, "should do"); -- return; -- } -- } -- } -- } -- direct_to_method = true; -- break; -- -- case MethodHandles::_bound_ref_direct_mh: -- case MethodHandles::_bound_int_direct_mh: -- case MethodHandles::_bound_long_direct_mh: -- direct_to_method = true; -- // fall through -- case MethodHandles::_bound_ref_mh: -- 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 = 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); -- -- // Create the new slot(s) -- intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle); -- insert_vmslots(arg_slot, arg_slots, THREAD); -- if (HAS_PENDING_EXCEPTION) { -- // all oops trashed -- stack->set_sp(unwind_sp); -- return; -- } -- vmslots = stack->sp(); -- -- // Store bound argument into new stack slot -- oop arg = java_lang_invoke_BoundMethodHandle::argument(method_handle); -- if (arg_type == T_OBJECT) { -- assert(arg_slots == 1, "should be"); -- SET_VMSLOTS_OBJECT(arg, arg_slot); -- } -- else { -- jvalue arg_value; -- arg_type = java_lang_boxing_object::get_value(arg, &arg_value); -- switch (arg_type) { -- case T_BOOLEAN: -- SET_VMSLOTS_INT(arg_value.z, arg_slot); -- break; -- case T_CHAR: -- SET_VMSLOTS_INT(arg_value.c, arg_slot); -- break; -- case T_BYTE: -- SET_VMSLOTS_INT(arg_value.b, arg_slot); -- break; -- case T_SHORT: -- SET_VMSLOTS_INT(arg_value.s, arg_slot); -- break; -- case T_INT: -- SET_VMSLOTS_INT(arg_value.i, arg_slot); -- break; -- case T_FLOAT: -- SET_VMSLOTS_FLOAT(arg_value.f, arg_slot); -- break; -- case T_LONG: -- SET_VMSLOTS_LONG(arg_value.j, arg_slot + 1); -- break; -- case T_DOUBLE: -- SET_VMSLOTS_DOUBLE(arg_value.d, arg_slot + 1); -- break; -- default: -- tty->print_cr("unhandled type %s", type2name(arg_type)); -- ShouldNotReachHere(); -- } -- } -- } -- break; -- -- case MethodHandles::_adapter_retype_only: -- case MethodHandles::_adapter_retype_raw: -- src_rtype = result_type_of_handle( -- java_lang_invoke_MethodHandle::next_target(method_handle)); -- dst_rtype = result_type_of_handle(method_handle); -- break; -- -- case MethodHandles::_adapter_check_cast: -- { -- int arg_slot = -- java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); -- oop arg = VMSLOTS_OBJECT(arg_slot); -- if (arg != NULL) { -- Klass* objKlassOop = arg->klass(); -- Klass* klassOf = java_lang_Class::as_Klass( -- java_lang_invoke_AdapterMethodHandle::argument(method_handle)); -- -- if (objKlassOop != klassOf && -- !objKlassOop->is_subtype_of(klassOf)) { -- 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; -- } -- } -- } -- break; -- -- case MethodHandles::_adapter_dup_args: -- { -- int arg_slot = -- java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); -- int conv = -- java_lang_invoke_AdapterMethodHandle::conversion(method_handle); -- int num_slots = -MethodHandles::adapter_conversion_stack_move(conv); -- assert(num_slots > 0, "should be"); -- -- // Create the new slot(s) -- intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle); -- stack->overflow_check(num_slots, THREAD); -- if (HAS_PENDING_EXCEPTION) { -- // all oops trashed -- stack->set_sp(unwind_sp); -- return; -- } -- -- // Duplicate the arguments -- for (int i = num_slots - 1; i >= 0; i--) -- stack->push(*VMSLOTS_SLOT(arg_slot + i)); -- -- vmslots = stack->sp(); // unused, but let the compiler figure that out -- } -- break; -- -- case MethodHandles::_adapter_drop_args: -- { -- int arg_slot = -- java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); -- int conv = -- java_lang_invoke_AdapterMethodHandle::conversion(method_handle); -- int num_slots = MethodHandles::adapter_conversion_stack_move(conv); -- assert(num_slots > 0, "should be"); -- -- remove_vmslots(arg_slot, num_slots, THREAD); // doesn't trap -- vmslots = stack->sp(); // unused, but let the compiler figure that out -- } -- break; -- -- case MethodHandles::_adapter_opt_swap_1: -- case MethodHandles::_adapter_opt_swap_2: -- case MethodHandles::_adapter_opt_rot_1_up: -- case MethodHandles::_adapter_opt_rot_1_down: -- case MethodHandles::_adapter_opt_rot_2_up: -- case MethodHandles::_adapter_opt_rot_2_down: -- { -- int arg1 = -- java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); -- int conv = -- 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 = 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) { -- case 0: // swap -- for (int i = 0; i < swap_slots; i++) { -- tmp = *VMSLOTS_SLOT(arg1 + i); -- SET_VMSLOTS_SLOT(VMSLOTS_SLOT(arg2 + i), arg1 + i); -- SET_VMSLOTS_SLOT(&tmp, arg2 + i); -- } -- break; -- -- case 1: // up -- assert(arg1 - swap_slots > arg2, "should be"); -- -- tmp = *VMSLOTS_SLOT(arg1); -- for (int i = arg1 - swap_slots; i >= arg2; i--) -- SET_VMSLOTS_SLOT(VMSLOTS_SLOT(i), i + swap_slots); -- SET_VMSLOTS_SLOT(&tmp, arg2); -- -- break; -- -- case -1: // down -- assert(arg2 - swap_slots > arg1, "should be"); -- -- tmp = *VMSLOTS_SLOT(arg1); -- for (int i = arg1 + swap_slots; i <= arg2; i++) -- SET_VMSLOTS_SLOT(VMSLOTS_SLOT(i), i - swap_slots); -- SET_VMSLOTS_SLOT(&tmp, arg2); -- break; -- -- default: -- ShouldNotReachHere(); -- } -- } -- break; -- -- case MethodHandles::_adapter_opt_i2l: -- { -- int arg_slot = -- java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); -- int arg = VMSLOTS_INT(arg_slot); -- intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle); -- insert_vmslots(arg_slot, 1, THREAD); -- if (HAS_PENDING_EXCEPTION) { -- // all oops trashed -- stack->set_sp(unwind_sp); -- return; -- } -- vmslots = stack->sp(); -- arg_slot++; -- SET_VMSLOTS_LONG(arg, arg_slot); -- } -- break; -- -- case MethodHandles::_adapter_opt_unboxi: -- case MethodHandles::_adapter_opt_unboxl: -- { -- int arg_slot = -- java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); -- oop arg = VMSLOTS_OBJECT(arg_slot); -- jvalue arg_value; -- if (arg == NULL) { -- // 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; -- } -- BasicType arg_type = java_lang_boxing_object::get_value(arg, &arg_value); -- if (arg_type == T_LONG || arg_type == T_DOUBLE) { -- intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle); -- insert_vmslots(arg_slot, 1, THREAD); -- if (HAS_PENDING_EXCEPTION) { -- // all oops trashed -- stack->set_sp(unwind_sp); -- return; -- } -- vmslots = stack->sp(); -- arg_slot++; -- } -- switch (arg_type) { -- case T_BOOLEAN: -- SET_VMSLOTS_INT(arg_value.z, arg_slot); -- break; -- case T_CHAR: -- SET_VMSLOTS_INT(arg_value.c, arg_slot); -- break; -- case T_BYTE: -- SET_VMSLOTS_INT(arg_value.b, arg_slot); -- break; -- case T_SHORT: -- SET_VMSLOTS_INT(arg_value.s, arg_slot); -- break; -- case T_INT: -- SET_VMSLOTS_INT(arg_value.i, arg_slot); -- break; -- case T_FLOAT: -- SET_VMSLOTS_FLOAT(arg_value.f, arg_slot); -- break; -- case T_LONG: -- SET_VMSLOTS_LONG(arg_value.j, arg_slot); -- break; -- case T_DOUBLE: -- SET_VMSLOTS_DOUBLE(arg_value.d, arg_slot); -- break; -- default: -- tty->print_cr("unhandled type %s", type2name(arg_type)); -- ShouldNotReachHere(); -- } -- } -- break; -- -- 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(); -- } -- -- -- // Continue along the chain -- if (direct_to_method) { -- if (method == NULL) { -- method = -- (Method*) java_lang_invoke_MethodHandle::vmtarget(method_handle); -- } -- address entry_point = method->from_interpreted_entry(); -- Interpreter::invoke_method(method, entry_point, THREAD); -- } -- else { -- process_method_handle( -- java_lang_invoke_MethodHandle::next_target(method_handle), THREAD); -- } -- // NB all oops now trashed -- -- // Adapt the result type, if necessary -- if (src_rtype != dst_rtype && !HAS_PENDING_EXCEPTION) { -- switch (dst_rtype) { -- case T_VOID: -- for (int i = 0; i < type2size[src_rtype]; i++) -- stack->pop(); -- return; -- -- case T_INT: -- switch (src_rtype) { -- case T_VOID: -- stack->overflow_check(1, CHECK); -- stack->push(0); -- return; -- -- case T_BOOLEAN: -- case T_CHAR: -- case T_BYTE: -- case T_SHORT: -- return; -- } -- // INT results sometimes need narrowing -- case T_BOOLEAN: -- case T_CHAR: -- case T_BYTE: -- case T_SHORT: -- switch (src_rtype) { -- case T_INT: -- return; -- } -- } -- -- tty->print_cr("unhandled conversion:"); -- tty->print_cr("src_rtype = %s", type2name(src_rtype)); -- 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. - // Slots < insert_before will have the same slot number after the insert. - // Slots >= insert_before will become old_slot + num_slots. -@@ -1693,10 +853,6 @@ - entry_point = ((InterpreterGenerator*) this)->generate_abstract_entry(); - break; - -- case Interpreter::method_handle: -- entry_point = ((InterpreterGenerator*) this)->generate_method_handle_entry(); -- break; -- - case Interpreter::java_lang_math_sin: - case Interpreter::java_lang_math_cos: - case Interpreter::java_lang_math_tan: -diff --git a/src/cpu/zero/vm/cppInterpreter_zero.hpp b/src/cpu/zero/vm/cppInterpreter_zero.hpp ---- a/src/cpu/zero/vm/cppInterpreter_zero.hpp -+++ b/src/cpu/zero/vm/cppInterpreter_zero.hpp -@@ -36,7 +36,6 @@ - static int native_entry(Method* method, intptr_t UNUSED, TRAPS); - static int accessor_entry(Method* method, intptr_t UNUSED, TRAPS); - static int empty_entry(Method* method, intptr_t UNUSED, TRAPS); -- static int method_handle_entry(Method* method, intptr_t UNUSED, TRAPS); - - public: - // Main loop of normal_entry -@@ -44,7 +43,6 @@ - - private: - // Helpers for method_handle_entry -- static void process_method_handle(oop method_handle, TRAPS); - static void insert_vmslots(int insert_before, int num_slots, TRAPS); - static void remove_vmslots(int first_slot, int num_slots, TRAPS); - static BasicType result_type_of_handle(oop method_handle); -diff --git a/src/cpu/zero/vm/interpreterGenerator_zero.hpp b/src/cpu/zero/vm/interpreterGenerator_zero.hpp ---- a/src/cpu/zero/vm/interpreterGenerator_zero.hpp -+++ b/src/cpu/zero/vm/interpreterGenerator_zero.hpp -@@ -30,6 +30,9 @@ - // - friend class AbstractInterpreterGenerator; - -+ public: -+ static address generate_method_entry_impl(AbstractInterpreter::MethodKind kind); -+ - private: - address generate_normal_entry(bool synchronized); - address generate_native_entry(bool synchronized); -diff --git a/src/cpu/zero/vm/methodHandles_zero.cpp b/src/cpu/zero/vm/methodHandles_zero.cpp ---- a/src/cpu/zero/vm/methodHandles_zero.cpp -+++ b/src/cpu/zero/vm/methodHandles_zero.cpp -@@ -24,30 +24,13 @@ - */ - - #include "precompiled.hpp" -+#include "interpreter/interpreterGenerator.hpp" - #include "interpreter/interpreter.hpp" - #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) -- |(1<<java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST) -- |(1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM) -- |(1<<java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM) -- |(1<<java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS) -- |(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) -- ); --} -- --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, -@@ -59,54 +42,154 @@ - (*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::invoke_target(methodOop method, TRAPS) { -+ -+ JavaThread *thread = (JavaThread *) THREAD; -+ ZeroStack *stack = thread->zero_stack(); -+ InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); -+ interpreterState istate = frame->interpreter_state(); -+ -+ // Trim back the stack to put the parameters at the top -+ stack->set_sp(istate->stack() + 1); -+ -+ Interpreter::invoke_method(method, method->from_interpreted_entry(), THREAD); -+ -+ // Convert the result -+ istate->set_stack(stack->sp() - 1); -+ - } - --void MethodHandles::ricochet_frame_oops_do(const frame& fr, OopClosure* blk, const RegisterMap* reg_map) { -- // ResourceMark rm; -- // RicochetFrame* f = RicochetFrame::from_frame(fr); -+oop MethodHandles::popFromStack(TRAPS) { - -- // 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()); -+ JavaThread *thread = (JavaThread *) THREAD; -+ InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); -+ interpreterState istate = frame->interpreter_state(); -+ intptr_t* topOfStack = istate->stack(); - -- // process variable arguments: -- // if (cookie.is_null()) return; // no arguments to describe -+ oop top = STACK_OBJECT(-1); -+ MORE_STACK(-1); -+ istate->set_stack(topOfStack); - -- // 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"); -+ return top; -+ - } -+ -+int MethodHandles::method_handle_entry_invokeBasic(methodOop method, intptr_t UNUSED, TRAPS) { -+ -+ JavaThread *thread = (JavaThread *) THREAD; -+ InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); -+ interpreterState istate = frame->interpreter_state(); -+ intptr_t* topOfStack = istate->stack(); -+ -+ // 'this' is a MethodHandle. We resolve the target method by accessing this.form.vmentry.vmtarget. -+ int numArgs = method->size_of_parameters(); -+ oop lform1 = java_lang_invoke_MethodHandle::form(STACK_OBJECT(-numArgs)); // this.form -+ oop vmEntry1 = java_lang_invoke_LambdaForm::vmentry(lform1); -+ methodOop vmtarget = (methodOop) java_lang_invoke_MemberName::vmtarget(vmEntry1); -+ -+ invoke_target(vmtarget, THREAD); -+ -+ // No deoptimized frames on the stack -+ return 0; -+} -+ -+int MethodHandles::method_handle_entry_linkToStaticOrSpecial(methodOop method, intptr_t UNUSED, TRAPS) { -+ -+ // Pop appendix argument from stack. This is a MemberName which we resolve to the -+ // target method. -+ oop vmentry = popFromStack(THREAD); -+ -+ methodOop vmtarget = (methodOop) java_lang_invoke_MemberName::vmtarget(vmentry); -+ -+ invoke_target(vmtarget, THREAD); -+ -+ return 0; -+} -+ -+int MethodHandles::method_handle_entry_linkToInterface(methodOop method, intptr_t UNUSED, TRAPS) { -+ JavaThread *thread = (JavaThread *) THREAD; -+ InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); -+ interpreterState istate = frame->interpreter_state(); -+ intptr_t* topOfStack = istate->stack(); -+ -+ // Pop appendix argument from stack. This is a MemberName which we resolve to the -+ // target method. -+ oop vmentry = popFromStack(THREAD); -+ -+ // Resolve target method by looking up in the receiver object's itable. -+ klassOop clazz = java_lang_Class::as_klassOop(java_lang_invoke_MemberName::clazz(vmentry)); -+ intptr_t vmindex = java_lang_invoke_MemberName::vmindex(vmentry); -+ methodOop target = (methodOop) java_lang_invoke_MemberName::vmtarget(vmentry); -+ -+ int numArgs = target->size_of_parameters(); -+ oop recv = STACK_OBJECT(-numArgs); -+ -+ instanceKlass* klass_part = (instanceKlass*) recv->klass()->klass_part(); -+ itableOffsetEntry* ki = (itableOffsetEntry*) klass_part->start_of_itable(); -+ int i; -+ for ( i = 0 ; i < klass_part->itable_length() ; i++, ki++ ) { -+ if (ki->interface_klass() == clazz) break; -+ } -+ -+ itableMethodEntry* im = ki->first_method_entry(recv->klass()); -+ methodOop vmtarget = im[vmindex].method(); -+ -+ invoke_target(vmtarget, THREAD); -+ -+ return 0; -+} -+ -+int MethodHandles::method_handle_entry_linkToVirtual(methodOop method, intptr_t UNUSED, TRAPS) { -+ JavaThread *thread = (JavaThread *) THREAD; -+ -+ InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); -+ interpreterState istate = frame->interpreter_state(); -+ intptr_t* topOfStack = istate->stack(); -+ -+ // Pop appendix argument from stack. This is a MemberName which we resolve to the -+ // target method. -+ oop vmentry = popFromStack(THREAD); -+ -+ // Resolve target method by looking up in the receiver object's vtable. -+ intptr_t vmindex = java_lang_invoke_MemberName::vmindex(vmentry); -+ methodOop target = (methodOop) java_lang_invoke_MemberName::vmtarget(vmentry); -+ int numArgs = target->size_of_parameters(); -+ oop recv = STACK_OBJECT(-numArgs); -+ klassOop clazz = recv->klass(); -+ Klass* klass_part = clazz->klass_part(); -+ klassVtable* vtable = klass_part->vtable(); -+ methodOop vmtarget = vtable->method_at(vmindex); -+ -+ invoke_target(vmtarget, THREAD); -+ -+ return 0; -+} -+ -+int MethodHandles::method_handle_entry_invalid(methodOop method, intptr_t UNUSED, TRAPS) { -+ ShouldNotReachHere(); -+ return 0; -+} -+ -+address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* masm, -+ vmIntrinsics::ID iid) { -+ switch (iid) { -+ case vmIntrinsics::_invokeGeneric: -+ case vmIntrinsics::_compiledLambdaForm: -+ // Perhaps surprisingly, the symbolic references visible to Java are not directly used. -+ // They are linked to Java-generated adapters via MethodHandleNatives.linkMethod. -+ // They all allow an appendix argument. -+ return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_invalid); -+ case vmIntrinsics::_invokeBasic: -+ return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_invokeBasic); -+ case vmIntrinsics::_linkToStatic: -+ case vmIntrinsics::_linkToSpecial: -+ return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_linkToStaticOrSpecial); -+ case vmIntrinsics::_linkToInterface: -+ return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_linkToInterface); -+ case vmIntrinsics::_linkToVirtual: -+ return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_linkToVirtual); -+ default: -+ ShouldNotReachHere(); -+ return NULL; -+ } -+} -diff --git a/src/cpu/zero/vm/methodHandles_zero.hpp b/src/cpu/zero/vm/methodHandles_zero.hpp ---- a/src/cpu/zero/vm/methodHandles_zero.hpp -+++ b/src/cpu/zero/vm/methodHandles_zero.hpp -@@ -26,7 +26,7 @@ - - // Adapters - enum /* platform_dependent_constants */ { -- adapter_code_size = 0 -+ adapter_code_size = 20000 - }; - - class RicochetFrame : public ResourceObj { -@@ -52,3 +52,12 @@ - int* frame_size_in_words); - - }; -+ -+private: -+ static oop popFromStack(TRAPS); -+ static void invoke_target(methodOop method, TRAPS); -+ static int method_handle_entry_invokeBasic(methodOop method, intptr_t UNUSED, TRAPS); -+ static int method_handle_entry_linkToStaticOrSpecial(methodOop method, intptr_t UNUSED, TRAPS); -+ static int method_handle_entry_linkToVirtual(methodOop method, intptr_t UNUSED, TRAPS); -+ static int method_handle_entry_linkToInterface(methodOop method, intptr_t UNUSED, TRAPS); -+ static int method_handle_entry_invalid(methodOop method, intptr_t UNUSED, TRAPS); -diff --git a/src/cpu/zero/vm/register_zero.hpp b/src/cpu/zero/vm/register_zero.hpp ---- a/src/cpu/zero/vm/register_zero.hpp -+++ b/src/cpu/zero/vm/register_zero.hpp -@@ -114,5 +114,8 @@ - }; - - CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1)); -+#ifndef DONT_USE_REGISTER_DEFINES -+#define noreg ((Register)(noreg_RegisterEnumValue)) -+#endif - - #endif // CPU_ZERO_VM_REGISTER_ZERO_HPP -diff --git a/src/cpu/zero/vm/stubRoutines_zero.hpp b/src/cpu/zero/vm/stubRoutines_zero.hpp ---- a/src/cpu/zero/vm/stubRoutines_zero.hpp -+++ b/src/cpu/zero/vm/stubRoutines_zero.hpp -@@ -40,8 +40,8 @@ - } - - enum platform_dependent_constants { -- code_size1 = 0, // The assembler will fail with a guarantee -- code_size2 = 0 // if these are too small. Simply increase -+ code_size1 = 20000, // The assembler will fail with a guarantee -+ code_size2 = 20000 // if these are too small. Simply increase - }; // them if that happens. - - enum method_handles_platform_dependent_constants { -diff --git a/src/share/vm/asm/assembler.cpp b/src/share/vm/asm/assembler.cpp ---- a/src/share/vm/asm/assembler.cpp -+++ b/src/share/vm/asm/assembler.cpp -@@ -59,6 +59,7 @@ - _code_section = cs; - _code_begin = cs->start(); - _code_limit = cs->limit(); -+ assert(_code_limit > _code_begin, "no empty code buffer"); - _code_pos = cs->end(); - _oop_recorder= code->oop_recorder(); - DEBUG_ONLY( _short_branch_delta = 0; ) -diff --git a/src/share/vm/interpreter/bytecodeInterpreter.cpp b/src/share/vm/interpreter/bytecodeInterpreter.cpp ---- a/src/share/vm/interpreter/bytecodeInterpreter.cpp -+++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp -@@ -235,10 +235,6 @@ - #endif - #endif - --// JavaStack Implementation --#define MORE_STACK(count) \ -- (topOfStack -= ((count) * Interpreter::stackElementWords)) -- - - #define UPDATE_PC(opsize) {pc += opsize; } - /* -@@ -575,7 +571,7 @@ - - /* 0xE0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, - /* 0xE4 */ &&opc_default, &&opc_fast_aldc, &&opc_fast_aldc_w, &&opc_return_register_finalizer, --/* 0xE8 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -+/* 0xE8 */ &&opc_invokehandle,&&opc_default, &&opc_default, &&opc_default, - /* 0xEC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, - - /* 0xF0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -@@ -2190,6 +2186,7 @@ - } - - CASE(_invokedynamic): { -+ - if (!EnableInvokeDynamic) { - // We should not encounter this bytecode if !EnableInvokeDynamic. - // The verifier will stop it. However, if we get past the verifier, -@@ -2212,17 +2209,54 @@ - result = THREAD->vm_result(); - } - -- VERIFY_OOP(result); -- oop method_handle = java_lang_invoke_CallSite::target(result); -- CHECK_NULL(method_handle); -- -- istate->set_msg(call_method_handle); -- istate->set_callee((Method*) method_handle); -+ methodOop method = cache->f2_as_vfinal_method(); -+ VERIFY_OOP(method); -+ -+ if (cache->has_appendix()) { -+ SET_STACK_OBJECT(cache->f1_appendix(), 0); -+ MORE_STACK(1); -+ } -+ -+ istate->set_msg(call_method); -+ istate->set_callee((methodOop) method); -+ istate->set_callee_entry_point(method->from_interpreted_entry()); - istate->set_bcp_advance(5); - - UPDATE_PC_AND_RETURN(0); // I'll be back... - } - -+ CASE(_invokehandle): { -+ -+ if (!EnableInvokeDynamic) { -+ ShouldNotReachHere(); -+ } -+ -+ u2 index = Bytes::get_native_u2(pc+1); -+ -+ ConstantPoolCacheEntry* cache = cp->entry_at(index); -+ -+ if (! cache->is_resolved((Bytecodes::Code) opcode)) { -+ CALL_VM(InterpreterRuntime::resolve_invokehandle(THREAD), -+ handle_exception); -+ cache = cp->entry_at(index); -+ } -+ methodOop method = cache->f2_as_vfinal_method(); -+ -+ VERIFY_OOP(method); -+ -+ if (cache->has_appendix()) { -+ SET_STACK_OBJECT(cache->f1_appendix(), 0); -+ MORE_STACK(1); -+ } -+ -+ istate->set_msg(call_method); -+ istate->set_callee(method); -+ istate->set_callee_entry_point(method->from_interpreted_entry()); -+ istate->set_bcp_advance(3); -+ -+ UPDATE_PC_AND_RETURN(0); // I'll be back... -+ } -+ - CASE(_invokeinterface): { - u2 index = Bytes::get_native_u2(pc+1); - -diff --git a/src/share/vm/interpreter/bytecodeInterpreter.hpp b/src/share/vm/interpreter/bytecodeInterpreter.hpp ---- a/src/share/vm/interpreter/bytecodeInterpreter.hpp -+++ b/src/share/vm/interpreter/bytecodeInterpreter.hpp -@@ -50,6 +50,10 @@ - - #ifdef CC_INTERP - -+// JavaStack Implementation -+#define MORE_STACK(count) \ -+ (topOfStack -= ((count) * Interpreter::stackElementWords)) -+ - // CVM definitions find hotspot equivalents... - - union VMJavaVal64 { -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 -@@ -117,7 +117,6 @@ - method_entry(empty); - method_entry(accessor); - method_entry(abstract); -- method_entry(method_handle); - method_entry(java_lang_math_sin ); - method_entry(java_lang_math_cos ); - method_entry(java_lang_math_tan );
--- a/zero-new-math.patch Fri Oct 05 19:46:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -# 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);
--- a/zero-segfault.patch Fri Oct 05 19:46:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -# 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,