changeset 3802:a3e2f723f2a5

8000780: make Zero build and run with JDK8 Reviewed-by: coleenp, dholmes, twisti Contributed-by: Roman Kennke <rkennke@redhat.com>
author twisti
date Mon, 29 Oct 2012 11:08:48 -0700
parents a516debe2cee
children d8f9034920f6
files make/Makefile src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp src/cpu/zero/vm/cppInterpreter_zero.cpp src/cpu/zero/vm/cppInterpreter_zero.hpp src/cpu/zero/vm/frame_zero.cpp src/cpu/zero/vm/frame_zero.inline.hpp src/cpu/zero/vm/icBuffer_zero.cpp src/cpu/zero/vm/methodHandles_zero.cpp src/cpu/zero/vm/methodHandles_zero.hpp src/cpu/zero/vm/register_zero.hpp src/cpu/zero/vm/relocInfo_zero.cpp src/cpu/zero/vm/sharedRuntime_zero.cpp src/share/vm/asm/codeBuffer.cpp src/share/vm/interpreter/abstractInterpreter.hpp src/share/vm/interpreter/bytecodeInterpreter.cpp src/share/vm/interpreter/bytecodeInterpreter.hpp src/share/vm/interpreter/cppInterpreter.cpp src/share/vm/interpreter/interpreter.cpp src/share/vm/interpreter/templateInterpreter.cpp src/share/vm/runtime/vmStructs.cpp src/share/vm/utilities/macros.hpp
diffstat 21 files changed, 324 insertions(+), 618 deletions(-) [+]
line wrap: on
line diff
--- a/make/Makefile	Fri Oct 26 14:18:57 2012 -0700
+++ b/make/Makefile	Mon Oct 29 11:08:48 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/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp	Mon Oct 29 11:08:48 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/src/cpu/zero/vm/cppInterpreter_zero.cpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp	Mon Oct 29 11:08:48 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/src/cpu/zero/vm/cppInterpreter_zero.hpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/cpu/zero/vm/cppInterpreter_zero.hpp	Mon Oct 29 11:08:48 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/src/cpu/zero/vm/frame_zero.cpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/cpu/zero/vm/frame_zero.cpp	Mon Oct 29 11:08:48 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/src/cpu/zero/vm/frame_zero.inline.hpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/cpu/zero/vm/frame_zero.inline.hpp	Mon Oct 29 11:08:48 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/src/cpu/zero/vm/icBuffer_zero.cpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/cpu/zero/vm/icBuffer_zero.cpp	Mon Oct 29 11:08:48 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/src/cpu/zero/vm/methodHandles_zero.cpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/cpu/zero/vm/methodHandles_zero.cpp	Mon Oct 29 11:08:48 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);
+
 }
 
-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;
+  }
+}
--- a/src/cpu/zero/vm/methodHandles_zero.hpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/cpu/zero/vm/methodHandles_zero.hpp	Mon Oct 29 11:08:48 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/src/cpu/zero/vm/register_zero.hpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/cpu/zero/vm/register_zero.hpp	Mon Oct 29 11:08:48 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/src/cpu/zero/vm/relocInfo_zero.cpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/cpu/zero/vm/relocInfo_zero.cpp	Mon Oct 29 11:08:48 2012 -0700
@@ -77,3 +77,7 @@
                                                        CodeBuffer*       dst) {
   ShouldNotCallThis();
 }
+
+void metadata_Relocation::pd_fix_value(address x) {
+  ShouldNotCallThis();
+}
--- a/src/cpu/zero/vm/sharedRuntime_zero.cpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/cpu/zero/vm/sharedRuntime_zero.cpp	Mon Oct 29 11:08:48 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/src/share/vm/asm/codeBuffer.cpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/share/vm/asm/codeBuffer.cpp	Mon Oct 29 11:08:48 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/src/share/vm/interpreter/abstractInterpreter.hpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/share/vm/interpreter/abstractInterpreter.hpp	Mon Oct 29 11:08:48 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/src/share/vm/interpreter/bytecodeInterpreter.cpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp	Mon Oct 29 11:08:48 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,30 +2196,68 @@
           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);
 
--- a/src/share/vm/interpreter/bytecodeInterpreter.hpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/share/vm/interpreter/bytecodeInterpreter.hpp	Mon Oct 29 11:08:48 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/src/share/vm/interpreter/cppInterpreter.cpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/share/vm/interpreter/cppInterpreter.cpp	Mon Oct 29 11:08:48 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/src/share/vm/interpreter/interpreter.cpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/share/vm/interpreter/interpreter.cpp	Mon Oct 29 11:08:48 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/src/share/vm/interpreter/templateInterpreter.cpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/share/vm/interpreter/templateInterpreter.cpp	Mon Oct 29 11:08:48 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/src/share/vm/runtime/vmStructs.cpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/share/vm/runtime/vmStructs.cpp	Mon Oct 29 11:08:48 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/src/share/vm/utilities/macros.hpp	Fri Oct 26 14:18:57 2012 -0700
+++ b/src/share/vm/utilities/macros.hpp	Mon Oct 29 11:08:48 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