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 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 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 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 * 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 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 * 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 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 * 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 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 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 * 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 */ 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 */ 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 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 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 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