diff src/share/vm/c1/c1_LIRGenerator.cpp @ 1295:3cf667df43ef

6919934: JSR 292 needs to support x86 C1 Summary: This implements JSR 292 support for C1 x86. Reviewed-by: never, jrose, kvn
author twisti
date Tue, 09 Mar 2010 20:16:19 +0100
parents 6deeaebad47a
children 76c1d7d13ec5
line wrap: on
line diff
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Mon Mar 08 04:46:30 2010 -0800
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Mar 09 20:16:19 2010 +0100
@@ -2284,7 +2284,7 @@
 
 
 void LIRGenerator::invoke_load_arguments(Invoke* x, LIRItemList* args, const LIR_OprList* arg_list) {
-  int i = x->has_receiver() ? 1 : 0;
+  int i = (x->has_receiver() || x->is_invokedynamic()) ? 1 : 0;
   for (; i < args->length(); i++) {
     LIRItem* param = args->at(i);
     LIR_Opr loc = arg_list->at(i);
@@ -2322,6 +2322,10 @@
     LIRItem* receiver = new LIRItem(x->receiver(), this);
     argument_items->append(receiver);
   }
+  if (x->is_invokedynamic()) {
+    // Insert a dummy for the synthetic MethodHandle argument.
+    argument_items->append(NULL);
+  }
   int idx = x->has_receiver() ? 1 : 0;
   for (int i = 0; i < x->number_of_arguments(); i++) {
     LIRItem* param = new LIRItem(x->argument_at(i), this);
@@ -2371,6 +2375,10 @@
 
   CodeEmitInfo* info = state_for(x, x->state());
 
+  // invokedynamics can deoptimize.
+  bool is_invokedynamic = x->code() == Bytecodes::_invokedynamic;
+  CodeEmitInfo* deopt_info = is_invokedynamic ? state_for(x, x->state_before()) : NULL;
+
   invoke_load_arguments(x, args, arg_list);
 
   if (x->has_receiver()) {
@@ -2407,6 +2415,47 @@
         __ call_virtual(x->target(), receiver, result_register, vtable_offset, arg_list, info);
       }
       break;
+    case Bytecodes::_invokedynamic: {
+      ciBytecodeStream bcs(x->scope()->method());
+      bcs.force_bci(x->bci());
+      assert(bcs.cur_bc() == Bytecodes::_invokedynamic, "wrong stream");
+      ciCPCache* cpcache = bcs.get_cpcache();
+
+      // Get CallSite offset from constant pool cache pointer.
+      int index = bcs.get_method_index();
+      size_t call_site_offset = cpcache->get_f1_offset(index);
+
+      // If this invokedynamic call site hasn't been executed yet in
+      // the interpreter, the CallSite object in the constant pool
+      // cache is still null and we need to deoptimize.
+      if (cpcache->is_f1_null_at(index)) {
+        // Cannot re-use same xhandlers for multiple CodeEmitInfos, so
+        // clone all handlers.  This is handled transparently in other
+        // places by the CodeEmitInfo cloning logic but is handled
+        // specially here because a stub isn't being used.
+        x->set_exception_handlers(new XHandlers(x->exception_handlers()));
+
+        DeoptimizeStub* deopt_stub = new DeoptimizeStub(deopt_info);
+        __ jump(deopt_stub);
+      }
+
+      // Use the receiver register for the synthetic MethodHandle
+      // argument.
+      receiver = LIR_Assembler::receiverOpr();
+      LIR_Opr tmp = new_register(objectType);
+
+      // Load CallSite object from constant pool cache.
+      __ oop2reg(cpcache->constant_encoding(), tmp);
+      __ load(new LIR_Address(tmp, call_site_offset, T_OBJECT), tmp);
+
+      // Load target MethodHandle from CallSite object.
+      __ load(new LIR_Address(tmp, java_dyn_CallSite::target_offset_in_bytes(), T_OBJECT), receiver);
+
+      __ call_dynamic(x->target(), receiver, result_register,
+                      SharedRuntime::get_resolve_opt_virtual_call_stub(),
+                      arg_list, info);
+      break;
+    }
     default:
       ShouldNotReachHere();
       break;