--- old/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	2008-11-08 23:39:21.000000000 -0800
+++ new/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	2008-11-08 23:39:21.000000000 -0800
@@ -160,7 +160,16 @@
 }
 
 
-address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) {
+address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, bool unbox) {
+  TosState incoming_state = state;
+  if (InvokeDynamic) {
+    if (unbox) {
+      incoming_state = atos;
+    }
+  } else {
+    assert(!unbox, "old behavior");
+  }
+
   address compiled_entry = __ pc();
   Label cont;
 
@@ -175,7 +184,7 @@
   // do this here. Unfortunately if we did a rethrow we'd see an machepilog node
   // first which would move g1 -> O0/O1 and destroy the exception we were throwing.
 
-  if( state == ltos ) {
+  if( incoming_state == ltos ) {
     __ srl (G1, 0,O1);
     __ srlx(G1,32,O0);
   }
@@ -192,10 +201,27 @@
 
   __ mov(Llast_SP, SP);   // Remove any adapter added stack space.
 
+  if (unbox && state != atos) {
+    // cast and unbox
+    __ unimplemented();
+  }
 
   const Register cache = G3_scratch;
   const Register size  = G1_scratch;
+  Label L_got_cache, L_giant_index;
+  if (InvokeDynamic) {
+    __ ldub(Lbcp, 0, size);
+    __ cmp(size, Bytecodes::_invokedynamic);
+    __ br(Assembler::equal, false, Assembler::pn, L_giant_index);
+    __ delayed()->nop();
+  }
   __ get_cache_and_index_at_bcp(cache, G1_scratch, 1);
+  ////__ get_cache_and_index_at_bcp(cache, G1_scratch, 1, false);
+  __ bind(L_got_cache);
+  if (unbox && state == atos) {
+    // insert a casting conversion, to keep verifier sane
+    __ unimplemented();
+  }
   __ ld_ptr(Address(cache, 0, in_bytes(constantPoolCacheOopDesc::base_offset()) +
                     in_bytes(ConstantPoolCacheEntry::flags_offset())), size);
   __ and3(size, 0xFF, size);                   // argument size in words
@@ -203,6 +229,15 @@
   __ add(Lesp, size, Lesp);                    // pop arguments
   __ dispatch_next(state, step);
 
+  // out of the main line of code...
+  if (InvokeDynamic) {
+    __ bind(L_giant_index);
+    __ unimplemented();
+    ////__ get_cache_and_index_at_bcp(cache, G1_scratch, 1, true);
+    __ ba(false, L_got_cache);
+    __ delayed()->nop();
+  }
+
   return entry;
 }
 
