1fb3fb4f3Stomee /*
2fb3fb4f3Stomee  * CDDL HEADER START
3fb3fb4f3Stomee  *
4fb3fb4f3Stomee  * The contents of this file are subject to the terms of the
5fb3fb4f3Stomee  * Common Development and Distribution License (the "License").
6fb3fb4f3Stomee  * You may not use this file except in compliance with the License.
7fb3fb4f3Stomee  *
8fb3fb4f3Stomee  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fb3fb4f3Stomee  * or http://www.opensolaris.org/os/licensing.
10fb3fb4f3Stomee  * See the License for the specific language governing permissions
11fb3fb4f3Stomee  * and limitations under the License.
12fb3fb4f3Stomee  *
13fb3fb4f3Stomee  * When distributing Covered Code, include this CDDL HEADER in each
14fb3fb4f3Stomee  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fb3fb4f3Stomee  * If applicable, add the following below this CDDL HEADER, with the
16fb3fb4f3Stomee  * fields enclosed by brackets "[]" replaced with your own identifying
17fb3fb4f3Stomee  * information: Portions Copyright [yyyy] [name of copyright owner]
18fb3fb4f3Stomee  *
19fb3fb4f3Stomee  * CDDL HEADER END
20fb3fb4f3Stomee  */
21fb3fb4f3Stomee 
22fb3fb4f3Stomee /*
23e77b06d2Stomee  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24fb3fb4f3Stomee  * Use is subject to license terms.
25fb3fb4f3Stomee  */
26fb3fb4f3Stomee 
27fb3fb4f3Stomee #include <stdlib.h>
28fb3fb4f3Stomee #include <stddef.h>
29fb3fb4f3Stomee #include <limits.h>
30fb3fb4f3Stomee #include <strings.h>
31fb3fb4f3Stomee #include <pthread.h>
32fb3fb4f3Stomee #include <dtrace_jni.h>
33fb3fb4f3Stomee 
34fb3fb4f3Stomee /*
35fb3fb4f3Stomee  * dtj_jnitab.c defines the JNI table of classes, methods, and fields belonging
36fb3fb4f3Stomee  * to the Java DTrace API.  Another JNI table defining classes from the JDK is
37fb3fb4f3Stomee  * defined in dtj_util.c.  Utility functions specific to the Java DTrace API are
38fb3fb4f3Stomee  * also defined here, while general utilities are defined in dtj_util.c.
39fb3fb4f3Stomee  */
40fb3fb4f3Stomee 
41fb3fb4f3Stomee static uu_list_pool_t *g_request_pool = NULL;
42fb3fb4f3Stomee static uu_list_pool_t *g_program_pool = NULL;
43fb3fb4f3Stomee static uu_list_pool_t *g_aggval_pool = NULL;
44fb3fb4f3Stomee 
45fb3fb4f3Stomee static boolean_t dtj_check_request_pool(void);
46fb3fb4f3Stomee static boolean_t dtj_check_program_pool(void);
47fb3fb4f3Stomee static boolean_t dtj_check_aggval_pool(void);
48fb3fb4f3Stomee 
49fb3fb4f3Stomee /* LocalConsumer */
50fb3fb4f3Stomee jclass g_caller_jc = 0;
51fb3fb4f3Stomee jmethodID g_gethandle_jm = 0;
52fb3fb4f3Stomee jmethodID g_sethandle_jm = 0;
53fb3fb4f3Stomee jmethodID g_pdatanext_jm = 0;
54fb3fb4f3Stomee jmethodID g_drop_jm = 0;
55fb3fb4f3Stomee jmethodID g_error_jm = 0;
56fb3fb4f3Stomee jmethodID g_proc_jm = 0;
57fb3fb4f3Stomee jmethodID g_interval_began_jm = 0;
58fb3fb4f3Stomee jmethodID g_interval_ended_jm = 0;
59fb3fb4f3Stomee jfieldID g_consumer_lock_jf = 0;
60fb3fb4f3Stomee 
61fb3fb4f3Stomee /* DTraceException */
62fb3fb4f3Stomee jclass g_dtx_jc = 0;
63fb3fb4f3Stomee jmethodID g_dtxinit_jm = 0;
64fb3fb4f3Stomee 
65fb3fb4f3Stomee /* InterfaceAttributes */
66fb3fb4f3Stomee jclass g_attr_jc = 0;
67fb3fb4f3Stomee jmethodID g_attrinit_jm = 0;
68fb3fb4f3Stomee jmethodID g_attrset_name_jm = 0;
69fb3fb4f3Stomee jmethodID g_attrset_data_jm = 0;
70fb3fb4f3Stomee jmethodID g_attrset_class_jm = 0;
71fb3fb4f3Stomee 
72fb3fb4f3Stomee /* ProbeDescription */
73fb3fb4f3Stomee jclass g_probedesc_jc = 0;
74fb3fb4f3Stomee jmethodID g_probedescinit_jm = 0;
75fb3fb4f3Stomee jfieldID g_probedesc_id_jf = 0;
76fb3fb4f3Stomee 
77fb3fb4f3Stomee /* ProbeInfo */
78fb3fb4f3Stomee jclass g_probeinfo_jc = 0;
79fb3fb4f3Stomee jmethodID g_probeinfoinit_jm = 0;
80fb3fb4f3Stomee 
81fb3fb4f3Stomee /* Probe */
82fb3fb4f3Stomee jclass g_probe_jc = 0;
83fb3fb4f3Stomee jmethodID g_probeinit_jm = 0;
84fb3fb4f3Stomee 
85fb3fb4f3Stomee /* Program */
86fb3fb4f3Stomee jclass g_program_jc = 0;
87fb3fb4f3Stomee jmethodID g_proginit_jm = 0;
88fb3fb4f3Stomee jfieldID g_progid_jf = 0;
89fb3fb4f3Stomee jfieldID g_proginfo_jf = 0;
90fb3fb4f3Stomee 
91fb3fb4f3Stomee /* Program.File */
92fb3fb4f3Stomee jclass g_programfile_jc = 0;
93fb3fb4f3Stomee jmethodID g_fproginit_jm = 0;
94fb3fb4f3Stomee 
95fb3fb4f3Stomee /* ProgramInfo */
96fb3fb4f3Stomee jclass g_proginfo_jc = 0;
97fb3fb4f3Stomee jmethodID g_proginfoinit_jm = 0;
98fb3fb4f3Stomee 
99fb3fb4f3Stomee /* Flow */
100fb3fb4f3Stomee jclass g_flow_jc = 0;
101fb3fb4f3Stomee jmethodID g_flowinit_jm = 0;
102fb3fb4f3Stomee 
103fb3fb4f3Stomee /* ProbeData */
104fb3fb4f3Stomee jclass g_pdata_jc = 0;
105fb3fb4f3Stomee jmethodID g_pdatainit_jm = 0;
106fb3fb4f3Stomee jmethodID g_pdataadd_jm = 0;
107fb3fb4f3Stomee jmethodID g_pdataadd_rec_jm = 0;
108fb3fb4f3Stomee jmethodID g_pdataadd_trace_jm = 0;
109fb3fb4f3Stomee jmethodID g_pdataadd_stack_jm = 0;
110127bbe13Stomee jmethodID g_pdataadd_symbol_jm = 0;
111fb3fb4f3Stomee jmethodID g_pdataadd_printf_jm = 0;
112fb3fb4f3Stomee jmethodID g_pdataadd_printa_jm = 0;
113fb3fb4f3Stomee jmethodID g_pdatainvalidate_printa_jm = 0;
114fb3fb4f3Stomee jmethodID g_pdataadd_aggrec_jm = 0;
115fb3fb4f3Stomee jmethodID g_pdataadd_printa_str_jm = 0;
116fb3fb4f3Stomee jmethodID g_pdataadd_exit_jm = 0;
117fb3fb4f3Stomee jmethodID g_pdataattach_jm = 0;
118fb3fb4f3Stomee jmethodID g_pdataset_formatted_jm = 0;
119fb3fb4f3Stomee jmethodID g_pdataclear_jm = 0;
120fb3fb4f3Stomee 
121fb3fb4f3Stomee /* Drop */
122fb3fb4f3Stomee jclass g_drop_jc = 0;
123fb3fb4f3Stomee jmethodID g_dropinit_jm = 0;
124fb3fb4f3Stomee 
125fb3fb4f3Stomee /* Error */
126fb3fb4f3Stomee jclass g_error_jc = 0;
127fb3fb4f3Stomee jmethodID g_errinit_jm = 0;
128fb3fb4f3Stomee 
129fb3fb4f3Stomee /* ProcessState */
130fb3fb4f3Stomee jclass g_process_jc = 0;
131fb3fb4f3Stomee jmethodID g_procinit_jm = 0;
132fb3fb4f3Stomee jmethodID g_procexit_jm = 0;
133fb3fb4f3Stomee 
134fb3fb4f3Stomee /* Aggregate */
135fb3fb4f3Stomee jclass g_agg_jc = 0;
136fb3fb4f3Stomee jmethodID g_agginit_jm = 0;
137fb3fb4f3Stomee jmethodID g_aggaddrec_jm = 0;
138fb3fb4f3Stomee 
139fb3fb4f3Stomee /* AggregateSpec */
140fb3fb4f3Stomee jclass g_aggspec_jc = 0;
141fb3fb4f3Stomee jmethodID g_aggspec_included_jm = 0;
142fb3fb4f3Stomee jmethodID g_aggspec_cleared_jm = 0;
143fb3fb4f3Stomee 
144fb3fb4f3Stomee /* Tuple */
145fb3fb4f3Stomee jclass g_tuple_jc = 0;
146fb3fb4f3Stomee jmethodID g_tupleinit_jm = 0;
147fb3fb4f3Stomee jmethodID g_tupleadd_jm = 0;
148fb3fb4f3Stomee jmethodID g_tuplesize_jm = 0;
149fb3fb4f3Stomee jfieldID g_tuple_EMPTY_jsf = 0;
150fb3fb4f3Stomee 
151fb3fb4f3Stomee /* AggregationRecord */
152fb3fb4f3Stomee jclass g_aggrec_jc = 0;
153fb3fb4f3Stomee jmethodID g_aggrecinit_jm = 0;
154fb3fb4f3Stomee jmethodID g_aggrecget_tuple_jm = 0;
155fb3fb4f3Stomee 
156fb3fb4f3Stomee /* SumValue */
157fb3fb4f3Stomee jclass g_aggsum_jc = 0;
158fb3fb4f3Stomee jmethodID g_aggsuminit_jm = 0;
159fb3fb4f3Stomee 
160fb3fb4f3Stomee /* CountValue */
161fb3fb4f3Stomee jclass g_aggcount_jc = 0;
162fb3fb4f3Stomee jmethodID g_aggcountinit_jm = 0;
163fb3fb4f3Stomee 
164fb3fb4f3Stomee /* AvgValue */
165fb3fb4f3Stomee jclass g_aggavg_jc = 0;
166fb3fb4f3Stomee jmethodID g_aggavginit_jm = 0;
167fb3fb4f3Stomee 
168fb3fb4f3Stomee /* MinValue */
169fb3fb4f3Stomee jclass g_aggmin_jc = 0;
170fb3fb4f3Stomee jmethodID g_aggmininit_jm = 0;
171fb3fb4f3Stomee 
172fb3fb4f3Stomee /* MaxValue */
173fb3fb4f3Stomee jclass g_aggmax_jc = 0;
174fb3fb4f3Stomee jmethodID g_aggmaxinit_jm = 0;
175fb3fb4f3Stomee 
176e77b06d2Stomee /* StddevValue */
177e77b06d2Stomee jclass g_aggstddev_jc = 0;
178e77b06d2Stomee jmethodID g_aggstddevinit_jm = 0;
179e77b06d2Stomee 
180fb3fb4f3Stomee /* KernelStackRecord */
181fb3fb4f3Stomee jclass g_stack_jc = 0;
182fb3fb4f3Stomee jmethodID g_parsestack_jsm = 0;
183fb3fb4f3Stomee jmethodID g_stackinit_jm = 0;
184fb3fb4f3Stomee jmethodID g_stackset_frames_jm = 0;
185fb3fb4f3Stomee 
186fb3fb4f3Stomee /* UserStackRecord */
187fb3fb4f3Stomee jclass g_ustack_jc = 0;
188fb3fb4f3Stomee jmethodID g_ustackinit_jm = 0;
189fb3fb4f3Stomee jmethodID g_ustackset_frames_jm = 0;
190fb3fb4f3Stomee 
191fb3fb4f3Stomee /* Distribution */
192fb3fb4f3Stomee jclass g_adist_jc = 0;
193fb3fb4f3Stomee jmethodID g_dist_normal_jm = 0;
194fb3fb4f3Stomee 
195fb3fb4f3Stomee /* LogDistribution */
196fb3fb4f3Stomee jclass g_dist_jc = 0;
197fb3fb4f3Stomee jmethodID g_distinit_jm = 0;
198fb3fb4f3Stomee 
199*ae94d716SRichard Lowe /* LogLinear Distribution */
200*ae94d716SRichard Lowe jclass g_lldist_jc = 0;
201*ae94d716SRichard Lowe jmethodID g_lldistinit_jm = 0;
202*ae94d716SRichard Lowe 
203fb3fb4f3Stomee /* LinearDistribution */
204fb3fb4f3Stomee jclass g_ldist_jc = 0;
205fb3fb4f3Stomee jmethodID g_ldistinit_jm = 0;
206fb3fb4f3Stomee 
207127bbe13Stomee /* KernelSymbolRecord */
208127bbe13Stomee jclass g_symbol_jc = 0;
209127bbe13Stomee jmethodID g_symbolinit_jm = 0;
210127bbe13Stomee jmethodID g_symbolset_name_jm = 0;
211127bbe13Stomee 
212127bbe13Stomee /* UserSymbolRecord */
213127bbe13Stomee jclass g_usymbol_jc = 0;
214127bbe13Stomee jmethodID g_usymbolinit_jm = 0;
215127bbe13Stomee jmethodID g_usymbolset_name_jm = 0;
216127bbe13Stomee 
217127bbe13Stomee /* ScalarRecord */
218127bbe13Stomee jclass g_scalar_jc = 0;
219127bbe13Stomee jmethodID g_scalarinit_jm = 0;
220127bbe13Stomee 
221fb3fb4f3Stomee 
222fb3fb4f3Stomee static dtj_status_t
dtj_table_load(JNIEnv * jenv)223fb3fb4f3Stomee dtj_table_load(JNIEnv *jenv)
224fb3fb4f3Stomee {
2254ae67516Stomee 	/*
2264ae67516Stomee 	 * If you change this table, increment DTRACE_JNI_VERSION in
2274ae67516Stomee 	 * dtrace_jni.c.
2284ae67516Stomee 	 */
229fb3fb4f3Stomee 	static const dtj_table_entry_t table[] = {
230fb3fb4f3Stomee 		/* LocalConsumer */
231fb3fb4f3Stomee 		{ JCLASS,  &g_caller_jc,
232fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/LocalConsumer" },
233fb3fb4f3Stomee 		{ JMETHOD, &g_gethandle_jm, "getHandle", "()I" },
234fb3fb4f3Stomee 		{ JMETHOD, &g_sethandle_jm, "setHandle", "(I)V" },
235fb3fb4f3Stomee 		{ JMETHOD, &g_pdatanext_jm, "nextProbeData",
236fb3fb4f3Stomee 			"(Lorg/opensolaris/os/dtrace/ProbeData;)V" },
237fb3fb4f3Stomee 		{ JMETHOD, &g_drop_jm, "dataDropped",
238fb3fb4f3Stomee 			"(Lorg/opensolaris/os/dtrace/Drop;)V" },
239fb3fb4f3Stomee 		{ JMETHOD, &g_error_jm, "errorEncountered",
240fb3fb4f3Stomee 			"(Lorg/opensolaris/os/dtrace/Error;)V" },
241fb3fb4f3Stomee 		{ JMETHOD, &g_proc_jm, "processStateChanged",
242fb3fb4f3Stomee 			"(Lorg/opensolaris/os/dtrace/ProcessState;)V" },
243fb3fb4f3Stomee 		{ JMETHOD, &g_interval_began_jm, "intervalBegan", "()V" },
244fb3fb4f3Stomee 		{ JMETHOD, &g_interval_ended_jm, "intervalEnded", "()V" },
245fb3fb4f3Stomee 		{ JFIELD,  &g_consumer_lock_jf, "consumerLock",
246fb3fb4f3Stomee 			"Ljava/lang/Object;" },
247fb3fb4f3Stomee 
248fb3fb4f3Stomee 		/* DTraceException */
249fb3fb4f3Stomee 		{ JCLASS,  &g_dtx_jc,
250fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/DTraceException" },
251fb3fb4f3Stomee 		{ JMETHOD, &g_dtxinit_jm, CONSTRUCTOR,
252fb3fb4f3Stomee 			"(Ljava/lang/String;)V" },
253fb3fb4f3Stomee 
254fb3fb4f3Stomee 		/* InterfaceAttributes */
255fb3fb4f3Stomee 		{ JCLASS,  &g_attr_jc,
256fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/InterfaceAttributes" },
257fb3fb4f3Stomee 		{ JMETHOD, &g_attrinit_jm, CONSTRUCTOR, "()V" },
258fb3fb4f3Stomee 		{ JMETHOD, &g_attrset_name_jm, "setNameStability",
259fb3fb4f3Stomee 			"(Ljava/lang/String;)V" },
260fb3fb4f3Stomee 		{ JMETHOD, &g_attrset_data_jm, "setDataStability",
261fb3fb4f3Stomee 			"(Ljava/lang/String;)V" },
262fb3fb4f3Stomee 		{ JMETHOD, &g_attrset_class_jm, "setDependencyClass",
263fb3fb4f3Stomee 			"(Ljava/lang/String;)V" },
264fb3fb4f3Stomee 
265fb3fb4f3Stomee 		/* ProbeDescription */
266fb3fb4f3Stomee 		{ JCLASS,  &g_probedesc_jc,
267fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/ProbeDescription" },
268fb3fb4f3Stomee 		{ JMETHOD, &g_probedescinit_jm, CONSTRUCTOR,
269fb3fb4f3Stomee 			"(Ljava/lang/String;Ljava/lang/String;"
270fb3fb4f3Stomee 			    "Ljava/lang/String;Ljava/lang/String;)V" },
271fb3fb4f3Stomee 		{ JFIELD,  &g_probedesc_id_jf, "id", "I" },
272fb3fb4f3Stomee 
273fb3fb4f3Stomee 		/* ProbeInfo */
274fb3fb4f3Stomee 		{ JCLASS,  &g_probeinfo_jc,
275fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/ProbeInfo" },
276fb3fb4f3Stomee 		{ JMETHOD, &g_probeinfoinit_jm, CONSTRUCTOR,
277fb3fb4f3Stomee 			"(Lorg/opensolaris/os/dtrace/InterfaceAttributes;"
278fb3fb4f3Stomee 			    "Lorg/opensolaris/os/dtrace/InterfaceAttributes;"
279fb3fb4f3Stomee 			    ")V" },
280fb3fb4f3Stomee 
281fb3fb4f3Stomee 		/* Probe */
282fb3fb4f3Stomee 		{ JCLASS,  &g_probe_jc, "org/opensolaris/os/dtrace/Probe" },
283fb3fb4f3Stomee 		{ JMETHOD, &g_probeinit_jm, CONSTRUCTOR,
284fb3fb4f3Stomee 			"(Lorg/opensolaris/os/dtrace/ProbeDescription;"
285fb3fb4f3Stomee 			    "Lorg/opensolaris/os/dtrace/ProbeInfo;)V" },
286fb3fb4f3Stomee 
287fb3fb4f3Stomee 		/* Program */
288fb3fb4f3Stomee 		{ JCLASS,  &g_program_jc,
289fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/Program" },
290fb3fb4f3Stomee 		{ JMETHOD, &g_proginit_jm, CONSTRUCTOR, "()V" },
291fb3fb4f3Stomee 		{ JFIELD,  &g_progid_jf, "id", "I" },
292fb3fb4f3Stomee 		{ JFIELD,  &g_proginfo_jf, "info",
293fb3fb4f3Stomee 			"Lorg/opensolaris/os/dtrace/ProgramInfo;" },
294fb3fb4f3Stomee 
295fb3fb4f3Stomee 		/* Program.File */
296fb3fb4f3Stomee 		{ JCLASS,  &g_programfile_jc,
297fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/Program$File" },
298fb3fb4f3Stomee 		{ JMETHOD, &g_fproginit_jm, CONSTRUCTOR, "()V" },
299fb3fb4f3Stomee 
300fb3fb4f3Stomee 		/* ProgramInfo */
301fb3fb4f3Stomee 		{ JCLASS,  &g_proginfo_jc,
302fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/ProgramInfo" },
303fb3fb4f3Stomee 		{ JMETHOD, &g_proginfoinit_jm, CONSTRUCTOR,
304fb3fb4f3Stomee 			"(Lorg/opensolaris/os/dtrace/InterfaceAttributes;"
305fb3fb4f3Stomee 			    "Lorg/opensolaris/os/dtrace/InterfaceAttributes;"
306fb3fb4f3Stomee 			    "I)V" },
307fb3fb4f3Stomee 
308fb3fb4f3Stomee 		/* Flow */
309fb3fb4f3Stomee 		{ JCLASS,  &g_flow_jc, "org/opensolaris/os/dtrace/Flow" },
310fb3fb4f3Stomee 		{ JMETHOD, &g_flowinit_jm, CONSTRUCTOR,
311fb3fb4f3Stomee 			"(Ljava/lang/String;I)V" },
312fb3fb4f3Stomee 
313fb3fb4f3Stomee 		/* ProbeData */
314fb3fb4f3Stomee 		{ JCLASS,  &g_pdata_jc,
315fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/ProbeData" },
316fb3fb4f3Stomee 		{ JMETHOD, &g_pdatainit_jm, CONSTRUCTOR,
317fb3fb4f3Stomee 			"(IILorg/opensolaris/os/dtrace/ProbeDescription;"
318fb3fb4f3Stomee 			    "Lorg/opensolaris/os/dtrace/Flow;I)V" },
319fb3fb4f3Stomee 		{ JMETHOD, &g_pdataadd_jm, "addDataElement",
320127bbe13Stomee 			"(Lorg/opensolaris/os/dtrace/Record;)V" },
321fb3fb4f3Stomee 		{ JMETHOD, &g_pdataadd_rec_jm, "addRecord",
322fb3fb4f3Stomee 			"(Lorg/opensolaris/os/dtrace/Record;)V" },
323fb3fb4f3Stomee 		{ JMETHOD, &g_pdataadd_trace_jm, "addTraceRecord", "(I)V" },
324fb3fb4f3Stomee 		{ JMETHOD, &g_pdataadd_stack_jm, "addStackRecord",
325fb3fb4f3Stomee 			"(ILjava/lang/String;)V" },
326127bbe13Stomee 		{ JMETHOD, &g_pdataadd_symbol_jm, "addSymbolRecord",
327127bbe13Stomee 			"(ILjava/lang/String;)V" },
328fb3fb4f3Stomee 		{ JMETHOD, &g_pdataadd_printf_jm, "addPrintfRecord", "()V" },
329fb3fb4f3Stomee 		{ JMETHOD, &g_pdataadd_printa_jm, "addPrintaRecord", "(JZ)V" },
330fb3fb4f3Stomee 		{ JMETHOD, &g_pdatainvalidate_printa_jm,
331fb3fb4f3Stomee 			"invalidatePrintaRecord", "()V" },
332fb3fb4f3Stomee 		{ JMETHOD, &g_pdataadd_aggrec_jm, "addAggregationRecord",
333fb3fb4f3Stomee 			"(Ljava/lang/String;J"
334fb3fb4f3Stomee 			    "Lorg/opensolaris/os/dtrace/AggregationRecord;)V" },
335fb3fb4f3Stomee 		{ JMETHOD, &g_pdataadd_printa_str_jm,
336fb3fb4f3Stomee 			"addPrintaFormattedString",
337fb3fb4f3Stomee 			"(Lorg/opensolaris/os/dtrace/Tuple;"
338fb3fb4f3Stomee 			    "Ljava/lang/String;)V" },
339fb3fb4f3Stomee 		{ JMETHOD, &g_pdataadd_exit_jm, "addExitRecord", "(I)V" },
340fb3fb4f3Stomee 		{ JMETHOD, &g_pdataattach_jm, "attachRecordElements",
341fb3fb4f3Stomee 			"(II)V" },
342fb3fb4f3Stomee 		{ JMETHOD, &g_pdataset_formatted_jm, "setFormattedString",
343fb3fb4f3Stomee 			"(Ljava/lang/String;)V" },
344fb3fb4f3Stomee 		{ JMETHOD, &g_pdataclear_jm, "clearNativeElements", "()V" },
345fb3fb4f3Stomee 
346fb3fb4f3Stomee 		/* Drop */
347fb3fb4f3Stomee 		{ JCLASS,  &g_drop_jc, "org/opensolaris/os/dtrace/Drop" },
348fb3fb4f3Stomee 		{ JMETHOD, &g_dropinit_jm, CONSTRUCTOR,
349fb3fb4f3Stomee 			"(ILjava/lang/String;JJLjava/lang/String;)V" },
350fb3fb4f3Stomee 
351fb3fb4f3Stomee 		/* Error */
352fb3fb4f3Stomee 		{ JCLASS,  &g_error_jc, "org/opensolaris/os/dtrace/Error" },
353fb3fb4f3Stomee 		{ JMETHOD, &g_errinit_jm, CONSTRUCTOR,
354fb3fb4f3Stomee 			"(Lorg/opensolaris/os/dtrace/ProbeDescription;IIII"
355fb3fb4f3Stomee 			    "Ljava/lang/String;JLjava/lang/String;)V" },
356fb3fb4f3Stomee 
357fb3fb4f3Stomee 		/* ProcessState */
358fb3fb4f3Stomee 		{ JCLASS,  &g_process_jc,
359fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/ProcessState" },
360fb3fb4f3Stomee 		{ JMETHOD, &g_procinit_jm, CONSTRUCTOR,
361fb3fb4f3Stomee 			"(ILjava/lang/String;ILjava/lang/String;"
362fb3fb4f3Stomee 			    "Ljava/lang/Integer;Ljava/lang/String;)V" },
363fb3fb4f3Stomee 		{ JMETHOD, &g_procexit_jm, "setExitStatus", "(I)V" },
364fb3fb4f3Stomee 
365fb3fb4f3Stomee 		/* Aggregate */
366fb3fb4f3Stomee 		{ JCLASS,  &g_agg_jc, "org/opensolaris/os/dtrace/Aggregate" },
367fb3fb4f3Stomee 		{ JMETHOD, &g_agginit_jm, CONSTRUCTOR, "(J)V" },
368fb3fb4f3Stomee 		{ JMETHOD, &g_aggaddrec_jm, "addRecord",
369fb3fb4f3Stomee 		    "(Ljava/lang/String;J"
370fb3fb4f3Stomee 			"Lorg/opensolaris/os/dtrace/AggregationRecord;)V" },
371fb3fb4f3Stomee 
372fb3fb4f3Stomee 		/* AggregateSpec */
373fb3fb4f3Stomee 		{ JCLASS,  &g_aggspec_jc,
374fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/AggregateSpec" },
375fb3fb4f3Stomee 		{ JMETHOD, &g_aggspec_included_jm, "isIncluded",
376fb3fb4f3Stomee 			"(Ljava/lang/String;)Z" },
377fb3fb4f3Stomee 		{ JMETHOD, &g_aggspec_cleared_jm, "isCleared",
378fb3fb4f3Stomee 			"(Ljava/lang/String;)Z" },
379fb3fb4f3Stomee 
380fb3fb4f3Stomee 		/* Tuple */
381fb3fb4f3Stomee 		{ JCLASS,  &g_tuple_jc, "org/opensolaris/os/dtrace/Tuple" },
382fb3fb4f3Stomee 		{ JMETHOD, &g_tupleinit_jm, CONSTRUCTOR, "()V" },
383fb3fb4f3Stomee 		{ JMETHOD, &g_tupleadd_jm, "addElement",
384127bbe13Stomee 			"(Lorg/opensolaris/os/dtrace/ValueRecord;)V" },
385fb3fb4f3Stomee 		{ JMETHOD, &g_tuplesize_jm, "size", "()I" },
386fb3fb4f3Stomee 		{ JFIELD_STATIC, &g_tuple_EMPTY_jsf, "EMPTY",
387fb3fb4f3Stomee 			"Lorg/opensolaris/os/dtrace/Tuple;" },
388fb3fb4f3Stomee 
389fb3fb4f3Stomee 		/* AggregationRecord */
390fb3fb4f3Stomee 		{ JCLASS,  &g_aggrec_jc,
391fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/AggregationRecord" },
392fb3fb4f3Stomee 		{ JMETHOD, &g_aggrecinit_jm, CONSTRUCTOR,
393fb3fb4f3Stomee 			"(Lorg/opensolaris/os/dtrace/Tuple;"
394fb3fb4f3Stomee 			    "Lorg/opensolaris/os/dtrace/AggregationValue;)V" },
395fb3fb4f3Stomee 		{ JMETHOD, &g_aggrecget_tuple_jm, "getTuple",
396fb3fb4f3Stomee 			"()Lorg/opensolaris/os/dtrace/Tuple;" },
397fb3fb4f3Stomee 
398fb3fb4f3Stomee 		/* SumValue */
399fb3fb4f3Stomee 		{ JCLASS,  &g_aggsum_jc,
400fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/SumValue" },
401fb3fb4f3Stomee 		{ JMETHOD, &g_aggsuminit_jm, CONSTRUCTOR, "(J)V" },
402fb3fb4f3Stomee 
403fb3fb4f3Stomee 		/* CountValue */
404fb3fb4f3Stomee 		{ JCLASS,  &g_aggcount_jc,
405fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/CountValue" },
406fb3fb4f3Stomee 		{ JMETHOD, &g_aggcountinit_jm, CONSTRUCTOR, "(J)V" },
407fb3fb4f3Stomee 
408fb3fb4f3Stomee 		/* AvgValue */
409fb3fb4f3Stomee 		{ JCLASS,  &g_aggavg_jc,
410fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/AvgValue" },
411fb3fb4f3Stomee 		{ JMETHOD, &g_aggavginit_jm, CONSTRUCTOR, "(JJJ)V" },
412fb3fb4f3Stomee 
413fb3fb4f3Stomee 		/* MinValue */
414fb3fb4f3Stomee 		{ JCLASS,  &g_aggmin_jc,
415fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/MinValue" },
416fb3fb4f3Stomee 		{ JMETHOD, &g_aggmininit_jm, CONSTRUCTOR, "(J)V" },
417fb3fb4f3Stomee 
418fb3fb4f3Stomee 		/* MaxValue */
419fb3fb4f3Stomee 		{ JCLASS,  &g_aggmax_jc,
420fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/MaxValue" },
421fb3fb4f3Stomee 		{ JMETHOD, &g_aggmaxinit_jm, CONSTRUCTOR, "(J)V" },
422fb3fb4f3Stomee 
423e77b06d2Stomee 		/* StddevValue */
424e77b06d2Stomee 		{ JCLASS,  &g_aggstddev_jc,
425e77b06d2Stomee 			"org/opensolaris/os/dtrace/StddevValue" },
426e77b06d2Stomee 		{ JMETHOD, &g_aggstddevinit_jm, CONSTRUCTOR,
427e77b06d2Stomee 			"(JJLjava/math/BigInteger;)V" },
428e77b06d2Stomee 
429fb3fb4f3Stomee 		/* KernelStackRecord */
430fb3fb4f3Stomee 		{ JCLASS,  &g_stack_jc,
431fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/KernelStackRecord" },
432fb3fb4f3Stomee 		{ JMETHOD_STATIC, &g_parsestack_jsm, "parse",
433fb3fb4f3Stomee 			"(Ljava/lang/String;)"
434fb3fb4f3Stomee 			    "[Lorg/opensolaris/os/dtrace/StackFrame;" },
435fb3fb4f3Stomee 		{ JMETHOD, &g_stackinit_jm, CONSTRUCTOR, "([B)V" },
436fb3fb4f3Stomee 		{ JMETHOD, &g_stackset_frames_jm, "setStackFrames",
437fb3fb4f3Stomee 			"([Lorg/opensolaris/os/dtrace/StackFrame;)V" },
438fb3fb4f3Stomee 
439fb3fb4f3Stomee 		/* UserStackRecord */
440fb3fb4f3Stomee 		{ JCLASS,  &g_ustack_jc,
441fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/UserStackRecord" },
442fb3fb4f3Stomee 		{ JMETHOD, &g_ustackinit_jm, CONSTRUCTOR, "(I[B)V" },
443fb3fb4f3Stomee 		{ JMETHOD, &g_ustackset_frames_jm, "setStackFrames",
444fb3fb4f3Stomee 			"([Lorg/opensolaris/os/dtrace/StackFrame;)V" },
445fb3fb4f3Stomee 
446fb3fb4f3Stomee 		/* Distribution */
447fb3fb4f3Stomee 		{ JCLASS,  &g_adist_jc,
448fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/Distribution" },
449fb3fb4f3Stomee 		{ JMETHOD, &g_dist_normal_jm, "normalizeBuckets", "(J)V" },
450fb3fb4f3Stomee 
451fb3fb4f3Stomee 		/* LogDistribution */
452fb3fb4f3Stomee 		{ JCLASS,  &g_dist_jc,
453fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/LogDistribution" },
454fb3fb4f3Stomee 		{ JMETHOD,  &g_distinit_jm, CONSTRUCTOR, "([J)V" },
455fb3fb4f3Stomee 
456*ae94d716SRichard Lowe 		/* LogLinearDistribution */
457*ae94d716SRichard Lowe 		{ JCLASS, &g_lldist_jc,
458*ae94d716SRichard Lowe 			"org/opensolaris/os/dtrace/LogLinearDistribution" },
459*ae94d716SRichard Lowe 		{ JMETHOD, &g_lldistinit_jm, CONSTRUCTOR, "(J[J)V" },
460*ae94d716SRichard Lowe 
461fb3fb4f3Stomee 		/* LinearDistribution */
462fb3fb4f3Stomee 		{ JCLASS,  &g_ldist_jc,
463fb3fb4f3Stomee 			"org/opensolaris/os/dtrace/LinearDistribution" },
464fb3fb4f3Stomee 		{ JMETHOD,  &g_ldistinit_jm, CONSTRUCTOR, "(JJ[J)V" },
465fb3fb4f3Stomee 
466127bbe13Stomee 		/* KernelSymbolRecord */
467127bbe13Stomee 		{ JCLASS,  &g_symbol_jc,
468127bbe13Stomee 			"org/opensolaris/os/dtrace/KernelSymbolRecord" },
469127bbe13Stomee 		{ JMETHOD,  &g_symbolinit_jm, CONSTRUCTOR, "(J)V" },
470127bbe13Stomee 		{ JMETHOD,  &g_symbolset_name_jm, "setSymbol",
471127bbe13Stomee 			"(Ljava/lang/String;)V" },
472127bbe13Stomee 
473127bbe13Stomee 		/* UserSymbolRecord */
474127bbe13Stomee 		{ JCLASS,  &g_usymbol_jc,
475127bbe13Stomee 			"org/opensolaris/os/dtrace/UserSymbolRecord" },
476127bbe13Stomee 		{ JMETHOD,  &g_usymbolinit_jm, CONSTRUCTOR, "(IJ)V" },
477127bbe13Stomee 		{ JMETHOD,  &g_usymbolset_name_jm, "setSymbol",
478127bbe13Stomee 			"(Ljava/lang/String;)V" },
479127bbe13Stomee 
480127bbe13Stomee 		/* ScalarRecord */
481127bbe13Stomee 		{ JCLASS,  &g_scalar_jc,
482127bbe13Stomee 			"org/opensolaris/os/dtrace/ScalarRecord" },
483127bbe13Stomee 		{ JMETHOD,  &g_scalarinit_jm, CONSTRUCTOR,
484127bbe13Stomee 			"(Ljava/lang/Object;I)V" },
485127bbe13Stomee 
486fb3fb4f3Stomee 		{ DTJ_TYPE_END }
487fb3fb4f3Stomee 	};
488fb3fb4f3Stomee 
489fb3fb4f3Stomee 	return (dtj_cache_jni_classes(jenv, table));
490fb3fb4f3Stomee }
491fb3fb4f3Stomee 
492fb3fb4f3Stomee dtj_status_t
dtj_load(JNIEnv * jenv)493fb3fb4f3Stomee dtj_load(JNIEnv *jenv)
494fb3fb4f3Stomee {
495fb3fb4f3Stomee 	if (dtj_load_common(jenv) != DTJ_OK) {
496fb3fb4f3Stomee 		/* Java Error pending */
497fb3fb4f3Stomee 		return (DTJ_ERR);
498fb3fb4f3Stomee 	}
499fb3fb4f3Stomee 
500fb3fb4f3Stomee 	return (dtj_table_load(jenv));
501fb3fb4f3Stomee }
502fb3fb4f3Stomee 
503fb3fb4f3Stomee static boolean_t
dtj_check_request_pool(void)504fb3fb4f3Stomee dtj_check_request_pool(void)
505fb3fb4f3Stomee {
506fb3fb4f3Stomee 	if (!g_request_pool) {
507fb3fb4f3Stomee 		g_request_pool = uu_list_pool_create("g_request_pool",
508fb3fb4f3Stomee 		    sizeof (dtj_request_t),
509fb3fb4f3Stomee 		    offsetof(dtj_request_t, dtjr_node),
510fb3fb4f3Stomee 		    dtj_pointer_list_entry_cmp,
511fb3fb4f3Stomee 		    (g_dtj_util_debug ? UU_LIST_POOL_DEBUG : 0));
512fb3fb4f3Stomee 		if (!g_request_pool) {
513fb3fb4f3Stomee 			return (B_FALSE);
514fb3fb4f3Stomee 		}
515fb3fb4f3Stomee 	}
516fb3fb4f3Stomee 	return (B_TRUE);
517fb3fb4f3Stomee }
518fb3fb4f3Stomee 
519fb3fb4f3Stomee dtj_request_t *
dtj_request_create(JNIEnv * jenv,dtj_request_type_t type,...)520fb3fb4f3Stomee dtj_request_create(JNIEnv *jenv, dtj_request_type_t type, ...)
521fb3fb4f3Stomee {
522fb3fb4f3Stomee 	dtj_request_t *r;
523fb3fb4f3Stomee 
524fb3fb4f3Stomee 	if (!dtj_check_request_pool()) {
525fb3fb4f3Stomee 		dtj_throw_out_of_memory(jenv,
526fb3fb4f3Stomee 		    "Failed to allocate request pool");
527fb3fb4f3Stomee 		return (NULL);
528fb3fb4f3Stomee 	}
529fb3fb4f3Stomee 
530fb3fb4f3Stomee 	r = uu_zalloc(sizeof (dtj_request_t));
531fb3fb4f3Stomee 	if (r) {
532fb3fb4f3Stomee 		uu_list_node_init(r, &r->dtjr_node, g_request_pool);
533fb3fb4f3Stomee 		r->dtjr_type = type;
534fb3fb4f3Stomee 		r->dtjr_args = dtj_string_list_create();
535fb3fb4f3Stomee 		if (r->dtjr_args) {
536fb3fb4f3Stomee 			va_list ap;
537fb3fb4f3Stomee 			const char *arg;
538fb3fb4f3Stomee 			int i, len;
539fb3fb4f3Stomee 
540fb3fb4f3Stomee 			va_start(ap, type);
541fb3fb4f3Stomee 			switch (type) {
542fb3fb4f3Stomee 			case DTJ_REQUEST_OPTION:
543fb3fb4f3Stomee 				len = 2;
544fb3fb4f3Stomee 				break;
545fb3fb4f3Stomee 			default:
546fb3fb4f3Stomee 				len = 0;
547fb3fb4f3Stomee 			}
548fb3fb4f3Stomee 
549fb3fb4f3Stomee 			for (i = 0; i < len; ++i) {
550fb3fb4f3Stomee 				arg = va_arg(ap, char *);
551fb3fb4f3Stomee 				if (!dtj_string_list_add(r->dtjr_args, arg)) {
552fb3fb4f3Stomee 					dtj_throw_out_of_memory(jenv,
553fb3fb4f3Stomee 					    "Failed to add request arg");
554fb3fb4f3Stomee 					uu_list_node_fini(r, &r->dtjr_node,
555fb3fb4f3Stomee 					    g_request_pool);
556fb3fb4f3Stomee 					dtj_request_destroy(r, NULL);
557fb3fb4f3Stomee 					r = NULL;
558fb3fb4f3Stomee 				}
559fb3fb4f3Stomee 			}
560fb3fb4f3Stomee 			va_end(ap);
561fb3fb4f3Stomee 		} else {
562fb3fb4f3Stomee 			dtj_throw_out_of_memory(jenv,
563fb3fb4f3Stomee 			    "Failed to allocate request arglist");
564fb3fb4f3Stomee 			uu_list_node_fini(r, &r->dtjr_node, g_request_pool);
565fb3fb4f3Stomee 			dtj_request_destroy(r, NULL);
566fb3fb4f3Stomee 			r = NULL;
567fb3fb4f3Stomee 		}
568fb3fb4f3Stomee 	} else {
569fb3fb4f3Stomee 		dtj_throw_out_of_memory(jenv,
570fb3fb4f3Stomee 		    "Failed to allocate request");
571fb3fb4f3Stomee 	}
572fb3fb4f3Stomee 
573fb3fb4f3Stomee 	return (r);
574fb3fb4f3Stomee }
575fb3fb4f3Stomee 
576fb3fb4f3Stomee static boolean_t
dtj_check_program_pool(void)577fb3fb4f3Stomee dtj_check_program_pool(void)
578fb3fb4f3Stomee {
579fb3fb4f3Stomee 	if (!g_program_pool) {
580fb3fb4f3Stomee 		g_program_pool = uu_list_pool_create("g_program_pool",
581fb3fb4f3Stomee 		    sizeof (dtj_program_t),
582fb3fb4f3Stomee 		    offsetof(dtj_program_t, dtjp_node),
583fb3fb4f3Stomee 		    dtj_pointer_list_entry_cmp,
584fb3fb4f3Stomee 		    (g_dtj_util_debug ? UU_LIST_POOL_DEBUG : 0));
585fb3fb4f3Stomee 		if (!g_program_pool) {
586fb3fb4f3Stomee 			return (B_FALSE);
587fb3fb4f3Stomee 		}
588fb3fb4f3Stomee 	}
589fb3fb4f3Stomee 	return (B_TRUE);
590fb3fb4f3Stomee }
591fb3fb4f3Stomee 
592fb3fb4f3Stomee dtj_program_t *
dtj_program_create(JNIEnv * jenv,dtj_program_type_t type,const char * name)593fb3fb4f3Stomee dtj_program_create(JNIEnv *jenv, dtj_program_type_t type, const char *name)
594fb3fb4f3Stomee {
595fb3fb4f3Stomee 	dtj_program_t *p;
596fb3fb4f3Stomee 
597fb3fb4f3Stomee 	if (!dtj_check_program_pool()) {
598fb3fb4f3Stomee 		dtj_throw_out_of_memory(jenv,
599fb3fb4f3Stomee 		    "Failed to allocate program pool");
600fb3fb4f3Stomee 		return (NULL);
601fb3fb4f3Stomee 	}
602fb3fb4f3Stomee 
603fb3fb4f3Stomee 	p = uu_zalloc(sizeof (dtj_program_t));
604fb3fb4f3Stomee 	if (p) {
605fb3fb4f3Stomee 		char *program_name;
606fb3fb4f3Stomee 
607fb3fb4f3Stomee 		uu_list_node_init(p, &p->dtjp_node, g_program_pool);
608fb3fb4f3Stomee 		p->dtjp_type = type;
609fb3fb4f3Stomee 		program_name = malloc((size_t)
610fb3fb4f3Stomee 		    (sizeof (char)) * (strlen(name) + 1));
611fb3fb4f3Stomee 		if (program_name) {
612fb3fb4f3Stomee 			(void) strcpy(program_name, name);
613fb3fb4f3Stomee 			p->dtjp_name = program_name;
614fb3fb4f3Stomee 			p->dtjp_enabled = B_FALSE;
615fb3fb4f3Stomee 		} else {
616fb3fb4f3Stomee 			dtj_throw_out_of_memory(jenv,
617fb3fb4f3Stomee 			    "Failed to allocate program name");
618fb3fb4f3Stomee 			uu_list_node_fini(p, &p->dtjp_node, g_program_pool);
619fb3fb4f3Stomee 			dtj_program_destroy(p, NULL);
620fb3fb4f3Stomee 			p = NULL;
621fb3fb4f3Stomee 		}
622fb3fb4f3Stomee 	} else {
623fb3fb4f3Stomee 		dtj_throw_out_of_memory(jenv,
624fb3fb4f3Stomee 		    "Failed to allocate program");
625fb3fb4f3Stomee 	}
626fb3fb4f3Stomee 
627fb3fb4f3Stomee 	return (p);
628fb3fb4f3Stomee }
629fb3fb4f3Stomee 
630fb3fb4f3Stomee static boolean_t
dtj_check_aggval_pool(void)631fb3fb4f3Stomee dtj_check_aggval_pool(void)
632fb3fb4f3Stomee {
633fb3fb4f3Stomee 	if (!g_aggval_pool) {
634fb3fb4f3Stomee 		g_aggval_pool = uu_list_pool_create("g_aggval_pool",
635fb3fb4f3Stomee 		    sizeof (dtj_aggval_t),
636fb3fb4f3Stomee 		    offsetof(dtj_aggval_t, dtja_node),
637fb3fb4f3Stomee 		    dtj_pointer_list_entry_cmp,
638fb3fb4f3Stomee 		    (g_dtj_util_debug ? UU_LIST_POOL_DEBUG : 0));
639fb3fb4f3Stomee 		if (!g_aggval_pool) {
640fb3fb4f3Stomee 			return (B_FALSE);
641fb3fb4f3Stomee 		}
642fb3fb4f3Stomee 	}
643fb3fb4f3Stomee 	return (B_TRUE);
644fb3fb4f3Stomee }
645fb3fb4f3Stomee 
646fb3fb4f3Stomee dtj_aggval_t *
dtj_aggval_create(JNIEnv * jenv,jobject aggval,const char * aggname,int64_t aggid)647fb3fb4f3Stomee dtj_aggval_create(JNIEnv *jenv, jobject aggval, const char *aggname,
648fb3fb4f3Stomee     int64_t aggid)
649fb3fb4f3Stomee {
650fb3fb4f3Stomee 	dtj_aggval_t *e;
651fb3fb4f3Stomee 
652fb3fb4f3Stomee 	if (!dtj_check_aggval_pool()) {
653fb3fb4f3Stomee 		dtj_throw_out_of_memory(jenv,
654fb3fb4f3Stomee 		    "Failed to allocate aggval entry pool");
655fb3fb4f3Stomee 		return (NULL);
656fb3fb4f3Stomee 	}
657fb3fb4f3Stomee 
658fb3fb4f3Stomee 	e = uu_zalloc(sizeof (dtj_aggval_t));
659fb3fb4f3Stomee 	if (e) {
660fb3fb4f3Stomee 		char *a_name;
661fb3fb4f3Stomee 
662fb3fb4f3Stomee 		uu_list_node_init(e, &e->dtja_node, g_aggval_pool);
663fb3fb4f3Stomee 		e->dtja_value = aggval;
664fb3fb4f3Stomee 		a_name = malloc((size_t)
665fb3fb4f3Stomee 		    (sizeof (char)) * (strlen(aggname) + 1));
666fb3fb4f3Stomee 		if (a_name) {
667fb3fb4f3Stomee 			(void) strcpy(a_name, aggname);
668fb3fb4f3Stomee 			e->dtja_aggname = a_name;
669fb3fb4f3Stomee 		} else {
670fb3fb4f3Stomee 			dtj_throw_out_of_memory(jenv,
671fb3fb4f3Stomee 			    "Failed to allocate aggregation name");
672fb3fb4f3Stomee 			uu_list_node_fini(e, &e->dtja_node, g_aggval_pool);
673fb3fb4f3Stomee 			/* caller responsible for input java reference */
674fb3fb4f3Stomee 			e->dtja_value = NULL;
675fb3fb4f3Stomee 			dtj_aggval_destroy(e, jenv);
676fb3fb4f3Stomee 			e = NULL;
677fb3fb4f3Stomee 		}
678fb3fb4f3Stomee 		e->dtja_aggid = aggid;
679fb3fb4f3Stomee 	} else {
680fb3fb4f3Stomee 		dtj_throw_out_of_memory(jenv,
681fb3fb4f3Stomee 		    "Failed to allocate aggval entry");
682fb3fb4f3Stomee 	}
683fb3fb4f3Stomee 
684fb3fb4f3Stomee 	return (e);
685fb3fb4f3Stomee }
686fb3fb4f3Stomee 
687fb3fb4f3Stomee dtj_status_t
dtj_java_consumer_init(JNIEnv * jenv,dtj_java_consumer_t * jc)688fb3fb4f3Stomee dtj_java_consumer_init(JNIEnv *jenv, dtj_java_consumer_t *jc)
689fb3fb4f3Stomee {
690fb3fb4f3Stomee 	if (!dtj_check_aggval_pool()) {
691fb3fb4f3Stomee 		dtj_throw_out_of_memory(jenv,
692fb3fb4f3Stomee 		    "Failed to allocate aggval pool");
693fb3fb4f3Stomee 		return (DTJ_ERR);
694fb3fb4f3Stomee 	}
695fb3fb4f3Stomee 
696fb3fb4f3Stomee 	jc->dtjj_aggval_list = uu_list_create(g_aggval_pool, NULL,
697fb3fb4f3Stomee 	    (g_dtj_util_debug ? UU_LIST_DEBUG : 0));
698fb3fb4f3Stomee 	if (!jc->dtjj_aggval_list) {
699fb3fb4f3Stomee 		dtj_throw_out_of_memory(jenv,
700fb3fb4f3Stomee 		    "Failed to allocate aggval list");
701fb3fb4f3Stomee 		return (DTJ_ERR);
702fb3fb4f3Stomee 	}
703fb3fb4f3Stomee 
704fb3fb4f3Stomee 	/* Does not throw exceptions */
705fb3fb4f3Stomee 	jc->dtjj_consumer_lock = (*jenv)->GetObjectField(jenv, jc->dtjj_caller,
706fb3fb4f3Stomee 	    g_consumer_lock_jf);
707fb3fb4f3Stomee 
708fb3fb4f3Stomee 	return (DTJ_OK);
709fb3fb4f3Stomee }
710fb3fb4f3Stomee 
711fb3fb4f3Stomee void
dtj_java_consumer_fini(JNIEnv * jenv,dtj_java_consumer_t * jc)712fb3fb4f3Stomee dtj_java_consumer_fini(JNIEnv *jenv, dtj_java_consumer_t *jc)
713fb3fb4f3Stomee {
714fb3fb4f3Stomee 	if (jc) {
715fb3fb4f3Stomee 		if (jc->dtjj_probedata) {
716fb3fb4f3Stomee 			(*jenv)->DeleteLocalRef(jenv, jc->dtjj_probedata);
717fb3fb4f3Stomee 			jc->dtjj_probedata = NULL;
718fb3fb4f3Stomee 		}
719fb3fb4f3Stomee 		if (jc->dtjj_printa_buffer) {
720fb3fb4f3Stomee 			(*jenv)->DeleteLocalRef(jenv, jc->dtjj_printa_buffer);
721fb3fb4f3Stomee 			jc->dtjj_printa_buffer = NULL;
722fb3fb4f3Stomee 		}
723fb3fb4f3Stomee 		if (jc->dtjj_aggregate) {
724fb3fb4f3Stomee 			(*jenv)->DeleteLocalRef(jenv, jc->dtjj_aggregate);
725fb3fb4f3Stomee 			jc->dtjj_aggregate = NULL;
726fb3fb4f3Stomee 		}
727fb3fb4f3Stomee 		if (jc->dtjj_tuple) {
728fb3fb4f3Stomee 			(*jenv)->DeleteLocalRef(jenv, jc->dtjj_tuple);
729fb3fb4f3Stomee 			jc->dtjj_tuple = NULL;
730fb3fb4f3Stomee 		}
731fb3fb4f3Stomee 		if (jc->dtjj_aggval_list) {
732fb3fb4f3Stomee 			dtj_list_destroy(jc->dtjj_aggval_list,
733fb3fb4f3Stomee 			    dtj_aggval_destroy, jenv);
734fb3fb4f3Stomee 			jc->dtjj_aggval_list = NULL;
735fb3fb4f3Stomee 		}
736fb3fb4f3Stomee 
737fb3fb4f3Stomee 		/*
738fb3fb4f3Stomee 		 * aggregate_spec records an input argument to a native JNI
739fb3fb4f3Stomee 		 * function (a reference we did not create), so we are not
740fb3fb4f3Stomee 		 * responsible for it.
741fb3fb4f3Stomee 		 */
742fb3fb4f3Stomee 		jc->dtjj_aggregate_spec = NULL;
743fb3fb4f3Stomee 
744fb3fb4f3Stomee 		/*
745fb3fb4f3Stomee 		 * probelist records an in-out argument to a native JNI function
746fb3fb4f3Stomee 		 * (a reference we did not create), so we are not responsible
747fb3fb4f3Stomee 		 * for it.
748fb3fb4f3Stomee 		 */
749fb3fb4f3Stomee 		jc->dtjj_probelist = NULL;
750fb3fb4f3Stomee 
751fb3fb4f3Stomee 		if (jc->dtjj_exception) {
752fb3fb4f3Stomee 			(*jenv)->DeleteLocalRef(jenv, jc->dtjj_exception);
753fb3fb4f3Stomee 			jc->dtjj_exception = NULL;
754fb3fb4f3Stomee 		}
755fb3fb4f3Stomee 		(*jenv)->DeleteLocalRef(jenv, jc->dtjj_consumer_lock);
756fb3fb4f3Stomee 		jc->dtjj_consumer_lock = NULL;
757fb3fb4f3Stomee 	}
758fb3fb4f3Stomee }
759fb3fb4f3Stomee 
760fb3fb4f3Stomee dtj_consumer_t *
dtj_consumer_create(JNIEnv * jenv)761fb3fb4f3Stomee dtj_consumer_create(JNIEnv *jenv)
762fb3fb4f3Stomee {
763fb3fb4f3Stomee 	dtj_consumer_t *c;
764fb3fb4f3Stomee 
765fb3fb4f3Stomee 	if (!dtj_check_request_pool()) {
766fb3fb4f3Stomee 		dtj_throw_out_of_memory(jenv,
767fb3fb4f3Stomee 		    "Failed to allocate request pool");
768fb3fb4f3Stomee 		return (NULL);
769fb3fb4f3Stomee 	}
770fb3fb4f3Stomee 
771fb3fb4f3Stomee 	if (!dtj_check_program_pool()) {
772fb3fb4f3Stomee 		dtj_throw_out_of_memory(jenv,
773fb3fb4f3Stomee 		    "Failed to allocate program pool");
774fb3fb4f3Stomee 		return (NULL);
775fb3fb4f3Stomee 	}
776fb3fb4f3Stomee 
777fb3fb4f3Stomee 	c = uu_zalloc(sizeof (dtj_consumer_t));
778fb3fb4f3Stomee 	if (c) {
779fb3fb4f3Stomee 		c->dtjc_request_list = uu_list_create(g_request_pool, NULL,
780fb3fb4f3Stomee 		    (g_dtj_util_debug ? UU_LIST_DEBUG : 0));
781fb3fb4f3Stomee 		if (!c->dtjc_request_list) {
782fb3fb4f3Stomee 			dtj_throw_out_of_memory(jenv,
783fb3fb4f3Stomee 			    "Failed to allocate consumer request list");
784fb3fb4f3Stomee 			dtj_consumer_destroy(c);
785fb3fb4f3Stomee 			return (NULL);
786fb3fb4f3Stomee 		}
787fb3fb4f3Stomee 		(void) pthread_mutex_init(&c->dtjc_request_list_lock, NULL);
788fb3fb4f3Stomee 
789fb3fb4f3Stomee 		c->dtjc_program_list = uu_list_create(g_program_pool, NULL,
790fb3fb4f3Stomee 		    (g_dtj_util_debug ? UU_LIST_DEBUG : 0));
791fb3fb4f3Stomee 		if (!c->dtjc_program_list) {
792fb3fb4f3Stomee 			dtj_throw_out_of_memory(jenv,
793fb3fb4f3Stomee 			    "Failed to allocate consumer program list");
794fb3fb4f3Stomee 			dtj_consumer_destroy(c);
795fb3fb4f3Stomee 			return (NULL);
796fb3fb4f3Stomee 		}
797fb3fb4f3Stomee 
798fb3fb4f3Stomee 		c->dtjc_probedata_rec_i = 0;
799fb3fb4f3Stomee 		c->dtjc_probedata_act = DTRACEACT_NONE;
800fb3fb4f3Stomee 		c->dtjc_aggid = -1;
801fb3fb4f3Stomee 		c->dtjc_expected = -1;
802fb3fb4f3Stomee 		c->dtjc_state = DTJ_CONSUMER_INIT;
803fb3fb4f3Stomee 	} else {
804fb3fb4f3Stomee 		dtj_throw_out_of_memory(jenv,
805fb3fb4f3Stomee 		    "Failed to allocate consumer");
806fb3fb4f3Stomee 	}
807fb3fb4f3Stomee 
808fb3fb4f3Stomee 	return (c);
809fb3fb4f3Stomee }
810fb3fb4f3Stomee 
811fb3fb4f3Stomee void
812fb3fb4f3Stomee /* ARGSUSED */
dtj_request_destroy(void * v,void * arg)813fb3fb4f3Stomee dtj_request_destroy(void *v, void *arg)
814fb3fb4f3Stomee {
815fb3fb4f3Stomee 	if (v) {
816fb3fb4f3Stomee 		dtj_request_t *r = v;
817fb3fb4f3Stomee 		dtj_string_list_destroy(r->dtjr_args);
818fb3fb4f3Stomee 		uu_list_node_fini(r, &r->dtjr_node, g_request_pool);
819fb3fb4f3Stomee 		bzero(v, sizeof (dtj_request_t));
820fb3fb4f3Stomee 		uu_free(v);
821fb3fb4f3Stomee 	}
822fb3fb4f3Stomee }
823fb3fb4f3Stomee 
824fb3fb4f3Stomee void
825fb3fb4f3Stomee /* ARGSUSED */
dtj_program_destroy(void * v,void * arg)826fb3fb4f3Stomee dtj_program_destroy(void *v, void *arg)
827fb3fb4f3Stomee {
828fb3fb4f3Stomee 	if (v) {
829fb3fb4f3Stomee 		dtj_program_t *p = v;
830fb3fb4f3Stomee 		if (p->dtjp_name) {
831fb3fb4f3Stomee 			free((void *)p->dtjp_name);
832fb3fb4f3Stomee 		}
833fb3fb4f3Stomee 		uu_list_node_fini(p, &p->dtjp_node, g_program_pool);
834fb3fb4f3Stomee 		bzero(v, sizeof (dtj_program_t));
835fb3fb4f3Stomee 		uu_free(v);
836fb3fb4f3Stomee 	}
837fb3fb4f3Stomee }
838fb3fb4f3Stomee 
839fb3fb4f3Stomee void
dtj_aggval_destroy(void * v,void * arg)840fb3fb4f3Stomee dtj_aggval_destroy(void *v, void *arg)
841fb3fb4f3Stomee {
842fb3fb4f3Stomee 	if (v) {
843fb3fb4f3Stomee 		dtj_aggval_t *a = v;
844fb3fb4f3Stomee 		if (a->dtja_value && arg) {
845fb3fb4f3Stomee 			JNIEnv *jenv = arg;
846fb3fb4f3Stomee 			(*jenv)->DeleteLocalRef(jenv, a->dtja_value);
847fb3fb4f3Stomee 		}
848fb3fb4f3Stomee 		if (a->dtja_aggname) {
849fb3fb4f3Stomee 			free((void *)a->dtja_aggname);
850fb3fb4f3Stomee 		}
851fb3fb4f3Stomee 		uu_list_node_fini(a, &a->dtja_node, g_aggval_pool);
852fb3fb4f3Stomee 		bzero(v, sizeof (dtj_aggval_t));
853fb3fb4f3Stomee 		uu_free(v);
854fb3fb4f3Stomee 	}
855fb3fb4f3Stomee }
856fb3fb4f3Stomee 
857fb3fb4f3Stomee /*
858fb3fb4f3Stomee  * Frees per-consumer state.  Assumes that the DTrace handle has been closed
859fb3fb4f3Stomee  * already.
860fb3fb4f3Stomee  */
861fb3fb4f3Stomee void
dtj_consumer_destroy(dtj_consumer_t * c)862fb3fb4f3Stomee dtj_consumer_destroy(dtj_consumer_t *c)
863fb3fb4f3Stomee {
864fb3fb4f3Stomee 	if (c) {
865fb3fb4f3Stomee 		dtj_list_destroy(c->dtjc_request_list, dtj_request_destroy,
866fb3fb4f3Stomee 		    NULL);
867fb3fb4f3Stomee 		(void) pthread_mutex_destroy(&c->dtjc_request_list_lock);
868fb3fb4f3Stomee 		dtj_list_destroy(c->dtjc_program_list, dtj_program_destroy,
869fb3fb4f3Stomee 		    NULL);
870fb3fb4f3Stomee 		/*
871fb3fb4f3Stomee 		 * Cannot dtrace_proc_release the c->process_list proc
872fb3fb4f3Stomee 		 * elements here, because we need the dtrace handle for that.
873fb3fb4f3Stomee 		 * By the time this destructor is called, the dtrace handle is
874fb3fb4f3Stomee 		 * already closed.  The proc elements are released in
875fb3fb4f3Stomee 		 * dtrace_jni.c _close().
876fb3fb4f3Stomee 		 */
877fb3fb4f3Stomee 		if (c->dtjc_process_list) {
878fb3fb4f3Stomee 			dtj_list_destroy(c->dtjc_process_list, NULL, NULL);
879fb3fb4f3Stomee 		}
880fb3fb4f3Stomee 		bzero(c, sizeof (dtj_consumer_t));
881fb3fb4f3Stomee 		uu_free(c);
882fb3fb4f3Stomee 	}
883fb3fb4f3Stomee }
884fb3fb4f3Stomee 
885fb3fb4f3Stomee void
dtj_throw_dtrace_exception(dtj_java_consumer_t * jc,const char * fmt,...)886fb3fb4f3Stomee dtj_throw_dtrace_exception(dtj_java_consumer_t *jc, const char *fmt, ...)
887fb3fb4f3Stomee {
888fb3fb4f3Stomee 	JNIEnv *jenv = jc->dtjj_jenv;
889fb3fb4f3Stomee 
890fb3fb4f3Stomee 	va_list ap;
891fb3fb4f3Stomee 	char msg[DTJ_MSG_SIZE];
892fb3fb4f3Stomee 
893fb3fb4f3Stomee 	jobject message = NULL;
894fb3fb4f3Stomee 	jobject exception = NULL;
895fb3fb4f3Stomee 
896fb3fb4f3Stomee 	va_start(ap, fmt);
897fb3fb4f3Stomee 	(void) vsnprintf(msg, sizeof (msg), fmt, ap);
898fb3fb4f3Stomee 	va_end(ap);
899fb3fb4f3Stomee 
900fb3fb4f3Stomee 	message = dtj_NewStringNative(jenv, msg);
901fb3fb4f3Stomee 	if (!message) {
902fb3fb4f3Stomee 		return; /* java exception pending */
903fb3fb4f3Stomee 	}
904fb3fb4f3Stomee 
905fb3fb4f3Stomee 	exception = (*jenv)->NewObject(jenv, g_dtx_jc, g_dtxinit_jm, message);
906fb3fb4f3Stomee 	(*jenv)->DeleteLocalRef(jenv, message);
907fb3fb4f3Stomee 	if (exception) {
908fb3fb4f3Stomee 		(*jenv)->Throw(jenv, exception);
909fb3fb4f3Stomee 		(*jenv)->DeleteLocalRef(jenv, exception);
910fb3fb4f3Stomee 	}
911fb3fb4f3Stomee }
912