hotspot/src/share/vm/ci/ciEnv.cpp
changeset 5124 9dd40e895ad1
parent 5123 63268b13ffeb
parent 4764 d15bb22d4d39
child 5353 30f4b75f8005
--- a/hotspot/src/share/vm/ci/ciEnv.cpp	Mon Mar 15 15:51:36 2010 -0400
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp	Wed Mar 24 17:16:33 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,14 +38,9 @@
 ciTypeArrayKlassKlass* ciEnv::_type_array_klass_klass_instance;
 ciObjArrayKlassKlass*  ciEnv::_obj_array_klass_klass_instance;
 
-ciInstanceKlass* ciEnv::_ArrayStoreException;
-ciInstanceKlass* ciEnv::_Class;
-ciInstanceKlass* ciEnv::_ClassCastException;
-ciInstanceKlass* ciEnv::_Object;
-ciInstanceKlass* ciEnv::_Throwable;
-ciInstanceKlass* ciEnv::_Thread;
-ciInstanceKlass* ciEnv::_OutOfMemoryError;
-ciInstanceKlass* ciEnv::_String;
+#define WK_KLASS_DEFN(name, ignore_s, ignore_o) ciInstanceKlass* ciEnv::_##name = NULL;
+WK_KLASSES_DO(WK_KLASS_DEFN)
+#undef WK_KLASS_DEFN
 
 ciSymbol*        ciEnv::_unloaded_cisymbol = NULL;
 ciInstanceKlass* ciEnv::_unloaded_ciinstance_klass = NULL;
@@ -110,6 +105,8 @@
   _ArrayIndexOutOfBoundsException_instance = NULL;
   _ArrayStoreException_instance = NULL;
   _ClassCastException_instance = NULL;
+  _the_null_string = NULL;
+  _the_min_jint_string = NULL;
 }
 
 ciEnv::ciEnv(Arena* arena) {
@@ -163,6 +160,8 @@
   _ArrayIndexOutOfBoundsException_instance = NULL;
   _ArrayStoreException_instance = NULL;
   _ClassCastException_instance = NULL;
+  _the_null_string = NULL;
+  _the_min_jint_string = NULL;
 }
 
 ciEnv::~ciEnv() {
@@ -179,7 +178,7 @@
   _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint();
   _jvmti_can_examine_or_deopt_anywhere  = JvmtiExport::can_examine_or_deopt_anywhere();
   _jvmti_can_access_local_variables     = JvmtiExport::can_access_local_variables();
-  _jvmti_can_post_exceptions            = JvmtiExport::can_post_exceptions();
+  _jvmti_can_post_on_exceptions         = JvmtiExport::can_post_on_exceptions();
 }
 
 // ------------------------------------------------------------------
@@ -248,6 +247,22 @@
   return _ClassCastException_instance;
 }
 
