8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/systemDictionary.hpp"
27 #include "classfile/vmSymbols.hpp"
28 #include "oops/instanceKlass.hpp"
29 #include "oops/oop.inline.hpp"
30 #include "oops/symbol.hpp"
31 #include "prims/jni.h"
32 #include "prims/jniCheck.hpp"
33 #include "prims/jvm_misc.hpp"
34 #include "runtime/fieldDescriptor.hpp"
35 #include "runtime/handles.hpp"
36 #include "runtime/interfaceSupport.hpp"
37 #include "runtime/jfieldIDWorkaround.hpp"
38 #include "runtime/thread.hpp"
39 #ifdef TARGET_ARCH_x86
40 # include "jniTypes_x86.hpp"
41 #endif
42 #ifdef TARGET_ARCH_sparc
43 # include "jniTypes_sparc.hpp"
44 #endif
45 #ifdef TARGET_ARCH_zero
46 # include "jniTypes_zero.hpp"
47 #endif
306 check_primitive_array_type(JavaThread* thr, jarray jArray, BasicType elementType)
307 {
308 BasicType array_type;
309 arrayOop aOop;
310
311 aOop = check_is_primitive_array(thr, jArray);
312 array_type = TypeArrayKlass::cast(aOop->klass())->element_type();
313 if (array_type != elementType) {
314 ReportJNIFatalError(thr, fatal_element_type_mismatch);
315 }
316 }
317
318 static inline void
319 check_is_obj_array(JavaThread* thr, jarray jArray) {
320 arrayOop aOop = check_is_array(thr, jArray);
321 if (!aOop->is_objArray()) {
322 ReportJNIFatalError(thr, fatal_object_array_expected);
323 }
324 }
325
326 oop jniCheck::validate_handle(JavaThread* thr, jobject obj) {
327 if (JNIHandles::is_frame_handle(thr, obj) ||
328 JNIHandles::is_local_handle(thr, obj) ||
329 JNIHandles::is_global_handle(obj) ||
330 JNIHandles::is_weak_global_handle(obj)) {
331 ASSERT_OOPS_ALLOWED;
332 return JNIHandles::resolve_external_guard(obj);
333 }
334 ReportJNIFatalError(thr, fatal_bad_ref_to_jni);
335 return NULL;
336 }
337
338
339 Method* jniCheck::validate_jmethod_id(JavaThread* thr, jmethodID method_id) {
340 ASSERT_OOPS_ALLOWED;
341 // do the fast jmethodID check first
342 Method* moop = Method::checked_resolve_jmethod_id(method_id);
343 if (moop == NULL) {
344 ReportJNIFatalError(thr, fatal_wrong_class_or_method);
345 }
1297 jsize len))
1298 functionEnter(thr);
1299 jstring result = UNCHECKED()->NewString(env,unicode,len);
1300 functionExit(env);
1301 return result;
1302 JNI_END
1303
1304 JNI_ENTRY_CHECKED(jsize,
1305 checked_jni_GetStringLength(JNIEnv *env,
1306 jstring str))
1307 functionEnter(thr);
1308 IN_VM(
1309 checkString(thr, str);
1310 )
1311 jsize result = UNCHECKED()->GetStringLength(env,str);
1312 functionExit(env);
1313 return result;
1314 JNI_END
1315
1316 // Arbitrary (but well-known) tag
1317 const jint STRING_TAG = 0x47114711;
1318
1319 JNI_ENTRY_CHECKED(const jchar *,
1320 checked_jni_GetStringChars(JNIEnv *env,
1321 jstring str,
1322 jboolean *isCopy))
1323 functionEnter(thr);
1324 IN_VM(
1325 checkString(thr, str);
1326 )
1327 jchar* newResult = NULL;
1328 const jchar *result = UNCHECKED()->GetStringChars(env,str,isCopy);
1329 assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringChars didn't return a copy as expected");
1330 if (result != NULL) {
1331 size_t len = UNCHECKED()->GetStringLength(env,str) + 1; // + 1 for NULL termination
1332 jint* tagLocation = (jint*) AllocateHeap(len * sizeof(jchar) + sizeof(jint), mtInternal);
1333 *tagLocation = STRING_TAG;
1334 newResult = (jchar*) (tagLocation + 1);
1335 memcpy(newResult, result, len * sizeof(jchar));
1336 // Avoiding call to UNCHECKED()->ReleaseStringChars() since that will fire unexpected dtrace probes
1337 // Note that the dtrace arguments for the allocated memory will not match up with this solution.
1338 FreeHeap((char*)result);
1339 }
1340 functionExit(env);
1341 return newResult;
1342 JNI_END
1343
1344 JNI_ENTRY_CHECKED(void,
1345 checked_jni_ReleaseStringChars(JNIEnv *env,
1346 jstring str,
1347 const jchar *chars))
1348 functionEnterExceptionAllowed(thr);
1349 IN_VM(
1350 checkString(thr, str);
1351 )
1352 if (chars == NULL) {
1353 // still do the unchecked call to allow dtrace probes
1354 UNCHECKED()->ReleaseStringChars(env,str,chars);
1355 }
1356 else {
1357 jint* tagLocation = ((jint*) chars) - 1;
1358 if (*tagLocation != STRING_TAG) {
1359 NativeReportJNIFatalError(thr, "ReleaseStringChars called on something not allocated by GetStringChars");
1360 }
1361 UNCHECKED()->ReleaseStringChars(env,str,(const jchar*)tagLocation);
1362 }
1363 functionExit(env);
1364 JNI_END
1365
1366 JNI_ENTRY_CHECKED(jstring,
1367 checked_jni_NewStringUTF(JNIEnv *env,
1368 const char *utf))
1369 functionEnter(thr);
1370 jstring result = UNCHECKED()->NewStringUTF(env,utf);
1371 functionExit(env);
1372 return result;
1373 JNI_END
1374
1375 JNI_ENTRY_CHECKED(jsize,
1376 checked_jni_GetStringUTFLength(JNIEnv *env,
1377 jstring str))
1378 functionEnter(thr);
1379 IN_VM(
1380 checkString(thr, str);
1381 )
1382 jsize result = UNCHECKED()->GetStringUTFLength(env,str);
1383 functionExit(env);
1384 return result;
1385 JNI_END
1386
1387 // Arbitrary (but well-known) tag - different than GetStringChars
1388 const jint STRING_UTF_TAG = 0x48124812;
1389
1390 JNI_ENTRY_CHECKED(const char *,
1391 checked_jni_GetStringUTFChars(JNIEnv *env,
1392 jstring str,
1393 jboolean *isCopy))
1394 functionEnter(thr);
1395 IN_VM(
1396 checkString(thr, str);
1397 )
1398 char* newResult = NULL;
1399 const char *result = UNCHECKED()->GetStringUTFChars(env,str,isCopy);
1400 assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringUTFChars didn't return a copy as expected");
1401 if (result != NULL) {
1402 size_t len = strlen(result) + 1; // + 1 for NULL termination
1403 jint* tagLocation = (jint*) AllocateHeap(len + sizeof(jint), mtInternal);
1404 *tagLocation = STRING_UTF_TAG;
1405 newResult = (char*) (tagLocation + 1);
1406 strcpy(newResult, result);
1407 // Avoiding call to UNCHECKED()->ReleaseStringUTFChars() since that will fire unexpected dtrace probes
1408 // Note that the dtrace arguments for the allocated memory will not match up with this solution.
1409 FreeHeap((char*)result, mtInternal);
1410 }
1411 functionExit(env);
1412 return newResult;
1413 JNI_END
1414
1415 JNI_ENTRY_CHECKED(void,
1416 checked_jni_ReleaseStringUTFChars(JNIEnv *env,
1417 jstring str,
1418 const char* chars))
1419 functionEnterExceptionAllowed(thr);
1420 IN_VM(
1421 checkString(thr, str);
1422 )
1423 if (chars == NULL) {
1424 // still do the unchecked call to allow dtrace probes
1425 UNCHECKED()->ReleaseStringUTFChars(env,str,chars);
1426 }
1427 else {
1428 jint* tagLocation = ((jint*) chars) - 1;
1429 if (*tagLocation != STRING_UTF_TAG) {
1430 NativeReportJNIFatalError(thr, "ReleaseStringUTFChars called on something not allocated by GetStringUTFChars");
1431 }
1432 UNCHECKED()->ReleaseStringUTFChars(env,str,(const char*)tagLocation);
1433 }
1434 functionExit(env);
1435 JNI_END
1436
1437 JNI_ENTRY_CHECKED(jsize,
1438 checked_jni_GetArrayLength(JNIEnv *env,
1439 jarray array))
1440 functionEnter(thr);
1441 IN_VM(
1442 check_is_array(thr, array);
1443 )
1444 jsize result = UNCHECKED()->GetArrayLength(env,array);
1445 functionExit(env);
1446 return result;
1447 JNI_END
1448
1449 JNI_ENTRY_CHECKED(jobjectArray,
1450 checked_jni_NewObjectArray(JNIEnv *env,
1451 jsize len,
1452 jclass clazz,
1497 WRAPPER_NewScalarArray(jbyteArray, Byte)
1498 WRAPPER_NewScalarArray(jshortArray, Short)
1499 WRAPPER_NewScalarArray(jcharArray, Char)
1500 WRAPPER_NewScalarArray(jintArray, Int)
1501 WRAPPER_NewScalarArray(jlongArray, Long)
1502 WRAPPER_NewScalarArray(jfloatArray, Float)
1503 WRAPPER_NewScalarArray(jdoubleArray, Double)
1504
1505 #define WRAPPER_GetScalarArrayElements(ElementTag,ElementType,Result) \
1506 JNI_ENTRY_CHECKED(ElementType *, \
1507 checked_jni_Get##Result##ArrayElements(JNIEnv *env, \
1508 ElementType##Array array, \
1509 jboolean *isCopy)) \
1510 functionEnter(thr); \
1511 IN_VM( \
1512 check_primitive_array_type(thr, array, ElementTag); \
1513 ) \
1514 ElementType *result = UNCHECKED()->Get##Result##ArrayElements(env, \
1515 array, \
1516 isCopy); \
1517 functionExit(env); \
1518 return result; \
1519 JNI_END
1520
1521 WRAPPER_GetScalarArrayElements(T_BOOLEAN, jboolean, Boolean)
1522 WRAPPER_GetScalarArrayElements(T_BYTE, jbyte, Byte)
1523 WRAPPER_GetScalarArrayElements(T_SHORT, jshort, Short)
1524 WRAPPER_GetScalarArrayElements(T_CHAR, jchar, Char)
1525 WRAPPER_GetScalarArrayElements(T_INT, jint, Int)
1526 WRAPPER_GetScalarArrayElements(T_LONG, jlong, Long)
1527 WRAPPER_GetScalarArrayElements(T_FLOAT, jfloat, Float)
1528 WRAPPER_GetScalarArrayElements(T_DOUBLE, jdouble, Double)
1529
1530 #define WRAPPER_ReleaseScalarArrayElements(ElementTag,ElementType,Result,Tag) \
1531 JNI_ENTRY_CHECKED(void, \
1532 checked_jni_Release##Result##ArrayElements(JNIEnv *env, \
1533 ElementType##Array array, \
1534 ElementType *elems, \
1535 jint mode)) \
1536 functionEnterExceptionAllowed(thr); \
1537 IN_VM( \
1538 check_primitive_array_type(thr, array, ElementTag); \
1539 ASSERT_OOPS_ALLOWED; \
1540 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
1541 /* cannot check validity of copy, unless every request is logged by
1542 * checking code. Implementation of this check is deferred until a
1543 * subsequent release.
1544 */ \
1545 ) \
1546 UNCHECKED()->Release##Result##ArrayElements(env,array,elems,mode); \
1547 functionExit(env); \
1548 JNI_END
1549
1550 WRAPPER_ReleaseScalarArrayElements(T_BOOLEAN,jboolean, Boolean, bool)
1551 WRAPPER_ReleaseScalarArrayElements(T_BYTE, jbyte, Byte, byte)
1552 WRAPPER_ReleaseScalarArrayElements(T_SHORT, jshort, Short, short)
1553 WRAPPER_ReleaseScalarArrayElements(T_CHAR, jchar, Char, char)
1554 WRAPPER_ReleaseScalarArrayElements(T_INT, jint, Int, int)
1555 WRAPPER_ReleaseScalarArrayElements(T_LONG, jlong, Long, long)
1556 WRAPPER_ReleaseScalarArrayElements(T_FLOAT, jfloat, Float, float)
1557 WRAPPER_ReleaseScalarArrayElements(T_DOUBLE, jdouble, Double, double)
1558
1559 #define WRAPPER_GetScalarArrayRegion(ElementTag,ElementType,Result) \
1560 JNI_ENTRY_CHECKED(void, \
1561 checked_jni_Get##Result##ArrayRegion(JNIEnv *env, \
1562 ElementType##Array array, \
1563 jsize start, \
1564 jsize len, \
1565 ElementType *buf)) \
1566 functionEnter(thr); \
1677 jsize start,
1678 jsize len,
1679 char *buf))
1680 functionEnter(thr);
1681 IN_VM(
1682 checkString(thr, str);
1683 )
1684 UNCHECKED()->GetStringUTFRegion(env, str, start, len, buf);
1685 functionExit(env);
1686 JNI_END
1687
1688 JNI_ENTRY_CHECKED(void *,
1689 checked_jni_GetPrimitiveArrayCritical(JNIEnv *env,
1690 jarray array,
1691 jboolean *isCopy))
1692 functionEnterCritical(thr);
1693 IN_VM(
1694 check_is_primitive_array(thr, array);
1695 )
1696 void *result = UNCHECKED()->GetPrimitiveArrayCritical(env, array, isCopy);
1697 functionExit(env);
1698 return result;
1699 JNI_END
1700
1701 JNI_ENTRY_CHECKED(void,
1702 checked_jni_ReleasePrimitiveArrayCritical(JNIEnv *env,
1703 jarray array,
1704 void *carray,
1705 jint mode))
1706 functionEnterCriticalExceptionAllowed(thr);
1707 IN_VM(
1708 check_is_primitive_array(thr, array);
1709 )
1710 /* The Hotspot JNI code does not use the parameters, so just check the
1711 * array parameter as a minor sanity check
1712 */
1713 UNCHECKED()->ReleasePrimitiveArrayCritical(env, array, carray, mode);
1714 functionExit(env);
1715 JNI_END
1716
1717 JNI_ENTRY_CHECKED(const jchar*,
1718 checked_jni_GetStringCritical(JNIEnv *env,
1719 jstring string,
1720 jboolean *isCopy))
1721 functionEnterCritical(thr);
1722 IN_VM(
1723 checkString(thr, string);
1724 )
1725 const jchar *result = UNCHECKED()->GetStringCritical(env, string, isCopy);
1726 functionExit(env);
1727 return result;
1728 JNI_END
1729
1730 JNI_ENTRY_CHECKED(void,
1731 checked_jni_ReleaseStringCritical(JNIEnv *env,
1732 jstring str,
1733 const jchar *chars))
|
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/systemDictionary.hpp"
27 #include "classfile/vmSymbols.hpp"
28 #include "memory/fencedMemory.hpp"
29 #include "oops/instanceKlass.hpp"
30 #include "oops/oop.inline.hpp"
31 #include "oops/symbol.hpp"
32 #include "prims/jni.h"
33 #include "prims/jniCheck.hpp"
34 #include "prims/jvm_misc.hpp"
35 #include "runtime/fieldDescriptor.hpp"
36 #include "runtime/handles.hpp"
37 #include "runtime/interfaceSupport.hpp"
38 #include "runtime/jfieldIDWorkaround.hpp"
39 #include "runtime/thread.hpp"
40 #ifdef TARGET_ARCH_x86
41 # include "jniTypes_x86.hpp"
42 #endif
43 #ifdef TARGET_ARCH_sparc
44 # include "jniTypes_sparc.hpp"
45 #endif
46 #ifdef TARGET_ARCH_zero
47 # include "jniTypes_zero.hpp"
48 #endif
307 check_primitive_array_type(JavaThread* thr, jarray jArray, BasicType elementType)
308 {
309 BasicType array_type;
310 arrayOop aOop;
311
312 aOop = check_is_primitive_array(thr, jArray);
313 array_type = TypeArrayKlass::cast(aOop->klass())->element_type();
314 if (array_type != elementType) {
315 ReportJNIFatalError(thr, fatal_element_type_mismatch);
316 }
317 }
318
319 static inline void
320 check_is_obj_array(JavaThread* thr, jarray jArray) {
321 arrayOop aOop = check_is_array(thr, jArray);
322 if (!aOop->is_objArray()) {
323 ReportJNIFatalError(thr, fatal_object_array_expected);
324 }
325 }
326
327 /*
328 * Copy and wrap array elements for bounds checking.
329 * Remember the original elements (FencedMemory::get_tag())
330 */
331 static void* check_jni_wrap_copy_array(JavaThread* thr, jarray array, void* orig_elements) {
332 void* result;
333 IN_VM(
334 oop a = JNIHandles::resolve_non_null(array);
335 size_t len = arrayOop(a)->length() << TypeArrayKlass::cast(a->klass())->log2_element_size();
336 result = FencedMemory::wrap_copy(orig_elements, len, orig_elements);
337 )
338 return result;
339 }
340
341 static void* check_wrapped_array(JavaThread* thr, const char* fn_name, void* obj, void* carray, size_t* rsz) {
342 if (carray == NULL) {
343 tty->print_cr("%s: elements vector NULL" PTR_FORMAT, fn_name, obj);
344 NativeReportJNIFatalError(thr, "Elements vector NULL");
345 }
346 FencedMemory fenced(carray);
347 void* orig_result = fenced.get_tag();
348 if ((!fenced.verify_fences()) || (orig_result == NULL)) {
349 tty->print_cr("ReleasePrimitiveArrayCritical: unrecognized elements"
350 PTR_FORMAT " elements " PTR_FORMAT, obj, carray);
351 fenced.print_on(tty);
352 NativeReportJNIFatalError(thr, "Unrecognized elements");
353 }
354 if (rsz != NULL) {
355 *rsz = fenced.get_user_size();
356 }
357 return orig_result;
358 }
359
360 static void* check_wrapped_array_release(JavaThread* thr, const char* fn_name, void* obj, void* carray, jint mode) {
361 size_t sz;
362 void* orig_result = check_wrapped_array(thr, fn_name, obj, carray, &sz);
363 switch (mode) {
364 case 0:
365 memcpy(orig_result, carray, sz);
366 FencedMemory::free_copy(carray);
367 break;
368 case JNI_COMMIT:
369 memcpy(orig_result, carray, sz);
370 break;
371 case JNI_ABORT:
372 FencedMemory::free_copy(carray);
373 break;
374 default:
375 tty->print_cr("%s: Unrecognized mode %i releasing array "
376 PTR_FORMAT " elements " PTR_FORMAT, fn_name, mode, obj, carray);
377 NativeReportJNIFatalError(thr, "Unrecognized array release mode");
378 }
379 return orig_result;
380 }
381
382 oop jniCheck::validate_handle(JavaThread* thr, jobject obj) {
383 if (JNIHandles::is_frame_handle(thr, obj) ||
384 JNIHandles::is_local_handle(thr, obj) ||
385 JNIHandles::is_global_handle(obj) ||
386 JNIHandles::is_weak_global_handle(obj)) {
387 ASSERT_OOPS_ALLOWED;
388 return JNIHandles::resolve_external_guard(obj);
389 }
390 ReportJNIFatalError(thr, fatal_bad_ref_to_jni);
391 return NULL;
392 }
393
394
395 Method* jniCheck::validate_jmethod_id(JavaThread* thr, jmethodID method_id) {
396 ASSERT_OOPS_ALLOWED;
397 // do the fast jmethodID check first
398 Method* moop = Method::checked_resolve_jmethod_id(method_id);
399 if (moop == NULL) {
400 ReportJNIFatalError(thr, fatal_wrong_class_or_method);
401 }
1353 jsize len))
1354 functionEnter(thr);
1355 jstring result = UNCHECKED()->NewString(env,unicode,len);
1356 functionExit(env);
1357 return result;
1358 JNI_END
1359
1360 JNI_ENTRY_CHECKED(jsize,
1361 checked_jni_GetStringLength(JNIEnv *env,
1362 jstring str))
1363 functionEnter(thr);
1364 IN_VM(
1365 checkString(thr, str);
1366 )
1367 jsize result = UNCHECKED()->GetStringLength(env,str);
1368 functionExit(env);
1369 return result;
1370 JNI_END
1371
1372 // Arbitrary (but well-known) tag
1373 const void* STRING_TAG = (void*)0x47114711;
1374
1375 JNI_ENTRY_CHECKED(const jchar *,
1376 checked_jni_GetStringChars(JNIEnv *env,
1377 jstring str,
1378 jboolean *isCopy))
1379 functionEnter(thr);
1380 IN_VM(
1381 checkString(thr, str);
1382 )
1383 jchar* new_result = NULL;
1384 const jchar *result = UNCHECKED()->GetStringChars(env,str,isCopy);
1385 assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringChars didn't return a copy as expected");
1386 if (result != NULL) {
1387 size_t len = UNCHECKED()->GetStringLength(env,str) + 1; // + 1 for NULL termination
1388 len *= sizeof(jchar);
1389 new_result = (jchar*) FencedMemory::wrap_copy(result, len, STRING_TAG);
1390 if (new_result == NULL) {
1391 vm_exit_out_of_memory(len, OOM_MALLOC_ERROR, "checked_jni_GetStringChars");
1392 }
1393 // Avoiding call to UNCHECKED()->ReleaseStringChars() since that will fire unexpected dtrace probes
1394 // Note that the dtrace arguments for the allocated memory will not match up with this solution.
1395 FreeHeap((char*)result);
1396 }
1397 functionExit(env);
1398 return new_result;
1399 JNI_END
1400
1401 JNI_ENTRY_CHECKED(void,
1402 checked_jni_ReleaseStringChars(JNIEnv *env,
1403 jstring str,
1404 const jchar *chars))
1405 functionEnterExceptionAllowed(thr);
1406 IN_VM(
1407 checkString(thr, str);
1408 )
1409 if (chars == NULL) {
1410 // still do the unchecked call to allow dtrace probes
1411 UNCHECKED()->ReleaseStringChars(env,str,chars);
1412 }
1413 else {
1414 FencedMemory fenced((void*)chars);
1415 if ((!fenced.verify_fences()) || (fenced.get_tag() != STRING_TAG)) {
1416 NativeReportJNIFatalError(thr, "ReleaseStringChars called on something not allocated by GetStringChars");
1417 }
1418 UNCHECKED()->ReleaseStringChars(env, str, (const jchar*) fenced.release_for_freeing());
1419 }
1420 functionExit(env);
1421 JNI_END
1422
1423 JNI_ENTRY_CHECKED(jstring,
1424 checked_jni_NewStringUTF(JNIEnv *env,
1425 const char *utf))
1426 functionEnter(thr);
1427 jstring result = UNCHECKED()->NewStringUTF(env,utf);
1428 functionExit(env);
1429 return result;
1430 JNI_END
1431
1432 JNI_ENTRY_CHECKED(jsize,
1433 checked_jni_GetStringUTFLength(JNIEnv *env,
1434 jstring str))
1435 functionEnter(thr);
1436 IN_VM(
1437 checkString(thr, str);
1438 )
1439 jsize result = UNCHECKED()->GetStringUTFLength(env,str);
1440 functionExit(env);
1441 return result;
1442 JNI_END
1443
1444 // Arbitrary (but well-known) tag - different than GetStringChars
1445 const void* STRING_UTF_TAG = (void*) 0x48124812;
1446
1447 JNI_ENTRY_CHECKED(const char *,
1448 checked_jni_GetStringUTFChars(JNIEnv *env,
1449 jstring str,
1450 jboolean *isCopy))
1451 functionEnter(thr);
1452 IN_VM(
1453 checkString(thr, str);
1454 )
1455 char* new_result = NULL;
1456 const char *result = UNCHECKED()->GetStringUTFChars(env,str,isCopy);
1457 assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringUTFChars didn't return a copy as expected");
1458 if (result != NULL) {
1459 size_t len = strlen(result) + 1; // + 1 for NULL termination
1460 new_result = (char*) FencedMemory::wrap_copy(result, len, STRING_UTF_TAG);
1461 if (new_result == NULL) {
1462 vm_exit_out_of_memory(len, OOM_MALLOC_ERROR, "checked_jni_GetStringUTFChars");
1463 }
1464 // Avoiding call to UNCHECKED()->ReleaseStringUTFChars() since that will fire unexpected dtrace probes
1465 // Note that the dtrace arguments for the allocated memory will not match up with this solution.
1466 FreeHeap((char*)result, mtInternal);
1467 }
1468 functionExit(env);
1469 return new_result;
1470 JNI_END
1471
1472 JNI_ENTRY_CHECKED(void,
1473 checked_jni_ReleaseStringUTFChars(JNIEnv *env,
1474 jstring str,
1475 const char* chars))
1476 functionEnterExceptionAllowed(thr);
1477 IN_VM(
1478 checkString(thr, str);
1479 )
1480 if (chars == NULL) {
1481 // still do the unchecked call to allow dtrace probes
1482 UNCHECKED()->ReleaseStringUTFChars(env,str,chars);
1483 }
1484 else {
1485 FencedMemory fenced((void*)chars);
1486 if ((!fenced.verify_fences()) || (fenced.get_tag() != STRING_UTF_TAG)) {
1487 NativeReportJNIFatalError(thr, "ReleaseStringUTFChars called on something not allocated by GetStringUTFChars");
1488 }
1489 UNCHECKED()->ReleaseStringUTFChars(env,str,(const char*) fenced.release_for_freeing());
1490 }
1491 functionExit(env);
1492 JNI_END
1493
1494 JNI_ENTRY_CHECKED(jsize,
1495 checked_jni_GetArrayLength(JNIEnv *env,
1496 jarray array))
1497 functionEnter(thr);
1498 IN_VM(
1499 check_is_array(thr, array);
1500 )
1501 jsize result = UNCHECKED()->GetArrayLength(env,array);
1502 functionExit(env);
1503 return result;
1504 JNI_END
1505
1506 JNI_ENTRY_CHECKED(jobjectArray,
1507 checked_jni_NewObjectArray(JNIEnv *env,
1508 jsize len,
1509 jclass clazz,
1554 WRAPPER_NewScalarArray(jbyteArray, Byte)
1555 WRAPPER_NewScalarArray(jshortArray, Short)
1556 WRAPPER_NewScalarArray(jcharArray, Char)
1557 WRAPPER_NewScalarArray(jintArray, Int)
1558 WRAPPER_NewScalarArray(jlongArray, Long)
1559 WRAPPER_NewScalarArray(jfloatArray, Float)
1560 WRAPPER_NewScalarArray(jdoubleArray, Double)
1561
1562 #define WRAPPER_GetScalarArrayElements(ElementTag,ElementType,Result) \
1563 JNI_ENTRY_CHECKED(ElementType *, \
1564 checked_jni_Get##Result##ArrayElements(JNIEnv *env, \
1565 ElementType##Array array, \
1566 jboolean *isCopy)) \
1567 functionEnter(thr); \
1568 IN_VM( \
1569 check_primitive_array_type(thr, array, ElementTag); \
1570 ) \
1571 ElementType *result = UNCHECKED()->Get##Result##ArrayElements(env, \
1572 array, \
1573 isCopy); \
1574 if (result != NULL) { \
1575 result = (ElementType *) check_jni_wrap_copy_array(thr, array, result); \
1576 } \
1577 functionExit(env); \
1578 return result; \
1579 JNI_END
1580
1581 WRAPPER_GetScalarArrayElements(T_BOOLEAN, jboolean, Boolean)
1582 WRAPPER_GetScalarArrayElements(T_BYTE, jbyte, Byte)
1583 WRAPPER_GetScalarArrayElements(T_SHORT, jshort, Short)
1584 WRAPPER_GetScalarArrayElements(T_CHAR, jchar, Char)
1585 WRAPPER_GetScalarArrayElements(T_INT, jint, Int)
1586 WRAPPER_GetScalarArrayElements(T_LONG, jlong, Long)
1587 WRAPPER_GetScalarArrayElements(T_FLOAT, jfloat, Float)
1588 WRAPPER_GetScalarArrayElements(T_DOUBLE, jdouble, Double)
1589
1590 #define WRAPPER_ReleaseScalarArrayElements(ElementTag,ElementType,Result,Tag) \
1591 JNI_ENTRY_CHECKED(void, \
1592 checked_jni_Release##Result##ArrayElements(JNIEnv *env, \
1593 ElementType##Array array, \
1594 ElementType *elems, \
1595 jint mode)) \
1596 functionEnterExceptionAllowed(thr); \
1597 IN_VM( \
1598 check_primitive_array_type(thr, array, ElementTag); \
1599 ASSERT_OOPS_ALLOWED; \
1600 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
1601 ) \
1602 ElementType* orig_result = (ElementType *) check_wrapped_array_release( \
1603 thr, "checked_jni_Release"#Result"ArrayElements", array, elems, mode); \
1604 UNCHECKED()->Release##Result##ArrayElements(env,array,orig_result,mode); \
1605 functionExit(env); \
1606 JNI_END
1607
1608 WRAPPER_ReleaseScalarArrayElements(T_BOOLEAN,jboolean, Boolean, bool)
1609 WRAPPER_ReleaseScalarArrayElements(T_BYTE, jbyte, Byte, byte)
1610 WRAPPER_ReleaseScalarArrayElements(T_SHORT, jshort, Short, short)
1611 WRAPPER_ReleaseScalarArrayElements(T_CHAR, jchar, Char, char)
1612 WRAPPER_ReleaseScalarArrayElements(T_INT, jint, Int, int)
1613 WRAPPER_ReleaseScalarArrayElements(T_LONG, jlong, Long, long)
1614 WRAPPER_ReleaseScalarArrayElements(T_FLOAT, jfloat, Float, float)
1615 WRAPPER_ReleaseScalarArrayElements(T_DOUBLE, jdouble, Double, double)
1616
1617 #define WRAPPER_GetScalarArrayRegion(ElementTag,ElementType,Result) \
1618 JNI_ENTRY_CHECKED(void, \
1619 checked_jni_Get##Result##ArrayRegion(JNIEnv *env, \
1620 ElementType##Array array, \
1621 jsize start, \
1622 jsize len, \
1623 ElementType *buf)) \
1624 functionEnter(thr); \
1735 jsize start,
1736 jsize len,
1737 char *buf))
1738 functionEnter(thr);
1739 IN_VM(
1740 checkString(thr, str);
1741 )
1742 UNCHECKED()->GetStringUTFRegion(env, str, start, len, buf);
1743 functionExit(env);
1744 JNI_END
1745
1746 JNI_ENTRY_CHECKED(void *,
1747 checked_jni_GetPrimitiveArrayCritical(JNIEnv *env,
1748 jarray array,
1749 jboolean *isCopy))
1750 functionEnterCritical(thr);
1751 IN_VM(
1752 check_is_primitive_array(thr, array);
1753 )
1754 void *result = UNCHECKED()->GetPrimitiveArrayCritical(env, array, isCopy);
1755 if (result != NULL) {
1756 result = check_jni_wrap_copy_array(thr, array, result);
1757 }
1758 functionExit(env);
1759 return result;
1760 JNI_END
1761
1762 JNI_ENTRY_CHECKED(void,
1763 checked_jni_ReleasePrimitiveArrayCritical(JNIEnv *env,
1764 jarray array,
1765 void *carray,
1766 jint mode))
1767 functionEnterCriticalExceptionAllowed(thr);
1768 IN_VM(
1769 check_is_primitive_array(thr, array);
1770 )
1771 // Check the element array...
1772 void* orig_result = check_wrapped_array_release(thr, "ReleasePrimitiveArrayCritical", array, carray, mode);
1773 UNCHECKED()->ReleasePrimitiveArrayCritical(env, array, orig_result, mode);
1774 functionExit(env);
1775 JNI_END
1776
1777 JNI_ENTRY_CHECKED(const jchar*,
1778 checked_jni_GetStringCritical(JNIEnv *env,
1779 jstring string,
1780 jboolean *isCopy))
1781 functionEnterCritical(thr);
1782 IN_VM(
1783 checkString(thr, string);
1784 )
1785 const jchar *result = UNCHECKED()->GetStringCritical(env, string, isCopy);
1786 functionExit(env);
1787 return result;
1788 JNI_END
1789
1790 JNI_ENTRY_CHECKED(void,
1791 checked_jni_ReleaseStringCritical(JNIEnv *env,
1792 jstring str,
1793 const jchar *chars))
|