Mercurial > hg > truffle
annotate src/share/vm/prims/perf.cpp @ 8733:9def4075da6d
8008079: G1: Add nextObject routine to CMBitMapRO and replace nextWord
Summary: Update the task local finger to the start of the next object when marking aborts, in order to avoid the redundant scanning of all 0's when the marking task restarts, if otherwise updating to the next word. In addition, reuse the routine nextObject() in routine iterate().
Reviewed-by: johnc, ysr
Contributed-by: tamao <tao.mao@oracle.com>
author | tamao |
---|---|
date | Tue, 05 Mar 2013 15:36:56 -0800 |
parents | f95d63e2154a |
children | bf089b838c9e |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 2001, 2010, 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 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/vmSymbols.hpp" | |
27 #include "memory/allocation.inline.hpp" | |
28 #include "memory/resourceArea.hpp" | |
29 #include "oops/oop.inline.hpp" | |
30 #include "prims/jni.h" | |
31 #include "prims/jvm.h" | |
32 #include "runtime/interfaceSupport.hpp" | |
33 #include "runtime/perfData.hpp" | |
34 #include "runtime/perfMemory.hpp" | |
35 | |
0 | 36 /* |
37 * Implementation of class sun.misc.Perf | |
38 */ | |
39 | |
40 | |
41 #define PERF_ENTRY(result_type, header) \ | |
42 JVM_ENTRY(result_type, header) | |
43 | |
44 #define PERF_END JVM_END | |
45 | |
46 #define PerfWrapper(arg) /* Unimplemented at this time */ | |
47 | |
48 static char* jstr_to_utf(JNIEnv *env, jstring str, TRAPS) { | |
49 | |
50 char* utfstr = NULL; | |
51 | |
52 if (str == NULL) { | |
53 THROW_0(vmSymbols::java_lang_NullPointerException()); | |
54 //throw_new(env,"NullPointerException"); | |
55 } | |
56 | |
57 int len = env->GetStringUTFLength(str); | |
58 int unicode_len = env->GetStringLength(str); | |
59 | |
60 utfstr = NEW_RESOURCE_ARRAY(char, len + 1); | |
61 | |
62 env->GetStringUTFRegion(str, 0, unicode_len, utfstr); | |
63 | |
64 return utfstr; | |
65 } | |
66 | |
67 PERF_ENTRY(jobject, Perf_Attach(JNIEnv *env, jobject unused, jstring user, int vmid, int mode)) | |
68 | |
69 PerfWrapper("Perf_Attach"); | |
70 | |
71 char* address = 0; | |
72 size_t capacity = 0; | |
73 const char* user_utf = NULL; | |
74 | |
75 ResourceMark rm; | |
76 | |
77 { | |
78 ThreadToNativeFromVM ttnfv(thread); | |
79 | |
80 user_utf = user == NULL ? NULL : jstr_to_utf(env, user, CHECK_NULL); | |
81 } | |
82 | |
83 if (mode != PerfMemory::PERF_MODE_RO && | |
84 mode != PerfMemory::PERF_MODE_RW) { | |
85 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
86 } | |
87 | |
88 // attach to the PerfData memory region for the specified VM | |
89 PerfMemory::attach(user_utf, vmid, (PerfMemory::PerfMemoryMode) mode, | |
90 &address, &capacity, CHECK_NULL); | |
91 | |
92 { | |
93 ThreadToNativeFromVM ttnfv(thread); | |
94 return env->NewDirectByteBuffer(address, (jlong)capacity); | |
95 } | |
96 | |
97 PERF_END | |
98 | |
99 PERF_ENTRY(void, Perf_Detach(JNIEnv *env, jobject unused, jobject buffer)) | |
100 | |
101 PerfWrapper("Perf_Detach"); | |
102 | |
103 void* address = 0; | |
104 jlong capacity = 0; | |
105 | |
106 // get buffer address and capacity | |
107 { | |
108 ThreadToNativeFromVM ttnfv(thread); | |
109 address = env->GetDirectBufferAddress(buffer); | |
110 capacity = env->GetDirectBufferCapacity(buffer); | |
111 } | |
112 | |
113 PerfMemory::detach((char*)address, capacity, CHECK); | |
114 | |
115 PERF_END | |
116 | |
117 PERF_ENTRY(jobject, Perf_CreateLong(JNIEnv *env, jobject perf, jstring name, | |
118 int variability, int units, jlong value)) | |
119 | |
120 PerfWrapper("Perf_CreateLong"); | |
121 | |
122 char* name_utf = NULL; | |
123 | |
124 if (units <= 0 || units > PerfData::U_Last) { | |
125 debug_only(warning("unexpected units argument, units = %d", units)); | |
126 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
127 } | |
128 | |
129 ResourceMark rm; | |
130 | |
131 { | |
132 ThreadToNativeFromVM ttnfv(thread); | |
133 | |
134 name_utf = jstr_to_utf(env, name, CHECK_NULL); | |
135 } | |
136 | |
137 PerfLong* pl = NULL; | |
138 | |
139 // check that the PerfData name doesn't already exist | |
140 if (PerfDataManager::exists(name_utf)) { | |
141 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "PerfLong name already exists"); | |
142 } | |
143 | |
144 switch(variability) { | |
145 case 1: /* V_Constant */ | |
146 pl = PerfDataManager::create_long_constant(NULL_NS, (char *)name_utf, | |
147 (PerfData::Units)units, value, | |
148 CHECK_NULL); | |
149 break; | |
150 | |
151 case 2: /* V_Variable */ | |
152 pl = PerfDataManager::create_long_variable(NULL_NS, (char *)name_utf, | |
153 (PerfData::Units)units, value, | |
154 CHECK_NULL); | |
155 break; | |
156 | |
157 case 3: /* V_Monotonic Counter */ | |
158 pl = PerfDataManager::create_long_counter(NULL_NS, (char *)name_utf, | |
159 (PerfData::Units)units, value, | |
160 CHECK_NULL); | |
161 break; | |
162 | |
163 default: /* Illegal Argument */ | |
164 debug_only(warning("unexpected variability value: %d", variability)); | |
165 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
166 break; | |
167 } | |
168 | |
169 long* lp = (long*)pl->get_address(); | |
170 | |
171 { | |
172 ThreadToNativeFromVM ttnfv(thread); | |
173 return env->NewDirectByteBuffer(lp, sizeof(jlong)); | |
174 } | |
175 | |
176 PERF_END | |
177 | |
178 PERF_ENTRY(jobject, Perf_CreateByteArray(JNIEnv *env, jobject perf, | |
179 jstring name, jint variability, | |
180 jint units, jbyteArray value, | |
181 jint maxlength)) | |
182 | |
183 PerfWrapper("Perf_CreateByteArray"); | |
184 | |
185 // check for valid byte array objects | |
186 if (name == NULL || value == NULL) { | |
187 THROW_0(vmSymbols::java_lang_NullPointerException()); | |
188 } | |
189 | |
190 // check for valid variability classification | |
191 if (variability != PerfData::V_Constant && | |
192 variability != PerfData::V_Variable) { | |
193 debug_only(warning("unexpected variability value: %d", variability)); | |
194 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
195 } | |
196 | |
197 // check for valid units | |
198 if (units != PerfData::U_String) { | |
199 // only String based ByteArray objects are currently supported | |
200 debug_only(warning("unexpected units value: %d", variability)); | |
201 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
202 } | |
203 | |
204 int value_length; | |
205 char* name_utf = NULL; | |
206 jbyte* value_local = NULL; | |
207 | |
208 ResourceMark rm; | |
209 | |
210 { | |
211 ThreadToNativeFromVM ttnfv(thread); | |
212 | |
213 name_utf = jstr_to_utf(env, name, CHECK_NULL); | |
214 | |
215 value_length = env->GetArrayLength(value); | |
216 | |
217 value_local = NEW_RESOURCE_ARRAY(jbyte, value_length + 1); | |
218 | |
219 env->GetByteArrayRegion(value, 0, value_length, value_local); | |
220 } | |
221 | |
222 // check that the counter name doesn't already exist | |
223 if (PerfDataManager::exists((char*)name_utf)) { | |
224 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "PerfByteArray name already exists"); | |
225 } | |
226 | |
227 PerfByteArray* pbv = NULL; | |
228 | |
229 if (units == PerfData::U_String) { | |
230 | |
231 if (variability == PerfData::V_Constant) { | |
232 // create the string constant | |
233 pbv = PerfDataManager::create_string_constant(NULL_NS, (char*)name_utf, | |
234 (char*)value_local, | |
235 CHECK_NULL); | |
236 | |
237 assert(maxlength == value_length, "string constant length should be == maxlength"); | |
238 maxlength = value_length; | |
239 } | |
240 else { | |
241 | |
242 // create the string variable | |
243 pbv = PerfDataManager::create_string_variable(NULL_NS, (char*)name_utf, | |
244 maxlength, | |
245 (char*)value_local, | |
246 CHECK_NULL); | |
247 | |
248 assert(maxlength >= value_length,"string variable length should be <= maxlength"); | |
249 } | |
250 } | |
251 | |
252 char* cp = (char*)pbv->get_address(); | |
253 | |
254 { | |
255 ThreadToNativeFromVM ttnfv(thread); | |
256 return env->NewDirectByteBuffer(cp, maxlength+1); | |
257 } | |
258 | |
259 PERF_END | |
260 | |
261 PERF_ENTRY(jlong, Perf_HighResCounter(JNIEnv *env, jobject perf)) | |
262 | |
263 PerfWrapper("Perf_HighResCounter"); | |
264 | |
265 // this should be a method in java.lang.System. This value could | |
266 // be acquired through access to a PerfData performance counter, but | |
267 // doing so would require that the PerfData monitoring overhead be | |
268 // incurred by all Java applications, which is unacceptable. | |
269 | |
270 return os::elapsed_counter(); | |
271 | |
272 PERF_END | |
273 | |
274 PERF_ENTRY(jlong, Perf_HighResFrequency(JNIEnv *env, jobject perf)) | |
275 | |
276 PerfWrapper("Perf_HighResFrequency"); | |
277 | |
278 // this should be a method in java.lang.System. This value could | |
279 // be acquired through access to a PerfData performance counter, but | |
280 // doing so would require that the PerfData monitoring overhead be | |
281 // incurred by all Java applications, which is unacceptable. | |
282 | |
283 return os::elapsed_frequency(); | |
284 | |
285 PERF_END | |
286 | |
287 /// JVM_RegisterPerfMethods | |
288 | |
289 #define CC (char*) /*cast a literal from (const char*)*/ | |
290 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f) | |
291 #define BB "Ljava/nio/ByteBuffer;" | |
292 #define JLS "Ljava/lang/String;" | |
293 #define CL_ARGS CC"("JLS"IIJ)"BB | |
294 #define CBA_ARGS CC"("JLS"II[BI)"BB | |
295 | |
296 static JNINativeMethod perfmethods[] = { | |
297 | |
298 {CC"attach", CC"("JLS"II)"BB, FN_PTR(Perf_Attach)}, | |
299 {CC"detach", CC"("BB")V", FN_PTR(Perf_Detach)}, | |
300 {CC"createLong", CL_ARGS, FN_PTR(Perf_CreateLong)}, | |
301 {CC"createByteArray", CBA_ARGS, FN_PTR(Perf_CreateByteArray)}, | |
302 {CC"highResCounter", CC"()J", FN_PTR(Perf_HighResCounter)}, | |
303 {CC"highResFrequency", CC"()J", FN_PTR(Perf_HighResFrequency)} | |
304 }; | |
305 | |
306 #undef CBA_ARGS | |
307 #undef CL_ARGS | |
308 #undef JLS | |
309 #undef BB | |
310 #undef FN_PTR | |
311 #undef CC | |
312 | |
313 // This one function is exported, used by NativeLookup. | |
314 JVM_ENTRY(void, JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass)) | |
315 PerfWrapper("JVM_RegisterPerfMethods"); | |
316 { | |
317 ThreadToNativeFromVM ttnfv(thread); | |
318 int ok = env->RegisterNatives(perfclass, perfmethods, sizeof(perfmethods)/sizeof(JNINativeMethod)); | |
319 guarantee(ok == 0, "register perf natives"); | |
320 } | |
321 JVM_END |