< prev index next >

src/share/vm/runtime/jniHandles.hpp

Print this page
rev 12906 : [mq]: gc_interface


  23  */
  24 
  25 #ifndef SHARE_VM_RUNTIME_JNIHANDLES_HPP
  26 #define SHARE_VM_RUNTIME_JNIHANDLES_HPP
  27 
  28 #include "memory/allocation.hpp"
  29 #include "runtime/handles.hpp"
  30 
  31 class JNIHandleBlock;
  32 
  33 
  34 // Interface for creating and resolving local/global JNI handles
  35 
  36 class JNIHandles : AllStatic {
  37   friend class VMStructs;
  38  private:
  39   static JNIHandleBlock* _global_handles;             // First global handle block
  40   static JNIHandleBlock* _weak_global_handles;        // First weak global handle block
  41   static oop _deleted_handle;                         // Sentinel marking deleted handles
  42 

  43   inline static bool is_jweak(jobject handle);
  44   inline static oop& jobject_ref(jobject handle); // NOT jweak!
  45   inline static oop& jweak_ref(jobject handle);
  46 
  47   template<bool external_guard> inline static oop guard_value(oop value);
  48   template<bool external_guard> inline static oop resolve_impl(jobject handle);
  49   template<bool external_guard> static oop resolve_jweak(jweak handle);
  50 































































  51  public:
  52   // Low tag bit in jobject used to distinguish a jweak.  jweak is
  53   // type equivalent to jobject, but there are places where we need to
  54   // be able to distinguish jweak values from other jobjects, and
  55   // is_weak_global_handle is unsuitable for performance reasons.  To
  56   // provide such a test we add weak_tag_value to the (aligned) byte
  57   // address designated by the jobject to produce the corresponding
  58   // jweak.  Accessing the value of a jobject must account for it
  59   // being a possibly offset jweak.
  60   static const uintptr_t weak_tag_size = 1;
  61   static const uintptr_t weak_tag_alignment = (1u << weak_tag_size);
  62   static const uintptr_t weak_tag_mask = weak_tag_alignment - 1;
  63   static const int weak_tag_value = 1;
  64 
  65   // Resolve handle into oop
  66   inline static oop resolve(jobject handle);
  67   // Resolve externally provided handle into oop with some guards
  68   inline static oop resolve_external_guard(jobject handle);
  69   // Resolve handle into oop, result guaranteed not to be null
  70   inline static oop resolve_non_null(jobject handle);


 186   const size_t get_planned_capacity() { return _planned_capacity; }
 187   const size_t get_number_of_live_handles();
 188 
 189   // Debugging
 190   bool chain_contains(jobject handle) const;    // Does this block or following blocks contain handle
 191   bool contains(jobject handle) const;          // Does this block contain handle
 192   int length() const;                           // Length of chain starting with this block
 193   long memory_usage() const;
 194   #ifndef PRODUCT
 195   static bool any_contains(jobject handle);     // Does any block currently in use contain handle
 196   static void print_statistics();
 197   #endif
 198 };
 199 
 200 inline bool JNIHandles::is_jweak(jobject handle) {
 201   STATIC_ASSERT(weak_tag_size == 1);
 202   STATIC_ASSERT(weak_tag_value == 1);
 203   return (reinterpret_cast<uintptr_t>(handle) & weak_tag_mask) != 0;
 204 }
 205 
 206 inline oop& JNIHandles::jobject_ref(jobject handle) {
 207   assert(!is_jweak(handle), "precondition");
 208   return *reinterpret_cast<oop*>(handle);
 209 }
 210 
 211 inline oop& JNIHandles::jweak_ref(jobject handle) {
 212   assert(is_jweak(handle), "precondition");
 213   char* ptr = reinterpret_cast<char*>(handle) - weak_tag_value;
 214   return *reinterpret_cast<oop*>(ptr);
 215 }
 216 
 217 // external_guard is true if called from resolve_external_guard.
 218 // Treat deleted (and possibly zapped) as NULL for external_guard,
 219 // else as (asserted) error.
 220 template<bool external_guard>
 221 inline oop JNIHandles::guard_value(oop value) {
 222   if (!external_guard) {
 223     assert(value != badJNIHandle, "Pointing to zapped jni handle area");
 224     assert(value != deleted_handle(), "Used a deleted global handle");
 225   } else if ((value == badJNIHandle) || (value == deleted_handle())) {
 226     value = NULL;
 227   }
 228   return value;
 229 }
 230 
 231 // external_guard is true if called from resolve_external_guard.
 232 template<bool external_guard>
 233 inline oop JNIHandles::resolve_impl(jobject handle) {
 234   assert(handle != NULL, "precondition");
 235   oop result;
 236   if (is_jweak(handle)) {       // Unlikely
 237     result = resolve_jweak<external_guard>(handle);
 238   } else {
 239     result = jobject_ref(handle);
 240     // Construction of jobjects canonicalize a null value into a null
 241     // jobject, so for non-jweak the pointee should never be null.
 242     assert(external_guard || result != NULL,
 243            "Invalid value read from jni handle");
 244     result = guard_value<external_guard>(result);
 245   }
 246   return result;
 247 }
 248 
 249 inline oop JNIHandles::resolve(jobject handle) {
 250   oop result = NULL;
 251   if (handle != NULL) {
 252     result = resolve_impl<false /* external_guard */ >(handle);
 253   }
 254   return result;
 255 }
 256 
 257 // Resolve some erroneous cases to NULL, rather than treating them as
 258 // possibly unchecked errors.  In particular, deleted handles are
 259 // treated as NULL (though a deleted and later reallocated handle
 260 // isn't detected).
 261 inline oop JNIHandles::resolve_external_guard(jobject handle) {
 262   oop result = NULL;
 263   if (handle != NULL) {
 264     result = resolve_impl<true /* external_guard */ >(handle);
 265   }
 266   return result;
 267 }
 268 
 269 inline oop JNIHandles::resolve_non_null(jobject handle) {
 270   assert(handle != NULL, "JNI handle should not be null");
 271   oop result = resolve_impl<false /* external_guard */ >(handle);
 272   assert(result != NULL, "NULL read from jni handle");
 273   return result;
 274 }
 275 
 276 inline void JNIHandles::destroy_local(jobject handle) {
 277   if (handle != NULL) {
 278     jobject_ref(handle) = deleted_handle();
 279   }
 280 }
 281 
 282 #endif // SHARE_VM_RUNTIME_JNIHANDLES_HPP


  23  */
  24 
  25 #ifndef SHARE_VM_RUNTIME_JNIHANDLES_HPP
  26 #define SHARE_VM_RUNTIME_JNIHANDLES_HPP
  27 
  28 #include "memory/allocation.hpp"
  29 #include "runtime/handles.hpp"
  30 
  31 class JNIHandleBlock;
  32 
  33 
  34 // Interface for creating and resolving local/global JNI handles
  35 
  36 class JNIHandles : AllStatic {
  37   friend class VMStructs;
  38  private:
  39   static JNIHandleBlock* _global_handles;             // First global handle block
  40   static JNIHandleBlock* _weak_global_handles;        // First weak global handle block
  41   static oop _deleted_handle;                         // Sentinel marking deleted handles
  42 
  43   inline static oop* oop_addr(jobject handle);
  44   inline static bool is_jweak(jobject handle);


  45 
  46   template<bool external_guard> inline static oop guard_value(oop value);
  47   template<bool external_guard> inline static oop resolve_impl(jobject handle);
  48   template<bool external_guard> static oop resolve_jweak(jweak handle);
  49 
  50   static oop resolve_handle(jobject handle);
  51 
  52   enum ResolveType {
  53     DEFAULT,
  54     EXTERNAL_GUARD,
  55     NOT_NULL
  56   };
  57 
  58   template <ResolveType type>
  59   class JNIHandleResolver: public StackObj {
  60     oop _value;
  61 
  62     bool is_not_null() const {
  63       return type == NOT_NULL;
  64     }
  65 
  66     bool is_external_guard() const {
  67       return type == EXTERNAL_GUARD;
  68     }
  69 
  70     bool is_default() const {
  71       return type == DEFAULT;
  72     }
  73 
  74     bool is_dead(oop value) const {
  75       return value == NULL || value == badJNIHandle || value == deleted_handle();
  76     }
  77 
  78     void assert_not_dead(oop value) const {
  79       if (!is_external_guard()) {
  80         assert(value != badJNIHandle, "Pointing to zapped jni handle area");
  81         assert(value == NULL || value != deleted_handle(), "Used a deleted global handle");
  82       }
  83     }
  84 
  85   public:
  86     JNIHandleResolver(jobject handle) {
  87       oop value;
  88       assert(!is_not_null() || handle != NULL, "JNI handle should not be null");
  89       if (!is_not_null() && handle == NULL) {
  90         value = NULL;
  91       } else {
  92         value = *oop_addr(handle);
  93         assert_not_dead(value);
  94         if (is_external_guard() && is_dead(value)) {
  95           value = NULL;
  96         } else {
  97           value = resolve_handle(handle);
  98         }
  99       }
 100       _value = value;
 101     }
 102 
 103     oop value() const {
 104       return _value;
 105     }
 106 
 107     ~JNIHandleResolver() {
 108       assert_not_dead(_value);
 109       assert(!is_not_null() || _value != NULL, "NULL read from jni handle");
 110     }
 111   };
 112 
 113  public:
 114   // Low tag bit in jobject used to distinguish a jweak.  jweak is
 115   // type equivalent to jobject, but there are places where we need to
 116   // be able to distinguish jweak values from other jobjects, and
 117   // is_weak_global_handle is unsuitable for performance reasons.  To
 118   // provide such a test we add weak_tag_value to the (aligned) byte
 119   // address designated by the jobject to produce the corresponding
 120   // jweak.  Accessing the value of a jobject must account for it
 121   // being a possibly offset jweak.
 122   static const uintptr_t weak_tag_size = 1;
 123   static const uintptr_t weak_tag_alignment = (1u << weak_tag_size);
 124   static const uintptr_t weak_tag_mask = weak_tag_alignment - 1;
 125   static const int weak_tag_value = 1;
 126 
 127   // Resolve handle into oop
 128   inline static oop resolve(jobject handle);
 129   // Resolve externally provided handle into oop with some guards
 130   inline static oop resolve_external_guard(jobject handle);
 131   // Resolve handle into oop, result guaranteed not to be null
 132   inline static oop resolve_non_null(jobject handle);


 248   const size_t get_planned_capacity() { return _planned_capacity; }
 249   const size_t get_number_of_live_handles();
 250 
 251   // Debugging
 252   bool chain_contains(jobject handle) const;    // Does this block or following blocks contain handle
 253   bool contains(jobject handle) const;          // Does this block contain handle
 254   int length() const;                           // Length of chain starting with this block
 255   long memory_usage() const;
 256   #ifndef PRODUCT
 257   static bool any_contains(jobject handle);     // Does any block currently in use contain handle
 258   static void print_statistics();
 259   #endif
 260 };
 261 
 262 inline bool JNIHandles::is_jweak(jobject handle) {
 263   STATIC_ASSERT(weak_tag_size == 1);
 264   STATIC_ASSERT(weak_tag_value == 1);
 265   return (reinterpret_cast<uintptr_t>(handle) & weak_tag_mask) != 0;
 266 }
 267 
 268 inline oop* JNIHandles::oop_addr(jobject handle) {
 269   return (oop*)(reinterpret_cast<uintptr_t>(handle) & ~(weak_tag_mask));







































 270 }
 271 
 272 inline oop JNIHandles::resolve(jobject handle) {
 273   return JNIHandleResolver<DEFAULT>(handle).value();




 274 }
 275 
 276 // Resolve some erroneous cases to NULL, rather than treating them as
 277 // possibly unchecked errors.  In particular, deleted handles are
 278 // treated as NULL (though a deleted and later reallocated handle
 279 // isn't detected).
 280 inline oop JNIHandles::resolve_external_guard(jobject handle) {
 281   return JNIHandleResolver<EXTERNAL_GUARD>(handle).value();




 282 }
 283 
 284 inline oop JNIHandles::resolve_non_null(jobject handle) {
 285   return JNIHandleResolver<NOT_NULL>(handle).value();



 286 }
 287 
 288 inline void JNIHandles::destroy_local(jobject handle) {
 289   if (handle != NULL) {
 290     *oop_addr(handle) = deleted_handle();
 291   }
 292 }
 293 
 294 #endif // SHARE_VM_RUNTIME_JNIHANDLES_HPP
< prev index next >