src/share/vm/runtime/jniHandles.hpp

changeset 9669
32bc598624bd
parent 9665
a8441ccaff15
child 9703
2fdf635bcf28
     1.1 --- a/src/share/vm/runtime/jniHandles.hpp	Thu Nov 05 11:42:42 2015 +0100
     1.2 +++ b/src/share/vm/runtime/jniHandles.hpp	Tue May 07 20:38:26 2019 +0000
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -40,7 +40,28 @@
    1.11    static JNIHandleBlock* _weak_global_handles;        // First weak global handle block
    1.12    static oop _deleted_handle;                         // Sentinel marking deleted handles
    1.13  
    1.14 +  inline static bool is_jweak(jobject handle);
    1.15 +  inline static oop& jobject_ref(jobject handle); // NOT jweak!
    1.16 +  inline static oop& jweak_ref(jobject handle);
    1.17 +
    1.18 +  template<bool external_guard> inline static oop guard_value(oop value);
    1.19 +  template<bool external_guard> inline static oop resolve_impl(jobject handle);
    1.20 +  template<bool external_guard> static oop resolve_jweak(jweak handle);
    1.21 +
    1.22   public:
    1.23 +  // Low tag bit in jobject used to distinguish a jweak.  jweak is
    1.24 +  // type equivalent to jobject, but there are places where we need to
    1.25 +  // be able to distinguish jweak values from other jobjects, and
    1.26 +  // is_weak_global_handle is unsuitable for performance reasons.  To
    1.27 +  // provide such a test we add weak_tag_value to the (aligned) byte
    1.28 +  // address designated by the jobject to produce the corresponding
    1.29 +  // jweak.  Accessing the value of a jobject must account for it
    1.30 +  // being a possibly offset jweak.
    1.31 +  static const uintptr_t weak_tag_size = 1;
    1.32 +  static const uintptr_t weak_tag_alignment = (1u << weak_tag_size);
    1.33 +  static const uintptr_t weak_tag_mask = weak_tag_alignment - 1;
    1.34 +  static const int weak_tag_value = 1;
    1.35 +
    1.36    // Resolve handle into oop
    1.37    inline static oop resolve(jobject handle);
    1.38    // Resolve externally provided handle into oop with some guards
    1.39 @@ -173,36 +194,85 @@
    1.40    #endif
    1.41  };
    1.42  
    1.43 +inline bool JNIHandles::is_jweak(jobject handle) {
    1.44 +  STATIC_ASSERT(weak_tag_size == 1);
    1.45 +  STATIC_ASSERT(weak_tag_value == 1);
    1.46 +  return (reinterpret_cast<uintptr_t>(handle) & weak_tag_mask) != 0;
    1.47 +}
    1.48 +
    1.49 +inline oop& JNIHandles::jobject_ref(jobject handle) {
    1.50 +  assert(!is_jweak(handle), "precondition");
    1.51 +  return *reinterpret_cast<oop*>(handle);
    1.52 +}
    1.53 +
    1.54 +inline oop& JNIHandles::jweak_ref(jobject handle) {
    1.55 +  assert(is_jweak(handle), "precondition");
    1.56 +  char* ptr = reinterpret_cast<char*>(handle) - weak_tag_value;
    1.57 +  return *reinterpret_cast<oop*>(ptr);
    1.58 +}
    1.59 +
    1.60 +// external_guard is true if called from resolve_external_guard.
    1.61 +// Treat deleted (and possibly zapped) as NULL for external_guard,
    1.62 +// else as (asserted) error.
    1.63 +template<bool external_guard>
    1.64 +inline oop JNIHandles::guard_value(oop value) {
    1.65 +  if (!external_guard) {
    1.66 +    assert(value != badJNIHandle, "Pointing to zapped jni handle area");
    1.67 +    assert(value != deleted_handle(), "Used a deleted global handle");
    1.68 +  } else if ((value == badJNIHandle) || (value == deleted_handle())) {
    1.69 +    value = NULL;
    1.70 +  }
    1.71 +  return value;
    1.72 +}
    1.73 +
    1.74 +// external_guard is true if called from resolve_external_guard.
    1.75 +template<bool external_guard>
    1.76 +inline oop JNIHandles::resolve_impl(jobject handle) {
    1.77 +  assert(handle != NULL, "precondition");
    1.78 +  oop result;
    1.79 +  if (is_jweak(handle)) {       // Unlikely
    1.80 +    result = resolve_jweak<external_guard>(handle);
    1.81 +  } else {
    1.82 +    result = jobject_ref(handle);
    1.83 +    // Construction of jobjects canonicalize a null value into a null
    1.84 +    // jobject, so for non-jweak the pointee should never be null.
    1.85 +    assert(external_guard || result != NULL,
    1.86 +           "Invalid value read from jni handle");
    1.87 +    result = guard_value<external_guard>(result);
    1.88 +  }
    1.89 +  return result;
    1.90 +}
    1.91  
    1.92  inline oop JNIHandles::resolve(jobject handle) {
    1.93 -  oop result = (handle == NULL ? (oop)NULL : *(oop*)handle);
    1.94 -  assert(result != NULL || (handle == NULL || !CheckJNICalls || is_weak_global_handle(handle)), "Invalid value read from jni handle");
    1.95 -  assert(result != badJNIHandle, "Pointing to zapped jni handle area");
    1.96 +  oop result = NULL;
    1.97 +  if (handle != NULL) {
    1.98 +    result = resolve_impl<false /* external_guard */ >(handle);
    1.99 +  }
   1.100    return result;
   1.101 -};
   1.102 +}
   1.103  
   1.104 -
   1.105 +// Resolve some erroneous cases to NULL, rather than treating them as
   1.106 +// possibly unchecked errors.  In particular, deleted handles are
   1.107 +// treated as NULL (though a deleted and later reallocated handle
   1.108 +// isn't detected).
   1.109  inline oop JNIHandles::resolve_external_guard(jobject handle) {
   1.110 -  if (handle == NULL) return NULL;
   1.111 -  oop result = *(oop*)handle;
   1.112 -  if (result == NULL || result == badJNIHandle) return NULL;
   1.113 +  oop result = NULL;
   1.114 +  if (handle != NULL) {
   1.115 +    result = resolve_impl<true /* external_guard */ >(handle);
   1.116 +  }
   1.117    return result;
   1.118 -};
   1.119 -
   1.120 +}
   1.121  
   1.122  inline oop JNIHandles::resolve_non_null(jobject handle) {
   1.123    assert(handle != NULL, "JNI handle should not be null");
   1.124 -  oop result = *(oop*)handle;
   1.125 -  assert(result != NULL, "Invalid value read from jni handle");
   1.126 -  assert(result != badJNIHandle, "Pointing to zapped jni handle area");
   1.127 -  // Don't let that private _deleted_handle object escape into the wild.
   1.128 -  assert(result != deleted_handle(), "Used a deleted global handle.");
   1.129 +  oop result = resolve_impl<false /* external_guard */ >(handle);
   1.130 +  assert(result != NULL, "NULL read from jni handle");
   1.131    return result;
   1.132 -};
   1.133 +}
   1.134  
   1.135  inline void JNIHandles::destroy_local(jobject handle) {
   1.136    if (handle != NULL) {
   1.137 -    *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it
   1.138 +    jobject_ref(handle) = deleted_handle();
   1.139    }
   1.140  }
   1.141  

mercurial