Mercurial > hg > graal-compiler
annotate src/share/vm/prims/perf.cpp @ 1711:a6bff45449bc
6973570: OrderAccess::storestore() scales poorly on multi-socket x64 and sparc: cache-line ping-ponging
Summary: volatile store to static variable removed in favour of a volatile store to stack to avoid excessive cache coherency traffic; verified that the volatile store is not elided by any of our current compilers.
Reviewed-by: dholmes, dice, jcoomes, kvn
author | ysr |
---|---|
date | Tue, 10 Aug 2010 14:53:35 -0700 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
2 * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 /* | |
26 * Implementation of class sun.misc.Perf | |
27 */ | |
28 | |
29 #include "incls/_precompiled.incl" | |
30 #include "incls/_perf.cpp.incl" | |
31 | |
32 | |
33 #define PERF_ENTRY(result_type, header) \ | |
34 JVM_ENTRY(result_type, header) | |
35 | |
36 #define PERF_END JVM_END | |
37 | |
38 #define PerfWrapper(arg) /* Unimplemented at this time */ | |
39 | |
40 static char* jstr_to_utf(JNIEnv *env, jstring str, TRAPS) { | |
41 | |
42 char* utfstr = NULL; | |
43 | |
44 if (str == NULL) { | |
45 THROW_0(vmSymbols::java_lang_NullPointerException()); | |
46 //throw_new(env,"NullPointerException"); | |
47 } | |
48 | |
49 int len = env->GetStringUTFLength(str); | |
50 int unicode_len = env->GetStringLength(str); | |
51 | |
52 utfstr = NEW_RESOURCE_ARRAY(char, len + 1); | |
53 | |
54 env->GetStringUTFRegion(str, 0, unicode_len, utfstr); | |
55 | |
56 return utfstr; | |
57 } | |
58 | |
59 PERF_ENTRY(jobject, Perf_Attach(JNIEnv *env, jobject unused, jstring user, int vmid, int mode)) | |
60 | |
61 PerfWrapper("Perf_Attach"); | |
62 | |
63 char* address = 0; | |
64 size_t capacity = 0; | |
65 const char* user_utf = NULL; | |
66 | |
67 ResourceMark rm; | |
68 | |
69 { | |
70 ThreadToNativeFromVM ttnfv(thread); | |
71 | |
72 user_utf = user == NULL ? NULL : jstr_to_utf(env, user, CHECK_NULL); | |
73 } | |
74 | |
75 if (mode != PerfMemory::PERF_MODE_RO && | |
76 mode != PerfMemory::PERF_MODE_RW) { | |
77 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
78 } | |
79 | |
80 // attach to the PerfData memory region for the specified VM | |
81 PerfMemory::attach(user_utf, vmid, (PerfMemory::PerfMemoryMode) mode, | |
82 &address, &capacity, CHECK_NULL); | |
83 | |
84 { | |
85 ThreadToNativeFromVM ttnfv(thread); | |
86 return env->NewDirectByteBuffer(address, (jlong)capacity); | |
87 } | |
88 | |
89 PERF_END | |
90 | |
91 PERF_ENTRY(void, Perf_Detach(JNIEnv *env, jobject unused, jobject buffer)) | |
92 | |
93 PerfWrapper("Perf_Detach"); | |
94 | |
95 void* address = 0; | |
96 jlong capacity = 0; | |
97 | |
98 // get buffer address and capacity | |
99 { | |
100 ThreadToNativeFromVM ttnfv(thread); | |
101 address = env->GetDirectBufferAddress(buffer); | |
102 capacity = env->GetDirectBufferCapacity(buffer); | |
103 } | |
104 | |
105 PerfMemory::detach((char*)address, capacity, CHECK); | |
106 | |
107 PERF_END | |
108 | |
109 PERF_ENTRY(jobject, Perf_CreateLong(JNIEnv *env, jobject perf, jstring name, | |
110 int variability, int units, jlong value)) | |
111 | |
112 PerfWrapper("Perf_CreateLong"); | |
113 | |
114 char* name_utf = NULL; | |
115 | |
116 if (units <= 0 || units > PerfData::U_Last) { | |
117 debug_only(warning("unexpected units argument, units = %d", units)); | |
118 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
119 } | |
120 | |
121 ResourceMark rm; | |
122 | |
123 { | |
124 ThreadToNativeFromVM ttnfv(thread); | |
125 | |
126 name_utf = jstr_to_utf(env, name, CHECK_NULL); | |
127 } | |
128 | |
129 PerfLong* pl = NULL; | |
130 | |
131 // check that the PerfData name doesn't already exist | |
132 if (PerfDataManager::exists(name_utf)) { | |
133 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "PerfLong name already exists"); | |
134 } | |
135 | |
136 switch(variability) { | |
137 case 1: /* V_Constant */ | |
138 pl = PerfDataManager::create_long_constant(NULL_NS, (char *)name_utf, | |
139 (PerfData::Units)units, value, | |
140 CHECK_NULL); | |
141 break; | |
142 | |
143 case 2: /* V_Variable */ | |
144 pl = PerfDataManager::create_long_variable(NULL_NS, (char *)name_utf, | |
145 (PerfData::Units)units, value, | |
146 CHECK_NULL); | |
147 break; | |
148 | |
149 case 3: /* V_Monotonic Counter */ | |
150 pl = PerfDataManager::create_long_counter(NULL_NS, (char *)name_utf, | |
151 (PerfData::Units)units, value, | |
152 CHECK_NULL); | |
153 break; | |
154 | |
155 default: /* Illegal Argument */ | |
156 debug_only(warning("unexpected variability value: %d", variability)); | |
157 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
158 break; | |
159 } | |
160 | |
161 long* lp = (long*)pl->get_address(); | |
162 | |
163 { | |
164 ThreadToNativeFromVM ttnfv(thread); | |
165 return env->NewDirectByteBuffer(lp, sizeof(jlong)); | |
166 } | |
167 | |
168 PERF_END | |
169 | |
170 PERF_ENTRY(jobject, Perf_CreateByteArray(JNIEnv *env, jobject perf, | |
171 jstring name, jint variability, | |
172 jint units, jbyteArray value, | |
173 jint maxlength)) | |
174 | |
175 PerfWrapper("Perf_CreateByteArray"); | |
176 | |
177 // check for valid byte array objects | |
178 if (name == NULL || value == NULL) { | |
179 THROW_0(vmSymbols::java_lang_NullPointerException()); | |
180 } | |
181 | |
182 // check for valid variability classification | |
183 if (variability != PerfData::V_Constant && | |
184 variability != PerfData::V_Variable) { | |
185 debug_only(warning("unexpected variability value: %d", variability)); | |
186 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
187 } | |
188 | |
189 // check for valid units | |
190 if (units != PerfData::U_String) { | |
191 // only String based ByteArray objects are currently supported | |
192 debug_only(warning("unexpected units value: %d", variability)); | |
193 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
194 } | |
195 | |
196 int value_length; | |
197 char* name_utf = NULL; | |
198 jbyte* value_local = NULL; | |
199 | |
200 ResourceMark rm; | |
201 | |
202 { | |
203 ThreadToNativeFromVM ttnfv(thread); | |
204 | |
205 name_utf = jstr_to_utf(env, name, CHECK_NULL); | |
206 | |
207 value_length = env->GetArrayLength(value); | |
208 | |
209 value_local = NEW_RESOURCE_ARRAY(jbyte, value_length + 1); | |
210 | |
211 env->GetByteArrayRegion(value, 0, value_length, value_local); | |
212 } | |
213 | |
214 // check that the counter name doesn't already exist | |
215 if (PerfDataManager::exists((char*)name_utf)) { | |
216 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "PerfByteArray name already exists"); | |
217 } | |
218 | |
219 PerfByteArray* pbv = NULL; | |
220 | |
221 if (units == PerfData::U_String) { | |
222 | |
223 if (variability == PerfData::V_Constant) { | |
224 // create the string constant | |
225 pbv = PerfDataManager::create_string_constant(NULL_NS, (char*)name_utf, | |
226 (char*)value_local, | |
227 CHECK_NULL); | |
228 | |
229 assert(maxlength == value_length, "string constant length should be == maxlength"); | |
230 maxlength = value_length; | |
231 } | |
232 else { | |
233 | |
234 // create the string variable | |
235 pbv = PerfDataManager::create_string_variable(NULL_NS, (char*)name_utf, | |
236 maxlength, | |
237 (char*)value_local, | |
238 CHECK_NULL); | |
239 | |
240 assert(maxlength >= value_length,"string variable length should be <= maxlength"); | |
241 } | |
242 } | |
243 | |
244 char* cp = (char*)pbv->get_address(); | |
245 | |
246 { | |
247 ThreadToNativeFromVM ttnfv(thread); | |
248 return env->NewDirectByteBuffer(cp, maxlength+1); | |
249 } | |
250 | |
251 PERF_END | |
252 | |
253 PERF_ENTRY(jlong, Perf_HighResCounter(JNIEnv *env, jobject perf)) | |
254 | |
255 PerfWrapper("Perf_HighResCounter"); | |
256 | |
257 // this should be a method in java.lang.System. This value could | |
258 // be acquired through access to a PerfData performance counter, but | |
259 // doing so would require that the PerfData monitoring overhead be | |
260 // incurred by all Java applications, which is unacceptable. | |
261 | |
262 return os::elapsed_counter(); | |
263 | |
264 PERF_END | |
265 | |
266 PERF_ENTRY(jlong, Perf_HighResFrequency(JNIEnv *env, jobject perf)) | |
267 | |
268 PerfWrapper("Perf_HighResFrequency"); | |
269 | |
270 // this should be a method in java.lang.System. This value could | |
271 // be acquired through access to a PerfData performance counter, but | |
272 // doing so would require that the PerfData monitoring overhead be | |
273 // incurred by all Java applications, which is unacceptable. | |
274 | |
275 return os::elapsed_frequency(); | |
276 | |
277 PERF_END | |
278 | |
279 /// JVM_RegisterPerfMethods | |
280 | |
281 #define CC (char*) /*cast a literal from (const char*)*/ | |
282 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f) | |
283 #define BB "Ljava/nio/ByteBuffer;" | |
284 #define JLS "Ljava/lang/String;" | |
285 #define CL_ARGS CC"("JLS"IIJ)"BB | |
286 #define CBA_ARGS CC"("JLS"II[BI)"BB | |
287 | |
288 static JNINativeMethod perfmethods[] = { | |
289 | |
290 {CC"attach", CC"("JLS"II)"BB, FN_PTR(Perf_Attach)}, | |
291 {CC"detach", CC"("BB")V", FN_PTR(Perf_Detach)}, | |
292 {CC"createLong", CL_ARGS, FN_PTR(Perf_CreateLong)}, | |
293 {CC"createByteArray", CBA_ARGS, FN_PTR(Perf_CreateByteArray)}, | |
294 {CC"highResCounter", CC"()J", FN_PTR(Perf_HighResCounter)}, | |
295 {CC"highResFrequency", CC"()J", FN_PTR(Perf_HighResFrequency)} | |
296 }; | |
297 | |
298 #undef CBA_ARGS | |
299 #undef CL_ARGS | |
300 #undef JLS | |
301 #undef BB | |
302 #undef FN_PTR | |
303 #undef CC | |
304 | |
305 // This one function is exported, used by NativeLookup. | |
306 JVM_ENTRY(void, JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass)) | |
307 PerfWrapper("JVM_RegisterPerfMethods"); | |
308 { | |
309 ThreadToNativeFromVM ttnfv(thread); | |
310 int ok = env->RegisterNatives(perfclass, perfmethods, sizeof(perfmethods)/sizeof(JNINativeMethod)); | |
311 guarantee(ok == 0, "register perf natives"); | |
312 } | |
313 JVM_END |