xref: /onnv-gate/usr/src/lib/libdtrace_jni/common/dtj_jnitab.c (revision 6136:b1f0a0698377)
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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
281449Stomee 
291449Stomee #include <stdlib.h>
301449Stomee #include <stddef.h>
311449Stomee #include <limits.h>
321449Stomee #include <strings.h>
331449Stomee #include <pthread.h>
341449Stomee #include <dtrace_jni.h>
351449Stomee 
361449Stomee /*
371449Stomee  * dtj_jnitab.c defines the JNI table of classes, methods, and fields belonging
381449Stomee  * to the Java DTrace API.  Another JNI table defining classes from the JDK is
391449Stomee  * defined in dtj_util.c.  Utility functions specific to the Java DTrace API are
401449Stomee  * also defined here, while general utilities are defined in dtj_util.c.
411449Stomee  */
421449Stomee 
431449Stomee static uu_list_pool_t *g_request_pool = NULL;
441449Stomee static uu_list_pool_t *g_program_pool = NULL;
451449Stomee static uu_list_pool_t *g_aggval_pool = NULL;
461449Stomee 
471449Stomee static boolean_t dtj_check_request_pool(void);
481449Stomee static boolean_t dtj_check_program_pool(void);
491449Stomee static boolean_t dtj_check_aggval_pool(void);
501449Stomee 
511449Stomee /* LocalConsumer */
521449Stomee jclass g_caller_jc = 0;
531449Stomee jmethodID g_gethandle_jm = 0;
541449Stomee jmethodID g_sethandle_jm = 0;
551449Stomee jmethodID g_pdatanext_jm = 0;
561449Stomee jmethodID g_drop_jm = 0;
571449Stomee jmethodID g_error_jm = 0;
581449Stomee jmethodID g_proc_jm = 0;
591449Stomee jmethodID g_interval_began_jm = 0;
601449Stomee jmethodID g_interval_ended_jm = 0;
611449Stomee jfieldID g_consumer_lock_jf = 0;
621449Stomee 
631449Stomee /* DTraceException */
641449Stomee jclass g_dtx_jc = 0;
651449Stomee jmethodID g_dtxinit_jm = 0;
661449Stomee 
671449Stomee /* InterfaceAttributes */
681449Stomee jclass g_attr_jc = 0;
691449Stomee jmethodID g_attrinit_jm = 0;
701449Stomee jmethodID g_attrset_name_jm = 0;
711449Stomee jmethodID g_attrset_data_jm = 0;
721449Stomee jmethodID g_attrset_class_jm = 0;
731449Stomee 
741449Stomee /* ProbeDescription */
751449Stomee jclass g_probedesc_jc = 0;
761449Stomee jmethodID g_probedescinit_jm = 0;
771449Stomee jfieldID g_probedesc_id_jf = 0;
781449Stomee 
791449Stomee /* ProbeInfo */
801449Stomee jclass g_probeinfo_jc = 0;
811449Stomee jmethodID g_probeinfoinit_jm = 0;
821449Stomee 
831449Stomee /* Probe */
841449Stomee jclass g_probe_jc = 0;
851449Stomee jmethodID g_probeinit_jm = 0;
861449Stomee 
871449Stomee /* Program */
881449Stomee jclass g_program_jc = 0;
891449Stomee jmethodID g_proginit_jm = 0;
901449Stomee jfieldID g_progid_jf = 0;
911449Stomee jfieldID g_proginfo_jf = 0;
921449Stomee 
931449Stomee /* Program.File */
941449Stomee jclass g_programfile_jc = 0;
951449Stomee jmethodID g_fproginit_jm = 0;
961449Stomee 
971449Stomee /* ProgramInfo */
981449Stomee jclass g_proginfo_jc = 0;
991449Stomee jmethodID g_proginfoinit_jm = 0;
1001449Stomee 
1011449Stomee /* Flow */
1021449Stomee jclass g_flow_jc = 0;
1031449Stomee jmethodID g_flowinit_jm = 0;
1041449Stomee 
1051449Stomee /* ProbeData */
1061449Stomee jclass g_pdata_jc = 0;
1071449Stomee jmethodID g_pdatainit_jm = 0;
1081449Stomee jmethodID g_pdataadd_jm = 0;
1091449Stomee jmethodID g_pdataadd_rec_jm = 0;
1101449Stomee jmethodID g_pdataadd_trace_jm = 0;
1111449Stomee jmethodID g_pdataadd_stack_jm = 0;
1122777Stomee jmethodID g_pdataadd_symbol_jm = 0;
1131449Stomee jmethodID g_pdataadd_printf_jm = 0;
1141449Stomee jmethodID g_pdataadd_printa_jm = 0;
1151449Stomee jmethodID g_pdatainvalidate_printa_jm = 0;
1161449Stomee jmethodID g_pdataadd_aggrec_jm = 0;
1171449Stomee jmethodID g_pdataadd_printa_str_jm = 0;
1181449Stomee jmethodID g_pdataadd_exit_jm = 0;
1191449Stomee jmethodID g_pdataattach_jm = 0;
1201449Stomee jmethodID g_pdataset_formatted_jm = 0;
1211449Stomee jmethodID g_pdataclear_jm = 0;
1221449Stomee 
1231449Stomee /* Drop */
1241449Stomee jclass g_drop_jc = 0;
1251449Stomee jmethodID g_dropinit_jm = 0;
1261449Stomee 
1271449Stomee /* Error */
1281449Stomee jclass g_error_jc = 0;
1291449Stomee jmethodID g_errinit_jm = 0;
1301449Stomee 
1311449Stomee /* ProcessState */
1321449Stomee jclass g_process_jc = 0;
1331449Stomee jmethodID g_procinit_jm = 0;
1341449Stomee jmethodID g_procexit_jm = 0;
1351449Stomee 
1361449Stomee /* Aggregate */
1371449Stomee jclass g_agg_jc = 0;
1381449Stomee jmethodID g_agginit_jm = 0;
1391449Stomee jmethodID g_aggaddrec_jm = 0;
1401449Stomee 
1411449Stomee /* AggregateSpec */
1421449Stomee jclass g_aggspec_jc = 0;
1431449Stomee jmethodID g_aggspec_included_jm = 0;
1441449Stomee jmethodID g_aggspec_cleared_jm = 0;
1451449Stomee 
1461449Stomee /* Tuple */
1471449Stomee jclass g_tuple_jc = 0;
1481449Stomee jmethodID g_tupleinit_jm = 0;
1491449Stomee jmethodID g_tupleadd_jm = 0;
1501449Stomee jmethodID g_tuplesize_jm = 0;
1511449Stomee jfieldID g_tuple_EMPTY_jsf = 0;
1521449Stomee 
1531449Stomee /* AggregationRecord */
1541449Stomee jclass g_aggrec_jc = 0;
1551449Stomee jmethodID g_aggrecinit_jm = 0;
1561449Stomee jmethodID g_aggrecget_tuple_jm = 0;
1571449Stomee 
1581449Stomee /* SumValue */
1591449Stomee jclass g_aggsum_jc = 0;
1601449Stomee jmethodID g_aggsuminit_jm = 0;
1611449Stomee 
1621449Stomee /* CountValue */
1631449Stomee jclass g_aggcount_jc = 0;
1641449Stomee jmethodID g_aggcountinit_jm = 0;
1651449Stomee 
1661449Stomee /* AvgValue */
1671449Stomee jclass g_aggavg_jc = 0;
1681449Stomee jmethodID g_aggavginit_jm = 0;
1691449Stomee 
1701449Stomee /* MinValue */
1711449Stomee jclass g_aggmin_jc = 0;
1721449Stomee jmethodID g_aggmininit_jm = 0;
1731449Stomee 
1741449Stomee /* MaxValue */
1751449Stomee jclass g_aggmax_jc = 0;
1761449Stomee jmethodID g_aggmaxinit_jm = 0;
1771449Stomee 
178*6136Stomee /* StddevValue */
179*6136Stomee jclass g_aggstddev_jc = 0;
180*6136Stomee jmethodID g_aggstddevinit_jm = 0;
181*6136Stomee 
1821449Stomee /* KernelStackRecord */
1831449Stomee jclass g_stack_jc = 0;
1841449Stomee jmethodID g_parsestack_jsm = 0;
1851449Stomee jmethodID g_stackinit_jm = 0;
1861449Stomee jmethodID g_stackset_frames_jm = 0;
1871449Stomee 
1881449Stomee /* UserStackRecord */
1891449Stomee jclass g_ustack_jc = 0;
1901449Stomee jmethodID g_ustackinit_jm = 0;
1911449Stomee jmethodID g_ustackset_frames_jm = 0;
1921449Stomee 
1931449Stomee /* Distribution */
1941449Stomee jclass g_adist_jc = 0;
1951449Stomee jmethodID g_dist_normal_jm = 0;
1961449Stomee 
1971449Stomee /* LogDistribution */
1981449Stomee jclass g_dist_jc = 0;
1991449Stomee jmethodID g_distinit_jm = 0;
2001449Stomee 
2011449Stomee /* LinearDistribution */
2021449Stomee jclass g_ldist_jc = 0;
2031449Stomee jmethodID g_ldistinit_jm = 0;
2041449Stomee 
2052777Stomee /* KernelSymbolRecord */
2062777Stomee jclass g_symbol_jc = 0;
2072777Stomee jmethodID g_symbolinit_jm = 0;
2082777Stomee jmethodID g_symbolset_name_jm = 0;
2092777Stomee 
2102777Stomee /* UserSymbolRecord */
2112777Stomee jclass g_usymbol_jc = 0;
2122777Stomee jmethodID g_usymbolinit_jm = 0;
2132777Stomee jmethodID g_usymbolset_name_jm = 0;
2142777Stomee 
2152777Stomee /* ScalarRecord */
2162777Stomee jclass g_scalar_jc = 0;
2172777Stomee jmethodID g_scalarinit_jm = 0;
2182777Stomee 
2191449Stomee 
2201449Stomee static dtj_status_t
dtj_table_load(JNIEnv * jenv)2211449Stomee dtj_table_load(JNIEnv *jenv)
2221449Stomee {
2233645Stomee 	/*
2243645Stomee 	 * If you change this table, increment DTRACE_JNI_VERSION in
2253645Stomee 	 * dtrace_jni.c.
2263645Stomee 	 */
2271449Stomee 	static const dtj_table_entry_t table[] = {
2281449Stomee 		/* LocalConsumer */
2291449Stomee 		{ JCLASS,  &g_caller_jc,
2301449Stomee 			"org/opensolaris/os/dtrace/LocalConsumer" },
2311449Stomee 		{ JMETHOD, &g_gethandle_jm, "getHandle", "()I" },
2321449Stomee 		{ JMETHOD, &g_sethandle_jm, "setHandle", "(I)V" },
2331449Stomee 		{ JMETHOD, &g_pdatanext_jm, "nextProbeData",
2341449Stomee 			"(Lorg/opensolaris/os/dtrace/ProbeData;)V" },
2351449Stomee 		{ JMETHOD, &g_drop_jm, "dataDropped",
2361449Stomee 			"(Lorg/opensolaris/os/dtrace/Drop;)V" },
2371449Stomee 		{ JMETHOD, &g_error_jm, "errorEncountered",
2381449Stomee 			"(Lorg/opensolaris/os/dtrace/Error;)V" },
2391449Stomee 		{ JMETHOD, &g_proc_jm, "processStateChanged",
2401449Stomee 			"(Lorg/opensolaris/os/dtrace/ProcessState;)V" },
2411449Stomee 		{ JMETHOD, &g_interval_began_jm, "intervalBegan", "()V" },
2421449Stomee 		{ JMETHOD, &g_interval_ended_jm, "intervalEnded", "()V" },
2431449Stomee 		{ JFIELD,  &g_consumer_lock_jf, "consumerLock",
2441449Stomee 			"Ljava/lang/Object;" },
2451449Stomee 
2461449Stomee 		/* DTraceException */
2471449Stomee 		{ JCLASS,  &g_dtx_jc,
2481449Stomee 			"org/opensolaris/os/dtrace/DTraceException" },
2491449Stomee 		{ JMETHOD, &g_dtxinit_jm, CONSTRUCTOR,
2501449Stomee 			"(Ljava/lang/String;)V" },
2511449Stomee 
2521449Stomee 		/* InterfaceAttributes */
2531449Stomee 		{ JCLASS,  &g_attr_jc,
2541449Stomee 			"org/opensolaris/os/dtrace/InterfaceAttributes" },
2551449Stomee 		{ JMETHOD, &g_attrinit_jm, CONSTRUCTOR, "()V" },
2561449Stomee 		{ JMETHOD, &g_attrset_name_jm, "setNameStability",
2571449Stomee 			"(Ljava/lang/String;)V" },
2581449Stomee 		{ JMETHOD, &g_attrset_data_jm, "setDataStability",
2591449Stomee 			"(Ljava/lang/String;)V" },
2601449Stomee 		{ JMETHOD, &g_attrset_class_jm, "setDependencyClass",
2611449Stomee 			"(Ljava/lang/String;)V" },
2621449Stomee 
2631449Stomee 		/* ProbeDescription */
2641449Stomee 		{ JCLASS,  &g_probedesc_jc,
2651449Stomee 			"org/opensolaris/os/dtrace/ProbeDescription" },
2661449Stomee 		{ JMETHOD, &g_probedescinit_jm, CONSTRUCTOR,
2671449Stomee 			"(Ljava/lang/String;Ljava/lang/String;"
2681449Stomee 			    "Ljava/lang/String;Ljava/lang/String;)V" },
2691449Stomee 		{ JFIELD,  &g_probedesc_id_jf, "id", "I" },
2701449Stomee 
2711449Stomee 		/* ProbeInfo */
2721449Stomee 		{ JCLASS,  &g_probeinfo_jc,
2731449Stomee 			"org/opensolaris/os/dtrace/ProbeInfo" },
2741449Stomee 		{ JMETHOD, &g_probeinfoinit_jm, CONSTRUCTOR,
2751449Stomee 			"(Lorg/opensolaris/os/dtrace/InterfaceAttributes;"
2761449Stomee 			    "Lorg/opensolaris/os/dtrace/InterfaceAttributes;"
2771449Stomee 			    ")V" },
2781449Stomee 
2791449Stomee 		/* Probe */
2801449Stomee 		{ JCLASS,  &g_probe_jc, "org/opensolaris/os/dtrace/Probe" },
2811449Stomee 		{ JMETHOD, &g_probeinit_jm, CONSTRUCTOR,
2821449Stomee 			"(Lorg/opensolaris/os/dtrace/ProbeDescription;"
2831449Stomee 			    "Lorg/opensolaris/os/dtrace/ProbeInfo;)V" },
2841449Stomee 
2851449Stomee 		/* Program */
2861449Stomee 		{ JCLASS,  &g_program_jc,
2871449Stomee 			"org/opensolaris/os/dtrace/Program" },
2881449Stomee 		{ JMETHOD, &g_proginit_jm, CONSTRUCTOR, "()V" },
2891449Stomee 		{ JFIELD,  &g_progid_jf, "id", "I" },
2901449Stomee 		{ JFIELD,  &g_proginfo_jf, "info",
2911449Stomee 			"Lorg/opensolaris/os/dtrace/ProgramInfo;" },
2921449Stomee 
2931449Stomee 		/* Program.File */
2941449Stomee 		{ JCLASS,  &g_programfile_jc,
2951449Stomee 			"org/opensolaris/os/dtrace/Program$File" },
2961449Stomee 		{ JMETHOD, &g_fproginit_jm, CONSTRUCTOR, "()V" },
2971449Stomee 
2981449Stomee 		/* ProgramInfo */
2991449Stomee 		{ JCLASS,  &g_proginfo_jc,
3001449Stomee 			"org/opensolaris/os/dtrace/ProgramInfo" },
3011449Stomee 		{ JMETHOD, &g_proginfoinit_jm, CONSTRUCTOR,
3021449Stomee 			"(Lorg/opensolaris/os/dtrace/InterfaceAttributes;"
3031449Stomee 			    "Lorg/opensolaris/os/dtrace/InterfaceAttributes;"
3041449Stomee 			    "I)V" },
3051449Stomee 
3061449Stomee 		/* Flow */
3071449Stomee 		{ JCLASS,  &g_flow_jc, "org/opensolaris/os/dtrace/Flow" },
3081449Stomee 		{ JMETHOD, &g_flowinit_jm, CONSTRUCTOR,
3091449Stomee 			"(Ljava/lang/String;I)V" },
3101449Stomee 
3111449Stomee 		/* ProbeData */
3121449Stomee 		{ JCLASS,  &g_pdata_jc,
3131449Stomee 			"org/opensolaris/os/dtrace/ProbeData" },
3141449Stomee 		{ JMETHOD, &g_pdatainit_jm, CONSTRUCTOR,
3151449Stomee 			"(IILorg/opensolaris/os/dtrace/ProbeDescription;"
3161449Stomee 			    "Lorg/opensolaris/os/dtrace/Flow;I)V" },
3171449Stomee 		{ JMETHOD, &g_pdataadd_jm, "addDataElement",
3182777Stomee 			"(Lorg/opensolaris/os/dtrace/Record;)V" },
3191449Stomee 		{ JMETHOD, &g_pdataadd_rec_jm, "addRecord",
3201449Stomee 			"(Lorg/opensolaris/os/dtrace/Record;)V" },
3211449Stomee 		{ JMETHOD, &g_pdataadd_trace_jm, "addTraceRecord", "(I)V" },
3221449Stomee 		{ JMETHOD, &g_pdataadd_stack_jm, "addStackRecord",
3231449Stomee 			"(ILjava/lang/String;)V" },
3242777Stomee 		{ JMETHOD, &g_pdataadd_symbol_jm, "addSymbolRecord",
3252777Stomee 			"(ILjava/lang/String;)V" },
3261449Stomee 		{ JMETHOD, &g_pdataadd_printf_jm, "addPrintfRecord", "()V" },
3271449Stomee 		{ JMETHOD, &g_pdataadd_printa_jm, "addPrintaRecord", "(JZ)V" },
3281449Stomee 		{ JMETHOD, &g_pdatainvalidate_printa_jm,
3291449Stomee 			"invalidatePrintaRecord", "()V" },
3301449Stomee 		{ JMETHOD, &g_pdataadd_aggrec_jm, "addAggregationRecord",
3311449Stomee 			"(Ljava/lang/String;J"
3321449Stomee 			    "Lorg/opensolaris/os/dtrace/AggregationRecord;)V" },
3331449Stomee 		{ JMETHOD, &g_pdataadd_printa_str_jm,
3341449Stomee 			"addPrintaFormattedString",
3351449Stomee 			"(Lorg/opensolaris/os/dtrace/Tuple;"
3361449Stomee 			    "Ljava/lang/String;)V" },
3371449Stomee 		{ JMETHOD, &g_pdataadd_exit_jm, "addExitRecord", "(I)V" },
3381449Stomee 		{ JMETHOD, &g_pdataattach_jm, "attachRecordElements",
3391449Stomee 			"(II)V" },
3401449Stomee 		{ JMETHOD, &g_pdataset_formatted_jm, "setFormattedString",
3411449Stomee 			"(Ljava/lang/String;)V" },
3421449Stomee 		{ JMETHOD, &g_pdataclear_jm, "clearNativeElements", "()V" },
3431449Stomee 
3441449Stomee 		/* Drop */
3451449Stomee 		{ JCLASS,  &g_drop_jc, "org/opensolaris/os/dtrace/Drop" },
3461449Stomee 		{ JMETHOD, &g_dropinit_jm, CONSTRUCTOR,
3471449Stomee 			"(ILjava/lang/String;JJLjava/lang/String;)V" },
3481449Stomee 
3491449Stomee 		/* Error */
3501449Stomee 		{ JCLASS,  &g_error_jc, "org/opensolaris/os/dtrace/Error" },
3511449Stomee 		{ JMETHOD, &g_errinit_jm, CONSTRUCTOR,
3521449Stomee 			"(Lorg/opensolaris/os/dtrace/ProbeDescription;IIII"
3531449Stomee 			    "Ljava/lang/String;JLjava/lang/String;)V" },
3541449Stomee 
3551449Stomee 		/* ProcessState */
3561449Stomee 		{ JCLASS,  &g_process_jc,
3571449Stomee 			"org/opensolaris/os/dtrace/ProcessState" },
3581449Stomee 		{ JMETHOD, &g_procinit_jm, CONSTRUCTOR,
3591449Stomee 			"(ILjava/lang/String;ILjava/lang/String;"
3601449Stomee 			    "Ljava/lang/Integer;Ljava/lang/String;)V" },
3611449Stomee 		{ JMETHOD, &g_procexit_jm, "setExitStatus", "(I)V" },
3621449Stomee 
3631449Stomee 		/* Aggregate */
3641449Stomee 		{ JCLASS,  &g_agg_jc, "org/opensolaris/os/dtrace/Aggregate" },
3651449Stomee 		{ JMETHOD, &g_agginit_jm, CONSTRUCTOR, "(J)V" },
3661449Stomee 		{ JMETHOD, &g_aggaddrec_jm, "addRecord",
3671449Stomee 		    "(Ljava/lang/String;J"
3681449Stomee 			"Lorg/opensolaris/os/dtrace/AggregationRecord;)V" },
3691449Stomee 
3701449Stomee 		/* AggregateSpec */
3711449Stomee 		{ JCLASS,  &g_aggspec_jc,
3721449Stomee 			"org/opensolaris/os/dtrace/AggregateSpec" },
3731449Stomee 		{ JMETHOD, &g_aggspec_included_jm, "isIncluded",
3741449Stomee 			"(Ljava/lang/String;)Z" },
3751449Stomee 		{ JMETHOD, &g_aggspec_cleared_jm, "isCleared",
3761449Stomee 			"(Ljava/lang/String;)Z" },
3771449Stomee 
3781449Stomee 		/* Tuple */
3791449Stomee 		{ JCLASS,  &g_tuple_jc, "org/opensolaris/os/dtrace/Tuple" },
3801449Stomee 		{ JMETHOD, &g_tupleinit_jm, CONSTRUCTOR, "()V" },
3811449Stomee 		{ JMETHOD, &g_tupleadd_jm, "addElement",
3822777Stomee 			"(Lorg/opensolaris/os/dtrace/ValueRecord;)V" },
3831449Stomee 		{ JMETHOD, &g_tuplesize_jm, "size", "()I" },
3841449Stomee 		{ JFIELD_STATIC, &g_tuple_EMPTY_jsf, "EMPTY",
3851449Stomee 			"Lorg/opensolaris/os/dtrace/Tuple;" },
3861449Stomee 
3871449Stomee 		/* AggregationRecord */
3881449Stomee 		{ JCLASS,  &g_aggrec_jc,
3891449Stomee 			"org/opensolaris/os/dtrace/AggregationRecord" },
3901449Stomee 		{ JMETHOD, &g_aggrecinit_jm, CONSTRUCTOR,
3911449Stomee 			"(Lorg/opensolaris/os/dtrace/Tuple;"
3921449Stomee 			    "Lorg/opensolaris/os/dtrace/AggregationValue;)V" },
3931449Stomee 		{ JMETHOD, &g_aggrecget_tuple_jm, "getTuple",
3941449Stomee 			"()Lorg/opensolaris/os/dtrace/Tuple;" },
3951449Stomee 
3961449Stomee 		/* SumValue */
3971449Stomee 		{ JCLASS,  &g_aggsum_jc,
3981449Stomee 			"org/opensolaris/os/dtrace/SumValue" },
3991449Stomee 		{ JMETHOD, &g_aggsuminit_jm, CONSTRUCTOR, "(J)V" },
4001449Stomee 
4011449Stomee 		/* CountValue */
4021449Stomee 		{ JCLASS,  &g_aggcount_jc,
4031449Stomee 			"org/opensolaris/os/dtrace/CountValue" },
4041449Stomee 		{ JMETHOD, &g_aggcountinit_jm, CONSTRUCTOR, "(J)V" },
4051449Stomee 
4061449Stomee 		/* AvgValue */
4071449Stomee 		{ JCLASS,  &g_aggavg_jc,
4081449Stomee 			"org/opensolaris/os/dtrace/AvgValue" },
4091449Stomee 		{ JMETHOD, &g_aggavginit_jm, CONSTRUCTOR, "(JJJ)V" },
4101449Stomee 
4111449Stomee 		/* MinValue */
4121449Stomee 		{ JCLASS,  &g_aggmin_jc,
4131449Stomee 			"org/opensolaris/os/dtrace/MinValue" },
4141449Stomee 		{ JMETHOD, &g_aggmininit_jm, CONSTRUCTOR, "(J)V" },
4151449Stomee 
4161449Stomee 		/* MaxValue */
4171449Stomee 		{ JCLASS,  &g_aggmax_jc,
4181449Stomee 			"org/opensolaris/os/dtrace/MaxValue" },
4191449Stomee 		{ JMETHOD, &g_aggmaxinit_jm, CONSTRUCTOR, "(J)V" },
4201449Stomee 
421*6136Stomee 		/* StddevValue */
422*6136Stomee 		{ JCLASS,  &g_aggstddev_jc,
423*6136Stomee 			"org/opensolaris/os/dtrace/StddevValue" },
424*6136Stomee 		{ JMETHOD, &g_aggstddevinit_jm, CONSTRUCTOR,
425*6136Stomee 			"(JJLjava/math/BigInteger;)V" },
426*6136Stomee 
4271449Stomee 		/* KernelStackRecord */
4281449Stomee 		{ JCLASS,  &g_stack_jc,
4291449Stomee 			"org/opensolaris/os/dtrace/KernelStackRecord" },
4301449Stomee 		{ JMETHOD_STATIC, &g_parsestack_jsm, "parse",
4311449Stomee 			"(Ljava/lang/String;)"
4321449Stomee 			    "[Lorg/opensolaris/os/dtrace/StackFrame;" },
4331449Stomee 		{ JMETHOD, &g_stackinit_jm, CONSTRUCTOR, "([B)V" },
4341449Stomee 		{ JMETHOD, &g_stackset_frames_jm, "setStackFrames",
4351449Stomee 			"([Lorg/opensolaris/os/dtrace/StackFrame;)V" },
4361449Stomee 
4371449Stomee 		/* UserStackRecord */
4381449Stomee 		{ JCLASS,  &g_ustack_jc,
4391449Stomee 			"org/opensolaris/os/dtrace/UserStackRecord" },
4401449Stomee 		{ JMETHOD, &g_ustackinit_jm, CONSTRUCTOR, "(I[B)V" },
4411449Stomee 		{ JMETHOD, &g_ustackset_frames_jm, "setStackFrames",
4421449Stomee 			"([Lorg/opensolaris/os/dtrace/StackFrame;)V" },
4431449Stomee 
4441449Stomee 		/* Distribution */
4451449Stomee 		{ JCLASS,  &g_adist_jc,
4461449Stomee 			"org/opensolaris/os/dtrace/Distribution" },
4471449Stomee 		{ JMETHOD, &g_dist_normal_jm, "normalizeBuckets", "(J)V" },
4481449Stomee 
4491449Stomee 		/* LogDistribution */
4501449Stomee 		{ JCLASS,  &g_dist_jc,
4511449Stomee 			"org/opensolaris/os/dtrace/LogDistribution" },
4521449Stomee 		{ JMETHOD,  &g_distinit_jm, CONSTRUCTOR, "([J)V" },
4531449Stomee 
4541449Stomee 		/* LinearDistribution */
4551449Stomee 		{ JCLASS,  &g_ldist_jc,
4561449Stomee 			"org/opensolaris/os/dtrace/LinearDistribution" },
4571449Stomee 		{ JMETHOD,  &g_ldistinit_jm, CONSTRUCTOR, "(JJ[J)V" },
4581449Stomee 
4592777Stomee 		/* KernelSymbolRecord */
4602777Stomee 		{ JCLASS,  &g_symbol_jc,
4612777Stomee 			"org/opensolaris/os/dtrace/KernelSymbolRecord" },
4622777Stomee 		{ JMETHOD,  &g_symbolinit_jm, CONSTRUCTOR, "(J)V" },
4632777Stomee 		{ JMETHOD,  &g_symbolset_name_jm, "setSymbol",
4642777Stomee 			"(Ljava/lang/String;)V" },
4652777Stomee 
4662777Stomee 		/* UserSymbolRecord */
4672777Stomee 		{ JCLASS,  &g_usymbol_jc,
4682777Stomee 			"org/opensolaris/os/dtrace/UserSymbolRecord" },
4692777Stomee 		{ JMETHOD,  &g_usymbolinit_jm, CONSTRUCTOR, "(IJ)V" },
4702777Stomee 		{ JMETHOD,  &g_usymbolset_name_jm, "setSymbol",
4712777Stomee 			"(Ljava/lang/String;)V" },
4722777Stomee 
4732777Stomee 		/* ScalarRecord */
4742777Stomee 		{ JCLASS,  &g_scalar_jc,
4752777Stomee 			"org/opensolaris/os/dtrace/ScalarRecord" },
4762777Stomee 		{ JMETHOD,  &g_scalarinit_jm, CONSTRUCTOR,
4772777Stomee 			"(Ljava/lang/Object;I)V" },
4782777Stomee 
4791449Stomee 		{ DTJ_TYPE_END }
4801449Stomee 	};
4811449Stomee 
4821449Stomee 	return (dtj_cache_jni_classes(jenv, table));
4831449Stomee }
4841449Stomee 
4851449Stomee dtj_status_t
dtj_load(JNIEnv * jenv)4861449Stomee dtj_load(JNIEnv *jenv)
4871449Stomee {
4881449Stomee 	if (dtj_load_common(jenv) != DTJ_OK) {
4891449Stomee 		/* Java Error pending */
4901449Stomee 		return (DTJ_ERR);
4911449Stomee 	}
4921449Stomee 
4931449Stomee 	return (dtj_table_load(jenv));
4941449Stomee }
4951449Stomee 
4961449Stomee static boolean_t
dtj_check_request_pool(void)4971449Stomee dtj_check_request_pool(void)
4981449Stomee {
4991449Stomee 	if (!g_request_pool) {
5001449Stomee 		g_request_pool = uu_list_pool_create("g_request_pool",
5011449Stomee 		    sizeof (dtj_request_t),
5021449Stomee 		    offsetof(dtj_request_t, dtjr_node),
5031449Stomee 		    dtj_pointer_list_entry_cmp,
5041449Stomee 		    (g_dtj_util_debug ? UU_LIST_POOL_DEBUG : 0));
5051449Stomee 		if (!g_request_pool) {
5061449Stomee 			return (B_FALSE);
5071449Stomee 		}
5081449Stomee 	}
5091449Stomee 	return (B_TRUE);
5101449Stomee }
5111449Stomee 
5121449Stomee dtj_request_t *
dtj_request_create(JNIEnv * jenv,dtj_request_type_t type,...)5131449Stomee dtj_request_create(JNIEnv *jenv, dtj_request_type_t type, ...)
5141449Stomee {
5151449Stomee 	dtj_request_t *r;
5161449Stomee 
5171449Stomee 	if (!dtj_check_request_pool()) {
5181449Stomee 		dtj_throw_out_of_memory(jenv,
5191449Stomee 		    "Failed to allocate request pool");
5201449Stomee 		return (NULL);
5211449Stomee 	}
5221449Stomee 
5231449Stomee 	r = uu_zalloc(sizeof (dtj_request_t));
5241449Stomee 	if (r) {
5251449Stomee 		uu_list_node_init(r, &r->dtjr_node, g_request_pool);
5261449Stomee 		r->dtjr_type = type;
5271449Stomee 		r->dtjr_args = dtj_string_list_create();
5281449Stomee 		if (r->dtjr_args) {
5291449Stomee 			va_list ap;
5301449Stomee 			const char *arg;
5311449Stomee 			int i, len;
5321449Stomee 
5331449Stomee 			va_start(ap, type);
5341449Stomee 			switch (type) {
5351449Stomee 			case DTJ_REQUEST_OPTION:
5361449Stomee 				len = 2;
5371449Stomee 				break;
5381449Stomee 			default:
5391449Stomee 				len = 0;
5401449Stomee 			}
5411449Stomee 
5421449Stomee 			for (i = 0; i < len; ++i) {
5431449Stomee 				arg = va_arg(ap, char *);
5441449Stomee 				if (!dtj_string_list_add(r->dtjr_args, arg)) {
5451449Stomee 					dtj_throw_out_of_memory(jenv,
5461449Stomee 					    "Failed to add request arg");
5471449Stomee 					uu_list_node_fini(r, &r->dtjr_node,
5481449Stomee 					    g_request_pool);
5491449Stomee 					dtj_request_destroy(r, NULL);
5501449Stomee 					r = NULL;
5511449Stomee 				}
5521449Stomee 			}
5531449Stomee 			va_end(ap);
5541449Stomee 		} else {
5551449Stomee 			dtj_throw_out_of_memory(jenv,
5561449Stomee 			    "Failed to allocate request arglist");
5571449Stomee 			uu_list_node_fini(r, &r->dtjr_node, g_request_pool);
5581449Stomee 			dtj_request_destroy(r, NULL);
5591449Stomee 			r = NULL;
5601449Stomee 		}
5611449Stomee 	} else {
5621449Stomee 		dtj_throw_out_of_memory(jenv,
5631449Stomee 		    "Failed to allocate request");
5641449Stomee 	}
5651449Stomee 
5661449Stomee 	return (r);
5671449Stomee }
5681449Stomee 
5691449Stomee static boolean_t
dtj_check_program_pool(void)5701449Stomee dtj_check_program_pool(void)
5711449Stomee {
5721449Stomee 	if (!g_program_pool) {
5731449Stomee 		g_program_pool = uu_list_pool_create("g_program_pool",
5741449Stomee 		    sizeof (dtj_program_t),
5751449Stomee 		    offsetof(dtj_program_t, dtjp_node),
5761449Stomee 		    dtj_pointer_list_entry_cmp,
5771449Stomee 		    (g_dtj_util_debug ? UU_LIST_POOL_DEBUG : 0));
5781449Stomee 		if (!g_program_pool) {
5791449Stomee 			return (B_FALSE);
5801449Stomee 		}
5811449Stomee 	}
5821449Stomee 	return (B_TRUE);
5831449Stomee }
5841449Stomee 
5851449Stomee dtj_program_t *
dtj_program_create(JNIEnv * jenv,dtj_program_type_t type,const char * name)5861449Stomee dtj_program_create(JNIEnv *jenv, dtj_program_type_t type, const char *name)
5871449Stomee {
5881449Stomee 	dtj_program_t *p;
5891449Stomee 
5901449Stomee 	if (!dtj_check_program_pool()) {
5911449Stomee 		dtj_throw_out_of_memory(jenv,
5921449Stomee 		    "Failed to allocate program pool");
5931449Stomee 		return (NULL);
5941449Stomee 	}
5951449Stomee 
5961449Stomee 	p = uu_zalloc(sizeof (dtj_program_t));
5971449Stomee 	if (p) {
5981449Stomee 		char *program_name;
5991449Stomee 
6001449Stomee 		uu_list_node_init(p, &p->dtjp_node, g_program_pool);
6011449Stomee 		p->dtjp_type = type;
6021449Stomee 		program_name = malloc((size_t)
6031449Stomee 		    (sizeof (char)) * (strlen(name) + 1));
6041449Stomee 		if (program_name) {
6051449Stomee 			(void) strcpy(program_name, name);
6061449Stomee 			p->dtjp_name = program_name;
6071449Stomee 			p->dtjp_enabled = B_FALSE;
6081449Stomee 		} else {
6091449Stomee 			dtj_throw_out_of_memory(jenv,
6101449Stomee 			    "Failed to allocate program name");
6111449Stomee 			uu_list_node_fini(p, &p->dtjp_node, g_program_pool);
6121449Stomee 			dtj_program_destroy(p, NULL);
6131449Stomee 			p = NULL;
6141449Stomee 		}
6151449Stomee 	} else {
6161449Stomee 		dtj_throw_out_of_memory(jenv,
6171449Stomee 		    "Failed to allocate program");
6181449Stomee 	}
6191449Stomee 
6201449Stomee 	return (p);
6211449Stomee }
6221449Stomee 
6231449Stomee static boolean_t
dtj_check_aggval_pool(void)6241449Stomee dtj_check_aggval_pool(void)
6251449Stomee {
6261449Stomee 	if (!g_aggval_pool) {
6271449Stomee 		g_aggval_pool = uu_list_pool_create("g_aggval_pool",
6281449Stomee 		    sizeof (dtj_aggval_t),
6291449Stomee 		    offsetof(dtj_aggval_t, dtja_node),
6301449Stomee 		    dtj_pointer_list_entry_cmp,
6311449Stomee 		    (g_dtj_util_debug ? UU_LIST_POOL_DEBUG : 0));
6321449Stomee 		if (!g_aggval_pool) {
6331449Stomee 			return (B_FALSE);
6341449Stomee 		}
6351449Stomee 	}
6361449Stomee 	return (B_TRUE);
6371449Stomee }
6381449Stomee 
6391449Stomee dtj_aggval_t *
dtj_aggval_create(JNIEnv * jenv,jobject aggval,const char * aggname,int64_t aggid)6401449Stomee dtj_aggval_create(JNIEnv *jenv, jobject aggval, const char *aggname,
6411449Stomee     int64_t aggid)
6421449Stomee {
6431449Stomee 	dtj_aggval_t *e;
6441449Stomee 
6451449Stomee 	if (!dtj_check_aggval_pool()) {
6461449Stomee 		dtj_throw_out_of_memory(jenv,
6471449Stomee 		    "Failed to allocate aggval entry pool");
6481449Stomee 		return (NULL);
6491449Stomee 	}
6501449Stomee 
6511449Stomee 	e = uu_zalloc(sizeof (dtj_aggval_t));
6521449Stomee 	if (e) {
6531449Stomee 		char *a_name;
6541449Stomee 
6551449Stomee 		uu_list_node_init(e, &e->dtja_node, g_aggval_pool);
6561449Stomee 		e->dtja_value = aggval;
6571449Stomee 		a_name = malloc((size_t)
6581449Stomee 		    (sizeof (char)) * (strlen(aggname) + 1));
6591449Stomee 		if (a_name) {
6601449Stomee 			(void) strcpy(a_name, aggname);
6611449Stomee 			e->dtja_aggname = a_name;
6621449Stomee 		} else {
6631449Stomee 			dtj_throw_out_of_memory(jenv,
6641449Stomee 			    "Failed to allocate aggregation name");
6651449Stomee 			uu_list_node_fini(e, &e->dtja_node, g_aggval_pool);
6661449Stomee 			/* caller responsible for input java reference */
6671449Stomee 			e->dtja_value = NULL;
6681449Stomee 			dtj_aggval_destroy(e, jenv);
6691449Stomee 			e = NULL;
6701449Stomee 		}
6711449Stomee 		e->dtja_aggid = aggid;
6721449Stomee 	} else {
6731449Stomee 		dtj_throw_out_of_memory(jenv,
6741449Stomee 		    "Failed to allocate aggval entry");
6751449Stomee 	}
6761449Stomee 
6771449Stomee 	return (e);
6781449Stomee }
6791449Stomee 
6801449Stomee dtj_status_t
dtj_java_consumer_init(JNIEnv * jenv,dtj_java_consumer_t * jc)6811449Stomee dtj_java_consumer_init(JNIEnv *jenv, dtj_java_consumer_t *jc)
6821449Stomee {
6831449Stomee 	if (!dtj_check_aggval_pool()) {
6841449Stomee 		dtj_throw_out_of_memory(jenv,
6851449Stomee 		    "Failed to allocate aggval pool");
6861449Stomee 		return (DTJ_ERR);
6871449Stomee 	}
6881449Stomee 
6891449Stomee 	jc->dtjj_aggval_list = uu_list_create(g_aggval_pool, NULL,
6901449Stomee 	    (g_dtj_util_debug ? UU_LIST_DEBUG : 0));
6911449Stomee 	if (!jc->dtjj_aggval_list) {
6921449Stomee 		dtj_throw_out_of_memory(jenv,
6931449Stomee 		    "Failed to allocate aggval list");
6941449Stomee 		return (DTJ_ERR);
6951449Stomee 	}
6961449Stomee 
6971449Stomee 	/* Does not throw exceptions */
6981449Stomee 	jc->dtjj_consumer_lock = (*jenv)->GetObjectField(jenv, jc->dtjj_caller,
6991449Stomee 	    g_consumer_lock_jf);
7001449Stomee 
7011449Stomee 	return (DTJ_OK);
7021449Stomee }
7031449Stomee 
7041449Stomee void
dtj_java_consumer_fini(JNIEnv * jenv,dtj_java_consumer_t * jc)7051449Stomee dtj_java_consumer_fini(JNIEnv *jenv, dtj_java_consumer_t *jc)
7061449Stomee {
7071449Stomee 	if (jc) {
7081449Stomee 		if (jc->dtjj_probedata) {
7091449Stomee 			(*jenv)->DeleteLocalRef(jenv, jc->dtjj_probedata);
7101449Stomee 			jc->dtjj_probedata = NULL;
7111449Stomee 		}
7121449Stomee 		if (jc->dtjj_printa_buffer) {
7131449Stomee 			(*jenv)->DeleteLocalRef(jenv, jc->dtjj_printa_buffer);
7141449Stomee 			jc->dtjj_printa_buffer = NULL;
7151449Stomee 		}
7161449Stomee 		if (jc->dtjj_aggregate) {
7171449Stomee 			(*jenv)->DeleteLocalRef(jenv, jc->dtjj_aggregate);
7181449Stomee 			jc->dtjj_aggregate = NULL;
7191449Stomee 		}
7201449Stomee 		if (jc->dtjj_tuple) {
7211449Stomee 			(*jenv)->DeleteLocalRef(jenv, jc->dtjj_tuple);
7221449Stomee 			jc->dtjj_tuple = NULL;
7231449Stomee 		}
7241449Stomee 		if (jc->dtjj_aggval_list) {
7251449Stomee 			dtj_list_destroy(jc->dtjj_aggval_list,
7261449Stomee 			    dtj_aggval_destroy, jenv);
7271449Stomee 			jc->dtjj_aggval_list = NULL;
7281449Stomee 		}
7291449Stomee 
7301449Stomee 		/*
7311449Stomee 		 * aggregate_spec records an input argument to a native JNI
7321449Stomee 		 * function (a reference we did not create), so we are not
7331449Stomee 		 * responsible for it.
7341449Stomee 		 */
7351449Stomee 		jc->dtjj_aggregate_spec = NULL;
7361449Stomee 
7371449Stomee 		/*
7381449Stomee 		 * probelist records an in-out argument to a native JNI function
7391449Stomee 		 * (a reference we did not create), so we are not responsible
7401449Stomee 		 * for it.
7411449Stomee 		 */
7421449Stomee 		jc->dtjj_probelist = NULL;
7431449Stomee 
7441449Stomee 		if (jc->dtjj_exception) {
7451449Stomee 			(*jenv)->DeleteLocalRef(jenv, jc->dtjj_exception);
7461449Stomee 			jc->dtjj_exception = NULL;
7471449Stomee 		}
7481449Stomee 		(*jenv)->DeleteLocalRef(jenv, jc->dtjj_consumer_lock);
7491449Stomee 		jc->dtjj_consumer_lock = NULL;
7501449Stomee 	}
7511449Stomee }
7521449Stomee 
7531449Stomee dtj_consumer_t *
dtj_consumer_create(JNIEnv * jenv)7541449Stomee dtj_consumer_create(JNIEnv *jenv)
7551449Stomee {
7561449Stomee 	dtj_consumer_t *c;
7571449Stomee 
7581449Stomee 	if (!dtj_check_request_pool()) {
7591449Stomee 		dtj_throw_out_of_memory(jenv,
7601449Stomee 		    "Failed to allocate request pool");
7611449Stomee 		return (NULL);
7621449Stomee 	}
7631449Stomee 
7641449Stomee 	if (!dtj_check_program_pool()) {
7651449Stomee 		dtj_throw_out_of_memory(jenv,
7661449Stomee 		    "Failed to allocate program pool");
7671449Stomee 		return (NULL);
7681449Stomee 	}
7691449Stomee 
7701449Stomee 	c = uu_zalloc(sizeof (dtj_consumer_t));
7711449Stomee 	if (c) {
7721449Stomee 		c->dtjc_request_list = uu_list_create(g_request_pool, NULL,
7731449Stomee 		    (g_dtj_util_debug ? UU_LIST_DEBUG : 0));
7741449Stomee 		if (!c->dtjc_request_list) {
7751449Stomee 			dtj_throw_out_of_memory(jenv,
7761449Stomee 			    "Failed to allocate consumer request list");
7771449Stomee 			dtj_consumer_destroy(c);
7781449Stomee 			return (NULL);
7791449Stomee 		}
7801449Stomee 		(void) pthread_mutex_init(&c->dtjc_request_list_lock, NULL);
7811449Stomee 
7821449Stomee 		c->dtjc_program_list = uu_list_create(g_program_pool, NULL,
7831449Stomee 		    (g_dtj_util_debug ? UU_LIST_DEBUG : 0));
7841449Stomee 		if (!c->dtjc_program_list) {
7851449Stomee 			dtj_throw_out_of_memory(jenv,
7861449Stomee 			    "Failed to allocate consumer program list");
7871449Stomee 			dtj_consumer_destroy(c);
7881449Stomee 			return (NULL);
7891449Stomee 		}
7901449Stomee 
7911449Stomee 		c->dtjc_probedata_rec_i = 0;
7921449Stomee 		c->dtjc_probedata_act = DTRACEACT_NONE;
7931449Stomee 		c->dtjc_aggid = -1;
7941449Stomee 		c->dtjc_expected = -1;
7951449Stomee 		c->dtjc_state = DTJ_CONSUMER_INIT;
7961449Stomee 	} else {
7971449Stomee 		dtj_throw_out_of_memory(jenv,
7981449Stomee 		    "Failed to allocate consumer");
7991449Stomee 	}
8001449Stomee 
8011449Stomee 	return (c);
8021449Stomee }
8031449Stomee 
8041449Stomee void
8051449Stomee /* ARGSUSED */
dtj_request_destroy(void * v,void * arg)8061449Stomee dtj_request_destroy(void *v, void *arg)
8071449Stomee {
8081449Stomee 	if (v) {
8091449Stomee 		dtj_request_t *r = v;
8101449Stomee 		dtj_string_list_destroy(r->dtjr_args);
8111449Stomee 		uu_list_node_fini(r, &r->dtjr_node, g_request_pool);
8121449Stomee 		bzero(v, sizeof (dtj_request_t));
8131449Stomee 		uu_free(v);
8141449Stomee 	}
8151449Stomee }
8161449Stomee 
8171449Stomee void
8181449Stomee /* ARGSUSED */
dtj_program_destroy(void * v,void * arg)8191449Stomee dtj_program_destroy(void *v, void *arg)
8201449Stomee {
8211449Stomee 	if (v) {
8221449Stomee 		dtj_program_t *p = v;
8231449Stomee 		if (p->dtjp_name) {
8241449Stomee 			free((void *)p->dtjp_name);
8251449Stomee 		}
8261449Stomee 		uu_list_node_fini(p, &p->dtjp_node, g_program_pool);
8271449Stomee 		bzero(v, sizeof (dtj_program_t));
8281449Stomee 		uu_free(v);
8291449Stomee 	}
8301449Stomee }
8311449Stomee 
8321449Stomee void
dtj_aggval_destroy(void * v,void * arg)8331449Stomee dtj_aggval_destroy(void *v, void *arg)
8341449Stomee {
8351449Stomee 	if (v) {
8361449Stomee 		dtj_aggval_t *a = v;
8371449Stomee 		if (a->dtja_value && arg) {
8381449Stomee 			JNIEnv *jenv = arg;
8391449Stomee 			(*jenv)->DeleteLocalRef(jenv, a->dtja_value);
8401449Stomee 		}
8411449Stomee 		if (a->dtja_aggname) {
8421449Stomee 			free((void *)a->dtja_aggname);
8431449Stomee 		}
8441449Stomee 		uu_list_node_fini(a, &a->dtja_node, g_aggval_pool);
8451449Stomee 		bzero(v, sizeof (dtj_aggval_t));
8461449Stomee 		uu_free(v);
8471449Stomee 	}
8481449Stomee }
8491449Stomee 
8501449Stomee /*
8511449Stomee  * Frees per-consumer state.  Assumes that the DTrace handle has been closed
8521449Stomee  * already.
8531449Stomee  */
8541449Stomee void
dtj_consumer_destroy(dtj_consumer_t * c)8551449Stomee dtj_consumer_destroy(dtj_consumer_t *c)
8561449Stomee {
8571449Stomee 	if (c) {
8581449Stomee 		dtj_list_destroy(c->dtjc_request_list, dtj_request_destroy,
8591449Stomee 		    NULL);
8601449Stomee 		(void) pthread_mutex_destroy(&c->dtjc_request_list_lock);
8611449Stomee 		dtj_list_destroy(c->dtjc_program_list, dtj_program_destroy,
8621449Stomee 		    NULL);
8631449Stomee 		/*
8641449Stomee 		 * Cannot dtrace_proc_release the c->process_list proc
8651449Stomee 		 * elements here, because we need the dtrace handle for that.
8661449Stomee 		 * By the time this destructor is called, the dtrace handle is
8671449Stomee 		 * already closed.  The proc elements are released in
8681449Stomee 		 * dtrace_jni.c _close().
8691449Stomee 		 */
8701449Stomee 		if (c->dtjc_process_list) {
8711449Stomee 			dtj_list_destroy(c->dtjc_process_list, NULL, NULL);
8721449Stomee 		}
8731449Stomee 		bzero(c, sizeof (dtj_consumer_t));
8741449Stomee 		uu_free(c);
8751449Stomee 	}
8761449Stomee }
8771449Stomee 
8781449Stomee void
dtj_throw_dtrace_exception(dtj_java_consumer_t * jc,const char * fmt,...)8791449Stomee dtj_throw_dtrace_exception(dtj_java_consumer_t *jc, const char *fmt, ...)
8801449Stomee {
8811449Stomee 	JNIEnv *jenv = jc->dtjj_jenv;
8821449Stomee 
8831449Stomee 	va_list ap;
8841449Stomee 	char msg[DTJ_MSG_SIZE];
8851449Stomee 
8861449Stomee 	jobject message = NULL;
8871449Stomee 	jobject exception = NULL;
8881449Stomee 
8891449Stomee 	va_start(ap, fmt);
8901449Stomee 	(void) vsnprintf(msg, sizeof (msg), fmt, ap);
8911449Stomee 	va_end(ap);
8921449Stomee 
8931449Stomee 	message = dtj_NewStringNative(jenv, msg);
8941449Stomee 	if (!message) {
8951449Stomee 		return; /* java exception pending */
8961449Stomee 	}
8971449Stomee 
8981449Stomee 	exception = (*jenv)->NewObject(jenv, g_dtx_jc, g_dtxinit_jm, message);
8991449Stomee 	(*jenv)->DeleteLocalRef(jenv, message);
9001449Stomee 	if (exception) {
9011449Stomee 		(*jenv)->Throw(jenv, exception);
9021449Stomee 		(*jenv)->DeleteLocalRef(jenv, exception);
9031449Stomee 	}
9041449Stomee }
905