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*3645Stomee * Copyright 2007 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 1781449Stomee /* KernelStackRecord */ 1791449Stomee jclass g_stack_jc = 0; 1801449Stomee jmethodID g_parsestack_jsm = 0; 1811449Stomee jmethodID g_stackinit_jm = 0; 1821449Stomee jmethodID g_stackset_frames_jm = 0; 1831449Stomee 1841449Stomee /* UserStackRecord */ 1851449Stomee jclass g_ustack_jc = 0; 1861449Stomee jmethodID g_ustackinit_jm = 0; 1871449Stomee jmethodID g_ustackset_frames_jm = 0; 1881449Stomee 1891449Stomee /* Distribution */ 1901449Stomee jclass g_adist_jc = 0; 1911449Stomee jmethodID g_dist_normal_jm = 0; 1921449Stomee 1931449Stomee /* LogDistribution */ 1941449Stomee jclass g_dist_jc = 0; 1951449Stomee jmethodID g_distinit_jm = 0; 1961449Stomee 1971449Stomee /* LinearDistribution */ 1981449Stomee jclass g_ldist_jc = 0; 1991449Stomee jmethodID g_ldistinit_jm = 0; 2001449Stomee 2012777Stomee /* KernelSymbolRecord */ 2022777Stomee jclass g_symbol_jc = 0; 2032777Stomee jmethodID g_symbolinit_jm = 0; 2042777Stomee jmethodID g_symbolset_name_jm = 0; 2052777Stomee 2062777Stomee /* UserSymbolRecord */ 2072777Stomee jclass g_usymbol_jc = 0; 2082777Stomee jmethodID g_usymbolinit_jm = 0; 2092777Stomee jmethodID g_usymbolset_name_jm = 0; 2102777Stomee 2112777Stomee /* ScalarRecord */ 2122777Stomee jclass g_scalar_jc = 0; 2132777Stomee jmethodID g_scalarinit_jm = 0; 2142777Stomee 2151449Stomee 2161449Stomee static dtj_status_t 2171449Stomee dtj_table_load(JNIEnv *jenv) 2181449Stomee { 219*3645Stomee /* 220*3645Stomee * If you change this table, increment DTRACE_JNI_VERSION in 221*3645Stomee * dtrace_jni.c. 222*3645Stomee */ 2231449Stomee static const dtj_table_entry_t table[] = { 2241449Stomee /* LocalConsumer */ 2251449Stomee { JCLASS, &g_caller_jc, 2261449Stomee "org/opensolaris/os/dtrace/LocalConsumer" }, 2271449Stomee { JMETHOD, &g_gethandle_jm, "getHandle", "()I" }, 2281449Stomee { JMETHOD, &g_sethandle_jm, "setHandle", "(I)V" }, 2291449Stomee { JMETHOD, &g_pdatanext_jm, "nextProbeData", 2301449Stomee "(Lorg/opensolaris/os/dtrace/ProbeData;)V" }, 2311449Stomee { JMETHOD, &g_drop_jm, "dataDropped", 2321449Stomee "(Lorg/opensolaris/os/dtrace/Drop;)V" }, 2331449Stomee { JMETHOD, &g_error_jm, "errorEncountered", 2341449Stomee "(Lorg/opensolaris/os/dtrace/Error;)V" }, 2351449Stomee { JMETHOD, &g_proc_jm, "processStateChanged", 2361449Stomee "(Lorg/opensolaris/os/dtrace/ProcessState;)V" }, 2371449Stomee { JMETHOD, &g_interval_began_jm, "intervalBegan", "()V" }, 2381449Stomee { JMETHOD, &g_interval_ended_jm, "intervalEnded", "()V" }, 2391449Stomee { JFIELD, &g_consumer_lock_jf, "consumerLock", 2401449Stomee "Ljava/lang/Object;" }, 2411449Stomee 2421449Stomee /* DTraceException */ 2431449Stomee { JCLASS, &g_dtx_jc, 2441449Stomee "org/opensolaris/os/dtrace/DTraceException" }, 2451449Stomee { JMETHOD, &g_dtxinit_jm, CONSTRUCTOR, 2461449Stomee "(Ljava/lang/String;)V" }, 2471449Stomee 2481449Stomee /* InterfaceAttributes */ 2491449Stomee { JCLASS, &g_attr_jc, 2501449Stomee "org/opensolaris/os/dtrace/InterfaceAttributes" }, 2511449Stomee { JMETHOD, &g_attrinit_jm, CONSTRUCTOR, "()V" }, 2521449Stomee { JMETHOD, &g_attrset_name_jm, "setNameStability", 2531449Stomee "(Ljava/lang/String;)V" }, 2541449Stomee { JMETHOD, &g_attrset_data_jm, "setDataStability", 2551449Stomee "(Ljava/lang/String;)V" }, 2561449Stomee { JMETHOD, &g_attrset_class_jm, "setDependencyClass", 2571449Stomee "(Ljava/lang/String;)V" }, 2581449Stomee 2591449Stomee /* ProbeDescription */ 2601449Stomee { JCLASS, &g_probedesc_jc, 2611449Stomee "org/opensolaris/os/dtrace/ProbeDescription" }, 2621449Stomee { JMETHOD, &g_probedescinit_jm, CONSTRUCTOR, 2631449Stomee "(Ljava/lang/String;Ljava/lang/String;" 2641449Stomee "Ljava/lang/String;Ljava/lang/String;)V" }, 2651449Stomee { JFIELD, &g_probedesc_id_jf, "id", "I" }, 2661449Stomee 2671449Stomee /* ProbeInfo */ 2681449Stomee { JCLASS, &g_probeinfo_jc, 2691449Stomee "org/opensolaris/os/dtrace/ProbeInfo" }, 2701449Stomee { JMETHOD, &g_probeinfoinit_jm, CONSTRUCTOR, 2711449Stomee "(Lorg/opensolaris/os/dtrace/InterfaceAttributes;" 2721449Stomee "Lorg/opensolaris/os/dtrace/InterfaceAttributes;" 2731449Stomee ")V" }, 2741449Stomee 2751449Stomee /* Probe */ 2761449Stomee { JCLASS, &g_probe_jc, "org/opensolaris/os/dtrace/Probe" }, 2771449Stomee { JMETHOD, &g_probeinit_jm, CONSTRUCTOR, 2781449Stomee "(Lorg/opensolaris/os/dtrace/ProbeDescription;" 2791449Stomee "Lorg/opensolaris/os/dtrace/ProbeInfo;)V" }, 2801449Stomee 2811449Stomee /* Program */ 2821449Stomee { JCLASS, &g_program_jc, 2831449Stomee "org/opensolaris/os/dtrace/Program" }, 2841449Stomee { JMETHOD, &g_proginit_jm, CONSTRUCTOR, "()V" }, 2851449Stomee { JFIELD, &g_progid_jf, "id", "I" }, 2861449Stomee { JFIELD, &g_proginfo_jf, "info", 2871449Stomee "Lorg/opensolaris/os/dtrace/ProgramInfo;" }, 2881449Stomee 2891449Stomee /* Program.File */ 2901449Stomee { JCLASS, &g_programfile_jc, 2911449Stomee "org/opensolaris/os/dtrace/Program$File" }, 2921449Stomee { JMETHOD, &g_fproginit_jm, CONSTRUCTOR, "()V" }, 2931449Stomee 2941449Stomee /* ProgramInfo */ 2951449Stomee { JCLASS, &g_proginfo_jc, 2961449Stomee "org/opensolaris/os/dtrace/ProgramInfo" }, 2971449Stomee { JMETHOD, &g_proginfoinit_jm, CONSTRUCTOR, 2981449Stomee "(Lorg/opensolaris/os/dtrace/InterfaceAttributes;" 2991449Stomee "Lorg/opensolaris/os/dtrace/InterfaceAttributes;" 3001449Stomee "I)V" }, 3011449Stomee 3021449Stomee /* Flow */ 3031449Stomee { JCLASS, &g_flow_jc, "org/opensolaris/os/dtrace/Flow" }, 3041449Stomee { JMETHOD, &g_flowinit_jm, CONSTRUCTOR, 3051449Stomee "(Ljava/lang/String;I)V" }, 3061449Stomee 3071449Stomee /* ProbeData */ 3081449Stomee { JCLASS, &g_pdata_jc, 3091449Stomee "org/opensolaris/os/dtrace/ProbeData" }, 3101449Stomee { JMETHOD, &g_pdatainit_jm, CONSTRUCTOR, 3111449Stomee "(IILorg/opensolaris/os/dtrace/ProbeDescription;" 3121449Stomee "Lorg/opensolaris/os/dtrace/Flow;I)V" }, 3131449Stomee { JMETHOD, &g_pdataadd_jm, "addDataElement", 3142777Stomee "(Lorg/opensolaris/os/dtrace/Record;)V" }, 3151449Stomee { JMETHOD, &g_pdataadd_rec_jm, "addRecord", 3161449Stomee "(Lorg/opensolaris/os/dtrace/Record;)V" }, 3171449Stomee { JMETHOD, &g_pdataadd_trace_jm, "addTraceRecord", "(I)V" }, 3181449Stomee { JMETHOD, &g_pdataadd_stack_jm, "addStackRecord", 3191449Stomee "(ILjava/lang/String;)V" }, 3202777Stomee { JMETHOD, &g_pdataadd_symbol_jm, "addSymbolRecord", 3212777Stomee "(ILjava/lang/String;)V" }, 3221449Stomee { JMETHOD, &g_pdataadd_printf_jm, "addPrintfRecord", "()V" }, 3231449Stomee { JMETHOD, &g_pdataadd_printa_jm, "addPrintaRecord", "(JZ)V" }, 3241449Stomee { JMETHOD, &g_pdatainvalidate_printa_jm, 3251449Stomee "invalidatePrintaRecord", "()V" }, 3261449Stomee { JMETHOD, &g_pdataadd_aggrec_jm, "addAggregationRecord", 3271449Stomee "(Ljava/lang/String;J" 3281449Stomee "Lorg/opensolaris/os/dtrace/AggregationRecord;)V" }, 3291449Stomee { JMETHOD, &g_pdataadd_printa_str_jm, 3301449Stomee "addPrintaFormattedString", 3311449Stomee "(Lorg/opensolaris/os/dtrace/Tuple;" 3321449Stomee "Ljava/lang/String;)V" }, 3331449Stomee { JMETHOD, &g_pdataadd_exit_jm, "addExitRecord", "(I)V" }, 3341449Stomee { JMETHOD, &g_pdataattach_jm, "attachRecordElements", 3351449Stomee "(II)V" }, 3361449Stomee { JMETHOD, &g_pdataset_formatted_jm, "setFormattedString", 3371449Stomee "(Ljava/lang/String;)V" }, 3381449Stomee { JMETHOD, &g_pdataclear_jm, "clearNativeElements", "()V" }, 3391449Stomee 3401449Stomee /* Drop */ 3411449Stomee { JCLASS, &g_drop_jc, "org/opensolaris/os/dtrace/Drop" }, 3421449Stomee { JMETHOD, &g_dropinit_jm, CONSTRUCTOR, 3431449Stomee "(ILjava/lang/String;JJLjava/lang/String;)V" }, 3441449Stomee 3451449Stomee /* Error */ 3461449Stomee { JCLASS, &g_error_jc, "org/opensolaris/os/dtrace/Error" }, 3471449Stomee { JMETHOD, &g_errinit_jm, CONSTRUCTOR, 3481449Stomee "(Lorg/opensolaris/os/dtrace/ProbeDescription;IIII" 3491449Stomee "Ljava/lang/String;JLjava/lang/String;)V" }, 3501449Stomee 3511449Stomee /* ProcessState */ 3521449Stomee { JCLASS, &g_process_jc, 3531449Stomee "org/opensolaris/os/dtrace/ProcessState" }, 3541449Stomee { JMETHOD, &g_procinit_jm, CONSTRUCTOR, 3551449Stomee "(ILjava/lang/String;ILjava/lang/String;" 3561449Stomee "Ljava/lang/Integer;Ljava/lang/String;)V" }, 3571449Stomee { JMETHOD, &g_procexit_jm, "setExitStatus", "(I)V" }, 3581449Stomee 3591449Stomee /* Aggregate */ 3601449Stomee { JCLASS, &g_agg_jc, "org/opensolaris/os/dtrace/Aggregate" }, 3611449Stomee { JMETHOD, &g_agginit_jm, CONSTRUCTOR, "(J)V" }, 3621449Stomee { JMETHOD, &g_aggaddrec_jm, "addRecord", 3631449Stomee "(Ljava/lang/String;J" 3641449Stomee "Lorg/opensolaris/os/dtrace/AggregationRecord;)V" }, 3651449Stomee 3661449Stomee /* AggregateSpec */ 3671449Stomee { JCLASS, &g_aggspec_jc, 3681449Stomee "org/opensolaris/os/dtrace/AggregateSpec" }, 3691449Stomee { JMETHOD, &g_aggspec_included_jm, "isIncluded", 3701449Stomee "(Ljava/lang/String;)Z" }, 3711449Stomee { JMETHOD, &g_aggspec_cleared_jm, "isCleared", 3721449Stomee "(Ljava/lang/String;)Z" }, 3731449Stomee 3741449Stomee /* Tuple */ 3751449Stomee { JCLASS, &g_tuple_jc, "org/opensolaris/os/dtrace/Tuple" }, 3761449Stomee { JMETHOD, &g_tupleinit_jm, CONSTRUCTOR, "()V" }, 3771449Stomee { JMETHOD, &g_tupleadd_jm, "addElement", 3782777Stomee "(Lorg/opensolaris/os/dtrace/ValueRecord;)V" }, 3791449Stomee { JMETHOD, &g_tuplesize_jm, "size", "()I" }, 3801449Stomee { JFIELD_STATIC, &g_tuple_EMPTY_jsf, "EMPTY", 3811449Stomee "Lorg/opensolaris/os/dtrace/Tuple;" }, 3821449Stomee 3831449Stomee /* AggregationRecord */ 3841449Stomee { JCLASS, &g_aggrec_jc, 3851449Stomee "org/opensolaris/os/dtrace/AggregationRecord" }, 3861449Stomee { JMETHOD, &g_aggrecinit_jm, CONSTRUCTOR, 3871449Stomee "(Lorg/opensolaris/os/dtrace/Tuple;" 3881449Stomee "Lorg/opensolaris/os/dtrace/AggregationValue;)V" }, 3891449Stomee { JMETHOD, &g_aggrecget_tuple_jm, "getTuple", 3901449Stomee "()Lorg/opensolaris/os/dtrace/Tuple;" }, 3911449Stomee 3921449Stomee /* SumValue */ 3931449Stomee { JCLASS, &g_aggsum_jc, 3941449Stomee "org/opensolaris/os/dtrace/SumValue" }, 3951449Stomee { JMETHOD, &g_aggsuminit_jm, CONSTRUCTOR, "(J)V" }, 3961449Stomee 3971449Stomee /* CountValue */ 3981449Stomee { JCLASS, &g_aggcount_jc, 3991449Stomee "org/opensolaris/os/dtrace/CountValue" }, 4001449Stomee { JMETHOD, &g_aggcountinit_jm, CONSTRUCTOR, "(J)V" }, 4011449Stomee 4021449Stomee /* AvgValue */ 4031449Stomee { JCLASS, &g_aggavg_jc, 4041449Stomee "org/opensolaris/os/dtrace/AvgValue" }, 4051449Stomee { JMETHOD, &g_aggavginit_jm, CONSTRUCTOR, "(JJJ)V" }, 4061449Stomee 4071449Stomee /* MinValue */ 4081449Stomee { JCLASS, &g_aggmin_jc, 4091449Stomee "org/opensolaris/os/dtrace/MinValue" }, 4101449Stomee { JMETHOD, &g_aggmininit_jm, CONSTRUCTOR, "(J)V" }, 4111449Stomee 4121449Stomee /* MaxValue */ 4131449Stomee { JCLASS, &g_aggmax_jc, 4141449Stomee "org/opensolaris/os/dtrace/MaxValue" }, 4151449Stomee { JMETHOD, &g_aggmaxinit_jm, CONSTRUCTOR, "(J)V" }, 4161449Stomee 4171449Stomee /* KernelStackRecord */ 4181449Stomee { JCLASS, &g_stack_jc, 4191449Stomee "org/opensolaris/os/dtrace/KernelStackRecord" }, 4201449Stomee { JMETHOD_STATIC, &g_parsestack_jsm, "parse", 4211449Stomee "(Ljava/lang/String;)" 4221449Stomee "[Lorg/opensolaris/os/dtrace/StackFrame;" }, 4231449Stomee { JMETHOD, &g_stackinit_jm, CONSTRUCTOR, "([B)V" }, 4241449Stomee { JMETHOD, &g_stackset_frames_jm, "setStackFrames", 4251449Stomee "([Lorg/opensolaris/os/dtrace/StackFrame;)V" }, 4261449Stomee 4271449Stomee /* UserStackRecord */ 4281449Stomee { JCLASS, &g_ustack_jc, 4291449Stomee "org/opensolaris/os/dtrace/UserStackRecord" }, 4301449Stomee { JMETHOD, &g_ustackinit_jm, CONSTRUCTOR, "(I[B)V" }, 4311449Stomee { JMETHOD, &g_ustackset_frames_jm, "setStackFrames", 4321449Stomee "([Lorg/opensolaris/os/dtrace/StackFrame;)V" }, 4331449Stomee 4341449Stomee /* Distribution */ 4351449Stomee { JCLASS, &g_adist_jc, 4361449Stomee "org/opensolaris/os/dtrace/Distribution" }, 4371449Stomee { JMETHOD, &g_dist_normal_jm, "normalizeBuckets", "(J)V" }, 4381449Stomee 4391449Stomee /* LogDistribution */ 4401449Stomee { JCLASS, &g_dist_jc, 4411449Stomee "org/opensolaris/os/dtrace/LogDistribution" }, 4421449Stomee { JMETHOD, &g_distinit_jm, CONSTRUCTOR, "([J)V" }, 4431449Stomee 4441449Stomee /* LinearDistribution */ 4451449Stomee { JCLASS, &g_ldist_jc, 4461449Stomee "org/opensolaris/os/dtrace/LinearDistribution" }, 4471449Stomee { JMETHOD, &g_ldistinit_jm, CONSTRUCTOR, "(JJ[J)V" }, 4481449Stomee 4492777Stomee /* KernelSymbolRecord */ 4502777Stomee { JCLASS, &g_symbol_jc, 4512777Stomee "org/opensolaris/os/dtrace/KernelSymbolRecord" }, 4522777Stomee { JMETHOD, &g_symbolinit_jm, CONSTRUCTOR, "(J)V" }, 4532777Stomee { JMETHOD, &g_symbolset_name_jm, "setSymbol", 4542777Stomee "(Ljava/lang/String;)V" }, 4552777Stomee 4562777Stomee /* UserSymbolRecord */ 4572777Stomee { JCLASS, &g_usymbol_jc, 4582777Stomee "org/opensolaris/os/dtrace/UserSymbolRecord" }, 4592777Stomee { JMETHOD, &g_usymbolinit_jm, CONSTRUCTOR, "(IJ)V" }, 4602777Stomee { JMETHOD, &g_usymbolset_name_jm, "setSymbol", 4612777Stomee "(Ljava/lang/String;)V" }, 4622777Stomee 4632777Stomee /* ScalarRecord */ 4642777Stomee { JCLASS, &g_scalar_jc, 4652777Stomee "org/opensolaris/os/dtrace/ScalarRecord" }, 4662777Stomee { JMETHOD, &g_scalarinit_jm, CONSTRUCTOR, 4672777Stomee "(Ljava/lang/Object;I)V" }, 4682777Stomee 4691449Stomee { DTJ_TYPE_END } 4701449Stomee }; 4711449Stomee 4721449Stomee return (dtj_cache_jni_classes(jenv, table)); 4731449Stomee } 4741449Stomee 4751449Stomee dtj_status_t 4761449Stomee dtj_load(JNIEnv *jenv) 4771449Stomee { 4781449Stomee if (dtj_load_common(jenv) != DTJ_OK) { 4791449Stomee /* Java Error pending */ 4801449Stomee return (DTJ_ERR); 4811449Stomee } 4821449Stomee 4831449Stomee return (dtj_table_load(jenv)); 4841449Stomee } 4851449Stomee 4861449Stomee static boolean_t 4871449Stomee dtj_check_request_pool(void) 4881449Stomee { 4891449Stomee if (!g_request_pool) { 4901449Stomee g_request_pool = uu_list_pool_create("g_request_pool", 4911449Stomee sizeof (dtj_request_t), 4921449Stomee offsetof(dtj_request_t, dtjr_node), 4931449Stomee dtj_pointer_list_entry_cmp, 4941449Stomee (g_dtj_util_debug ? UU_LIST_POOL_DEBUG : 0)); 4951449Stomee if (!g_request_pool) { 4961449Stomee return (B_FALSE); 4971449Stomee } 4981449Stomee } 4991449Stomee return (B_TRUE); 5001449Stomee } 5011449Stomee 5021449Stomee dtj_request_t * 5031449Stomee dtj_request_create(JNIEnv *jenv, dtj_request_type_t type, ...) 5041449Stomee { 5051449Stomee dtj_request_t *r; 5061449Stomee 5071449Stomee if (!dtj_check_request_pool()) { 5081449Stomee dtj_throw_out_of_memory(jenv, 5091449Stomee "Failed to allocate request pool"); 5101449Stomee return (NULL); 5111449Stomee } 5121449Stomee 5131449Stomee r = uu_zalloc(sizeof (dtj_request_t)); 5141449Stomee if (r) { 5151449Stomee uu_list_node_init(r, &r->dtjr_node, g_request_pool); 5161449Stomee r->dtjr_type = type; 5171449Stomee r->dtjr_args = dtj_string_list_create(); 5181449Stomee if (r->dtjr_args) { 5191449Stomee va_list ap; 5201449Stomee const char *arg; 5211449Stomee int i, len; 5221449Stomee 5231449Stomee va_start(ap, type); 5241449Stomee switch (type) { 5251449Stomee case DTJ_REQUEST_OPTION: 5261449Stomee len = 2; 5271449Stomee break; 5281449Stomee default: 5291449Stomee len = 0; 5301449Stomee } 5311449Stomee 5321449Stomee for (i = 0; i < len; ++i) { 5331449Stomee arg = va_arg(ap, char *); 5341449Stomee if (!dtj_string_list_add(r->dtjr_args, arg)) { 5351449Stomee dtj_throw_out_of_memory(jenv, 5361449Stomee "Failed to add request arg"); 5371449Stomee uu_list_node_fini(r, &r->dtjr_node, 5381449Stomee g_request_pool); 5391449Stomee dtj_request_destroy(r, NULL); 5401449Stomee r = NULL; 5411449Stomee } 5421449Stomee } 5431449Stomee va_end(ap); 5441449Stomee } else { 5451449Stomee dtj_throw_out_of_memory(jenv, 5461449Stomee "Failed to allocate request arglist"); 5471449Stomee uu_list_node_fini(r, &r->dtjr_node, g_request_pool); 5481449Stomee dtj_request_destroy(r, NULL); 5491449Stomee r = NULL; 5501449Stomee } 5511449Stomee } else { 5521449Stomee dtj_throw_out_of_memory(jenv, 5531449Stomee "Failed to allocate request"); 5541449Stomee } 5551449Stomee 5561449Stomee return (r); 5571449Stomee } 5581449Stomee 5591449Stomee static boolean_t 5601449Stomee dtj_check_program_pool(void) 5611449Stomee { 5621449Stomee if (!g_program_pool) { 5631449Stomee g_program_pool = uu_list_pool_create("g_program_pool", 5641449Stomee sizeof (dtj_program_t), 5651449Stomee offsetof(dtj_program_t, dtjp_node), 5661449Stomee dtj_pointer_list_entry_cmp, 5671449Stomee (g_dtj_util_debug ? UU_LIST_POOL_DEBUG : 0)); 5681449Stomee if (!g_program_pool) { 5691449Stomee return (B_FALSE); 5701449Stomee } 5711449Stomee } 5721449Stomee return (B_TRUE); 5731449Stomee } 5741449Stomee 5751449Stomee dtj_program_t * 5761449Stomee dtj_program_create(JNIEnv *jenv, dtj_program_type_t type, const char *name) 5771449Stomee { 5781449Stomee dtj_program_t *p; 5791449Stomee 5801449Stomee if (!dtj_check_program_pool()) { 5811449Stomee dtj_throw_out_of_memory(jenv, 5821449Stomee "Failed to allocate program pool"); 5831449Stomee return (NULL); 5841449Stomee } 5851449Stomee 5861449Stomee p = uu_zalloc(sizeof (dtj_program_t)); 5871449Stomee if (p) { 5881449Stomee char *program_name; 5891449Stomee 5901449Stomee uu_list_node_init(p, &p->dtjp_node, g_program_pool); 5911449Stomee p->dtjp_type = type; 5921449Stomee program_name = malloc((size_t) 5931449Stomee (sizeof (char)) * (strlen(name) + 1)); 5941449Stomee if (program_name) { 5951449Stomee (void) strcpy(program_name, name); 5961449Stomee p->dtjp_name = program_name; 5971449Stomee p->dtjp_enabled = B_FALSE; 5981449Stomee } else { 5991449Stomee dtj_throw_out_of_memory(jenv, 6001449Stomee "Failed to allocate program name"); 6011449Stomee uu_list_node_fini(p, &p->dtjp_node, g_program_pool); 6021449Stomee dtj_program_destroy(p, NULL); 6031449Stomee p = NULL; 6041449Stomee } 6051449Stomee } else { 6061449Stomee dtj_throw_out_of_memory(jenv, 6071449Stomee "Failed to allocate program"); 6081449Stomee } 6091449Stomee 6101449Stomee return (p); 6111449Stomee } 6121449Stomee 6131449Stomee static boolean_t 6141449Stomee dtj_check_aggval_pool(void) 6151449Stomee { 6161449Stomee if (!g_aggval_pool) { 6171449Stomee g_aggval_pool = uu_list_pool_create("g_aggval_pool", 6181449Stomee sizeof (dtj_aggval_t), 6191449Stomee offsetof(dtj_aggval_t, dtja_node), 6201449Stomee dtj_pointer_list_entry_cmp, 6211449Stomee (g_dtj_util_debug ? UU_LIST_POOL_DEBUG : 0)); 6221449Stomee if (!g_aggval_pool) { 6231449Stomee return (B_FALSE); 6241449Stomee } 6251449Stomee } 6261449Stomee return (B_TRUE); 6271449Stomee } 6281449Stomee 6291449Stomee dtj_aggval_t * 6301449Stomee dtj_aggval_create(JNIEnv *jenv, jobject aggval, const char *aggname, 6311449Stomee int64_t aggid) 6321449Stomee { 6331449Stomee dtj_aggval_t *e; 6341449Stomee 6351449Stomee if (!dtj_check_aggval_pool()) { 6361449Stomee dtj_throw_out_of_memory(jenv, 6371449Stomee "Failed to allocate aggval entry pool"); 6381449Stomee return (NULL); 6391449Stomee } 6401449Stomee 6411449Stomee e = uu_zalloc(sizeof (dtj_aggval_t)); 6421449Stomee if (e) { 6431449Stomee char *a_name; 6441449Stomee 6451449Stomee uu_list_node_init(e, &e->dtja_node, g_aggval_pool); 6461449Stomee e->dtja_value = aggval; 6471449Stomee a_name = malloc((size_t) 6481449Stomee (sizeof (char)) * (strlen(aggname) + 1)); 6491449Stomee if (a_name) { 6501449Stomee (void) strcpy(a_name, aggname); 6511449Stomee e->dtja_aggname = a_name; 6521449Stomee } else { 6531449Stomee dtj_throw_out_of_memory(jenv, 6541449Stomee "Failed to allocate aggregation name"); 6551449Stomee uu_list_node_fini(e, &e->dtja_node, g_aggval_pool); 6561449Stomee /* caller responsible for input java reference */ 6571449Stomee e->dtja_value = NULL; 6581449Stomee dtj_aggval_destroy(e, jenv); 6591449Stomee e = NULL; 6601449Stomee } 6611449Stomee e->dtja_aggid = aggid; 6621449Stomee } else { 6631449Stomee dtj_throw_out_of_memory(jenv, 6641449Stomee "Failed to allocate aggval entry"); 6651449Stomee } 6661449Stomee 6671449Stomee return (e); 6681449Stomee } 6691449Stomee 6701449Stomee dtj_status_t 6711449Stomee dtj_java_consumer_init(JNIEnv *jenv, dtj_java_consumer_t *jc) 6721449Stomee { 6731449Stomee if (!dtj_check_aggval_pool()) { 6741449Stomee dtj_throw_out_of_memory(jenv, 6751449Stomee "Failed to allocate aggval pool"); 6761449Stomee return (DTJ_ERR); 6771449Stomee } 6781449Stomee 6791449Stomee jc->dtjj_aggval_list = uu_list_create(g_aggval_pool, NULL, 6801449Stomee (g_dtj_util_debug ? UU_LIST_DEBUG : 0)); 6811449Stomee if (!jc->dtjj_aggval_list) { 6821449Stomee dtj_throw_out_of_memory(jenv, 6831449Stomee "Failed to allocate aggval list"); 6841449Stomee return (DTJ_ERR); 6851449Stomee } 6861449Stomee 6871449Stomee /* Does not throw exceptions */ 6881449Stomee jc->dtjj_consumer_lock = (*jenv)->GetObjectField(jenv, jc->dtjj_caller, 6891449Stomee g_consumer_lock_jf); 6901449Stomee 6911449Stomee return (DTJ_OK); 6921449Stomee } 6931449Stomee 6941449Stomee void 6951449Stomee dtj_java_consumer_fini(JNIEnv *jenv, dtj_java_consumer_t *jc) 6961449Stomee { 6971449Stomee if (jc) { 6981449Stomee if (jc->dtjj_probedata) { 6991449Stomee (*jenv)->DeleteLocalRef(jenv, jc->dtjj_probedata); 7001449Stomee jc->dtjj_probedata = NULL; 7011449Stomee } 7021449Stomee if (jc->dtjj_printa_buffer) { 7031449Stomee (*jenv)->DeleteLocalRef(jenv, jc->dtjj_printa_buffer); 7041449Stomee jc->dtjj_printa_buffer = NULL; 7051449Stomee } 7061449Stomee if (jc->dtjj_aggregate) { 7071449Stomee (*jenv)->DeleteLocalRef(jenv, jc->dtjj_aggregate); 7081449Stomee jc->dtjj_aggregate = NULL; 7091449Stomee } 7101449Stomee if (jc->dtjj_tuple) { 7111449Stomee (*jenv)->DeleteLocalRef(jenv, jc->dtjj_tuple); 7121449Stomee jc->dtjj_tuple = NULL; 7131449Stomee } 7141449Stomee if (jc->dtjj_aggval_list) { 7151449Stomee dtj_list_destroy(jc->dtjj_aggval_list, 7161449Stomee dtj_aggval_destroy, jenv); 7171449Stomee jc->dtjj_aggval_list = NULL; 7181449Stomee } 7191449Stomee 7201449Stomee /* 7211449Stomee * aggregate_spec records an input argument to a native JNI 7221449Stomee * function (a reference we did not create), so we are not 7231449Stomee * responsible for it. 7241449Stomee */ 7251449Stomee jc->dtjj_aggregate_spec = NULL; 7261449Stomee 7271449Stomee /* 7281449Stomee * probelist records an in-out argument to a native JNI function 7291449Stomee * (a reference we did not create), so we are not responsible 7301449Stomee * for it. 7311449Stomee */ 7321449Stomee jc->dtjj_probelist = NULL; 7331449Stomee 7341449Stomee if (jc->dtjj_exception) { 7351449Stomee (*jenv)->DeleteLocalRef(jenv, jc->dtjj_exception); 7361449Stomee jc->dtjj_exception = NULL; 7371449Stomee } 7381449Stomee (*jenv)->DeleteLocalRef(jenv, jc->dtjj_consumer_lock); 7391449Stomee jc->dtjj_consumer_lock = NULL; 7401449Stomee } 7411449Stomee } 7421449Stomee 7431449Stomee dtj_consumer_t * 7441449Stomee dtj_consumer_create(JNIEnv *jenv) 7451449Stomee { 7461449Stomee dtj_consumer_t *c; 7471449Stomee 7481449Stomee if (!dtj_check_request_pool()) { 7491449Stomee dtj_throw_out_of_memory(jenv, 7501449Stomee "Failed to allocate request pool"); 7511449Stomee return (NULL); 7521449Stomee } 7531449Stomee 7541449Stomee if (!dtj_check_program_pool()) { 7551449Stomee dtj_throw_out_of_memory(jenv, 7561449Stomee "Failed to allocate program pool"); 7571449Stomee return (NULL); 7581449Stomee } 7591449Stomee 7601449Stomee c = uu_zalloc(sizeof (dtj_consumer_t)); 7611449Stomee if (c) { 7621449Stomee c->dtjc_request_list = uu_list_create(g_request_pool, NULL, 7631449Stomee (g_dtj_util_debug ? UU_LIST_DEBUG : 0)); 7641449Stomee if (!c->dtjc_request_list) { 7651449Stomee dtj_throw_out_of_memory(jenv, 7661449Stomee "Failed to allocate consumer request list"); 7671449Stomee dtj_consumer_destroy(c); 7681449Stomee return (NULL); 7691449Stomee } 7701449Stomee (void) pthread_mutex_init(&c->dtjc_request_list_lock, NULL); 7711449Stomee 7721449Stomee c->dtjc_program_list = uu_list_create(g_program_pool, NULL, 7731449Stomee (g_dtj_util_debug ? UU_LIST_DEBUG : 0)); 7741449Stomee if (!c->dtjc_program_list) { 7751449Stomee dtj_throw_out_of_memory(jenv, 7761449Stomee "Failed to allocate consumer program list"); 7771449Stomee dtj_consumer_destroy(c); 7781449Stomee return (NULL); 7791449Stomee } 7801449Stomee 7811449Stomee c->dtjc_probedata_rec_i = 0; 7821449Stomee c->dtjc_probedata_act = DTRACEACT_NONE; 7831449Stomee c->dtjc_aggid = -1; 7841449Stomee c->dtjc_expected = -1; 7851449Stomee c->dtjc_state = DTJ_CONSUMER_INIT; 7861449Stomee } else { 7871449Stomee dtj_throw_out_of_memory(jenv, 7881449Stomee "Failed to allocate consumer"); 7891449Stomee } 7901449Stomee 7911449Stomee return (c); 7921449Stomee } 7931449Stomee 7941449Stomee void 7951449Stomee /* ARGSUSED */ 7961449Stomee dtj_request_destroy(void *v, void *arg) 7971449Stomee { 7981449Stomee if (v) { 7991449Stomee dtj_request_t *r = v; 8001449Stomee dtj_string_list_destroy(r->dtjr_args); 8011449Stomee uu_list_node_fini(r, &r->dtjr_node, g_request_pool); 8021449Stomee bzero(v, sizeof (dtj_request_t)); 8031449Stomee uu_free(v); 8041449Stomee } 8051449Stomee } 8061449Stomee 8071449Stomee void 8081449Stomee /* ARGSUSED */ 8091449Stomee dtj_program_destroy(void *v, void *arg) 8101449Stomee { 8111449Stomee if (v) { 8121449Stomee dtj_program_t *p = v; 8131449Stomee if (p->dtjp_name) { 8141449Stomee free((void *)p->dtjp_name); 8151449Stomee } 8161449Stomee uu_list_node_fini(p, &p->dtjp_node, g_program_pool); 8171449Stomee bzero(v, sizeof (dtj_program_t)); 8181449Stomee uu_free(v); 8191449Stomee } 8201449Stomee } 8211449Stomee 8221449Stomee void 8231449Stomee dtj_aggval_destroy(void *v, void *arg) 8241449Stomee { 8251449Stomee if (v) { 8261449Stomee dtj_aggval_t *a = v; 8271449Stomee if (a->dtja_value && arg) { 8281449Stomee JNIEnv *jenv = arg; 8291449Stomee (*jenv)->DeleteLocalRef(jenv, a->dtja_value); 8301449Stomee } 8311449Stomee if (a->dtja_aggname) { 8321449Stomee free((void *)a->dtja_aggname); 8331449Stomee } 8341449Stomee uu_list_node_fini(a, &a->dtja_node, g_aggval_pool); 8351449Stomee bzero(v, sizeof (dtj_aggval_t)); 8361449Stomee uu_free(v); 8371449Stomee } 8381449Stomee } 8391449Stomee 8401449Stomee /* 8411449Stomee * Frees per-consumer state. Assumes that the DTrace handle has been closed 8421449Stomee * already. 8431449Stomee */ 8441449Stomee void 8451449Stomee dtj_consumer_destroy(dtj_consumer_t *c) 8461449Stomee { 8471449Stomee if (c) { 8481449Stomee dtj_list_destroy(c->dtjc_request_list, dtj_request_destroy, 8491449Stomee NULL); 8501449Stomee (void) pthread_mutex_destroy(&c->dtjc_request_list_lock); 8511449Stomee dtj_list_destroy(c->dtjc_program_list, dtj_program_destroy, 8521449Stomee NULL); 8531449Stomee /* 8541449Stomee * Cannot dtrace_proc_release the c->process_list proc 8551449Stomee * elements here, because we need the dtrace handle for that. 8561449Stomee * By the time this destructor is called, the dtrace handle is 8571449Stomee * already closed. The proc elements are released in 8581449Stomee * dtrace_jni.c _close(). 8591449Stomee */ 8601449Stomee if (c->dtjc_process_list) { 8611449Stomee dtj_list_destroy(c->dtjc_process_list, NULL, NULL); 8621449Stomee } 8631449Stomee bzero(c, sizeof (dtj_consumer_t)); 8641449Stomee uu_free(c); 8651449Stomee } 8661449Stomee } 8671449Stomee 8681449Stomee void 8691449Stomee dtj_throw_dtrace_exception(dtj_java_consumer_t *jc, const char *fmt, ...) 8701449Stomee { 8711449Stomee JNIEnv *jenv = jc->dtjj_jenv; 8721449Stomee 8731449Stomee va_list ap; 8741449Stomee char msg[DTJ_MSG_SIZE]; 8751449Stomee 8761449Stomee jobject message = NULL; 8771449Stomee jobject exception = NULL; 8781449Stomee 8791449Stomee va_start(ap, fmt); 8801449Stomee (void) vsnprintf(msg, sizeof (msg), fmt, ap); 8811449Stomee va_end(ap); 8821449Stomee 8831449Stomee message = dtj_NewStringNative(jenv, msg); 8841449Stomee if (!message) { 8851449Stomee return; /* java exception pending */ 8861449Stomee } 8871449Stomee 8881449Stomee exception = (*jenv)->NewObject(jenv, g_dtx_jc, g_dtxinit_jm, message); 8891449Stomee (*jenv)->DeleteLocalRef(jenv, message); 8901449Stomee if (exception) { 8911449Stomee (*jenv)->Throw(jenv, exception); 8921449Stomee (*jenv)->DeleteLocalRef(jenv, exception); 8931449Stomee } 8941449Stomee } 895