src/share/vm/prims/jniCheck.cpp

changeset 2331
017cd8bce8a8
parent 2314
f95d63e2154a
child 2497
3582bf76420e
     1.1 --- a/src/share/vm/prims/jniCheck.cpp	Mon Dec 06 20:21:15 2010 -0500
     1.2 +++ b/src/share/vm/prims/jniCheck.cpp	Tue Dec 07 03:15:45 2010 -0800
     1.3 @@ -1288,6 +1288,9 @@
     1.4      return result;
     1.5  JNI_END
     1.6  
     1.7 +// Arbitrary (but well-known) tag
     1.8 +const jint STRING_TAG = 0x47114711;
     1.9 +
    1.10  JNI_ENTRY_CHECKED(const jchar *,
    1.11    checked_jni_GetStringChars(JNIEnv *env,
    1.12                               jstring str,
    1.13 @@ -1297,8 +1300,19 @@
    1.14        checkString(thr, str);
    1.15      )
    1.16      const jchar *result = UNCHECKED()->GetStringChars(env,str,isCopy);
    1.17 +    assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringChars didn't return a copy as expected");
    1.18 +
    1.19 +    size_t len = UNCHECKED()->GetStringLength(env,str) + 1; // + 1 for NULL termination
    1.20 +    jint* tagLocation = (jint*) AllocateHeap(len * sizeof(jchar) + sizeof(jint), "checked_jni_GetStringChars");
    1.21 +    *tagLocation = STRING_TAG;
    1.22 +    jchar* newResult = (jchar*) (tagLocation + 1);
    1.23 +    memcpy(newResult, result, len * sizeof(jchar));
    1.24 +    // Avoiding call to UNCHECKED()->ReleaseStringChars() since that will fire unexpected dtrace probes
    1.25 +    // Note that the dtrace arguments for the allocated memory will not match up with this solution.
    1.26 +    FreeHeap((char*)result);
    1.27 +
    1.28      functionExit(env);
    1.29 -    return result;
    1.30 +    return newResult;
    1.31  JNI_END
    1.32  
    1.33  JNI_ENTRY_CHECKED(void,
    1.34 @@ -1309,11 +1323,17 @@
    1.35      IN_VM(
    1.36        checkString(thr, str);
    1.37      )
    1.38 -    /* cannot check validity of copy, unless every request is logged by
    1.39 -     * checking code.  Implementation of this check is deferred until a
    1.40 -     * subsequent release.
    1.41 -     */
    1.42 -    UNCHECKED()->ReleaseStringChars(env,str,chars);
    1.43 +    if (chars == NULL) {
    1.44 +       // still do the unchecked call to allow dtrace probes
    1.45 +       UNCHECKED()->ReleaseStringChars(env,str,chars);
    1.46 +    }
    1.47 +    else {
    1.48 +       jint* tagLocation = ((jint*) chars) - 1;
    1.49 +       if (*tagLocation != STRING_TAG) {
    1.50 +          NativeReportJNIFatalError(thr, "ReleaseStringChars called on something not allocated by GetStringChars");
    1.51 +       }
    1.52 +       UNCHECKED()->ReleaseStringChars(env,str,(const jchar*)tagLocation);
    1.53 +    }
    1.54      functionExit(env);
    1.55  JNI_END
    1.56  
    1.57 @@ -1338,6 +1358,9 @@
    1.58      return result;
    1.59  JNI_END
    1.60  
    1.61 +// Arbitrary (but well-known) tag - different than GetStringChars
    1.62 +const jint STRING_UTF_TAG = 0x48124812;
    1.63 +
    1.64  JNI_ENTRY_CHECKED(const char *,
    1.65    checked_jni_GetStringUTFChars(JNIEnv *env,
    1.66                                  jstring str,
    1.67 @@ -1347,8 +1370,19 @@
    1.68        checkString(thr, str);
    1.69      )
    1.70      const char *result = UNCHECKED()->GetStringUTFChars(env,str,isCopy);
    1.71 +    assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringUTFChars didn't return a copy as expected");
    1.72 +
    1.73 +    size_t len = strlen(result) + 1; // + 1 for NULL termination
    1.74 +    jint* tagLocation = (jint*) AllocateHeap(len + sizeof(jint), "checked_jni_GetStringUTFChars");
    1.75 +    *tagLocation = STRING_UTF_TAG;
    1.76 +    char* newResult = (char*) (tagLocation + 1);
    1.77 +    strcpy(newResult, result);
    1.78 +    // Avoiding call to UNCHECKED()->ReleaseStringUTFChars() since that will fire unexpected dtrace probes
    1.79 +    // Note that the dtrace arguments for the allocated memory will not match up with this solution.
    1.80 +    FreeHeap((char*)result);
    1.81 +
    1.82      functionExit(env);
    1.83 -    return result;
    1.84 +    return newResult;
    1.85  JNI_END
    1.86  
    1.87  JNI_ENTRY_CHECKED(void,
    1.88 @@ -1359,11 +1393,17 @@
    1.89      IN_VM(
    1.90        checkString(thr, str);
    1.91      )
    1.92 -    /* cannot check validity of copy, unless every request is logged by
    1.93 -     * checking code.  Implementation of this check is deferred until a
    1.94 -     * subsequent release.
    1.95 -     */
    1.96 -    UNCHECKED()->ReleaseStringUTFChars(env,str,chars);
    1.97 +    if (chars == NULL) {
    1.98 +       // still do the unchecked call to allow dtrace probes
    1.99 +       UNCHECKED()->ReleaseStringUTFChars(env,str,chars);
   1.100 +    }
   1.101 +    else {
   1.102 +       jint* tagLocation = ((jint*) chars) - 1;
   1.103 +       if (*tagLocation != STRING_UTF_TAG) {
   1.104 +          NativeReportJNIFatalError(thr, "ReleaseStringUTFChars called on something not allocated by GetStringUTFChars");
   1.105 +       }
   1.106 +       UNCHECKED()->ReleaseStringUTFChars(env,str,(const char*)tagLocation);
   1.107 +    }
   1.108      functionExit(env);
   1.109  JNI_END
   1.110  

mercurial