+ciInstance* ciEnv::the_null_string() {
+  if (_the_null_string == NULL) {
+    VM_ENTRY_MARK;
+    _the_null_string = get_object(Universe::the_null_string())->as_instance();
+  }
+  return _the_null_string;
+}
+
+ciInstance* ciEnv::the_min_jint_string() {
+  if (_the_min_jint_string == NULL) {
+    VM_ENTRY_MARK;
+    _the_min_jint_string = get_object(Universe::the_min_jint_string())->as_instance();
+  }
+  return _the_min_jint_string;
+}
+
 // ------------------------------------------------------------------
 // ciEnv::get_method_from_handle
 ciMethod* ciEnv::get_method_from_handle(jobject method) {
@@ -419,12 +434,11 @@
 // ciEnv::get_klass_by_index_impl
 //
 // Implementation of get_klass_by_index.
-ciKlass* ciEnv::get_klass_by_index_impl(ciInstanceKlass* accessor,
+ciKlass* ciEnv::get_klass_by_index_impl(constantPoolHandle cpool,
                                         int index,
-                                        bool& is_accessible) {
-  assert(accessor->get_instanceKlass()->is_linked(), "must be linked before accessing constant pool");
+                                        bool& is_accessible,
+                                        ciInstanceKlass* accessor) {
   EXCEPTION_CONTEXT;
-  constantPoolHandle cpool(THREAD, accessor->get_instanceKlass()->constants());
   KlassHandle klass (THREAD, constantPoolOopDesc::klass_at_if_loaded(cpool, index));
   symbolHandle klass_name;
   if (klass.is_null()) {
@@ -486,22 +500,21 @@
 // ciEnv::get_klass_by_index
 //
 // Get a klass from the constant pool.
-ciKlass* ciEnv::get_klass_by_index(ciInstanceKlass* accessor,
+ciKlass* ciEnv::get_klass_by_index(constantPoolHandle cpool,
                                    int index,
-                                   bool& is_accessible) {
-  GUARDED_VM_ENTRY(return get_klass_by_index_impl(accessor, index, is_accessible);)
+                                   bool& is_accessible,
+                                   ciInstanceKlass* accessor) {
+  GUARDED_VM_ENTRY(return get_klass_by_index_impl(cpool, index, is_accessible, accessor);)
 }
 
 // ------------------------------------------------------------------
 // ciEnv::get_constant_by_index_impl
 //
 // Implementation of get_constant_by_index().
-ciConstant ciEnv::get_constant_by_index_impl(ciInstanceKlass* accessor,
-                                             int index) {
+ciConstant ciEnv::get_constant_by_index_impl(constantPoolHandle cpool,
+                                             int index,
+                                             ciInstanceKlass* accessor) {
   EXCEPTION_CONTEXT;
-  instanceKlass* ik_accessor = accessor->get_instanceKlass();
-  assert(ik_accessor->is_linked(), "must be linked before accessing constant pool");
-  constantPoolOop cpool = ik_accessor->constants();
   constantTag tag = cpool->tag_at(index);
   if (tag.is_int()) {
     return ciConstant(T_INT, (jint)cpool->int_at(index));
@@ -529,7 +542,7 @@
   } else if (tag.is_klass() || tag.is_unresolved_klass()) {
     // 4881222: allow ldc to take a class type
     bool ignore;
-    ciKlass* klass = get_klass_by_index_impl(accessor, index, ignore);
+    ciKlass* klass = get_klass_by_index_impl(cpool, index, ignore, accessor);
     if (HAS_PENDING_EXCEPTION) {
       CLEAR_PENDING_EXCEPTION;
       record_out_of_memory_failure();
@@ -538,6 +551,11 @@
     assert (klass->is_instance_klass() || klass->is_array_klass(),
             "must be an instance or array klass ");
     return ciConstant(T_OBJECT, klass);
+  } else if (tag.is_object()) {
+    oop obj = cpool->object_at(index);
+    assert(obj->is_instance(), "must be an instance");
+    ciObject* ciobj = get_object(obj);
+    return ciConstant(T_OBJECT, ciobj);
   } else {
     ShouldNotReachHere();
     return ciConstant();
@@ -574,9 +592,10 @@
 // Pull a constant out of the constant pool.  How appropriate.
 //
 // Implementation note: this query is currently in no way cached.
-ciConstant ciEnv::get_constant_by_index(ciInstanceKlass* accessor,
-                                        int index) {
-  GUARDED_VM_ENTRY(return get_constant_by_index_impl(accessor, index); )
+ciConstant ciEnv::get_constant_by_index(constantPoolHandle cpool,
+                                        int index,
+                                        ciInstanceKlass* accessor) {
+  GUARDED_VM_ENTRY(return get_constant_by_index_impl(cpool, index, accessor);)
 }
 
 // ------------------------------------------------------------------
@@ -586,7 +605,7 @@
 //
 // Implementation note: this query is currently in no way cached.
 bool ciEnv::is_unresolved_string(ciInstanceKlass* accessor,
-                                        int index) const {
+                                 int index) const {
   GUARDED_VM_ENTRY(return is_unresolved_string_impl(accessor->get_instanceKlass(), index); )
 }
 
@@ -597,7 +616,7 @@
 //
 // Implementation note: this query is currently in no way cached.
 bool ciEnv::is_unresolved_klass(ciInstanceKlass* accessor,
-                                        int index) const {
+                                int index) const {
   GUARDED_VM_ENTRY(return is_unresolved_klass_impl(accessor->get_instanceKlass(), index); )
 }
 
@@ -678,22 +697,17 @@
 
 // ------------------------------------------------------------------
 // ciEnv::get_method_by_index_impl
-ciMethod* ciEnv::get_method_by_index_impl(ciInstanceKlass* accessor,
-                                     int index, Bytecodes::Code bc) {
-  // Get the method's declared holder.
-
-  assert(accessor->get_instanceKlass()->is_linked(), "must be linked before accessing constant pool");
-  constantPoolHandle cpool = accessor->get_instanceKlass()->constants();
+ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool,
+                                          int index, Bytecodes::Code bc,
+                                          ciInstanceKlass* accessor) {
   int holder_index = cpool->klass_ref_index_at(index);
   bool holder_is_accessible;
-  ciKlass* holder = get_klass_by_index_impl(accessor, holder_index, holder_is_accessible);
+  ciKlass* holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor);
   ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder);
 
   // Get the method's name and signature.
-  int nt_index = cpool->name_and_type_ref_index_at(index);
-  int sig_index = cpool->signature_ref_index_at(nt_index);
   symbolOop name_sym = cpool->name_ref_at(index);
-  symbolOop sig_sym = cpool->symbol_at(sig_index);
+  symbolOop sig_sym  = cpool->signature_ref_at(index);
 
   if (holder_is_accessible) { // Our declared holder is loaded.
     instanceKlass* lookup = declared_holder->get_instanceKlass();
@@ -715,6 +729,33 @@
 
 
 // ------------------------------------------------------------------
+// ciEnv::get_fake_invokedynamic_method_impl
+ciMethod* ciEnv::get_fake_invokedynamic_method_impl(constantPoolHandle cpool,
+                                                    int index, Bytecodes::Code bc) {
+  assert(bc == Bytecodes::_invokedynamic, "must be invokedynamic");
+
+  // Get the CallSite from the constant pool cache.
+  ConstantPoolCacheEntry* cpc_entry = cpool->cache()->secondary_entry_at(index);
+  assert(cpc_entry != NULL && cpc_entry->is_secondary_entry(), "sanity");
+  Handle call_site = cpc_entry->f1();
+
+  // Call site might not be linked yet.
+  if (call_site.is_null()) {
+    ciInstanceKlass* mh_klass = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass();
+    ciSymbol*       sig_sym   = get_object(cpool->signature_ref_at(index))->as_symbol();
+    return get_unloaded_method(mh_klass, ciSymbol::invoke_name(), sig_sym);
+  }
+
+  // Get the methodOop from the CallSite.
+  methodOop method_oop = (methodOop) java_dyn_CallSite::vmmethod(call_site());
+  assert(method_oop != NULL, "sanity");
+  assert(method_oop->is_method_handle_invoke(), "consistent");
+
+  return get_object(method_oop)->as_method();
+}
+
+
+// ------------------------------------------------------------------
 // ciEnv::get_instance_klass_for_declared_method_holder
 ciInstanceKlass* ciEnv::get_instance_klass_for_declared_method_holder(ciKlass* method_holder) {
   // For the case of <array>.clone(), the method holder can be a ciArrayKlass
@@ -736,15 +777,19 @@
 }
 
 
-
-
 // ------------------------------------------------------------------
 // ciEnv::get_method_by_index
-ciMethod* ciEnv::get_method_by_index(ciInstanceKlass* accessor,
-                                     int index, Bytecodes::Code bc) {
-  GUARDED_VM_ENTRY(return get_method_by_index_impl(accessor, index, bc);)
+ciMethod* ciEnv::get_method_by_index(constantPoolHandle cpool,
+                                     int index, Bytecodes::Code bc,
+                                     ciInstanceKlass* accessor) {
+  if (bc == Bytecodes::_invokedynamic) {
+    GUARDED_VM_ENTRY(return get_fake_invokedynamic_method_impl(cpool, index, bc);)
+  } else {
+    GUARDED_VM_ENTRY(return get_method_by_index_impl(cpool, index, bc, accessor);)
+  }
 }
 
+
 // ------------------------------------------------------------------
 // ciEnv::name_buffer
 char *ciEnv::name_buffer(int req_len) {
@@ -846,8 +891,8 @@
            JvmtiExport::can_examine_or_deopt_anywhere()) ||
           (!jvmti_can_access_local_variables() &&
            JvmtiExport::can_access_local_variables()) ||
-          (!jvmti_can_post_exceptions() &&
-           JvmtiExport::can_post_exceptions()) )) {
+          (!jvmti_can_post_on_exceptions() &&
+           JvmtiExport::can_post_on_exceptions()) )) {
       record_failure("Jvmti state change invalidated dependencies");
     }
 
@@ -917,18 +962,10 @@
     if (nm == NULL) {
       // The CodeCache is full.  Print out warning and disable compilation.
       record_failure("code cache is full");
-      UseInterpreter = true;
-      if (UseCompiler || AlwaysCompileLoopMethods ) {
-#ifndef PRODUCT
-        warning("CodeCache is full. Compiler has been disabled");
-        if (CompileTheWorld || ExitOnFullCodeCache) {
-          before_exit(JavaThread::current());
-          exit_globals(); // will delete tty
-          vm_direct_exit(CompileTheWorld ? 0 : 1);
-        }
-#endif
-        UseCompiler               = false;
-        AlwaysCompileLoopMethods  = false;
+      {
+        MutexUnlocker ml(Compile_lock);
+        MutexUnlocker locker(MethodCompileQueue_lock);
+        CompileBroker::handle_full_code_cache();
       }
     } else {
       NOT_PRODUCT(nm->set_has_debug_info(has_debug_info); )