4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
30 #pragma ident "%Z%%M% %I% %E% SMI"
40 * dtj_util.h separates functionality that is generally useful from
41 * that which is specific to the Java DTrace API. If moved to a separate
42 * library, this functionality could be shared by other JNI wrappers.
45 #ifdef JNI_VERSION_1_4
46 #define JNI_VERSION JNI_VERSION_1_4
48 #define JNI_VERSION JNI_VERSION_1_2
51 #define CONSTRUCTOR "<init>"
52 #define DTJ_MSG_SIZE 1024
53 #define DTJ_INVALID_PTR ((void *)-1)
54 #define DTJ_INVALID_STR ((const char *)-1)
56 #define WRAP_EXCEPTION(JENV) dtj_wrap_exception((JENV), __FILE__, __LINE__)
58 extern boolean_t g_dtj_util_debug
;
60 typedef enum dtj_status
{
65 typedef enum dtj_type
{
75 * Convenient description format for java classes, methods, and fields. The
76 * java_class_t, java_method_t, and java_field_t structures derived from these
77 * descriptions are used to create a table of usable JNI jclass, jmethodID, and
80 typedef struct dtj_table_entry
{
81 dtj_type_t djte_type
; /* JNI type */
82 void *djte_addr
; /* jclass, jmethodID, or jfieldID address */
83 char *djte_name
; /* symbol name declared in Java */
84 char *djte_desc
; /* JNI descriptor (string format) */
87 typedef struct dtj_java_class
{
88 jclass
*djc_ptr
; /* address in user-defined structure */
89 char *djc_name
; /* fully qualified '/' delimited class name */
90 uu_list_t
*djc_methods
; /* element type (java_method_t *) */
91 uu_list_t
*djc_fields
; /* element type (java_field_t *) */
92 uu_list_node_t djc_node
;
95 typedef struct dtj_java_method
{
96 jmethodID
*djm_ptr
; /* address in user-defined structure */
97 char *djm_name
; /* method name in java source file */
98 char *djm_signature
; /* javap -s method signature string */
99 boolean_t djm_static
; /* flag indicating static qualifier */
100 uu_list_node_t djm_node
;
103 typedef struct dtj_java_field
{
104 jfieldID
*djf_ptr
; /* address in user-defined structure */
105 char *djf_name
; /* field name in java source file */
106 char *djf_type
; /* javap -s field type string */
107 boolean_t djf_static
; /* flag indicating static qualifier */
108 uu_list_node_t djf_node
;
112 * Table of cached jclass, jmethodID, and jfieldID values usable across multiple
113 * native method calls and multiple threads.
115 * Suffix conventions:
118 * jsm java static method
120 * jsf java static field
123 /* NativeException */
124 extern jclass g_nx_jc
;
125 extern jmethodID g_nxinit_jm
;
127 /* java.io.Serializable */
128 extern jclass g_serial_jc
;
130 /* java.lang.Number */
131 extern jclass g_number_jc
;
132 extern jmethodID g_shortval_jm
;
133 extern jmethodID g_intval_jm
;
134 extern jmethodID g_longval_jm
;
137 extern jclass g_byte_jc
;
138 extern jmethodID g_byteinit_jm
;
140 /* java.lang.Character */
141 extern jclass g_char_jc
;
142 extern jmethodID g_charinit_jm
;
143 extern jmethodID g_charval_jm
;
145 /* java.lang.Short */
146 extern jclass g_short_jc
;
147 extern jmethodID g_shortinit_jm
;
149 /* java.lang.Integer */
150 extern jclass g_int_jc
;
151 extern jmethodID g_intinit_jm
;
154 extern jclass g_long_jc
;
155 extern jmethodID g_longinit_jm
;
157 /* java.math.BigInteger */
158 extern jclass g_bigint_jc
;
159 extern jmethodID g_bigint_val_jsm
;
160 extern jmethodID g_bigint_div_jm
;
161 extern jmethodID g_bigint_shl_jm
;
162 extern jmethodID g_bigint_or_jm
;
163 extern jmethodID g_bigint_setbit_jm
;
165 /* java.lang.String */
166 extern jclass g_string_jc
;
167 extern jmethodID g_strinit_bytes_jm
;
168 extern jmethodID g_strbytes_jm
;
169 extern jmethodID g_trim_jm
;
171 /* java.lang.StringBuffer */
172 extern jclass g_buf_jc
;
173 extern jmethodID g_bufinit_jm
;
174 extern jmethodID g_buf_append_char_jm
;
175 extern jmethodID g_buf_append_int_jm
;
176 extern jmethodID g_buf_append_long_jm
;
177 extern jmethodID g_buf_append_str_jm
;
178 extern jmethodID g_buf_append_obj_jm
;
179 extern jmethodID g_buflen_jm
;
180 extern jmethodID g_bufsetlen_jm
;
182 /* java.lang.Object */
183 extern jclass g_object_jc
;
184 extern jmethodID g_tostring_jm
;
185 extern jmethodID g_equals_jm
;
188 extern jclass g_enum_jc
;
189 extern jmethodID g_enumname_jm
;
192 extern jclass g_list_jc
;
193 extern jmethodID g_listclear_jm
;
194 extern jmethodID g_listadd_jm
;
195 extern jmethodID g_listget_jm
;
196 extern jmethodID g_listsize_jm
;
199 * Populates the common java class references and associated method and field
200 * IDs declared in this file (above) using the dtj_cache_jni_classes() method.
202 extern dtj_status_t
dtj_load_common(JNIEnv
*);
205 * Populates the user-declared java class references and associated method and
206 * field IDs described in the given table. Because the class references are
207 * created as global JNI references, the method and field IDs remain valid
208 * across multiple native method calls and across multiple threads.
210 * This function assumes that the given table of java class, method, and field
211 * descriptions is terminated by an entry with DTJ_TYPE_END, and that the
212 * method and field descriptions immediately follow the description of their
215 * Throws NoClassDefFoundError, NoSuchMethodError, or NoSuchFieldError if any
216 * dtj_table_entry_t in common_jni_table.c is incorrect.
218 extern dtj_status_t
dtj_cache_jni_classes(JNIEnv
*, const dtj_table_entry_t
*);
220 /* Common utilities */
223 * The following functions each create a pending Java Error or Exception:
226 * NullPointerException
227 * IllegalArgumentException
228 * IllegalStateException
229 * NoSuchElementException
232 * org.opensolaris.os.dtrace.ResourceLimitException
234 * Control should be returned to Java immediately afterwards.
236 extern void dtj_throw_out_of_memory(JNIEnv
*, const char *, ...);
237 extern void dtj_throw_null_pointer(JNIEnv
*, const char *, ...);
238 extern void dtj_throw_illegal_argument(JNIEnv
*, const char *, ...);
239 extern void dtj_throw_illegal_state(JNIEnv
*, const char *, ...);
240 extern void dtj_throw_no_such_element(JNIEnv
*, const char *, ...);
241 extern void dtj_throw_class_cast(JNIEnv
*, const char *, ...);
242 extern void dtj_throw_assertion(JNIEnv
*, const char *, ...);
243 extern void dtj_throw_resource_limit(JNIEnv
*, const char *, ...);
246 * Attaches native filename and line number to the currently pending java
247 * exception, since that information is not present in the exception stack
250 extern void dtj_wrap_exception(JNIEnv
*, const char *, int);
253 * Calls the toString() method of the given object and prints the value to
254 * stdout (useful for debugging). If an exception is thrown in this function,
255 * it is described on stdout and cleared. It's guaranteed that no exception is
256 * pending when this function returns.
258 extern void dtj_print_object(JNIEnv
*jenv
, jobject obj
);
261 * Gets a java.math.BigInteger representing a 64-bit unsigned integer.
263 extern jobject
dtj_uint64(JNIEnv
*jenv
, uint64_t);
266 * Gets a java.math.BigInteger representing a 128-bit integer given as 64 high
267 * bits (1st arg) and 64 low bits (2nd arg).
269 extern jobject
dtj_int128(JNIEnv
*jenv
, uint64_t, uint64_t);
272 * Gets a formatted String (local reference) from a format and a variable
273 * argument list of placeholder values. Returns NULL if OutOfMemoryError is
276 extern jstring
dtj_format_string(JNIEnv
*jenv
, const char *fmt
, ...);
279 * Internationalization support. These functions taken (not verbatim) from
280 * Section 8.2 of The Java Native Interface by Sheng Liang, The Java Series.
281 * Use these functions for locale-specific strings such as file names.
283 extern jstring
dtj_NewStringNative(JNIEnv
*jenv
, const char *str
);
284 extern char *dtj_GetStringNativeChars(JNIEnv
*jenv
, jstring jstr
);
285 extern void dtj_ReleaseStringNativeChars(JNIEnv
*jenv
, jstring jstr
,
289 * Converts the args array of main(String[] args) in Java into a native
290 * dynamically allocated array of strings. The returned array must be
291 * deallocated by calling free_argv(). A java exception is pending if this
292 * function returns NULL (in that case, any allocations made up to the point of
293 * failure in get_argv() are automatically freed).
295 * Returns a NULL-terminated array that works with functions that expect a
296 * terminating NULL rather than relying on an element count. The argc parameter
297 * is also overwritten with the number of returned array elements (not including
298 * the terminating NULL).
300 extern char **dtj_get_argv(JNIEnv
*jenv
, jobjectArray args
, int *argc
);
302 * Tokenizes a command string to create a native dynamically allocated array of
303 * strings. The first element of the returned array is assumed to be the name
304 * of the command, and subsequent elements are arguments to that command.
305 * Otherwise behaves exactly like get_argv() above, including requiring a
306 * subsequent call to free_argv() on the returned array.
307 * Throws NullPointerException if cmd is NULL.
308 * Throws IllegalArgumentException if cmd is empty.
310 extern char **dtj_make_argv(JNIEnv
*jenv
, jstring cmd
, int *argc
);
311 extern void dtj_free_argv(char **argv
);
314 /* Wrappers for uu_list_t */
317 * List element destructor.
318 * params: node pointer, user arg (may be NULL)
320 typedef void dtj_value_destroy_f(void *, void *);
323 * uu_list_t generic entry type for pointers compared by pointer value, similar
324 * to Java's default Object.equals() implementation (referenced objects are
325 * equal only if they have the same address in memory). Used with
326 * pointer_list_entry_cmp.
328 typedef struct dtj_pointer_list_entry
{
330 uu_list_node_t dple_node
;
331 } dtj_pointer_list_entry_t
;
333 typedef struct dtj_string_list_entry
{
335 uu_list_node_t dsle_node
;
336 } dtj_string_list_entry_t
;
338 /* Comparison functions, uu_compare_fn_t signature */
339 extern int dtj_pointer_list_entry_cmp(const void *, const void *, void *);
340 extern int dtj_string_list_entry_cmp(const void *, const void *, void *);
343 extern uu_list_t
*dtj_pointer_list_create(void);
344 extern dtj_pointer_list_entry_t
*dtj_pointer_list_entry_create(void *);
345 extern uu_list_t
*dtj_string_list_create(void);
346 extern dtj_string_list_entry_t
*dtj_string_list_entry_create(const char *);
349 extern void dtj_pointer_list_entry_destroy(void *, dtj_value_destroy_f
*,
351 extern void dtj_string_list_entry_destroy(void *, void *);
353 * Convenience function destroys a uu_list_t and its values.
355 * param list: list to be destroyed, call is a no-op if list is NULL
356 * param value_destroy: optional destructor; if non-NULL, it is called on each
358 * param arg: user argument to the optional destructor
360 extern void dtj_list_destroy(uu_list_t
*, dtj_value_destroy_f
*, void *);
361 extern void dtj_pointer_list_destroy(uu_list_t
*, dtj_value_destroy_f
*,
363 extern void dtj_string_list_destroy(uu_list_t
*);
366 * Convenience functions clear a uu_list_t without destroying it. Destroys all
367 * list elements and leaves the list empty. The *_list_destroy() functions
368 * implicitly clear the list before destroying it.
370 extern void dtj_list_clear(uu_list_t
*, dtj_value_destroy_f
*, void *);
371 extern void dtj_pointer_list_clear(uu_list_t
*, dtj_value_destroy_f
*,
373 extern void dtj_string_list_clear(uu_list_t
*);
375 extern boolean_t
dtj_list_empty(uu_list_t
*);
376 /* Return B_TRUE if successful, B_FALSE otherwise */
377 extern boolean_t
dtj_list_add(uu_list_t
*, void *);
378 extern boolean_t
dtj_pointer_list_add(uu_list_t
*, void *);
379 extern boolean_t
dtj_string_list_add(uu_list_t
*, const char *);
380 /* Return INVALID_PTR if list is empty (NULL is a valid list element) */
381 extern void * dtj_pointer_list_first(uu_list_t
*);
382 extern void * dtj_pointer_list_last(uu_list_t
*);
383 /* Return INVALID_STR if list is empty (NULL is a valid list element) */
384 extern const char *dtj_string_list_first(uu_list_t
*);
385 extern const char *dtj_string_list_last(uu_list_t
*);
386 /* Return INVALID_PTR at end of list (NULL is a valid list element) */
387 extern void *dtj_pointer_list_walk_next(uu_list_walk_t
*);
388 /* Return INVALID_STR at end of list (NULL is a valid list element) */
389 extern const char *dtj_string_list_walk_next(uu_list_walk_t
*);
395 #endif /* _DTJ_UTIL_H */