1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/prims/perf.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,313 @@ 1.4 +/* 1.5 + * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +/* 1.29 + * Implementation of class sun.misc.Perf 1.30 + */ 1.31 + 1.32 +#include "incls/_precompiled.incl" 1.33 +#include "incls/_perf.cpp.incl" 1.34 + 1.35 + 1.36 +#define PERF_ENTRY(result_type, header) \ 1.37 + JVM_ENTRY(result_type, header) 1.38 + 1.39 +#define PERF_END JVM_END 1.40 + 1.41 +#define PerfWrapper(arg) /* Unimplemented at this time */ 1.42 + 1.43 +static char* jstr_to_utf(JNIEnv *env, jstring str, TRAPS) { 1.44 + 1.45 + char* utfstr = NULL; 1.46 + 1.47 + if (str == NULL) { 1.48 + THROW_0(vmSymbols::java_lang_NullPointerException()); 1.49 + //throw_new(env,"NullPointerException"); 1.50 + } 1.51 + 1.52 + int len = env->GetStringUTFLength(str); 1.53 + int unicode_len = env->GetStringLength(str); 1.54 + 1.55 + utfstr = NEW_RESOURCE_ARRAY(char, len + 1); 1.56 + 1.57 + env->GetStringUTFRegion(str, 0, unicode_len, utfstr); 1.58 + 1.59 + return utfstr; 1.60 +} 1.61 + 1.62 +PERF_ENTRY(jobject, Perf_Attach(JNIEnv *env, jobject unused, jstring user, int vmid, int mode)) 1.63 + 1.64 + PerfWrapper("Perf_Attach"); 1.65 + 1.66 + char* address = 0; 1.67 + size_t capacity = 0; 1.68 + const char* user_utf = NULL; 1.69 + 1.70 + ResourceMark rm; 1.71 + 1.72 + { 1.73 + ThreadToNativeFromVM ttnfv(thread); 1.74 + 1.75 + user_utf = user == NULL ? NULL : jstr_to_utf(env, user, CHECK_NULL); 1.76 + } 1.77 + 1.78 + if (mode != PerfMemory::PERF_MODE_RO && 1.79 + mode != PerfMemory::PERF_MODE_RW) { 1.80 + THROW_0(vmSymbols::java_lang_IllegalArgumentException()); 1.81 + } 1.82 + 1.83 + // attach to the PerfData memory region for the specified VM 1.84 + PerfMemory::attach(user_utf, vmid, (PerfMemory::PerfMemoryMode) mode, 1.85 + &address, &capacity, CHECK_NULL); 1.86 + 1.87 + { 1.88 + ThreadToNativeFromVM ttnfv(thread); 1.89 + return env->NewDirectByteBuffer(address, (jlong)capacity); 1.90 + } 1.91 + 1.92 +PERF_END 1.93 + 1.94 +PERF_ENTRY(void, Perf_Detach(JNIEnv *env, jobject unused, jobject buffer)) 1.95 + 1.96 + PerfWrapper("Perf_Detach"); 1.97 + 1.98 + void* address = 0; 1.99 + jlong capacity = 0; 1.100 + 1.101 + // get buffer address and capacity 1.102 + { 1.103 + ThreadToNativeFromVM ttnfv(thread); 1.104 + address = env->GetDirectBufferAddress(buffer); 1.105 + capacity = env->GetDirectBufferCapacity(buffer); 1.106 + } 1.107 + 1.108 + PerfMemory::detach((char*)address, capacity, CHECK); 1.109 + 1.110 +PERF_END 1.111 + 1.112 +PERF_ENTRY(jobject, Perf_CreateLong(JNIEnv *env, jobject perf, jstring name, 1.113 + int variability, int units, jlong value)) 1.114 + 1.115 + PerfWrapper("Perf_CreateLong"); 1.116 + 1.117 + char* name_utf = NULL; 1.118 + 1.119 + if (units <= 0 || units > PerfData::U_Last) { 1.120 + debug_only(warning("unexpected units argument, units = %d", units)); 1.121 + THROW_0(vmSymbols::java_lang_IllegalArgumentException()); 1.122 + } 1.123 + 1.124 + ResourceMark rm; 1.125 + 1.126 + { 1.127 + ThreadToNativeFromVM ttnfv(thread); 1.128 + 1.129 + name_utf = jstr_to_utf(env, name, CHECK_NULL); 1.130 + } 1.131 + 1.132 + PerfLong* pl = NULL; 1.133 + 1.134 + // check that the PerfData name doesn't already exist 1.135 + if (PerfDataManager::exists(name_utf)) { 1.136 + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "PerfLong name already exists"); 1.137 + } 1.138 + 1.139 + switch(variability) { 1.140 + case 1: /* V_Constant */ 1.141 + pl = PerfDataManager::create_long_constant(NULL_NS, (char *)name_utf, 1.142 + (PerfData::Units)units, value, 1.143 + CHECK_NULL); 1.144 + break; 1.145 + 1.146 + case 2: /* V_Variable */ 1.147 + pl = PerfDataManager::create_long_variable(NULL_NS, (char *)name_utf, 1.148 + (PerfData::Units)units, value, 1.149 + CHECK_NULL); 1.150 + break; 1.151 + 1.152 + case 3: /* V_Monotonic Counter */ 1.153 + pl = PerfDataManager::create_long_counter(NULL_NS, (char *)name_utf, 1.154 + (PerfData::Units)units, value, 1.155 + CHECK_NULL); 1.156 + break; 1.157 + 1.158 + default: /* Illegal Argument */ 1.159 + debug_only(warning("unexpected variability value: %d", variability)); 1.160 + THROW_0(vmSymbols::java_lang_IllegalArgumentException()); 1.161 + break; 1.162 + } 1.163 + 1.164 + long* lp = (long*)pl->get_address(); 1.165 + 1.166 + { 1.167 + ThreadToNativeFromVM ttnfv(thread); 1.168 + return env->NewDirectByteBuffer(lp, sizeof(jlong)); 1.169 + } 1.170 + 1.171 +PERF_END 1.172 + 1.173 +PERF_ENTRY(jobject, Perf_CreateByteArray(JNIEnv *env, jobject perf, 1.174 + jstring name, jint variability, 1.175 + jint units, jbyteArray value, 1.176 + jint maxlength)) 1.177 + 1.178 + PerfWrapper("Perf_CreateByteArray"); 1.179 + 1.180 + // check for valid byte array objects 1.181 + if (name == NULL || value == NULL) { 1.182 + THROW_0(vmSymbols::java_lang_NullPointerException()); 1.183 + } 1.184 + 1.185 + // check for valid variability classification 1.186 + if (variability != PerfData::V_Constant && 1.187 + variability != PerfData::V_Variable) { 1.188 + debug_only(warning("unexpected variability value: %d", variability)); 1.189 + THROW_0(vmSymbols::java_lang_IllegalArgumentException()); 1.190 + } 1.191 + 1.192 + // check for valid units 1.193 + if (units != PerfData::U_String) { 1.194 + // only String based ByteArray objects are currently supported 1.195 + debug_only(warning("unexpected units value: %d", variability)); 1.196 + THROW_0(vmSymbols::java_lang_IllegalArgumentException()); 1.197 + } 1.198 + 1.199 + int value_length; 1.200 + char* name_utf = NULL; 1.201 + jbyte* value_local = NULL; 1.202 + 1.203 + ResourceMark rm; 1.204 + 1.205 + { 1.206 + ThreadToNativeFromVM ttnfv(thread); 1.207 + 1.208 + name_utf = jstr_to_utf(env, name, CHECK_NULL); 1.209 + 1.210 + value_length = env->GetArrayLength(value); 1.211 + 1.212 + value_local = NEW_RESOURCE_ARRAY(jbyte, value_length + 1); 1.213 + 1.214 + env->GetByteArrayRegion(value, 0, value_length, value_local); 1.215 + } 1.216 + 1.217 + // check that the counter name doesn't already exist 1.218 + if (PerfDataManager::exists((char*)name_utf)) { 1.219 + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "PerfByteArray name already exists"); 1.220 + } 1.221 + 1.222 + PerfByteArray* pbv = NULL; 1.223 + 1.224 + if (units == PerfData::U_String) { 1.225 + 1.226 + if (variability == PerfData::V_Constant) { 1.227 + // create the string constant 1.228 + pbv = PerfDataManager::create_string_constant(NULL_NS, (char*)name_utf, 1.229 + (char*)value_local, 1.230 + CHECK_NULL); 1.231 + 1.232 + assert(maxlength == value_length, "string constant length should be == maxlength"); 1.233 + maxlength = value_length; 1.234 + } 1.235 + else { 1.236 + 1.237 + // create the string variable 1.238 + pbv = PerfDataManager::create_string_variable(NULL_NS, (char*)name_utf, 1.239 + maxlength, 1.240 + (char*)value_local, 1.241 + CHECK_NULL); 1.242 + 1.243 + assert(maxlength >= value_length,"string variable length should be <= maxlength"); 1.244 + } 1.245 + } 1.246 + 1.247 + char* cp = (char*)pbv->get_address(); 1.248 + 1.249 + { 1.250 + ThreadToNativeFromVM ttnfv(thread); 1.251 + return env->NewDirectByteBuffer(cp, maxlength+1); 1.252 + } 1.253 + 1.254 +PERF_END 1.255 + 1.256 +PERF_ENTRY(jlong, Perf_HighResCounter(JNIEnv *env, jobject perf)) 1.257 + 1.258 + PerfWrapper("Perf_HighResCounter"); 1.259 + 1.260 + // this should be a method in java.lang.System. This value could 1.261 + // be acquired through access to a PerfData performance counter, but 1.262 + // doing so would require that the PerfData monitoring overhead be 1.263 + // incurred by all Java applications, which is unacceptable. 1.264 + 1.265 + return os::elapsed_counter(); 1.266 + 1.267 +PERF_END 1.268 + 1.269 +PERF_ENTRY(jlong, Perf_HighResFrequency(JNIEnv *env, jobject perf)) 1.270 + 1.271 + PerfWrapper("Perf_HighResFrequency"); 1.272 + 1.273 + // this should be a method in java.lang.System. This value could 1.274 + // be acquired through access to a PerfData performance counter, but 1.275 + // doing so would require that the PerfData monitoring overhead be 1.276 + // incurred by all Java applications, which is unacceptable. 1.277 + 1.278 + return os::elapsed_frequency(); 1.279 + 1.280 +PERF_END 1.281 + 1.282 +/// JVM_RegisterPerfMethods 1.283 + 1.284 +#define CC (char*) /*cast a literal from (const char*)*/ 1.285 +#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f) 1.286 +#define BB "Ljava/nio/ByteBuffer;" 1.287 +#define JLS "Ljava/lang/String;" 1.288 +#define CL_ARGS CC"("JLS"IIJ)"BB 1.289 +#define CBA_ARGS CC"("JLS"II[BI)"BB 1.290 + 1.291 +static JNINativeMethod perfmethods[] = { 1.292 + 1.293 + {CC"attach", CC"("JLS"II)"BB, FN_PTR(Perf_Attach)}, 1.294 + {CC"detach", CC"("BB")V", FN_PTR(Perf_Detach)}, 1.295 + {CC"createLong", CL_ARGS, FN_PTR(Perf_CreateLong)}, 1.296 + {CC"createByteArray", CBA_ARGS, FN_PTR(Perf_CreateByteArray)}, 1.297 + {CC"highResCounter", CC"()J", FN_PTR(Perf_HighResCounter)}, 1.298 + {CC"highResFrequency", CC"()J", FN_PTR(Perf_HighResFrequency)} 1.299 +}; 1.300 + 1.301 +#undef CBA_ARGS 1.302 +#undef CL_ARGS 1.303 +#undef JLS 1.304 +#undef BB 1.305 +#undef FN_PTR 1.306 +#undef CC 1.307 + 1.308 +// This one function is exported, used by NativeLookup. 1.309 +JVM_ENTRY(void, JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass)) 1.310 + PerfWrapper("JVM_RegisterPerfMethods"); 1.311 + { 1.312 + ThreadToNativeFromVM ttnfv(thread); 1.313 + int ok = env->RegisterNatives(perfclass, perfmethods, sizeof(perfmethods)/sizeof(JNINativeMethod)); 1.314 + guarantee(ok == 0, "register perf natives"); 1.315 + } 1.316 +JVM_END