--- a/hotspot/make/Makefile Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/make/Makefile Fri Nov 02 04:06:00 2012 -0700
@@ -453,14 +453,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
ifeq ($(JVM_VARIANT_MINIMAL1), true)
$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(MINIMAL1_DIR)/%.$(LIBRARY_SUFFIX)
--- a/hotspot/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp Fri Nov 02 04:06:00 2012 -0700
@@ -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
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Fri Nov 02 04:06:00 2012 -0700
@@ -180,25 +180,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 +516,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 +554,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 +610,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 +851,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 +858,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;
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp Fri Nov 02 04:06:00 2012 -0700
@@ -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);
--- a/hotspot/src/cpu/zero/vm/frame_zero.cpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/cpu/zero/vm/frame_zero.cpp Fri Nov 02 04:06:00 2012 -0700
@@ -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(),
@@ -430,4 +430,3 @@
// unused... but returns fp() to minimize changes introduced by 7087445
return fp();
}
-
--- a/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp Fri Nov 02 04:06:00 2012 -0700
@@ -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;
--- a/hotspot/src/cpu/zero/vm/icBuffer_zero.cpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/cpu/zero/vm/icBuffer_zero.cpp Fri Nov 02 04:06:00 2012 -0700
@@ -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();
}
--- a/hotspot/src/cpu/zero/vm/methodHandles_zero.cpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/cpu/zero/vm/methodHandles_zero.cpp Fri Nov 02 04:06:00 2012 -0700
@@ -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);
+
+}
+
+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;
}
-void MethodHandles::generate_method_handle_stub(MacroAssembler* masm,
- MethodHandles::EntryKind ek) {
- init_entry(ek, (MethodHandleEntry *) ek);
+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;
+ }
+}
--- a/hotspot/src/cpu/zero/vm/methodHandles_zero.hpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/cpu/zero/vm/methodHandles_zero.hpp Fri Nov 02 04:06:00 2012 -0700
@@ -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);
--- a/hotspot/src/cpu/zero/vm/register_zero.hpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/cpu/zero/vm/register_zero.hpp Fri Nov 02 04:06:00 2012 -0700
@@ -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
--- a/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp Fri Nov 02 04:06:00 2012 -0700
@@ -77,3 +77,7 @@
CodeBuffer* dst) {
ShouldNotCallThis();
}
+
+void metadata_Relocation::pd_fix_value(address x) {
+ ShouldNotCallThis();
+}
--- a/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp Fri Nov 02 04:06:00 2012 -0700
@@ -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) {
--- a/hotspot/src/share/vm/asm/codeBuffer.cpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/share/vm/asm/codeBuffer.cpp Fri Nov 02 04:06:00 2012 -0700
@@ -758,7 +758,7 @@
}
}
- if (dest->blob() == NULL) {
+ if (dest->blob() == NULL && dest_filled != NULL) {
// 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,
--- a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp Fri Nov 02 04:06:00 2012 -0700
@@ -320,6 +320,7 @@
void bang_stack_shadow_pages(bool native_call);
void generate_all();
+ void initialize_method_handle_entries();
public:
AbstractInterpreterGenerator(StubQueue* _code);
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Fri Nov 02 04:06:00 2012 -0700
@@ -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,26 +2196,64 @@
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);
+ }
+
+ 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();
}
- 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);
- istate->set_bcp_advance(5);
+ 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...
}
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp Fri Nov 02 04:06:00 2012 -0700
@@ -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
--- a/hotspot/src/share/vm/interpreter/cppInterpreter.cpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/share/vm/interpreter/cppInterpreter.cpp Fri Nov 02 04:06:00 2012 -0700
@@ -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,7 +124,12 @@
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);
+
+ initialize_method_handle_entries();
+
Interpreter::_native_entry_begin = Interpreter::code()->code_end();
method_entry(native);
method_entry(native_synchronized);
--- a/hotspot/src/share/vm/interpreter/interpreter.cpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreter.cpp Fri Nov 02 04:06:00 2012 -0700
@@ -464,3 +464,11 @@
}
}
}
+
+void AbstractInterpreterGenerator::initialize_method_handle_entries() {
+ // method handle entry kinds are generated later in MethodHandlesAdapterGenerator::generate:
+ for (int i = Interpreter::method_handle_invoke_FIRST; i <= Interpreter::method_handle_invoke_LAST; i++) {
+ Interpreter::MethodKind kind = (Interpreter::MethodKind) i;
+ Interpreter::_entry_table[kind] = Interpreter::_entry_table[Interpreter::abstract];
+ }
+}
--- a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp Fri Nov 02 04:06:00 2012 -0700
@@ -373,11 +373,7 @@
method_entry(java_lang_math_pow )
method_entry(java_lang_ref_reference_get)
- // method handle entry kinds are generated later in MethodHandlesAdapterGenerator::generate:
- for (int i = Interpreter::method_handle_invoke_FIRST; i <= Interpreter::method_handle_invoke_LAST; i++) {
- Interpreter::MethodKind kind = (Interpreter::MethodKind) i;
- Interpreter::_entry_table[kind] = Interpreter::_entry_table[Interpreter::abstract];
- }
+ initialize_method_handle_entries();
// all native method kinds (must be one contiguous block)
Interpreter::_native_entry_begin = Interpreter::code()->code_end();
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Fri Nov 02 04:06:00 2012 -0700
@@ -2474,7 +2474,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) \
\
/*************/ \
--- a/hotspot/src/share/vm/utilities/macros.hpp Thu Nov 01 23:08:07 2012 -0700
+++ b/hotspot/src/share/vm/utilities/macros.hpp Fri Nov 02 04:06:00 2012 -0700
@@ -282,6 +282,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