hotspot/src/share/vm/code/dependencies.cpp
changeset 30296 95baefac8485
parent 30195 fff35af9b018
child 31037 01a5c5fa5681
--- a/hotspot/src/share/vm/code/dependencies.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/code/dependencies.cpp	Fri Apr 17 18:17:06 2015 +0300
@@ -117,8 +117,9 @@
 }
 
 void Dependencies::assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle) {
-  check_ctxk(call_site->klass());
-  assert_common_2(call_site_target_value, call_site, method_handle);
+  ciKlass* ctxk = call_site->get_context();
+  check_ctxk(ctxk);
+  assert_common_3(call_site_target_value, ctxk, call_site, method_handle);
 }
 
 // Helper function.  If we are adding a new dep. under ctxk2,
@@ -388,7 +389,7 @@
   3, // unique_concrete_subtypes_2 ctxk, k1, k2
   3, // unique_concrete_methods_2 ctxk, m1, m2
   1, // no_finalizable_subclasses ctxk
-  2  // call_site_target_value call_site, method_handle
+  3  // call_site_target_value ctxk, call_site, method_handle
 };
 
 const char* Dependencies::dep_name(Dependencies::DepType dept) {
@@ -594,7 +595,7 @@
   const int nargs = argument_count();
   GrowableArray<DepArgument>* args = new GrowableArray<DepArgument>(nargs);
   for (int j = 0; j < nargs; j++) {
-    if (type() == call_site_target_value) {
+    if (is_oop_argument(j)) {
       args->push(argument_oop(j));
     } else {
       args->push(argument(j));
@@ -614,7 +615,7 @@
   int nargs = argument_count();
   GrowableArray<DepArgument>* args = new GrowableArray<DepArgument>(nargs);
   for (int j = 0; j < nargs; j++) {
-    if (type() == call_site_target_value) {
+    if (is_oop_argument(j)) {
       args->push(argument_oop(j));
     } else {
       args->push(argument(j));
@@ -710,7 +711,7 @@
  * Returns a unique identifier for each dependency argument.
  */
 uintptr_t Dependencies::DepStream::get_identifier(int i) {
-  if (has_oop_argument()) {
+  if (is_oop_argument(i)) {
     return (uintptr_t)(oopDesc*)argument_oop(i);
   } else {
     return (uintptr_t)argument(i);
@@ -737,7 +738,7 @@
   }
 
   // Some dependencies are using the klass of the first object
-  // argument as implicit context type (e.g. call_site_target_value).
+  // argument as implicit context type.
   {
     int ctxkj = dep_implicit_context_arg(type());
     if (ctxkj >= 0) {
@@ -1514,9 +1515,16 @@
   return find_finalizable_subclass(search_at);
 }
 
-Klass* Dependencies::check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes) {
-  assert(call_site    ->is_a(SystemDictionary::CallSite_klass()),     "sanity");
-  assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "sanity");
+Klass* Dependencies::check_call_site_target_value(Klass* recorded_ctxk, oop call_site, oop method_handle, CallSiteDepChange* changes) {
+  assert(call_site->is_a(SystemDictionary::CallSite_klass()),     "sanity");
+  assert(!oopDesc::is_null(method_handle), "sanity");
+
+  Klass* call_site_ctxk = MethodHandles::get_call_site_context(call_site);
+  assert(!Klass::is_null(call_site_ctxk), "call site context should be initialized already");
+  if (recorded_ctxk != call_site_ctxk) {
+    // Stale context
+    return recorded_ctxk;
+  }
   if (changes == NULL) {
     // Validate all CallSites
     if (java_lang_invoke_CallSite::target(call_site) != method_handle)
@@ -1531,7 +1539,6 @@
   return NULL;  // assertion still valid
 }
 
-
 void Dependencies::DepStream::trace_and_log_witness(Klass* witness) {
   if (witness != NULL) {
     if (TraceDependencies) {
@@ -1592,7 +1599,7 @@
   Klass* witness = NULL;
   switch (type()) {
   case call_site_target_value:
-    witness = check_call_site_target_value(argument_oop(0), argument_oop(1), changes);
+    witness = check_call_site_target_value(context_type(), argument_oop(1), argument_oop(2), changes);
     break;
   default:
     witness = NULL;