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