11449Stomee /* 21449Stomee * CDDL HEADER START 31449Stomee * 41449Stomee * The contents of this file are subject to the terms of the 51449Stomee * Common Development and Distribution License (the "License"). 61449Stomee * You may not use this file except in compliance with the License. 71449Stomee * 81449Stomee * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 91449Stomee * or http://www.opensolaris.org/os/licensing. 101449Stomee * See the License for the specific language governing permissions 111449Stomee * and limitations under the License. 121449Stomee * 131449Stomee * When distributing Covered Code, include this CDDL HEADER in each 141449Stomee * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 151449Stomee * If applicable, add the following below this CDDL HEADER, with the 161449Stomee * fields enclosed by brackets "[]" replaced with your own identifying 171449Stomee * information: Portions Copyright [yyyy] [name of copyright owner] 181449Stomee * 191449Stomee * CDDL HEADER END 201449Stomee */ 211449Stomee 221449Stomee /* 23*6136Stomee * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 241449Stomee * Use is subject to license terms. 251449Stomee */ 261449Stomee 271449Stomee #ifndef _DTJ_UTIL_H 281449Stomee #define _DTJ_UTIL_H 291449Stomee 301449Stomee #pragma ident "%Z%%M% %I% %E% SMI" 311449Stomee 321449Stomee #include <jni.h> 331449Stomee #include <libuutil.h> 341449Stomee 351449Stomee #ifdef __cplusplus 361449Stomee extern "C" { 371449Stomee #endif 381449Stomee 391449Stomee /* 401449Stomee * dtj_util.h separates functionality that is generally useful from 411449Stomee * that which is specific to the Java DTrace API. If moved to a separate 421449Stomee * library, this functionality could be shared by other JNI wrappers. 431449Stomee */ 441449Stomee 451449Stomee #ifdef JNI_VERSION_1_4 461449Stomee #define JNI_VERSION JNI_VERSION_1_4 471449Stomee #else 481449Stomee #define JNI_VERSION JNI_VERSION_1_2 491449Stomee #endif 501449Stomee 511449Stomee #define CONSTRUCTOR "<init>" 521449Stomee #define DTJ_MSG_SIZE 1024 531449Stomee #define DTJ_INVALID_PTR ((void *)-1) 541449Stomee #define DTJ_INVALID_STR ((const char *)-1) 551449Stomee 561449Stomee #define WRAP_EXCEPTION(JENV) dtj_wrap_exception((JENV), __FILE__, __LINE__) 571449Stomee 581449Stomee extern boolean_t g_dtj_util_debug; 591449Stomee 601449Stomee typedef enum dtj_status { 611449Stomee DTJ_OK = JNI_OK, 621449Stomee DTJ_ERR = JNI_ERR 631449Stomee } dtj_status_t; 641449Stomee 651449Stomee typedef enum dtj_type { 661449Stomee JCLASS, 671449Stomee JMETHOD, 681449Stomee JMETHOD_STATIC, 691449Stomee JFIELD, 701449Stomee JFIELD_STATIC, 711449Stomee DTJ_TYPE_END = -1 721449Stomee } dtj_type_t; 731449Stomee 741449Stomee /* 751449Stomee * Convenient description format for java classes, methods, and fields. The 761449Stomee * java_class_t, java_method_t, and java_field_t structures derived from these 771449Stomee * descriptions are used to create a table of usable JNI jclass, jmethodID, and 781449Stomee * jfieldID instances. 791449Stomee */ 801449Stomee typedef struct dtj_table_entry { 811449Stomee dtj_type_t djte_type; /* JNI type */ 821449Stomee void *djte_addr; /* jclass, jmethodID, or jfieldID address */ 831449Stomee char *djte_name; /* symbol name declared in Java */ 841449Stomee char *djte_desc; /* JNI descriptor (string format) */ 851449Stomee } dtj_table_entry_t; 861449Stomee 871449Stomee typedef struct dtj_java_class { 881449Stomee jclass *djc_ptr; /* address in user-defined structure */ 891449Stomee char *djc_name; /* fully qualified '/' delimited class name */ 901449Stomee uu_list_t *djc_methods; /* element type (java_method_t *) */ 911449Stomee uu_list_t *djc_fields; /* element type (java_field_t *) */ 921449Stomee uu_list_node_t djc_node; 931449Stomee } dtj_java_class_t; 941449Stomee 951449Stomee typedef struct dtj_java_method { 961449Stomee jmethodID *djm_ptr; /* address in user-defined structure */ 971449Stomee char *djm_name; /* method name in java source file */ 981449Stomee char *djm_signature; /* javap -s method signature string */ 991449Stomee boolean_t djm_static; /* flag indicating static qualifier */ 1001449Stomee uu_list_node_t djm_node; 1011449Stomee } dtj_java_method_t; 1021449Stomee 1031449Stomee typedef struct dtj_java_field { 1041449Stomee jfieldID *djf_ptr; /* address in user-defined structure */ 1051449Stomee char *djf_name; /* field name in java source file */ 1061449Stomee char *djf_type; /* javap -s field type string */ 1071449Stomee boolean_t djf_static; /* flag indicating static qualifier */ 1081449Stomee uu_list_node_t djf_node; 1091449Stomee } dtj_java_field_t; 1101449Stomee 1111449Stomee /* 1121449Stomee * Table of cached jclass, jmethodID, and jfieldID values usable across multiple 1131449Stomee * native method calls and multiple threads. 1141449Stomee * 1151449Stomee * Suffix conventions: 1161449Stomee * jc java class 1171449Stomee * jm java method 1181449Stomee * jsm java static method 1191449Stomee * jf java field 1201449Stomee * jsf java static field 1211449Stomee */ 1221449Stomee 1231449Stomee /* NativeException */ 1241449Stomee extern jclass g_nx_jc; 1251449Stomee extern jmethodID g_nxinit_jm; 1261449Stomee 1271449Stomee /* java.io.Serializable */ 1281449Stomee extern jclass g_serial_jc; 1291449Stomee 1301449Stomee /* java.lang.Number */ 1311449Stomee extern jclass g_number_jc; 1321449Stomee extern jmethodID g_shortval_jm; 1331449Stomee extern jmethodID g_intval_jm; 1341449Stomee extern jmethodID g_longval_jm; 1351449Stomee 1361449Stomee /* java.lang.Byte */ 1371449Stomee extern jclass g_byte_jc; 1381449Stomee extern jmethodID g_byteinit_jm; 1391449Stomee 1401449Stomee /* java.lang.Character */ 1411449Stomee extern jclass g_char_jc; 1421449Stomee extern jmethodID g_charinit_jm; 1431449Stomee extern jmethodID g_charval_jm; 1441449Stomee 1451449Stomee /* java.lang.Short */ 1461449Stomee extern jclass g_short_jc; 1471449Stomee extern jmethodID g_shortinit_jm; 1481449Stomee 1491449Stomee /* java.lang.Integer */ 1501449Stomee extern jclass g_int_jc; 1511449Stomee extern jmethodID g_intinit_jm; 1521449Stomee 1531449Stomee /* java.lang.Long */ 1541449Stomee extern jclass g_long_jc; 1551449Stomee extern jmethodID g_longinit_jm; 1561449Stomee 157*6136Stomee /* java.math.BigInteger */ 158*6136Stomee extern jclass g_bigint_jc; 159*6136Stomee extern jmethodID g_bigint_val_jsm; 160*6136Stomee extern jmethodID g_bigint_div_jm; 161*6136Stomee extern jmethodID g_bigint_shl_jm; 162*6136Stomee extern jmethodID g_bigint_or_jm; 163*6136Stomee extern jmethodID g_bigint_setbit_jm; 164*6136Stomee 1651449Stomee /* java.lang.String */ 1661449Stomee extern jclass g_string_jc; 1671449Stomee extern jmethodID g_strinit_bytes_jm; 1681449Stomee extern jmethodID g_strbytes_jm; 1691449Stomee extern jmethodID g_trim_jm; 1701449Stomee 1711449Stomee /* java.lang.StringBuffer */ 1721449Stomee extern jclass g_buf_jc; 1731449Stomee extern jmethodID g_bufinit_jm; 1741449Stomee extern jmethodID g_buf_append_char_jm; 1751449Stomee extern jmethodID g_buf_append_int_jm; 1761449Stomee extern jmethodID g_buf_append_long_jm; 1771449Stomee extern jmethodID g_buf_append_str_jm; 1781449Stomee extern jmethodID g_buf_append_obj_jm; 1791449Stomee extern jmethodID g_buflen_jm; 1801449Stomee extern jmethodID g_bufsetlen_jm; 1811449Stomee 1821449Stomee /* java.lang.Object */ 1831449Stomee extern jclass g_object_jc; 1841449Stomee extern jmethodID g_tostring_jm; 1851449Stomee extern jmethodID g_equals_jm; 1861449Stomee 1871449Stomee /* java.lang.Enum */ 1881449Stomee extern jclass g_enum_jc; 1891449Stomee extern jmethodID g_enumname_jm; 1901449Stomee 1911449Stomee /* List */ 1921449Stomee extern jclass g_list_jc; 1931449Stomee extern jmethodID g_listclear_jm; 1941449Stomee extern jmethodID g_listadd_jm; 1951449Stomee extern jmethodID g_listget_jm; 1961449Stomee extern jmethodID g_listsize_jm; 1971449Stomee 1981449Stomee /* 1991449Stomee * Populates the common java class references and associated method and field 2001449Stomee * IDs declared in this file (above) using the dtj_cache_jni_classes() method. 2011449Stomee */ 2021449Stomee extern dtj_status_t dtj_load_common(JNIEnv *); 2031449Stomee 2041449Stomee /* 2051449Stomee * Populates the user-declared java class references and associated method and 2061449Stomee * field IDs described in the given table. Because the class references are 2071449Stomee * created as global JNI references, the method and field IDs remain valid 2081449Stomee * across multiple native method calls and across multiple threads. 2091449Stomee * 2101449Stomee * This function assumes that the given table of java class, method, and field 2111449Stomee * descriptions is terminated by an entry with DTJ_TYPE_END, and that the 2121449Stomee * method and field descriptions immediately follow the description of their 2131449Stomee * containing class. 2141449Stomee * 2151449Stomee * Throws NoClassDefFoundError, NoSuchMethodError, or NoSuchFieldError if any 2161449Stomee * dtj_table_entry_t in common_jni_table.c is incorrect. 2171449Stomee */ 2181449Stomee extern dtj_status_t dtj_cache_jni_classes(JNIEnv *, const dtj_table_entry_t *); 2191449Stomee 2201449Stomee /* Common utilities */ 2211449Stomee 2221449Stomee /* 2231449Stomee * The following functions each create a pending Java Error or Exception: 2241449Stomee * 2251449Stomee * OutOfMemoryError 2261449Stomee * NullPointerException 2271449Stomee * IllegalArgumentException 2281449Stomee * IllegalStateException 2291449Stomee * NoSuchElementException 2301449Stomee * ClassCastException 2311449Stomee * AssertionError 232*6136Stomee * org.opensolaris.os.dtrace.ResourceLimitException 2331449Stomee * 2341449Stomee * Control should be returned to Java immediately afterwards. 2351449Stomee */ 2361449Stomee extern void dtj_throw_out_of_memory(JNIEnv *, const char *, ...); 2371449Stomee extern void dtj_throw_null_pointer(JNIEnv *, const char *, ...); 2381449Stomee extern void dtj_throw_illegal_argument(JNIEnv *, const char *, ...); 2391449Stomee extern void dtj_throw_illegal_state(JNIEnv *, const char *, ...); 2401449Stomee extern void dtj_throw_no_such_element(JNIEnv *, const char *, ...); 2411449Stomee extern void dtj_throw_class_cast(JNIEnv *, const char *, ...); 2421449Stomee extern void dtj_throw_assertion(JNIEnv *, const char *, ...); 2431449Stomee extern void dtj_throw_resource_limit(JNIEnv *, const char *, ...); 2441449Stomee 2451449Stomee /* 2461449Stomee * Attaches native filename and line number to the currently pending java 2471449Stomee * exception, since that information is not present in the exception stack 2481449Stomee * trace. 2491449Stomee */ 2501449Stomee extern void dtj_wrap_exception(JNIEnv *, const char *, int); 2511449Stomee 2521449Stomee /* 2531449Stomee * Calls the toString() method of the given object and prints the value to 2541449Stomee * stdout (useful for debugging). If an exception is thrown in this function, 2551449Stomee * it is described on stdout and cleared. It's guaranteed that no exception is 2561449Stomee * pending when this function returns. 2571449Stomee */ 2581449Stomee extern void dtj_print_object(JNIEnv *jenv, jobject obj); 2591449Stomee 2601449Stomee /* 261*6136Stomee * Gets a java.math.BigInteger representing a 64-bit unsigned integer. 262*6136Stomee */ 263*6136Stomee extern jobject dtj_uint64(JNIEnv *jenv, uint64_t); 264*6136Stomee 265*6136Stomee /* 266*6136Stomee * Gets a java.math.BigInteger representing a 128-bit integer given as 64 high 267*6136Stomee * bits (1st arg) and 64 low bits (2nd arg). 268*6136Stomee */ 269*6136Stomee extern jobject dtj_int128(JNIEnv *jenv, uint64_t, uint64_t); 270*6136Stomee 271*6136Stomee /* 2721449Stomee * Gets a formatted String (local reference) from a format and a variable 2731449Stomee * argument list of placeholder values. Returns NULL if OutOfMemoryError is 2741449Stomee * thrown. 2751449Stomee */ 2761449Stomee extern jstring dtj_format_string(JNIEnv *jenv, const char *fmt, ...); 2771449Stomee 2781449Stomee /* 2791449Stomee * Internationalization support. These functions taken (not verbatim) from 2801449Stomee * Section 8.2 of The Java Native Interface by Sheng Liang, The Java Series. 2811449Stomee * Use these functions for locale-specific strings such as file names. 2821449Stomee */ 2831449Stomee extern jstring dtj_NewStringNative(JNIEnv *jenv, const char *str); 2841449Stomee extern char *dtj_GetStringNativeChars(JNIEnv *jenv, jstring jstr); 2851449Stomee extern void dtj_ReleaseStringNativeChars(JNIEnv *jenv, jstring jstr, 2861449Stomee const char *str); 2871449Stomee 2881449Stomee /* 2891449Stomee * Converts the args array of main(String[] args) in Java into a native 2901449Stomee * dynamically allocated array of strings. The returned array must be 2911449Stomee * deallocated by calling free_argv(). A java exception is pending if this 2921449Stomee * function returns NULL (in that case, any allocations made up to the point of 2931449Stomee * failure in get_argv() are automatically freed). 2941449Stomee * 2951449Stomee * Returns a NULL-terminated array that works with functions that expect a 2961449Stomee * terminating NULL rather than relying on an element count. The argc parameter 2971449Stomee * is also overwritten with the number of returned array elements (not including 2981449Stomee * the terminating NULL). 2991449Stomee */ 3001449Stomee extern char **dtj_get_argv(JNIEnv *jenv, jobjectArray args, int *argc); 3011449Stomee /* 3021449Stomee * Tokenizes a command string to create a native dynamically allocated array of 3031449Stomee * strings. The first element of the returned array is assumed to be the name 3041449Stomee * of the command, and subsequent elements are arguments to that command. 3051449Stomee * Otherwise behaves exactly like get_argv() above, including requiring a 3061449Stomee * subsequent call to free_argv() on the returned array. 3071449Stomee * Throws NullPointerException if cmd is NULL. 3081449Stomee * Throws IllegalArgumentException if cmd is empty. 3091449Stomee */ 3101449Stomee extern char **dtj_make_argv(JNIEnv *jenv, jstring cmd, int *argc); 3111449Stomee extern void dtj_free_argv(char **argv); 3121449Stomee 3131449Stomee 3141449Stomee /* Wrappers for uu_list_t */ 3151449Stomee 3161449Stomee /* 3171449Stomee * List element destructor. 3181449Stomee * params: node pointer, user arg (may be NULL) 3191449Stomee */ 3201449Stomee typedef void dtj_value_destroy_f(void *, void *); 3211449Stomee 3221449Stomee /* 3231449Stomee * uu_list_t generic entry type for pointers compared by pointer value, similar 3241449Stomee * to Java's default Object.equals() implementation (referenced objects are 3251449Stomee * equal only if they have the same address in memory). Used with 3261449Stomee * pointer_list_entry_cmp. 3271449Stomee */ 3281449Stomee typedef struct dtj_pointer_list_entry { 3291449Stomee void *dple_ptr; 3301449Stomee uu_list_node_t dple_node; 3311449Stomee } dtj_pointer_list_entry_t; 3321449Stomee 3331449Stomee typedef struct dtj_string_list_entry { 3341449Stomee char *dsle_value; 3351449Stomee uu_list_node_t dsle_node; 3361449Stomee } dtj_string_list_entry_t; 3371449Stomee 3381449Stomee /* Comparison functions, uu_compare_fn_t signature */ 3391449Stomee extern int dtj_pointer_list_entry_cmp(const void *, const void *, void *); 3401449Stomee extern int dtj_string_list_entry_cmp(const void *, const void *, void *); 3411449Stomee 3421449Stomee /* Constructors */ 3431449Stomee extern uu_list_t *dtj_pointer_list_create(void); 3441449Stomee extern dtj_pointer_list_entry_t *dtj_pointer_list_entry_create(void *); 3451449Stomee extern uu_list_t *dtj_string_list_create(void); 3461449Stomee extern dtj_string_list_entry_t *dtj_string_list_entry_create(const char *); 3471449Stomee 3481449Stomee /* Destructors */ 3491449Stomee extern void dtj_pointer_list_entry_destroy(void *, dtj_value_destroy_f *, 3501449Stomee void *); 3511449Stomee extern void dtj_string_list_entry_destroy(void *, void *); 3521449Stomee /* 3531449Stomee * Convenience function destroys a uu_list_t and its values. 3541449Stomee * 3551449Stomee * param list: list to be destroyed, call is a no-op if list is NULL 3561449Stomee * param value_destroy: optional destructor; if non-NULL, it is called on each 3571449Stomee * list value 3581449Stomee * param arg: user argument to the optional destructor 3591449Stomee */ 3601449Stomee extern void dtj_list_destroy(uu_list_t *, dtj_value_destroy_f *, void *); 3611449Stomee extern void dtj_pointer_list_destroy(uu_list_t *, dtj_value_destroy_f *, 3621449Stomee void *); 3631449Stomee extern void dtj_string_list_destroy(uu_list_t *); 3641449Stomee 3651449Stomee /* 3661449Stomee * Convenience functions clear a uu_list_t without destroying it. Destroys all 3671449Stomee * list elements and leaves the list empty. The *_list_destroy() functions 3681449Stomee * implicitly clear the list before destroying it. 3691449Stomee */ 3701449Stomee extern void dtj_list_clear(uu_list_t *, dtj_value_destroy_f *, void *); 3711449Stomee extern void dtj_pointer_list_clear(uu_list_t *, dtj_value_destroy_f *, 3721449Stomee void *); 3731449Stomee extern void dtj_string_list_clear(uu_list_t *); 3741449Stomee 3751449Stomee extern boolean_t dtj_list_empty(uu_list_t *); 3761449Stomee /* Return B_TRUE if successful, B_FALSE otherwise */ 3771449Stomee extern boolean_t dtj_list_add(uu_list_t *, void *); 3781449Stomee extern boolean_t dtj_pointer_list_add(uu_list_t *, void *); 3791449Stomee extern boolean_t dtj_string_list_add(uu_list_t *, const char *); 3801449Stomee /* Return INVALID_PTR if list is empty (NULL is a valid list element) */ 3811449Stomee extern void * dtj_pointer_list_first(uu_list_t *); 3821449Stomee extern void * dtj_pointer_list_last(uu_list_t *); 3831449Stomee /* Return INVALID_STR if list is empty (NULL is a valid list element) */ 3841449Stomee extern const char *dtj_string_list_first(uu_list_t *); 3851449Stomee extern const char *dtj_string_list_last(uu_list_t *); 3861449Stomee /* Return INVALID_PTR at end of list (NULL is a valid list element) */ 3871449Stomee extern void *dtj_pointer_list_walk_next(uu_list_walk_t *); 3881449Stomee /* Return INVALID_STR at end of list (NULL is a valid list element) */ 3891449Stomee extern const char *dtj_string_list_walk_next(uu_list_walk_t *); 3901449Stomee 3911449Stomee #ifdef __cplusplus 3921449Stomee } 3931449Stomee #endif 3941449Stomee 3951449Stomee #endif /* _DTJ_UTIL_H */ 396