Mercurial > hg > graal-jvmci-8
annotate src/share/vm/prims/jni.cpp @ 6972:bd7a7ce2e264
6830717: replay of compilations would help with debugging
Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method.
Reviewed-by: kvn, twisti, sspitsyn
Contributed-by: yumin.qi@oracle.com
author | minqi |
---|---|
date | Mon, 12 Nov 2012 14:03:53 -0800 |
parents | 18fb7da42534 |
children | 80e866b1d053 |
rev | line source |
---|---|
0 | 1 /* |
6125
dcfcdd01af4b
7171703: JNI DefineClass crashes client VM when first parameter is NULL
fparain
parents:
4800
diff
changeset
|
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
6837
75982791ddb6
7170638: Use DTRACE_PROBE[N] in JNI Set and SetStatic Field.
coleenp
parents:
6831
diff
changeset
|
3 * Copyright (c) 2012 Red Hat, Inc. |
0 | 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
5 * | |
6 * This code is free software; you can redistribute it and/or modify it | |
7 * under the terms of the GNU General Public License version 2 only, as | |
8 * published by the Free Software Foundation. | |
9 * | |
10 * This code is distributed in the hope that it will be useful, but WITHOUT | |
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
13 * version 2 for more details (a copy is included in the LICENSE file that | |
14 * accompanied this code). | |
15 * | |
16 * You should have received a copy of the GNU General Public License version | |
17 * 2 along with this work; if not, write to the Free Software Foundation, | |
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
19 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
21 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
22 * questions. |
0 | 23 * |
24 */ | |
25 | |
1972 | 26 #include "precompiled.hpp" |
6972
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
27 #include "ci/ciReplay.hpp" |
6162 | 28 #include "classfile/altHashing.hpp" |
1972 | 29 #include "classfile/classLoader.hpp" |
30 #include "classfile/javaClasses.hpp" | |
31 #include "classfile/symbolTable.hpp" | |
32 #include "classfile/systemDictionary.hpp" | |
33 #include "classfile/vmSymbols.hpp" | |
34 #include "interpreter/linkResolver.hpp" | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
35 #ifndef SERIALGC |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
36 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
37 #endif // SERIALGC |
6197 | 38 #include "memory/allocation.hpp" |
1972 | 39 #include "memory/allocation.inline.hpp" |
40 #include "memory/gcLocker.inline.hpp" | |
41 #include "memory/oopFactory.hpp" | |
42 #include "memory/universe.inline.hpp" | |
43 #include "oops/instanceKlass.hpp" | |
44 #include "oops/instanceOop.hpp" | |
45 #include "oops/markOop.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
46 #include "oops/method.hpp" |
1972 | 47 #include "oops/objArrayKlass.hpp" |
48 #include "oops/objArrayOop.hpp" | |
49 #include "oops/oop.inline.hpp" | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
50 #include "oops/symbol.hpp" |
1972 | 51 #include "oops/typeArrayKlass.hpp" |
52 #include "oops/typeArrayOop.hpp" | |
53 #include "prims/jni.h" | |
54 #include "prims/jniCheck.hpp" | |
4800
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
4708
diff
changeset
|
55 #include "prims/jniExport.hpp" |
1972 | 56 #include "prims/jniFastGetField.hpp" |
57 #include "prims/jvm.h" | |
58 #include "prims/jvm_misc.hpp" | |
59 #include "prims/jvmtiExport.hpp" | |
60 #include "prims/jvmtiThreadState.hpp" | |
61 #include "runtime/compilationPolicy.hpp" | |
62 #include "runtime/fieldDescriptor.hpp" | |
63 #include "runtime/fprofiler.hpp" | |
64 #include "runtime/handles.inline.hpp" | |
65 #include "runtime/interfaceSupport.hpp" | |
66 #include "runtime/java.hpp" | |
67 #include "runtime/javaCalls.hpp" | |
68 #include "runtime/jfieldIDWorkaround.hpp" | |
69 #include "runtime/reflection.hpp" | |
70 #include "runtime/sharedRuntime.hpp" | |
71 #include "runtime/signature.hpp" | |
72 #include "runtime/vm_operations.hpp" | |
73 #include "services/runtimeService.hpp" | |
4800
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
4708
diff
changeset
|
74 #include "trace/tracing.hpp" |
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
4708
diff
changeset
|
75 #include "trace/traceEventTypes.hpp" |
1972 | 76 #include "utilities/defaultStream.hpp" |
77 #include "utilities/dtrace.hpp" | |
78 #include "utilities/events.hpp" | |
79 #include "utilities/histogram.hpp" | |
80 #ifdef TARGET_OS_FAMILY_linux | |
81 # include "os_linux.inline.hpp" | |
82 # include "thread_linux.inline.hpp" | |
83 #endif | |
84 #ifdef TARGET_OS_FAMILY_solaris | |
85 # include "os_solaris.inline.hpp" | |
86 # include "thread_solaris.inline.hpp" | |
87 #endif | |
88 #ifdef TARGET_OS_FAMILY_windows | |
89 # include "os_windows.inline.hpp" | |
90 # include "thread_windows.inline.hpp" | |
91 #endif | |
3960 | 92 #ifdef TARGET_OS_FAMILY_bsd |
93 # include "os_bsd.inline.hpp" | |
94 # include "thread_bsd.inline.hpp" | |
95 #endif | |
0 | 96 |
97 static jint CurrentVersion = JNI_VERSION_1_6; | |
98 | |
99 | |
100 // The DT_RETURN_MARK macros create a scoped object to fire the dtrace | |
101 // '-return' probe regardless of the return path is taken out of the function. | |
102 // Methods that have multiple return paths use this to avoid having to | |
103 // instrument each return path. Methods that use CHECK or THROW must use this | |
104 // since those macros can cause an immedate uninstrumented return. | |
105 // | |
106 // In order to get the return value, a reference to the variable containing | |
107 // the return value must be passed to the contructor of the object, and | |
108 // the return value must be set before return (since the mark object has | |
109 // a reference to it). | |
110 // | |
111 // Example: | |
112 // DT_RETURN_MARK_DECL(SomeFunc, int); | |
113 // JNI_ENTRY(int, SomeFunc, ...) | |
114 // int return_value = 0; | |
115 // DT_RETURN_MARK(SomeFunc, int, (const int&)return_value); | |
116 // foo(CHECK_0) | |
117 // return_value = 5; | |
118 // return return_value; | |
119 // JNI_END | |
4006 | 120 #ifndef USDT2 |
0 | 121 #define DT_RETURN_MARK_DECL(name, type) \ |
122 HS_DTRACE_PROBE_DECL1(hotspot_jni, name##__return, type); \ | |
123 DTRACE_ONLY( \ | |
124 class DTraceReturnProbeMark_##name { \ | |
125 public: \ | |
126 const type& _ret_ref; \ | |
127 DTraceReturnProbeMark_##name(const type& v) : _ret_ref(v) {} \ | |
128 ~DTraceReturnProbeMark_##name() { \ | |
129 HS_DTRACE_PROBE1(hotspot_jni, name##__return, _ret_ref); \ | |
130 } \ | |
131 } \ | |
132 ) | |
133 // Void functions are simpler since there's no return value | |
134 #define DT_VOID_RETURN_MARK_DECL(name) \ | |
135 HS_DTRACE_PROBE_DECL0(hotspot_jni, name##__return); \ | |
136 DTRACE_ONLY( \ | |
137 class DTraceReturnProbeMark_##name { \ | |
138 public: \ | |
139 ~DTraceReturnProbeMark_##name() { \ | |
140 HS_DTRACE_PROBE0(hotspot_jni, name##__return); \ | |
141 } \ | |
142 } \ | |
143 ) | |
144 | |
4006 | 145 #else /* USDT2 */ |
146 | |
147 #define DT_RETURN_MARK_DECL(name, type, probe) \ | |
148 DTRACE_ONLY( \ | |
149 class DTraceReturnProbeMark_##name { \ | |
150 public: \ | |
151 const type& _ret_ref; \ | |
152 DTraceReturnProbeMark_##name(const type& v) : _ret_ref(v) {} \ | |
153 ~DTraceReturnProbeMark_##name() { \ | |
154 probe; \ | |
155 } \ | |
156 } \ | |
157 ) | |
158 // Void functions are simpler since there's no return value | |
159 #define DT_VOID_RETURN_MARK_DECL(name, probe) \ | |
160 DTRACE_ONLY( \ | |
161 class DTraceReturnProbeMark_##name { \ | |
162 public: \ | |
163 ~DTraceReturnProbeMark_##name() { \ | |
164 probe; \ | |
165 } \ | |
166 } \ | |
167 ) | |
168 #endif /* USDT2 */ | |
0 | 169 |
170 // Place these macros in the function to mark the return. Non-void | |
171 // functions need the type and address of the return value. | |
172 #define DT_RETURN_MARK(name, type, ref) \ | |
173 DTRACE_ONLY( DTraceReturnProbeMark_##name dtrace_return_mark(ref) ) | |
174 #define DT_VOID_RETURN_MARK(name) \ | |
175 DTRACE_ONLY( DTraceReturnProbeMark_##name dtrace_return_mark ) | |
176 | |
177 | |
178 // Use these to select distinct code for floating-point vs. non-floating point | |
179 // situations. Used from within common macros where we need slightly | |
180 // different behavior for Float/Double | |
181 #define FP_SELECT_Boolean(intcode, fpcode) intcode | |
182 #define FP_SELECT_Byte(intcode, fpcode) intcode | |
183 #define FP_SELECT_Char(intcode, fpcode) intcode | |
184 #define FP_SELECT_Short(intcode, fpcode) intcode | |
185 #define FP_SELECT_Object(intcode, fpcode) intcode | |
186 #define FP_SELECT_Int(intcode, fpcode) intcode | |
187 #define FP_SELECT_Long(intcode, fpcode) intcode | |
188 #define FP_SELECT_Float(intcode, fpcode) fpcode | |
189 #define FP_SELECT_Double(intcode, fpcode) fpcode | |
190 #define FP_SELECT(TypeName, intcode, fpcode) \ | |
191 FP_SELECT_##TypeName(intcode, fpcode) | |
192 | |
193 #define COMMA , | |
194 | |
195 // Choose DT_RETURN_MARK macros based on the type: float/double -> void | |
196 // (dtrace doesn't do FP yet) | |
4006 | 197 #ifndef USDT2 |
0 | 198 #define DT_RETURN_MARK_DECL_FOR(TypeName, name, type) \ |
199 FP_SELECT(TypeName, \ | |
200 DT_RETURN_MARK_DECL(name, type), DT_VOID_RETURN_MARK_DECL(name) ) | |
4006 | 201 #else /* USDT2 */ |
202 #define DT_RETURN_MARK_DECL_FOR(TypeName, name, type, probe) \ | |
203 FP_SELECT(TypeName, \ | |
204 DT_RETURN_MARK_DECL(name, type, probe), DT_VOID_RETURN_MARK_DECL(name, probe) ) | |
205 #endif /* USDT2 */ | |
0 | 206 #define DT_RETURN_MARK_FOR(TypeName, name, type, ref) \ |
207 FP_SELECT(TypeName, \ | |
208 DT_RETURN_MARK(name, type, ref), DT_VOID_RETURN_MARK(name) ) | |
209 | |
210 | |
211 // out-of-line helpers for class jfieldIDWorkaround: | |
212 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
213 bool jfieldIDWorkaround::is_valid_jfieldID(Klass* k, jfieldID id) { |
0 | 214 if (jfieldIDWorkaround::is_instance_jfieldID(k, id)) { |
215 uintptr_t as_uint = (uintptr_t) id; | |
216 intptr_t offset = raw_instance_offset(id); | |
217 if (is_checked_jfieldID(id)) { | |
218 if (!klass_hash_ok(k, id)) { | |
219 return false; | |
220 } | |
221 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
222 return InstanceKlass::cast(k)->contains_field_offset(offset); |
0 | 223 } else { |
224 JNIid* result = (JNIid*) id; | |
225 #ifdef ASSERT | |
226 return result != NULL && result->is_static_field_id(); | |
227 #else | |
228 return result != NULL; | |
229 #endif | |
230 } | |
231 } | |
232 | |
233 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
234 intptr_t jfieldIDWorkaround::encode_klass_hash(Klass* k, intptr_t offset) { |
0 | 235 if (offset <= small_offset_mask) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
236 Klass* field_klass = k; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
237 Klass* super_klass = Klass::cast(field_klass)->super(); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
238 // With compressed oops the most super class with nonstatic fields would |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
239 // be the owner of fields embedded in the header. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
240 while (InstanceKlass::cast(super_klass)->has_nonstatic_fields() && |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
241 InstanceKlass::cast(super_klass)->contains_field_offset(offset)) { |
0 | 242 field_klass = super_klass; // super contains the field also |
243 super_klass = Klass::cast(field_klass)->super(); | |
244 } | |
245 debug_only(No_Safepoint_Verifier nosafepoint;) | |
246 uintptr_t klass_hash = field_klass->identity_hash(); | |
247 return ((klass_hash & klass_mask) << klass_shift) | checked_mask_in_place; | |
248 } else { | |
249 #if 0 | |
250 #ifndef PRODUCT | |
251 { | |
252 ResourceMark rm; | |
253 warning("VerifyJNIFields: long offset %d in %s", offset, Klass::cast(k)->external_name()); | |
254 } | |
255 #endif | |
256 #endif | |
257 return 0; | |
258 } | |
259 } | |
260 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
261 bool jfieldIDWorkaround::klass_hash_ok(Klass* k, jfieldID id) { |
0 | 262 uintptr_t as_uint = (uintptr_t) id; |
263 intptr_t klass_hash = (as_uint >> klass_shift) & klass_mask; | |
264 do { | |
265 debug_only(No_Safepoint_Verifier nosafepoint;) | |
266 // Could use a non-blocking query for identity_hash here... | |
267 if ((k->identity_hash() & klass_mask) == klass_hash) | |
268 return true; | |
269 k = Klass::cast(k)->super(); | |
270 } while (k != NULL); | |
271 return false; | |
272 } | |
273 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
274 void jfieldIDWorkaround::verify_instance_jfieldID(Klass* k, jfieldID id) { |
0 | 275 guarantee(jfieldIDWorkaround::is_instance_jfieldID(k, id), "must be an instance field" ); |
276 uintptr_t as_uint = (uintptr_t) id; | |
277 intptr_t offset = raw_instance_offset(id); | |
278 if (VerifyJNIFields) { | |
279 if (is_checked_jfieldID(id)) { | |
280 guarantee(klass_hash_ok(k, id), | |
281 "Bug in native code: jfieldID class must match object"); | |
282 } else { | |
283 #if 0 | |
284 #ifndef PRODUCT | |
285 if (Verbose) { | |
286 ResourceMark rm; | |
287 warning("VerifyJNIFields: unverified offset %d for %s", offset, Klass::cast(k)->external_name()); | |
288 } | |
289 #endif | |
290 #endif | |
291 } | |
292 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
293 guarantee(InstanceKlass::cast(k)->contains_field_offset(offset), |
0 | 294 "Bug in native code: jfieldID offset must address interior of object"); |
295 } | |
296 | |
297 // Pick a reasonable higher bound for local capacity requested | |
298 // for EnsureLocalCapacity and PushLocalFrame. We don't want it too | |
299 // high because a test (or very unusual application) may try to allocate | |
300 // that many handles and run out of swap space. An implementation is | |
301 // permitted to allocate more handles than the ensured capacity, so this | |
302 // value is set high enough to prevent compatibility problems. | |
303 const int MAX_REASONABLE_LOCAL_CAPACITY = 4*K; | |
304 | |
305 | |
306 // Wrapper to trace JNI functions | |
307 | |
308 #ifdef ASSERT | |
309 Histogram* JNIHistogram; | |
310 static volatile jint JNIHistogram_lock = 0; | |
311 | |
312 class JNITraceWrapper : public StackObj { | |
313 public: | |
314 JNITraceWrapper(const char* format, ...) { | |
315 if (TraceJNICalls) { | |
316 va_list ap; | |
317 va_start(ap, format); | |
318 tty->print("JNI "); | |
319 tty->vprint_cr(format, ap); | |
320 va_end(ap); | |
321 } | |
322 } | |
323 }; | |
324 | |
325 class JNIHistogramElement : public HistogramElement { | |
326 public: | |
327 JNIHistogramElement(const char* name); | |
328 }; | |
329 | |
330 JNIHistogramElement::JNIHistogramElement(const char* elementName) { | |
331 _name = elementName; | |
332 uintx count = 0; | |
333 | |
334 while (Atomic::cmpxchg(1, &JNIHistogram_lock, 0) != 0) { | |
335 while (OrderAccess::load_acquire(&JNIHistogram_lock) != 0) { | |
336 count +=1; | |
337 if ( (WarnOnStalledSpinLock > 0) | |
338 && (count % WarnOnStalledSpinLock == 0)) { | |
339 warning("JNIHistogram_lock seems to be stalled"); | |
340 } | |
341 } | |
342 } | |
343 | |
344 | |
345 if(JNIHistogram == NULL) | |
346 JNIHistogram = new Histogram("JNI Call Counts",100); | |
347 | |
348 JNIHistogram->add_element(this); | |
349 Atomic::dec(&JNIHistogram_lock); | |
350 } | |
351 | |
352 #define JNICountWrapper(arg) \ | |
353 static JNIHistogramElement* e = new JNIHistogramElement(arg); \ | |
354 /* There is a MT-race condition in VC++. So we need to make sure that that e has been initialized */ \ | |
355 if (e != NULL) e->increment_count() | |
356 #define JNIWrapper(arg) JNICountWrapper(arg); JNITraceWrapper(arg) | |
357 #else | |
358 #define JNIWrapper(arg) | |
359 #endif | |
360 | |
361 | |
362 // Implementation of JNI entries | |
363 | |
4006 | 364 #ifndef USDT2 |
0 | 365 DT_RETURN_MARK_DECL(DefineClass, jclass); |
4006 | 366 #else /* USDT2 */ |
367 DT_RETURN_MARK_DECL(DefineClass, jclass | |
368 , HOTSPOT_JNI_DEFINECLASS_RETURN(_ret_ref)); | |
369 #endif /* USDT2 */ | |
0 | 370 |
371 JNI_ENTRY(jclass, jni_DefineClass(JNIEnv *env, const char *name, jobject loaderRef, | |
372 const jbyte *buf, jsize bufLen)) | |
373 JNIWrapper("DefineClass"); | |
374 | |
4006 | 375 #ifndef USDT2 |
0 | 376 DTRACE_PROBE5(hotspot_jni, DefineClass__entry, |
377 env, name, loaderRef, buf, bufLen); | |
4006 | 378 #else /* USDT2 */ |
379 HOTSPOT_JNI_DEFINECLASS_ENTRY( | |
380 env, (char*) name, loaderRef, (char*) buf, bufLen); | |
381 #endif /* USDT2 */ | |
0 | 382 jclass cls = NULL; |
383 DT_RETURN_MARK(DefineClass, jclass, (const jclass&)cls); | |
384 | |
6125
dcfcdd01af4b
7171703: JNI DefineClass crashes client VM when first parameter is NULL
fparain
parents:
4800
diff
changeset
|
385 TempNewSymbol class_name = NULL; |
0 | 386 // Since exceptions can be thrown, class initialization can take place |
387 // if name is NULL no check for class name in .class stream has to be made. | |
388 if (name != NULL) { | |
389 const int str_len = (int)strlen(name); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
390 if (str_len > Symbol::max_length()) { |
0 | 391 // It's impossible to create this class; the name cannot fit |
392 // into the constant pool. | |
393 THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name); | |
394 } | |
6125
dcfcdd01af4b
7171703: JNI DefineClass crashes client VM when first parameter is NULL
fparain
parents:
4800
diff
changeset
|
395 class_name = SymbolTable::new_symbol(name, CHECK_NULL); |
0 | 396 } |
397 ResourceMark rm(THREAD); | |
398 ClassFileStream st((u1*) buf, bufLen, NULL); | |
399 Handle class_loader (THREAD, JNIHandles::resolve(loaderRef)); | |
400 | |
401 if (UsePerfData && !class_loader.is_null()) { | |
402 // check whether the current caller thread holds the lock or not. | |
403 // If not, increment the corresponding counter | |
404 if (ObjectSynchronizer:: | |
405 query_lock_ownership((JavaThread*)THREAD, class_loader) != | |
406 ObjectSynchronizer::owner_self) { | |
407 ClassLoader::sync_JNIDefineClassLockFreeCounter()->inc(); | |
408 } | |
409 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
410 Klass* k = SystemDictionary::resolve_from_stream(class_name, class_loader, |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
657
diff
changeset
|
411 Handle(), &st, true, |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
657
diff
changeset
|
412 CHECK_NULL); |
0 | 413 |
657
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
414 if (TraceClassResolution && k != NULL) { |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
415 trace_class_resolution(k); |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
416 } |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
417 |
0 | 418 cls = (jclass)JNIHandles::make_local( |
419 env, Klass::cast(k)->java_mirror()); | |
420 return cls; | |
421 JNI_END | |
422 | |
423 | |
424 | |
425 static bool first_time_FindClass = true; | |
426 | |
4006 | 427 #ifndef USDT2 |
0 | 428 DT_RETURN_MARK_DECL(FindClass, jclass); |
4006 | 429 #else /* USDT2 */ |
430 DT_RETURN_MARK_DECL(FindClass, jclass | |
431 , HOTSPOT_JNI_FINDCLASS_RETURN(_ret_ref)); | |
432 #endif /* USDT2 */ | |
0 | 433 |
434 JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name)) | |
435 JNIWrapper("FindClass"); | |
4006 | 436 #ifndef USDT2 |
0 | 437 DTRACE_PROBE2(hotspot_jni, FindClass__entry, env, name); |
4006 | 438 #else /* USDT2 */ |
439 HOTSPOT_JNI_FINDCLASS_ENTRY( | |
440 env, (char *)name); | |
441 #endif /* USDT2 */ | |
0 | 442 |
443 jclass result = NULL; | |
444 DT_RETURN_MARK(FindClass, jclass, (const jclass&)result); | |
445 | |
446 // Remember if we are the first invocation of jni_FindClass | |
447 bool first_time = first_time_FindClass; | |
448 first_time_FindClass = false; | |
449 | |
450 // Sanity check the name: it cannot be null or larger than the maximum size | |
451 // name we can fit in the constant pool. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
452 if (name == NULL || (int)strlen(name) > Symbol::max_length()) { |
0 | 453 THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name); |
454 } | |
455 | |
456 //%note jni_3 | |
457 Handle loader; | |
458 Handle protection_domain; | |
459 // Find calling class | |
460 instanceKlassHandle k (THREAD, thread->security_get_caller_class(0)); | |
461 if (k.not_null()) { | |
462 loader = Handle(THREAD, k->class_loader()); | |
463 // Special handling to make sure JNI_OnLoad and JNI_OnUnload are executed | |
464 // in the correct class context. | |
465 if (loader.is_null() && | |
466 k->name() == vmSymbols::java_lang_ClassLoader_NativeLibrary()) { | |
467 JavaValue result(T_OBJECT); | |
468 JavaCalls::call_static(&result, k, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
469 vmSymbols::getFromClass_name(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
470 vmSymbols::void_class_signature(), |
0 | 471 thread); |
472 if (HAS_PENDING_EXCEPTION) { | |
473 Handle ex(thread, thread->pending_exception()); | |
474 CLEAR_PENDING_EXCEPTION; | |
475 THROW_HANDLE_0(ex); | |
476 } | |
477 oop mirror = (oop) result.get_jobject(); | |
478 loader = Handle(THREAD, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
479 InstanceKlass::cast(java_lang_Class::as_Klass(mirror))->class_loader()); |
0 | 480 protection_domain = Handle(THREAD, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
481 InstanceKlass::cast(java_lang_Class::as_Klass(mirror))->protection_domain()); |
0 | 482 } |
483 } else { | |
484 // We call ClassLoader.getSystemClassLoader to obtain the system class loader. | |
485 loader = Handle(THREAD, SystemDictionary::java_system_loader()); | |
486 } | |
487 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
488 TempNewSymbol sym = SymbolTable::new_symbol(name, CHECK_NULL); |
0 | 489 result = find_class_from_class_loader(env, sym, true, loader, |
490 protection_domain, true, thread); | |
491 | |
657
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
492 if (TraceClassResolution && result != NULL) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
493 trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result))); |
657
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
494 } |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
495 |
0 | 496 // If we were the first invocation of jni_FindClass, we enable compilation again |
497 // rather than just allowing invocation counter to overflow and decay. | |
498 // Controlled by flag DelayCompilationDuringStartup. | |
499 if (first_time && !CompileTheWorld) | |
500 CompilationPolicy::completed_vm_startup(); | |
501 | |
502 return result; | |
503 JNI_END | |
504 | |
4006 | 505 #ifndef USDT2 |
0 | 506 DT_RETURN_MARK_DECL(FromReflectedMethod, jmethodID); |
4006 | 507 #else /* USDT2 */ |
508 DT_RETURN_MARK_DECL(FromReflectedMethod, jmethodID | |
509 , HOTSPOT_JNI_FROMREFLECTEDMETHOD_RETURN((uintptr_t)_ret_ref)); | |
510 #endif /* USDT2 */ | |
0 | 511 |
512 JNI_ENTRY(jmethodID, jni_FromReflectedMethod(JNIEnv *env, jobject method)) | |
513 JNIWrapper("FromReflectedMethod"); | |
4006 | 514 #ifndef USDT2 |
0 | 515 DTRACE_PROBE2(hotspot_jni, FromReflectedMethod__entry, env, method); |
4006 | 516 #else /* USDT2 */ |
517 HOTSPOT_JNI_FROMREFLECTEDMETHOD_ENTRY( | |
518 env, method); | |
519 #endif /* USDT2 */ | |
0 | 520 jmethodID ret = NULL; |
521 DT_RETURN_MARK(FromReflectedMethod, jmethodID, (const jmethodID&)ret); | |
522 | |
523 // method is a handle to a java.lang.reflect.Method object | |
524 oop reflected = JNIHandles::resolve_non_null(method); | |
525 oop mirror = NULL; | |
526 int slot = 0; | |
527 | |
1142 | 528 if (reflected->klass() == SystemDictionary::reflect_Constructor_klass()) { |
0 | 529 mirror = java_lang_reflect_Constructor::clazz(reflected); |
530 slot = java_lang_reflect_Constructor::slot(reflected); | |
531 } else { | |
1142 | 532 assert(reflected->klass() == SystemDictionary::reflect_Method_klass(), "wrong type"); |
0 | 533 mirror = java_lang_reflect_Method::clazz(reflected); |
534 slot = java_lang_reflect_Method::slot(reflected); | |
535 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
536 Klass* k = java_lang_Class::as_Klass(mirror); |
0 | 537 |
538 KlassHandle k1(THREAD, k); | |
539 // Make sure class is initialized before handing id's out to methods | |
540 Klass::cast(k1())->initialize(CHECK_NULL); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
541 Method* m = InstanceKlass::cast(k1())->method_with_idnum(slot); |
0 | 542 ret = m==NULL? NULL : m->jmethod_id(); // return NULL if reflected method deleted |
543 return ret; | |
544 JNI_END | |
545 | |
4006 | 546 #ifndef USDT2 |
0 | 547 DT_RETURN_MARK_DECL(FromReflectedField, jfieldID); |
4006 | 548 #else /* USDT2 */ |
549 DT_RETURN_MARK_DECL(FromReflectedField, jfieldID | |
550 , HOTSPOT_JNI_FROMREFLECTEDFIELD_RETURN((uintptr_t)_ret_ref)); | |
551 #endif /* USDT2 */ | |
0 | 552 |
553 JNI_ENTRY(jfieldID, jni_FromReflectedField(JNIEnv *env, jobject field)) | |
554 JNIWrapper("FromReflectedField"); | |
4006 | 555 #ifndef USDT2 |
0 | 556 DTRACE_PROBE2(hotspot_jni, FromReflectedField__entry, env, field); |
4006 | 557 #else /* USDT2 */ |
558 HOTSPOT_JNI_FROMREFLECTEDFIELD_ENTRY( | |
559 env, field); | |
560 #endif /* USDT2 */ | |
0 | 561 jfieldID ret = NULL; |
562 DT_RETURN_MARK(FromReflectedField, jfieldID, (const jfieldID&)ret); | |
563 | |
564 // field is a handle to a java.lang.reflect.Field object | |
565 oop reflected = JNIHandles::resolve_non_null(field); | |
566 oop mirror = java_lang_reflect_Field::clazz(reflected); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
567 Klass* k = java_lang_Class::as_Klass(mirror); |
0 | 568 int slot = java_lang_reflect_Field::slot(reflected); |
569 int modifiers = java_lang_reflect_Field::modifiers(reflected); | |
570 | |
571 KlassHandle k1(THREAD, k); | |
572 // Make sure class is initialized before handing id's out to fields | |
573 Klass::cast(k1())->initialize(CHECK_NULL); | |
574 | |
575 // First check if this is a static field | |
576 if (modifiers & JVM_ACC_STATIC) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
577 intptr_t offset = InstanceKlass::cast(k1())->field_offset( slot ); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
578 JNIid* id = InstanceKlass::cast(k1())->jni_id_for(offset); |
0 | 579 assert(id != NULL, "corrupt Field object"); |
580 debug_only(id->set_is_static_field_id();) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
581 // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass* |
0 | 582 ret = jfieldIDWorkaround::to_static_jfieldID(id); |
583 return ret; | |
584 } | |
585 | |
586 // The slot is the index of the field description in the field-array | |
587 // The jfieldID is the offset of the field within the object | |
588 // It may also have hash bits for k, if VerifyJNIFields is turned on. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
589 intptr_t offset = InstanceKlass::cast(k1())->field_offset( slot ); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
590 assert(InstanceKlass::cast(k1())->contains_field_offset(offset), "stay within object"); |
0 | 591 ret = jfieldIDWorkaround::to_instance_jfieldID(k1(), offset); |
592 return ret; | |
593 JNI_END | |
594 | |
4006 | 595 #ifndef USDT2 |
0 | 596 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject); |
4006 | 597 #else /* USDT2 */ |
598 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject | |
599 , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref)); | |
600 #endif /* USDT2 */ | |
0 | 601 |
602 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic)) | |
603 JNIWrapper("ToReflectedMethod"); | |
4006 | 604 #ifndef USDT2 |
0 | 605 DTRACE_PROBE4(hotspot_jni, ToReflectedMethod__entry, env, cls, method_id, isStatic); |
4006 | 606 #else /* USDT2 */ |
607 HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY( | |
608 env, cls, (uintptr_t) method_id, isStatic); | |
609 #endif /* USDT2 */ | |
0 | 610 jobject ret = NULL; |
611 DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret); | |
612 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
613 methodHandle m (THREAD, Method::resolve_jmethod_id(method_id)); |
0 | 614 assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match"); |
615 oop reflection_method; | |
616 if (m->is_initializer()) { | |
617 reflection_method = Reflection::new_constructor(m, CHECK_NULL); | |
618 } else { | |
619 reflection_method = Reflection::new_method(m, UseNewReflection, false, CHECK_NULL); | |
620 } | |
621 ret = JNIHandles::make_local(env, reflection_method); | |
622 return ret; | |
623 JNI_END | |
624 | |
4006 | 625 #ifndef USDT2 |
0 | 626 DT_RETURN_MARK_DECL(GetSuperclass, jclass); |
4006 | 627 #else /* USDT2 */ |
628 DT_RETURN_MARK_DECL(GetSuperclass, jclass | |
629 , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref)); | |
630 #endif /* USDT2 */ | |
0 | 631 |
632 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub)) | |
633 JNIWrapper("GetSuperclass"); | |
4006 | 634 #ifndef USDT2 |
0 | 635 DTRACE_PROBE2(hotspot_jni, GetSuperclass__entry, env, sub); |
4006 | 636 #else /* USDT2 */ |
637 HOTSPOT_JNI_GETSUPERCLASS_ENTRY( | |
638 env, sub); | |
639 #endif /* USDT2 */ | |
0 | 640 jclass obj = NULL; |
641 DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj); | |
642 | |
643 oop mirror = JNIHandles::resolve_non_null(sub); | |
644 // primitive classes return NULL | |
645 if (java_lang_Class::is_primitive(mirror)) return NULL; | |
646 | |
647 // Rules of Class.getSuperClass as implemented by KLass::java_super: | |
648 // arrays return Object | |
649 // interfaces return NULL | |
650 // proper classes return Klass::super() | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
651 Klass* k = java_lang_Class::as_Klass(mirror); |
0 | 652 if (Klass::cast(k)->is_interface()) return NULL; |
653 | |
654 // return mirror for superclass | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
655 Klass* super = Klass::cast(k)->java_super(); |
0 | 656 // super2 is the value computed by the compiler's getSuperClass intrinsic: |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
657 debug_only(Klass* super2 = ( Klass::cast(k)->oop_is_array() |
1142 | 658 ? SystemDictionary::Object_klass() |
0 | 659 : Klass::cast(k)->super() ) ); |
660 assert(super == super2, | |
661 "java_super computation depends on interface, array, other super"); | |
662 obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(Klass::cast(super)->java_mirror()); | |
663 return obj; | |
664 JNI_END | |
665 | |
666 JNI_QUICK_ENTRY(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super)) | |
667 JNIWrapper("IsSubclassOf"); | |
4006 | 668 #ifndef USDT2 |
0 | 669 DTRACE_PROBE3(hotspot_jni, IsAssignableFrom__entry, env, sub, super); |
4006 | 670 #else /* USDT2 */ |
671 HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY( | |
672 env, sub, super); | |
673 #endif /* USDT2 */ | |
0 | 674 oop sub_mirror = JNIHandles::resolve_non_null(sub); |
675 oop super_mirror = JNIHandles::resolve_non_null(super); | |
676 if (java_lang_Class::is_primitive(sub_mirror) || | |
677 java_lang_Class::is_primitive(super_mirror)) { | |
678 jboolean ret = (sub_mirror == super_mirror); | |
4006 | 679 #ifndef USDT2 |
0 | 680 DTRACE_PROBE1(hotspot_jni, IsAssignableFrom__return, ret); |
4006 | 681 #else /* USDT2 */ |
682 HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN( | |
683 ret); | |
684 #endif /* USDT2 */ | |
0 | 685 return ret; |
686 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
687 Klass* sub_klass = java_lang_Class::as_Klass(sub_mirror); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
688 Klass* super_klass = java_lang_Class::as_Klass(super_mirror); |
0 | 689 assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom"); |
690 jboolean ret = Klass::cast(sub_klass)->is_subtype_of(super_klass) ? | |
691 JNI_TRUE : JNI_FALSE; | |
4006 | 692 #ifndef USDT2 |
0 | 693 DTRACE_PROBE1(hotspot_jni, IsAssignableFrom__return, ret); |
4006 | 694 #else /* USDT2 */ |
695 HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN( | |
696 ret); | |
697 #endif /* USDT2 */ | |
0 | 698 return ret; |
699 JNI_END | |
700 | |
4006 | 701 #ifndef USDT2 |
0 | 702 DT_RETURN_MARK_DECL(Throw, jint); |
4006 | 703 #else /* USDT2 */ |
704 DT_RETURN_MARK_DECL(Throw, jint | |
705 , HOTSPOT_JNI_THROW_RETURN(_ret_ref)); | |
706 #endif /* USDT2 */ | |
0 | 707 |
708 JNI_ENTRY(jint, jni_Throw(JNIEnv *env, jthrowable obj)) | |
709 JNIWrapper("Throw"); | |
4006 | 710 #ifndef USDT2 |
0 | 711 DTRACE_PROBE2(hotspot_jni, Throw__entry, env, obj); |
4006 | 712 #else /* USDT2 */ |
713 HOTSPOT_JNI_THROW_ENTRY( | |
714 env, obj); | |
715 #endif /* USDT2 */ | |
0 | 716 jint ret = JNI_OK; |
717 DT_RETURN_MARK(Throw, jint, (const jint&)ret); | |
718 | |
719 THROW_OOP_(JNIHandles::resolve(obj), JNI_OK); | |
720 ShouldNotReachHere(); | |
721 JNI_END | |
722 | |
4006 | 723 #ifndef USDT2 |
0 | 724 DT_RETURN_MARK_DECL(ThrowNew, jint); |
4006 | 725 #else /* USDT2 */ |
726 DT_RETURN_MARK_DECL(ThrowNew, jint | |
727 , HOTSPOT_JNI_THROWNEW_RETURN(_ret_ref)); | |
728 #endif /* USDT2 */ | |
0 | 729 |
730 JNI_ENTRY(jint, jni_ThrowNew(JNIEnv *env, jclass clazz, const char *message)) | |
731 JNIWrapper("ThrowNew"); | |
4006 | 732 #ifndef USDT2 |
0 | 733 DTRACE_PROBE3(hotspot_jni, ThrowNew__entry, env, clazz, message); |
4006 | 734 #else /* USDT2 */ |
735 HOTSPOT_JNI_THROWNEW_ENTRY( | |
736 env, clazz, (char *) message); | |
737 #endif /* USDT2 */ | |
0 | 738 jint ret = JNI_OK; |
739 DT_RETURN_MARK(ThrowNew, jint, (const jint&)ret); | |
740 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
741 InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
742 Symbol* name = k->name(); |
0 | 743 Handle class_loader (THREAD, k->class_loader()); |
744 Handle protection_domain (THREAD, k->protection_domain()); | |
745 THROW_MSG_LOADER_(name, (char *)message, class_loader, protection_domain, JNI_OK); | |
746 ShouldNotReachHere(); | |
747 JNI_END | |
748 | |
749 | |
750 // JNI functions only transform a pending async exception to a synchronous | |
751 // exception in ExceptionOccurred and ExceptionCheck calls, since | |
752 // delivering an async exception in other places won't change the native | |
753 // code's control flow and would be harmful when native code further calls | |
754 // JNI functions with a pending exception. Async exception is also checked | |
755 // during the call, so ExceptionOccurred/ExceptionCheck won't return | |
756 // false but deliver the async exception at the very end during | |
757 // state transition. | |
758 | |
759 static void jni_check_async_exceptions(JavaThread *thread) { | |
760 assert(thread == Thread::current(), "must be itself"); | |
761 thread->check_and_handle_async_exceptions(); | |
762 } | |
763 | |
764 JNI_ENTRY_NO_PRESERVE(jthrowable, jni_ExceptionOccurred(JNIEnv *env)) | |
765 JNIWrapper("ExceptionOccurred"); | |
4006 | 766 #ifndef USDT2 |
0 | 767 DTRACE_PROBE1(hotspot_jni, ExceptionOccurred__entry, env); |
4006 | 768 #else /* USDT2 */ |
769 HOTSPOT_JNI_EXCEPTIONOCCURRED_ENTRY( | |
770 env); | |
771 #endif /* USDT2 */ | |
0 | 772 jni_check_async_exceptions(thread); |
773 oop exception = thread->pending_exception(); | |
774 jthrowable ret = (jthrowable) JNIHandles::make_local(env, exception); | |
4006 | 775 #ifndef USDT2 |
0 | 776 DTRACE_PROBE1(hotspot_jni, ExceptionOccurred__return, ret); |
4006 | 777 #else /* USDT2 */ |
778 HOTSPOT_JNI_EXCEPTIONOCCURRED_RETURN( | |
779 ret); | |
780 #endif /* USDT2 */ | |
0 | 781 return ret; |
782 JNI_END | |
783 | |
784 | |
785 JNI_ENTRY_NO_PRESERVE(void, jni_ExceptionDescribe(JNIEnv *env)) | |
786 JNIWrapper("ExceptionDescribe"); | |
4006 | 787 #ifndef USDT2 |
0 | 788 DTRACE_PROBE1(hotspot_jni, ExceptionDescribe__entry, env); |
4006 | 789 #else /* USDT2 */ |
790 HOTSPOT_JNI_EXCEPTIONDESCRIBE_ENTRY( | |
791 env); | |
792 #endif /* USDT2 */ | |
0 | 793 if (thread->has_pending_exception()) { |
794 Handle ex(thread, thread->pending_exception()); | |
795 thread->clear_pending_exception(); | |
1142 | 796 if (ex->is_a(SystemDictionary::ThreadDeath_klass())) { |
0 | 797 // Don't print anything if we are being killed. |
798 } else { | |
799 jio_fprintf(defaultStream::error_stream(), "Exception "); | |
800 if (thread != NULL && thread->threadObj() != NULL) { | |
801 ResourceMark rm(THREAD); | |
802 jio_fprintf(defaultStream::error_stream(), | |
803 "in thread \"%s\" ", thread->get_thread_name()); | |
804 } | |
1142 | 805 if (ex->is_a(SystemDictionary::Throwable_klass())) { |
0 | 806 JavaValue result(T_VOID); |
807 JavaCalls::call_virtual(&result, | |
808 ex, | |
809 KlassHandle(THREAD, | |
1142 | 810 SystemDictionary::Throwable_klass()), |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
811 vmSymbols::printStackTrace_name(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
812 vmSymbols::void_method_signature(), |
0 | 813 THREAD); |
814 // If an exception is thrown in the call it gets thrown away. Not much | |
815 // we can do with it. The native code that calls this, does not check | |
816 // for the exception - hence, it might still be in the thread when DestroyVM gets | |
817 // called, potentially causing a few asserts to trigger - since no pending exception | |
818 // is expected. | |
819 CLEAR_PENDING_EXCEPTION; | |
820 } else { | |
821 ResourceMark rm(THREAD); | |
822 jio_fprintf(defaultStream::error_stream(), | |
823 ". Uncaught exception of type %s.", | |
824 Klass::cast(ex->klass())->external_name()); | |
825 } | |
826 } | |
827 } | |
4006 | 828 #ifndef USDT2 |
0 | 829 DTRACE_PROBE(hotspot_jni, ExceptionDescribe__return); |
4006 | 830 #else /* USDT2 */ |
831 HOTSPOT_JNI_EXCEPTIONDESCRIBE_RETURN( | |
832 ); | |
833 #endif /* USDT2 */ | |
0 | 834 JNI_END |
835 | |
836 | |
837 JNI_QUICK_ENTRY(void, jni_ExceptionClear(JNIEnv *env)) | |
838 JNIWrapper("ExceptionClear"); | |
4006 | 839 #ifndef USDT2 |
0 | 840 DTRACE_PROBE1(hotspot_jni, ExceptionClear__entry, env); |
4006 | 841 #else /* USDT2 */ |
842 HOTSPOT_JNI_EXCEPTIONCLEAR_ENTRY( | |
843 env); | |
844 #endif /* USDT2 */ | |
0 | 845 |
846 // The jni code might be using this API to clear java thrown exception. | |
847 // So just mark jvmti thread exception state as exception caught. | |
848 JvmtiThreadState *state = JavaThread::current()->jvmti_thread_state(); | |
849 if (state != NULL && state->is_exception_detected()) { | |
850 state->set_exception_caught(); | |
851 } | |
852 thread->clear_pending_exception(); | |
4006 | 853 #ifndef USDT2 |
0 | 854 DTRACE_PROBE(hotspot_jni, ExceptionClear__return); |
4006 | 855 #else /* USDT2 */ |
856 HOTSPOT_JNI_EXCEPTIONCLEAR_RETURN( | |
857 ); | |
858 #endif /* USDT2 */ | |
0 | 859 JNI_END |
860 | |
861 | |
862 JNI_ENTRY(void, jni_FatalError(JNIEnv *env, const char *msg)) | |
863 JNIWrapper("FatalError"); | |
4006 | 864 #ifndef USDT2 |
0 | 865 DTRACE_PROBE2(hotspot_jni, FatalError__entry, env, msg); |
4006 | 866 #else /* USDT2 */ |
867 HOTSPOT_JNI_FATALERROR_ENTRY( | |
868 env, (char *) msg); | |
869 #endif /* USDT2 */ | |
0 | 870 tty->print_cr("FATAL ERROR in native method: %s", msg); |
871 thread->print_stack(); | |
227
8d852b81e775
6694099: Hotspot vm_exit_out_of_memory should dump core
poonam
parents:
113
diff
changeset
|
872 os::abort(); // Dump core and abort |
0 | 873 JNI_END |
874 | |
875 | |
876 JNI_ENTRY(jint, jni_PushLocalFrame(JNIEnv *env, jint capacity)) | |
877 JNIWrapper("PushLocalFrame"); | |
4006 | 878 #ifndef USDT2 |
0 | 879 DTRACE_PROBE2(hotspot_jni, PushLocalFrame__entry, env, capacity); |
4006 | 880 #else /* USDT2 */ |
881 HOTSPOT_JNI_PUSHLOCALFRAME_ENTRY( | |
882 env, capacity); | |
883 #endif /* USDT2 */ | |
0 | 884 //%note jni_11 |
885 if (capacity < 0 && capacity > MAX_REASONABLE_LOCAL_CAPACITY) { | |
4006 | 886 #ifndef USDT2 |
0 | 887 DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, JNI_ERR); |
4006 | 888 #else /* USDT2 */ |
889 HOTSPOT_JNI_PUSHLOCALFRAME_RETURN( | |
890 (uint32_t)JNI_ERR); | |
891 #endif /* USDT2 */ | |
0 | 892 return JNI_ERR; |
893 } | |
894 JNIHandleBlock* old_handles = thread->active_handles(); | |
895 JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread); | |
896 assert(new_handles != NULL, "should not be NULL"); | |
897 new_handles->set_pop_frame_link(old_handles); | |
898 thread->set_active_handles(new_handles); | |
899 jint ret = JNI_OK; | |
4006 | 900 #ifndef USDT2 |
0 | 901 DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, ret); |
4006 | 902 #else /* USDT2 */ |
903 HOTSPOT_JNI_PUSHLOCALFRAME_RETURN( | |
904 ret); | |
905 #endif /* USDT2 */ | |
0 | 906 return ret; |
907 JNI_END | |
908 | |
909 | |
910 JNI_ENTRY(jobject, jni_PopLocalFrame(JNIEnv *env, jobject result)) | |
911 JNIWrapper("PopLocalFrame"); | |
4006 | 912 #ifndef USDT2 |
0 | 913 DTRACE_PROBE2(hotspot_jni, PopLocalFrame__entry, env, result); |
4006 | 914 #else /* USDT2 */ |
915 HOTSPOT_JNI_POPLOCALFRAME_ENTRY( | |
916 env, result); | |
917 #endif /* USDT2 */ | |
0 | 918 //%note jni_11 |
919 Handle result_handle(thread, JNIHandles::resolve(result)); | |
920 JNIHandleBlock* old_handles = thread->active_handles(); | |
921 JNIHandleBlock* new_handles = old_handles->pop_frame_link(); | |
922 if (new_handles != NULL) { | |
923 // As a sanity check we only release the handle blocks if the pop_frame_link is not NULL. | |
924 // This way code will still work if PopLocalFrame is called without a corresponding | |
925 // PushLocalFrame call. Note that we set the pop_frame_link to NULL explicitly, otherwise | |
926 // the release_block call will release the blocks. | |
927 thread->set_active_handles(new_handles); | |
928 old_handles->set_pop_frame_link(NULL); // clear link we won't release new_handles below | |
929 JNIHandleBlock::release_block(old_handles, thread); // may block | |
930 result = JNIHandles::make_local(thread, result_handle()); | |
931 } | |
4006 | 932 #ifndef USDT2 |
0 | 933 DTRACE_PROBE1(hotspot_jni, PopLocalFrame__return, result); |
4006 | 934 #else /* USDT2 */ |
935 HOTSPOT_JNI_POPLOCALFRAME_RETURN( | |
936 result); | |
937 #endif /* USDT2 */ | |
0 | 938 return result; |
939 JNI_END | |
940 | |
941 | |
942 JNI_ENTRY(jobject, jni_NewGlobalRef(JNIEnv *env, jobject ref)) | |
943 JNIWrapper("NewGlobalRef"); | |
4006 | 944 #ifndef USDT2 |
0 | 945 DTRACE_PROBE2(hotspot_jni, NewGlobalRef__entry, env, ref); |
4006 | 946 #else /* USDT2 */ |
947 HOTSPOT_JNI_NEWGLOBALREF_ENTRY( | |
948 env, ref); | |
949 #endif /* USDT2 */ | |
0 | 950 Handle ref_handle(thread, JNIHandles::resolve(ref)); |
951 jobject ret = JNIHandles::make_global(ref_handle); | |
4006 | 952 #ifndef USDT2 |
0 | 953 DTRACE_PROBE1(hotspot_jni, NewGlobalRef__return, ret); |
4006 | 954 #else /* USDT2 */ |
955 HOTSPOT_JNI_NEWGLOBALREF_RETURN( | |
956 ret); | |
957 #endif /* USDT2 */ | |
0 | 958 return ret; |
959 JNI_END | |
960 | |
961 // Must be JNI_ENTRY (with HandleMark) | |
962 JNI_ENTRY_NO_PRESERVE(void, jni_DeleteGlobalRef(JNIEnv *env, jobject ref)) | |
963 JNIWrapper("DeleteGlobalRef"); | |
4006 | 964 #ifndef USDT2 |
0 | 965 DTRACE_PROBE2(hotspot_jni, DeleteGlobalRef__entry, env, ref); |
4006 | 966 #else /* USDT2 */ |
967 HOTSPOT_JNI_DELETEGLOBALREF_ENTRY( | |
968 env, ref); | |
969 #endif /* USDT2 */ | |
0 | 970 JNIHandles::destroy_global(ref); |
4006 | 971 #ifndef USDT2 |
0 | 972 DTRACE_PROBE(hotspot_jni, DeleteGlobalRef__return); |
4006 | 973 #else /* USDT2 */ |
974 HOTSPOT_JNI_DELETEGLOBALREF_RETURN( | |
975 ); | |
976 #endif /* USDT2 */ | |
0 | 977 JNI_END |
978 | |
979 JNI_QUICK_ENTRY(void, jni_DeleteLocalRef(JNIEnv *env, jobject obj)) | |
980 JNIWrapper("DeleteLocalRef"); | |
4006 | 981 #ifndef USDT2 |
0 | 982 DTRACE_PROBE2(hotspot_jni, DeleteLocalRef__entry, env, obj); |
4006 | 983 #else /* USDT2 */ |
984 HOTSPOT_JNI_DELETELOCALREF_ENTRY( | |
985 env, obj); | |
986 #endif /* USDT2 */ | |
0 | 987 JNIHandles::destroy_local(obj); |
4006 | 988 #ifndef USDT2 |
0 | 989 DTRACE_PROBE(hotspot_jni, DeleteLocalRef__return); |
4006 | 990 #else /* USDT2 */ |
991 HOTSPOT_JNI_DELETELOCALREF_RETURN( | |
992 ); | |
993 #endif /* USDT2 */ | |
0 | 994 JNI_END |
995 | |
996 JNI_QUICK_ENTRY(jboolean, jni_IsSameObject(JNIEnv *env, jobject r1, jobject r2)) | |
997 JNIWrapper("IsSameObject"); | |
4006 | 998 #ifndef USDT2 |
0 | 999 DTRACE_PROBE3(hotspot_jni, IsSameObject__entry, env, r1, r2); |
4006 | 1000 #else /* USDT2 */ |
1001 HOTSPOT_JNI_ISSAMEOBJECT_ENTRY( | |
1002 env, r1, r2); | |
1003 #endif /* USDT2 */ | |
0 | 1004 oop a = JNIHandles::resolve(r1); |
1005 oop b = JNIHandles::resolve(r2); | |
1006 jboolean ret = (a == b) ? JNI_TRUE : JNI_FALSE; | |
4006 | 1007 #ifndef USDT2 |
0 | 1008 DTRACE_PROBE1(hotspot_jni, IsSameObject__return, ret); |
4006 | 1009 #else /* USDT2 */ |
1010 HOTSPOT_JNI_ISSAMEOBJECT_RETURN( | |
1011 ret); | |
1012 #endif /* USDT2 */ | |
0 | 1013 return ret; |
1014 JNI_END | |
1015 | |
1016 | |
1017 JNI_ENTRY(jobject, jni_NewLocalRef(JNIEnv *env, jobject ref)) | |
1018 JNIWrapper("NewLocalRef"); | |
4006 | 1019 #ifndef USDT2 |
0 | 1020 DTRACE_PROBE2(hotspot_jni, NewLocalRef__entry, env, ref); |
4006 | 1021 #else /* USDT2 */ |
1022 HOTSPOT_JNI_NEWLOCALREF_ENTRY( | |
1023 env, ref); | |
1024 #endif /* USDT2 */ | |
0 | 1025 jobject ret = JNIHandles::make_local(env, JNIHandles::resolve(ref)); |
4006 | 1026 #ifndef USDT2 |
0 | 1027 DTRACE_PROBE1(hotspot_jni, NewLocalRef__return, ret); |
4006 | 1028 #else /* USDT2 */ |
1029 HOTSPOT_JNI_NEWLOCALREF_RETURN( | |
1030 ret); | |
1031 #endif /* USDT2 */ | |
0 | 1032 return ret; |
1033 JNI_END | |
1034 | |
1035 JNI_LEAF(jint, jni_EnsureLocalCapacity(JNIEnv *env, jint capacity)) | |
1036 JNIWrapper("EnsureLocalCapacity"); | |
4006 | 1037 #ifndef USDT2 |
0 | 1038 DTRACE_PROBE2(hotspot_jni, EnsureLocalCapacity__entry, env, capacity); |
4006 | 1039 #else /* USDT2 */ |
1040 HOTSPOT_JNI_ENSURELOCALCAPACITY_ENTRY( | |
1041 env, capacity); | |
1042 #endif /* USDT2 */ | |
0 | 1043 jint ret; |
1044 if (capacity >= 0 && capacity <= MAX_REASONABLE_LOCAL_CAPACITY) { | |
1045 ret = JNI_OK; | |
1046 } else { | |
1047 ret = JNI_ERR; | |
1048 } | |
4006 | 1049 #ifndef USDT2 |
0 | 1050 DTRACE_PROBE1(hotspot_jni, EnsureLocalCapacity__return, ret); |
4006 | 1051 #else /* USDT2 */ |
1052 HOTSPOT_JNI_ENSURELOCALCAPACITY_RETURN( | |
1053 ret); | |
1054 #endif /* USDT2 */ | |
0 | 1055 return ret; |
1056 JNI_END | |
1057 | |
1058 // Return the Handle Type | |
1059 JNI_LEAF(jobjectRefType, jni_GetObjectRefType(JNIEnv *env, jobject obj)) | |
1060 JNIWrapper("GetObjectRefType"); | |
4006 | 1061 #ifndef USDT2 |
0 | 1062 DTRACE_PROBE2(hotspot_jni, GetObjectRefType__entry, env, obj); |
4006 | 1063 #else /* USDT2 */ |
1064 HOTSPOT_JNI_GETOBJECTREFTYPE_ENTRY( | |
1065 env, obj); | |
1066 #endif /* USDT2 */ | |
0 | 1067 jobjectRefType ret; |
1068 if (JNIHandles::is_local_handle(thread, obj) || | |
1069 JNIHandles::is_frame_handle(thread, obj)) | |
1070 ret = JNILocalRefType; | |
1071 else if (JNIHandles::is_global_handle(obj)) | |
1072 ret = JNIGlobalRefType; | |
1073 else if (JNIHandles::is_weak_global_handle(obj)) | |
1074 ret = JNIWeakGlobalRefType; | |
1075 else | |
1076 ret = JNIInvalidRefType; | |
4006 | 1077 #ifndef USDT2 |
0 | 1078 DTRACE_PROBE1(hotspot_jni, GetObjectRefType__return, ret); |
4006 | 1079 #else /* USDT2 */ |
1080 HOTSPOT_JNI_GETOBJECTREFTYPE_RETURN( | |
1081 (void *) ret); | |
1082 #endif /* USDT2 */ | |
0 | 1083 return ret; |
1084 JNI_END | |
1085 | |
1086 | |
1087 class JNI_ArgumentPusher : public SignatureIterator { | |
1088 protected: | |
1089 JavaCallArguments* _arguments; | |
1090 | |
1091 virtual void get_bool () = 0; | |
1092 virtual void get_char () = 0; | |
1093 virtual void get_short () = 0; | |
1094 virtual void get_byte () = 0; | |
1095 virtual void get_int () = 0; | |
1096 virtual void get_long () = 0; | |
1097 virtual void get_float () = 0; | |
1098 virtual void get_double () = 0; | |
1099 virtual void get_object () = 0; | |
1100 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1101 JNI_ArgumentPusher(Symbol* signature) : SignatureIterator(signature) { |
0 | 1102 this->_return_type = T_ILLEGAL; |
1103 _arguments = NULL; | |
1104 } | |
1105 | |
1106 public: | |
1107 virtual void iterate( uint64_t fingerprint ) = 0; | |
1108 | |
1109 void set_java_argument_object(JavaCallArguments *arguments) { _arguments = arguments; } | |
1110 | |
1111 inline void do_bool() { if (!is_return_type()) get_bool(); } | |
1112 inline void do_char() { if (!is_return_type()) get_char(); } | |
1113 inline void do_short() { if (!is_return_type()) get_short(); } | |
1114 inline void do_byte() { if (!is_return_type()) get_byte(); } | |
1115 inline void do_int() { if (!is_return_type()) get_int(); } | |
1116 inline void do_long() { if (!is_return_type()) get_long(); } | |
1117 inline void do_float() { if (!is_return_type()) get_float(); } | |
1118 inline void do_double() { if (!is_return_type()) get_double(); } | |
1119 inline void do_object(int begin, int end) { if (!is_return_type()) get_object(); } | |
1120 inline void do_array(int begin, int end) { if (!is_return_type()) get_object(); } // do_array uses get_object -- there is no get_array | |
1121 inline void do_void() { } | |
1122 | |
1123 JavaCallArguments* arguments() { return _arguments; } | |
1124 void push_receiver(Handle h) { _arguments->push_oop(h); } | |
1125 }; | |
1126 | |
1127 | |
1128 class JNI_ArgumentPusherVaArg : public JNI_ArgumentPusher { | |
1129 protected: | |
1130 va_list _ap; | |
1131 | |
1132 inline void get_bool() { _arguments->push_int(va_arg(_ap, jint)); } // bool is coerced to int when using va_arg | |
1133 inline void get_char() { _arguments->push_int(va_arg(_ap, jint)); } // char is coerced to int when using va_arg | |
1134 inline void get_short() { _arguments->push_int(va_arg(_ap, jint)); } // short is coerced to int when using va_arg | |
1135 inline void get_byte() { _arguments->push_int(va_arg(_ap, jint)); } // byte is coerced to int when using va_arg | |
1136 inline void get_int() { _arguments->push_int(va_arg(_ap, jint)); } | |
1137 | |
1138 // each of these paths is exercized by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests | |
1139 | |
1140 inline void get_long() { _arguments->push_long(va_arg(_ap, jlong)); } | |
1141 inline void get_float() { _arguments->push_float((jfloat)va_arg(_ap, jdouble)); } // float is coerced to double w/ va_arg | |
1142 inline void get_double() { _arguments->push_double(va_arg(_ap, jdouble)); } | |
1143 inline void get_object() { jobject l = va_arg(_ap, jobject); | |
1144 _arguments->push_oop(Handle((oop *)l, false)); } | |
1145 | |
1146 inline void set_ap(va_list rap) { | |
1147 #ifdef va_copy | |
1148 va_copy(_ap, rap); | |
1149 #elif defined (__va_copy) | |
1150 __va_copy(_ap, rap); | |
1151 #else | |
1152 _ap = rap; | |
1153 #endif | |
1154 } | |
1155 | |
1156 public: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1157 JNI_ArgumentPusherVaArg(Symbol* signature, va_list rap) |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1158 : JNI_ArgumentPusher(signature) { |
0 | 1159 set_ap(rap); |
1160 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1161 JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap) |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1162 : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)->signature()) { |
0 | 1163 set_ap(rap); |
1164 } | |
1165 | |
1166 // Optimized path if we have the bitvector form of signature | |
1167 void iterate( uint64_t fingerprint ) { | |
1168 if ( fingerprint == UCONST64(-1) ) SignatureIterator::iterate();// Must be too many arguments | |
1169 else { | |
1170 _return_type = (BasicType)((fingerprint >> static_feature_size) & | |
1171 result_feature_mask); | |
1172 | |
1173 assert(fingerprint, "Fingerprint should not be 0"); | |
1174 fingerprint = fingerprint >> (static_feature_size + result_feature_size); | |
1175 while ( 1 ) { | |
1176 switch ( fingerprint & parameter_feature_mask ) { | |
1177 case bool_parm: | |
1178 case char_parm: | |
1179 case short_parm: | |
1180 case byte_parm: | |
1181 case int_parm: | |
1182 get_int(); | |
1183 break; | |
1184 case obj_parm: | |
1185 get_object(); | |
1186 break; | |
1187 case long_parm: | |
1188 get_long(); | |
1189 break; | |
1190 case float_parm: | |
1191 get_float(); | |
1192 break; | |
1193 case double_parm: | |
1194 get_double(); | |
1195 break; | |
1196 case done_parm: | |
1197 return; | |
1198 break; | |
1199 default: | |
1200 ShouldNotReachHere(); | |
1201 break; | |
1202 } | |
1203 fingerprint >>= parameter_feature_size; | |
1204 } | |
1205 } | |
1206 } | |
1207 }; | |
1208 | |
1209 | |
1210 class JNI_ArgumentPusherArray : public JNI_ArgumentPusher { | |
1211 protected: | |
1212 const jvalue *_ap; | |
1213 | |
1214 inline void get_bool() { _arguments->push_int((jint)(_ap++)->z); } | |
1215 inline void get_char() { _arguments->push_int((jint)(_ap++)->c); } | |
1216 inline void get_short() { _arguments->push_int((jint)(_ap++)->s); } | |
1217 inline void get_byte() { _arguments->push_int((jint)(_ap++)->b); } | |
1218 inline void get_int() { _arguments->push_int((jint)(_ap++)->i); } | |
1219 | |
1220 inline void get_long() { _arguments->push_long((_ap++)->j); } | |
1221 inline void get_float() { _arguments->push_float((_ap++)->f); } | |
1222 inline void get_double() { _arguments->push_double((_ap++)->d);} | |
1223 inline void get_object() { _arguments->push_oop(Handle((oop *)(_ap++)->l, false)); } | |
1224 | |
1225 inline void set_ap(const jvalue *rap) { _ap = rap; } | |
1226 | |
1227 public: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1228 JNI_ArgumentPusherArray(Symbol* signature, const jvalue *rap) |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1229 : JNI_ArgumentPusher(signature) { |
0 | 1230 set_ap(rap); |
1231 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1232 JNI_ArgumentPusherArray(jmethodID method_id, const jvalue *rap) |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1233 : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)->signature()) { |
0 | 1234 set_ap(rap); |
1235 } | |
1236 | |
1237 // Optimized path if we have the bitvector form of signature | |
1238 void iterate( uint64_t fingerprint ) { | |
1239 if ( fingerprint == UCONST64(-1) ) SignatureIterator::iterate(); // Must be too many arguments | |
1240 else { | |
1241 _return_type = (BasicType)((fingerprint >> static_feature_size) & | |
1242 result_feature_mask); | |
1243 assert(fingerprint, "Fingerprint should not be 0"); | |
1244 fingerprint = fingerprint >> (static_feature_size + result_feature_size); | |
1245 while ( 1 ) { | |
1246 switch ( fingerprint & parameter_feature_mask ) { | |
1247 case bool_parm: | |
1248 get_bool(); | |
1249 break; | |
1250 case char_parm: | |
1251 get_char(); | |
1252 break; | |
1253 case short_parm: | |
1254 get_short(); | |
1255 break; | |
1256 case byte_parm: | |
1257 get_byte(); | |
1258 break; | |
1259 case int_parm: | |
1260 get_int(); | |
1261 break; | |
1262 case obj_parm: | |
1263 get_object(); | |
1264 break; | |
1265 case long_parm: | |
1266 get_long(); | |
1267 break; | |
1268 case float_parm: | |
1269 get_float(); | |
1270 break; | |
1271 case double_parm: | |
1272 get_double(); | |
1273 break; | |
1274 case done_parm: | |
1275 return; | |
1276 break; | |
1277 default: | |
1278 ShouldNotReachHere(); | |
1279 break; | |
1280 } | |
1281 fingerprint >>= parameter_feature_size; | |
1282 } | |
1283 } | |
1284 } | |
1285 }; | |
1286 | |
1287 | |
1288 enum JNICallType { | |
1289 JNI_STATIC, | |
1290 JNI_VIRTUAL, | |
1291 JNI_NONVIRTUAL | |
1292 }; | |
1293 | |
1294 static methodHandle jni_resolve_interface_call(Handle recv, methodHandle method, TRAPS) { | |
1295 assert(!method.is_null() , "method should not be null"); | |
1296 | |
1297 KlassHandle recv_klass; // Default to NULL (use of ?: can confuse gcc) | |
1298 if (recv.not_null()) recv_klass = KlassHandle(THREAD, recv->klass()); | |
1299 KlassHandle spec_klass (THREAD, method->method_holder()); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1300 Symbol* name = method->name(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1301 Symbol* signature = method->signature(); |
0 | 1302 CallInfo info; |
1303 LinkResolver::resolve_interface_call(info, recv, recv_klass, spec_klass, name, signature, KlassHandle(), false, true, CHECK_(methodHandle())); | |
1304 return info.selected_method(); | |
1305 } | |
1306 | |
1307 static methodHandle jni_resolve_virtual_call(Handle recv, methodHandle method, TRAPS) { | |
1308 assert(!method.is_null() , "method should not be null"); | |
1309 | |
1310 KlassHandle recv_klass; // Default to NULL (use of ?: can confuse gcc) | |
1311 if (recv.not_null()) recv_klass = KlassHandle(THREAD, recv->klass()); | |
1312 KlassHandle spec_klass (THREAD, method->method_holder()); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1313 Symbol* name = method->name(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1314 Symbol* signature = method->signature(); |
0 | 1315 CallInfo info; |
1316 LinkResolver::resolve_virtual_call(info, recv, recv_klass, spec_klass, name, signature, KlassHandle(), false, true, CHECK_(methodHandle())); | |
1317 return info.selected_method(); | |
1318 } | |
1319 | |
1320 | |
1321 | |
1322 static void jni_invoke_static(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1323 methodHandle method(THREAD, Method::resolve_jmethod_id(method_id)); |
0 | 1324 |
1325 // Create object to hold arguments for the JavaCall, and associate it with | |
1326 // the jni parser | |
1327 ResourceMark rm(THREAD); | |
1328 int number_of_parameters = method->size_of_parameters(); | |
1329 JavaCallArguments java_args(number_of_parameters); | |
1330 args->set_java_argument_object(&java_args); | |
1331 | |
1332 assert(method->is_static(), "method should be static"); | |
1333 | |
1334 // Fill out JavaCallArguments object | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1335 args->iterate( Fingerprinter(method).fingerprint() ); |
0 | 1336 // Initialize result type |
1337 result->set_type(args->get_ret_type()); | |
1338 | |
1339 // Invoke the method. Result is returned as oop. | |
1340 JavaCalls::call(result, method, &java_args, CHECK); | |
1341 | |
1342 // Convert result | |
1343 if (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY) { | |
1344 result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject())); | |
1345 } | |
1346 } | |
1347 | |
1348 | |
1349 static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) { | |
1350 oop recv = JNIHandles::resolve(receiver); | |
1351 if (recv == NULL) { | |
1352 THROW(vmSymbols::java_lang_NullPointerException()); | |
1353 } | |
1354 Handle h_recv(THREAD, recv); | |
1355 | |
1356 int number_of_parameters; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1357 Method* selected_method; |
0 | 1358 { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1359 Method* m = Method::resolve_jmethod_id(method_id); |
0 | 1360 number_of_parameters = m->size_of_parameters(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1361 Klass* holder = m->method_holder(); |
0 | 1362 if (!(Klass::cast(holder))->is_interface()) { |
1363 // non-interface call -- for that little speed boost, don't handlize | |
1364 debug_only(No_Safepoint_Verifier nosafepoint;) | |
1365 if (call_type == JNI_VIRTUAL) { | |
1366 // jni_GetMethodID makes sure class is linked and initialized | |
1367 // so m should have a valid vtable index. | |
1368 int vtbl_index = m->vtable_index(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1369 if (vtbl_index != Method::nonvirtual_vtable_index) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1370 Klass* k = h_recv->klass(); |
0 | 1371 // k might be an arrayKlassOop but all vtables start at |
1372 // the same place. The cast is to avoid virtual call and assertion. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1373 InstanceKlass *ik = (InstanceKlass*)k; |
0 | 1374 selected_method = ik->method_at_vtable(vtbl_index); |
1375 } else { | |
1376 // final method | |
1377 selected_method = m; | |
1378 } | |
1379 } else { | |
1380 // JNI_NONVIRTUAL call | |
1381 selected_method = m; | |
1382 } | |
1383 } else { | |
1384 // interface call | |
1385 KlassHandle h_holder(THREAD, holder); | |
1386 | |
1387 int itbl_index = m->cached_itable_index(); | |
1388 if (itbl_index == -1) { | |
1389 itbl_index = klassItable::compute_itable_index(m); | |
1390 m->set_cached_itable_index(itbl_index); | |
1391 // the above may have grabbed a lock, 'm' and anything non-handlized can't be used again | |
1392 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1393 Klass* k = h_recv->klass(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1394 selected_method = InstanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK); |
0 | 1395 } |
1396 } | |
1397 | |
1398 methodHandle method(THREAD, selected_method); | |
1399 | |
1400 // Create object to hold arguments for the JavaCall, and associate it with | |
1401 // the jni parser | |
1402 ResourceMark rm(THREAD); | |
1403 JavaCallArguments java_args(number_of_parameters); | |
1404 args->set_java_argument_object(&java_args); | |
1405 | |
1406 // handle arguments | |
1407 assert(!method->is_static(), "method should not be static"); | |
1408 args->push_receiver(h_recv); // Push jobject handle | |
1409 | |
1410 // Fill out JavaCallArguments object | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1411 args->iterate( Fingerprinter(method).fingerprint() ); |
0 | 1412 // Initialize result type |
1413 result->set_type(args->get_ret_type()); | |
1414 | |
1415 // Invoke the method. Result is returned as oop. | |
1416 JavaCalls::call(result, method, &java_args, CHECK); | |
1417 | |
1418 // Convert result | |
1419 if (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY) { | |
1420 result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject())); | |
1421 } | |
1422 } | |
1423 | |
1424 | |
1425 static instanceOop alloc_object(jclass clazz, TRAPS) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1426 KlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); |
0 | 1427 Klass::cast(k())->check_valid_for_instantiation(false, CHECK_NULL); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1428 InstanceKlass::cast(k())->initialize(CHECK_NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1429 instanceOop ih = InstanceKlass::cast(k())->allocate_instance(THREAD); |
0 | 1430 return ih; |
1431 } | |
1432 | |
4006 | 1433 #ifndef USDT2 |
0 | 1434 DT_RETURN_MARK_DECL(AllocObject, jobject); |
4006 | 1435 #else /* USDT2 */ |
1436 DT_RETURN_MARK_DECL(AllocObject, jobject | |
1437 , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref)); | |
1438 #endif /* USDT2 */ | |
0 | 1439 |
1440 JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz)) | |
1441 JNIWrapper("AllocObject"); | |
1442 | |
4006 | 1443 #ifndef USDT2 |
0 | 1444 DTRACE_PROBE2(hotspot_jni, AllocObject__entry, env, clazz); |
4006 | 1445 #else /* USDT2 */ |
1446 HOTSPOT_JNI_ALLOCOBJECT_ENTRY( | |
1447 env, clazz); | |
1448 #endif /* USDT2 */ | |
0 | 1449 jobject ret = NULL; |
1450 DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret); | |
1451 | |
1452 instanceOop i = alloc_object(clazz, CHECK_NULL); | |
1453 ret = JNIHandles::make_local(env, i); | |
1454 return ret; | |
1455 JNI_END | |
1456 | |
4006 | 1457 #ifndef USDT2 |
0 | 1458 DT_RETURN_MARK_DECL(NewObjectA, jobject); |
4006 | 1459 #else /* USDT2 */ |
1460 DT_RETURN_MARK_DECL(NewObjectA, jobject | |
1461 , HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref)); | |
1462 #endif /* USDT2 */ | |
0 | 1463 |
1464 JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args)) | |
1465 JNIWrapper("NewObjectA"); | |
4006 | 1466 #ifndef USDT2 |
0 | 1467 DTRACE_PROBE3(hotspot_jni, NewObjectA__entry, env, clazz, methodID); |
4006 | 1468 #else /* USDT2 */ |
1469 HOTSPOT_JNI_NEWOBJECTA_ENTRY( | |
1470 env, clazz, (uintptr_t) methodID); | |
1471 #endif /* USDT2 */ | |
0 | 1472 jobject obj = NULL; |
1473 DT_RETURN_MARK(NewObjectA, jobject, (const jobject)obj); | |
1474 | |
1475 instanceOop i = alloc_object(clazz, CHECK_NULL); | |
1476 obj = JNIHandles::make_local(env, i); | |
1477 JavaValue jvalue(T_VOID); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1478 JNI_ArgumentPusherArray ap(methodID, args); |
0 | 1479 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL); |
1480 return obj; | |
1481 JNI_END | |
1482 | |
4006 | 1483 #ifndef USDT2 |
0 | 1484 DT_RETURN_MARK_DECL(NewObjectV, jobject); |
4006 | 1485 #else /* USDT2 */ |
1486 DT_RETURN_MARK_DECL(NewObjectV, jobject | |
1487 , HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref)); | |
1488 #endif /* USDT2 */ | |
0 | 1489 |
1490 JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)) | |
1491 JNIWrapper("NewObjectV"); | |
4006 | 1492 #ifndef USDT2 |
0 | 1493 DTRACE_PROBE3(hotspot_jni, NewObjectV__entry, env, clazz, methodID); |
4006 | 1494 #else /* USDT2 */ |
1495 HOTSPOT_JNI_NEWOBJECTV_ENTRY( | |
1496 env, clazz, (uintptr_t) methodID); | |
1497 #endif /* USDT2 */ | |
0 | 1498 jobject obj = NULL; |
1499 DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj); | |
1500 | |
1501 instanceOop i = alloc_object(clazz, CHECK_NULL); | |
1502 obj = JNIHandles::make_local(env, i); | |
1503 JavaValue jvalue(T_VOID); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1504 JNI_ArgumentPusherVaArg ap(methodID, args); |
0 | 1505 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL); |
1506 return obj; | |
1507 JNI_END | |
1508 | |
4006 | 1509 #ifndef USDT2 |
0 | 1510 DT_RETURN_MARK_DECL(NewObject, jobject); |
4006 | 1511 #else /* USDT2 */ |
1512 DT_RETURN_MARK_DECL(NewObject, jobject | |
1513 , HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref)); | |
1514 #endif /* USDT2 */ | |
0 | 1515 |
1516 JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)) | |
1517 JNIWrapper("NewObject"); | |
4006 | 1518 #ifndef USDT2 |
0 | 1519 DTRACE_PROBE3(hotspot_jni, NewObject__entry, env, clazz, methodID); |
4006 | 1520 #else /* USDT2 */ |
1521 HOTSPOT_JNI_NEWOBJECT_ENTRY( | |
1522 env, clazz, (uintptr_t) methodID); | |
1523 #endif /* USDT2 */ | |
0 | 1524 jobject obj = NULL; |
1525 DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj); | |
1526 | |
1527 instanceOop i = alloc_object(clazz, CHECK_NULL); | |
1528 obj = JNIHandles::make_local(env, i); | |
1529 va_list args; | |
1530 va_start(args, methodID); | |
1531 JavaValue jvalue(T_VOID); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1532 JNI_ArgumentPusherVaArg ap(methodID, args); |
0 | 1533 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL); |
1534 va_end(args); | |
1535 return obj; | |
1536 JNI_END | |
1537 | |
1538 | |
1539 JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj)) | |
1540 JNIWrapper("GetObjectClass"); | |
4006 | 1541 #ifndef USDT2 |
0 | 1542 DTRACE_PROBE2(hotspot_jni, GetObjectClass__entry, env, obj); |
4006 | 1543 #else /* USDT2 */ |
1544 HOTSPOT_JNI_GETOBJECTCLASS_ENTRY( | |
1545 env, obj); | |
1546 #endif /* USDT2 */ | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1547 Klass* k = JNIHandles::resolve_non_null(obj)->klass(); |
0 | 1548 jclass ret = |
1549 (jclass) JNIHandles::make_local(env, Klass::cast(k)->java_mirror()); | |
4006 | 1550 #ifndef USDT2 |
0 | 1551 DTRACE_PROBE1(hotspot_jni, GetObjectClass__return, ret); |
4006 | 1552 #else /* USDT2 */ |
1553 HOTSPOT_JNI_GETOBJECTCLASS_RETURN( | |
1554 ret); | |
1555 #endif /* USDT2 */ | |
0 | 1556 return ret; |
1557 JNI_END | |
1558 | |
1559 JNI_QUICK_ENTRY(jboolean, jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)) | |
1560 JNIWrapper("IsInstanceOf"); | |
4006 | 1561 #ifndef USDT2 |
0 | 1562 DTRACE_PROBE3(hotspot_jni, IsInstanceOf__entry, env, obj, clazz); |
4006 | 1563 #else /* USDT2 */ |
1564 HOTSPOT_JNI_ISINSTANCEOF_ENTRY( | |
1565 env, obj, clazz); | |
1566 #endif /* USDT2 */ | |
0 | 1567 jboolean ret = JNI_TRUE; |
1568 if (obj != NULL) { | |
1569 ret = JNI_FALSE; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1570 Klass* k = java_lang_Class::as_Klass( |
0 | 1571 JNIHandles::resolve_non_null(clazz)); |
1572 if (k != NULL) { | |
1573 ret = JNIHandles::resolve_non_null(obj)->is_a(k) ? JNI_TRUE : JNI_FALSE; | |
1574 } | |
1575 } | |
4006 | 1576 #ifndef USDT2 |
0 | 1577 DTRACE_PROBE1(hotspot_jni, IsInstanceOf__return, ret); |
4006 | 1578 #else /* USDT2 */ |
1579 HOTSPOT_JNI_ISINSTANCEOF_RETURN( | |
1580 ret); | |
1581 #endif /* USDT2 */ | |
0 | 1582 return ret; |
1583 JNI_END | |
1584 | |
1585 | |
1586 static jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name_str, | |
1587 const char *sig, bool is_static, TRAPS) { | |
1588 // %%%% This code should probably just call into a method in the LinkResolver | |
1589 // | |
1590 // The class should have been loaded (we have an instance of the class | |
1591 // passed in) so the method and signature should already be in the symbol | |
1592 // table. If they're not there, the method doesn't exist. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1593 const char *name_to_probe = (name_str == NULL) |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1594 ? vmSymbols::object_initializer_name()->as_C_string() |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1595 : name_str; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1596 TempNewSymbol name = SymbolTable::probe(name_to_probe, (int)strlen(name_to_probe)); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1597 TempNewSymbol signature = SymbolTable::probe(sig, (int)strlen(sig)); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1598 |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1599 if (name == NULL || signature == NULL) { |
0 | 1600 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str); |
1601 } | |
1602 | |
1603 // Throw a NoSuchMethodError exception if we have an instance of a | |
1604 // primitive java.lang.Class | |
1605 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(clazz))) { | |
1606 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str); | |
1607 } | |
1608 | |
1609 KlassHandle klass(THREAD, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1610 java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); |
0 | 1611 |
1612 // Make sure class is linked and initialized before handing id's out to | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1613 // Method*s. |
0 | 1614 Klass::cast(klass())->initialize(CHECK_NULL); |
1615 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1616 Method* m; |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1617 if (name == vmSymbols::object_initializer_name() || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1618 name == vmSymbols::class_initializer_name()) { |
0 | 1619 // Never search superclasses for constructors |
1620 if (klass->oop_is_instance()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1621 m = InstanceKlass::cast(klass())->find_method(name, signature); |
0 | 1622 } else { |
1623 m = NULL; | |
1624 } | |
1625 } else { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1626 m = klass->lookup_method(name, signature); |
0 | 1627 // Look up interfaces |
1628 if (m == NULL && klass->oop_is_instance()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1629 m = InstanceKlass::cast(klass())->lookup_method_in_all_interfaces(name, |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1630 signature); |
0 | 1631 } |
1632 } | |
1633 if (m == NULL || (m->is_static() != is_static)) { | |
1634 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str); | |
1635 } | |
1636 return m->jmethod_id(); | |
1637 } | |
1638 | |
1639 | |
1640 JNI_ENTRY(jmethodID, jni_GetMethodID(JNIEnv *env, jclass clazz, | |
1641 const char *name, const char *sig)) | |
1642 JNIWrapper("GetMethodID"); | |
4006 | 1643 #ifndef USDT2 |
0 | 1644 DTRACE_PROBE4(hotspot_jni, GetMethodID__entry, env, clazz, name, sig); |
4006 | 1645 #else /* USDT2 */ |
1646 HOTSPOT_JNI_GETMETHODID_ENTRY( | |
1647 env, clazz, (char *) name, (char *) sig); | |
1648 #endif /* USDT2 */ | |
0 | 1649 jmethodID ret = get_method_id(env, clazz, name, sig, false, thread); |
4006 | 1650 #ifndef USDT2 |
0 | 1651 DTRACE_PROBE1(hotspot_jni, GetMethodID__return, ret); |
4006 | 1652 #else /* USDT2 */ |
1653 HOTSPOT_JNI_GETMETHODID_RETURN( | |
1654 (uintptr_t) ret); | |
1655 #endif /* USDT2 */ | |
0 | 1656 return ret; |
1657 JNI_END | |
1658 | |
1659 | |
1660 JNI_ENTRY(jmethodID, jni_GetStaticMethodID(JNIEnv *env, jclass clazz, | |
1661 const char *name, const char *sig)) | |
1662 JNIWrapper("GetStaticMethodID"); | |
4006 | 1663 #ifndef USDT2 |
0 | 1664 DTRACE_PROBE4(hotspot_jni, GetStaticMethodID__entry, env, clazz, name, sig); |
4006 | 1665 #else /* USDT2 */ |
1666 HOTSPOT_JNI_GETSTATICMETHODID_ENTRY( | |
1667 env, (char *) clazz, (char *) name, (char *)sig); | |
1668 #endif /* USDT2 */ | |
0 | 1669 jmethodID ret = get_method_id(env, clazz, name, sig, true, thread); |
4006 | 1670 #ifndef USDT2 |
0 | 1671 DTRACE_PROBE1(hotspot_jni, GetStaticMethodID__return, ret); |
4006 | 1672 #else /* USDT2 */ |
1673 HOTSPOT_JNI_GETSTATICMETHODID_RETURN( | |
1674 (uintptr_t) ret); | |
1675 #endif /* USDT2 */ | |
0 | 1676 return ret; |
1677 JNI_END | |
1678 | |
1679 | |
1680 | |
1681 // | |
1682 // Calling Methods | |
1683 // | |
1684 | |
4006 | 1685 #ifndef USDT2 |
0 | 1686 #define DEFINE_CALLMETHOD(ResultType, Result, Tag) \ |
1687 \ | |
1688 DT_RETURN_MARK_DECL_FOR(Result, Call##Result##Method, ResultType);\ | |
1689 DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodV, ResultType);\ | |
1690 DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodA, ResultType);\ | |
1691 \ | |
1692 JNI_ENTRY(ResultType, \ | |
1693 jni_Call##Result##Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)) \ | |
1694 JNIWrapper("Call" XSTR(Result) "Method"); \ | |
1695 \ | |
4006 | 1696 DTRACE_PROBE3(hotspot_jni, Call##Result##Method__entry, env, obj, methodID); \ |
0 | 1697 ResultType ret = 0;\ |
1698 DT_RETURN_MARK_FOR(Result, Call##Result##Method, ResultType, \ | |
1699 (const ResultType&)ret);\ | |
1700 \ | |
1701 va_list args; \ | |
1702 va_start(args, methodID); \ | |
1703 JavaValue jvalue(Tag); \ | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1704 JNI_ArgumentPusherVaArg ap(methodID, args); \ |
0 | 1705 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \ |
1706 va_end(args); \ | |
1707 ret = jvalue.get_##ResultType(); \ | |
1708 return ret;\ | |
1709 JNI_END \ | |
1710 \ | |
1711 \ | |
1712 JNI_ENTRY(ResultType, \ | |
1713 jni_Call##Result##MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)) \ | |
1714 JNIWrapper("Call" XSTR(Result) "MethodV"); \ | |
1715 \ | |
4006 | 1716 DTRACE_PROBE3(hotspot_jni, Call##Result##MethodV__entry, env, obj, methodID); \ |
0 | 1717 ResultType ret = 0;\ |
1718 DT_RETURN_MARK_FOR(Result, Call##Result##MethodV, ResultType, \ | |
1719 (const ResultType&)ret);\ | |
1720 \ | |
1721 JavaValue jvalue(Tag); \ | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1722 JNI_ArgumentPusherVaArg ap(methodID, args); \ |
0 | 1723 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \ |
1724 ret = jvalue.get_##ResultType(); \ | |
1725 return ret;\ | |
1726 JNI_END \ | |
1727 \ | |
1728 \ | |
1729 JNI_ENTRY(ResultType, \ | |
1730 jni_Call##Result##MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args)) \ | |
1731 JNIWrapper("Call" XSTR(Result) "MethodA"); \ | |
4006 | 1732 DTRACE_PROBE3(hotspot_jni, Call##Result##MethodA__entry, env, obj, methodID); \ |
0 | 1733 ResultType ret = 0;\ |
1734 DT_RETURN_MARK_FOR(Result, Call##Result##MethodA, ResultType, \ | |
1735 (const ResultType&)ret);\ | |
1736 \ | |
1737 JavaValue jvalue(Tag); \ | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1738 JNI_ArgumentPusherArray ap(methodID, args); \ |
0 | 1739 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \ |
1740 ret = jvalue.get_##ResultType(); \ | |
1741 return ret;\ | |
1742 JNI_END | |
1743 | |
1744 // the runtime type of subword integral basic types is integer | |
1745 DEFINE_CALLMETHOD(jboolean, Boolean, T_BOOLEAN) | |
1746 DEFINE_CALLMETHOD(jbyte, Byte, T_BYTE) | |
1747 DEFINE_CALLMETHOD(jchar, Char, T_CHAR) | |
1748 DEFINE_CALLMETHOD(jshort, Short, T_SHORT) | |
1749 | |
1750 DEFINE_CALLMETHOD(jobject, Object, T_OBJECT) | |
1751 DEFINE_CALLMETHOD(jint, Int, T_INT) | |
1752 DEFINE_CALLMETHOD(jlong, Long, T_LONG) | |
1753 DEFINE_CALLMETHOD(jfloat, Float, T_FLOAT) | |
1754 DEFINE_CALLMETHOD(jdouble, Double, T_DOUBLE) | |
1755 | |
1756 DT_VOID_RETURN_MARK_DECL(CallVoidMethod); | |
1757 DT_VOID_RETURN_MARK_DECL(CallVoidMethodV); | |
1758 DT_VOID_RETURN_MARK_DECL(CallVoidMethodA); | |
1759 | |
4006 | 1760 #else /* USDT2 */ |
1761 | |
1762 #define DEFINE_CALLMETHOD(ResultType, Result, Tag \ | |
1763 , EntryProbe, ReturnProbe) \ | |
1764 \ | |
1765 DT_RETURN_MARK_DECL_FOR(Result, Call##Result##Method, ResultType \ | |
1766 , ReturnProbe); \ | |
1767 \ | |
1768 JNI_ENTRY(ResultType, \ | |
1769 jni_Call##Result##Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)) \ | |
1770 JNIWrapper("Call" XSTR(Result) "Method"); \ | |
1771 \ | |
1772 EntryProbe; \ | |
1773 ResultType ret = 0;\ | |
1774 DT_RETURN_MARK_FOR(Result, Call##Result##Method, ResultType, \ | |
1775 (const ResultType&)ret);\ | |
1776 \ | |
1777 va_list args; \ | |
1778 va_start(args, methodID); \ | |
1779 JavaValue jvalue(Tag); \ | |
1780 JNI_ArgumentPusherVaArg ap(methodID, args); \ | |
1781 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \ | |
1782 va_end(args); \ | |
1783 ret = jvalue.get_##ResultType(); \ | |
1784 return ret;\ | |
1785 JNI_END | |
1786 | |
1787 // the runtime type of subword integral basic types is integer | |
1788 DEFINE_CALLMETHOD(jboolean, Boolean, T_BOOLEAN | |
1789 , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1790 HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref)) | |
1791 DEFINE_CALLMETHOD(jbyte, Byte, T_BYTE | |
1792 , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1793 HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref)) | |
1794 DEFINE_CALLMETHOD(jchar, Char, T_CHAR | |
1795 , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1796 HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref)) | |
1797 DEFINE_CALLMETHOD(jshort, Short, T_SHORT | |
1798 , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1799 HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref)) | |
1800 | |
1801 DEFINE_CALLMETHOD(jobject, Object, T_OBJECT | |
1802 , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1803 HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref)) | |
1804 DEFINE_CALLMETHOD(jint, Int, T_INT, | |
1805 HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1806 HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref)) | |
1807 DEFINE_CALLMETHOD(jlong, Long, T_LONG | |
1808 , HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1809 HOTSPOT_JNI_CALLLONGMETHOD_RETURN(_ret_ref)) | |
1810 // Float and double probes don't return value because dtrace doesn't currently support it | |
1811 DEFINE_CALLMETHOD(jfloat, Float, T_FLOAT | |
1812 , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1813 HOTSPOT_JNI_CALLFLOATMETHOD_RETURN()) | |
1814 DEFINE_CALLMETHOD(jdouble, Double, T_DOUBLE | |
1815 , HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1816 HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN()) | |
1817 | |
1818 #define DEFINE_CALLMETHODV(ResultType, Result, Tag \ | |
1819 , EntryProbe, ReturnProbe) \ | |
1820 \ | |
1821 DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodV, ResultType \ | |
1822 , ReturnProbe); \ | |
1823 \ | |
1824 JNI_ENTRY(ResultType, \ | |
1825 jni_Call##Result##MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)) \ | |
1826 JNIWrapper("Call" XSTR(Result) "MethodV"); \ | |
1827 \ | |
1828 EntryProbe;\ | |
1829 ResultType ret = 0;\ | |
1830 DT_RETURN_MARK_FOR(Result, Call##Result##MethodV, ResultType, \ | |
1831 (const ResultType&)ret);\ | |
1832 \ | |
1833 JavaValue jvalue(Tag); \ | |
1834 JNI_ArgumentPusherVaArg ap(methodID, args); \ | |
1835 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \ | |
1836 ret = jvalue.get_##ResultType(); \ | |
1837 return ret;\ | |
1838 JNI_END | |
1839 | |
1840 // the runtime type of subword integral basic types is integer | |
1841 DEFINE_CALLMETHODV(jboolean, Boolean, T_BOOLEAN | |
1842 , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1843 HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref)) | |
1844 DEFINE_CALLMETHODV(jbyte, Byte, T_BYTE | |
1845 , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1846 HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref)) | |
1847 DEFINE_CALLMETHODV(jchar, Char, T_CHAR | |
1848 , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1849 HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref)) | |
1850 DEFINE_CALLMETHODV(jshort, Short, T_SHORT | |
1851 , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1852 HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref)) | |
1853 | |
1854 DEFINE_CALLMETHODV(jobject, Object, T_OBJECT | |
1855 , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1856 HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref)) | |
1857 DEFINE_CALLMETHODV(jint, Int, T_INT, | |
1858 HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1859 HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref)) | |
1860 DEFINE_CALLMETHODV(jlong, Long, T_LONG | |
1861 , HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1862 HOTSPOT_JNI_CALLLONGMETHOD_RETURN(_ret_ref)) | |
1863 // Float and double probes don't return value because dtrace doesn't currently support it | |
1864 DEFINE_CALLMETHODV(jfloat, Float, T_FLOAT | |
1865 , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1866 HOTSPOT_JNI_CALLFLOATMETHOD_RETURN()) | |
1867 DEFINE_CALLMETHODV(jdouble, Double, T_DOUBLE | |
1868 , HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1869 HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN()) | |
1870 | |
1871 #define DEFINE_CALLMETHODA(ResultType, Result, Tag \ | |
1872 , EntryProbe, ReturnProbe) \ | |
1873 \ | |
1874 DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodA, ResultType \ | |
1875 , ReturnProbe); \ | |
1876 \ | |
1877 JNI_ENTRY(ResultType, \ | |
1878 jni_Call##Result##MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args)) \ | |
1879 JNIWrapper("Call" XSTR(Result) "MethodA"); \ | |
1880 EntryProbe; \ | |
1881 ResultType ret = 0;\ | |
1882 DT_RETURN_MARK_FOR(Result, Call##Result##MethodA, ResultType, \ | |
1883 (const ResultType&)ret);\ | |
1884 \ | |
1885 JavaValue jvalue(Tag); \ | |
1886 JNI_ArgumentPusherArray ap(methodID, args); \ | |
1887 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \ | |
1888 ret = jvalue.get_##ResultType(); \ | |
1889 return ret;\ | |
1890 JNI_END | |
1891 | |
1892 // the runtime type of subword integral basic types is integer | |
1893 DEFINE_CALLMETHODA(jboolean, Boolean, T_BOOLEAN | |
1894 , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1895 HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref)) | |
1896 DEFINE_CALLMETHODA(jbyte, Byte, T_BYTE | |
1897 , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1898 HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref)) | |
1899 DEFINE_CALLMETHODA(jchar, Char, T_CHAR | |
1900 , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1901 HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref)) | |
1902 DEFINE_CALLMETHODA(jshort, Short, T_SHORT | |
1903 , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1904 HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref)) | |
1905 | |
1906 DEFINE_CALLMETHODA(jobject, Object, T_OBJECT | |
1907 , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1908 HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref)) | |
1909 DEFINE_CALLMETHODA(jint, Int, T_INT, | |
1910 HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1911 HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref)) | |
1912 DEFINE_CALLMETHODA(jlong, Long, T_LONG | |
1913 , HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1914 HOTSPOT_JNI_CALLLONGMETHOD_RETURN(_ret_ref)) | |
1915 // Float and double probes don't return value because dtrace doesn't currently support it | |
1916 DEFINE_CALLMETHODA(jfloat, Float, T_FLOAT | |
1917 , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1918 HOTSPOT_JNI_CALLFLOATMETHOD_RETURN()) | |
1919 DEFINE_CALLMETHODA(jdouble, Double, T_DOUBLE | |
1920 , HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID), | |
1921 HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN()) | |
1922 | |
1923 DT_VOID_RETURN_MARK_DECL(CallVoidMethod, HOTSPOT_JNI_CALLVOIDMETHOD_RETURN()); | |
1924 DT_VOID_RETURN_MARK_DECL(CallVoidMethodV, HOTSPOT_JNI_CALLVOIDMETHODV_RETURN()); | |
1925 DT_VOID_RETURN_MARK_DECL(CallVoidMethodA, HOTSPOT_JNI_CALLVOIDMETHODA_RETURN()); | |
1926 | |
1927 #endif /* USDT2 */ | |
1928 | |
0 | 1929 JNI_ENTRY(void, jni_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)) |
1930 JNIWrapper("CallVoidMethod"); | |
4006 | 1931 #ifndef USDT2 |
0 | 1932 DTRACE_PROBE3(hotspot_jni, CallVoidMethod__entry, env, obj, methodID); |
4006 | 1933 #else /* USDT2 */ |
1934 HOTSPOT_JNI_CALLVOIDMETHOD_ENTRY( | |
1935 env, obj, (uintptr_t) methodID); | |
1936 #endif /* USDT2 */ | |
0 | 1937 DT_VOID_RETURN_MARK(CallVoidMethod); |
1938 | |
1939 va_list args; | |
1940 va_start(args, methodID); | |
1941 JavaValue jvalue(T_VOID); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1942 JNI_ArgumentPusherVaArg ap(methodID, args); |
0 | 1943 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK); |
1944 va_end(args); | |
1945 JNI_END | |
1946 | |
1947 | |
1948 JNI_ENTRY(void, jni_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)) | |
1949 JNIWrapper("CallVoidMethodV"); | |
4006 | 1950 #ifndef USDT2 |
0 | 1951 DTRACE_PROBE3(hotspot_jni, CallVoidMethodV__entry, env, obj, methodID); |
4006 | 1952 #else /* USDT2 */ |
1953 HOTSPOT_JNI_CALLVOIDMETHODV_ENTRY( | |
1954 env, obj, (uintptr_t) methodID); | |
1955 #endif /* USDT2 */ | |
0 | 1956 DT_VOID_RETURN_MARK(CallVoidMethodV); |
1957 | |
1958 JavaValue jvalue(T_VOID); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1959 JNI_ArgumentPusherVaArg ap(methodID, args); |
0 | 1960 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK); |
1961 JNI_END | |
1962 | |
1963 | |
1964 JNI_ENTRY(void, jni_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args)) | |
1965 JNIWrapper("CallVoidMethodA"); | |
4006 | 1966 #ifndef USDT2 |
0 | 1967 DTRACE_PROBE3(hotspot_jni, CallVoidMethodA__entry, env, obj, methodID); |
4006 | 1968 #else /* USDT2 */ |
1969 HOTSPOT_JNI_CALLVOIDMETHODA_ENTRY( | |
1970 env, obj, (uintptr_t) methodID); | |
1971 #endif /* USDT2 */ | |
0 | 1972 DT_VOID_RETURN_MARK(CallVoidMethodA); |
1973 | |
1974 JavaValue jvalue(T_VOID); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1975 JNI_ArgumentPusherArray ap(methodID, args); |
0 | 1976 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK); |
1977 JNI_END | |
1978 | |
1979 | |
4006 | 1980 #ifndef USDT2 |
0 | 1981 #define DEFINE_CALLNONVIRTUALMETHOD(ResultType, Result, Tag) \ |
1982 \ | |
1983 DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##Method, ResultType);\ | |
1984 DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodV, ResultType);\ | |
1985 DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodA, ResultType);\ | |
1986 \ | |
1987 JNI_ENTRY(ResultType, \ | |
1988 jni_CallNonvirtual##Result##Method(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...)) \ | |
1989 JNIWrapper("CallNonvitual" XSTR(Result) "Method"); \ | |
1990 \ | |
1991 DTRACE_PROBE4(hotspot_jni, CallNonvirtual##Result##Method__entry, env, obj, cls, methodID);\ | |
1992 ResultType ret;\ | |
1993 DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##Method, ResultType, \ | |
1994 (const ResultType&)ret);\ | |
1995 \ | |
1996 va_list args; \ | |
1997 va_start(args, methodID); \ | |
1998 JavaValue jvalue(Tag); \ | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
1999 JNI_ArgumentPusherVaArg ap(methodID, args); \ |
0 | 2000 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \ |
2001 va_end(args); \ | |
2002 ret = jvalue.get_##ResultType(); \ | |
2003 return ret;\ | |
2004 JNI_END \ | |
2005 \ | |
2006 JNI_ENTRY(ResultType, \ | |
2007 jni_CallNonvirtual##Result##MethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args)) \ | |
2008 JNIWrapper("CallNonvitual" XSTR(Result) "#MethodV"); \ | |
2009 DTRACE_PROBE4(hotspot_jni, CallNonvirtual##Result##MethodV__entry, env, obj, cls, methodID);\ | |
2010 ResultType ret;\ | |
2011 DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodV, ResultType, \ | |
2012 (const ResultType&)ret);\ | |
2013 \ | |
2014 JavaValue jvalue(Tag); \ | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
2015 JNI_ArgumentPusherVaArg ap(methodID, args); \ |
0 | 2016 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \ |
2017 ret = jvalue.get_##ResultType(); \ | |
2018 return ret;\ | |
2019 JNI_END \ | |
2020 \ | |
2021 JNI_ENTRY(ResultType, \ | |
2022 jni_CallNonvirtual##Result##MethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args)) \ | |
2023 JNIWrapper("CallNonvitual" XSTR(Result) "MethodA"); \ | |
2024 DTRACE_PROBE4(hotspot_jni, CallNonvirtual##Result##MethodA__entry, env, obj, cls, methodID);\ | |
2025 ResultType ret;\ | |
2026 DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodA, ResultType, \ | |
2027 (const ResultType&)ret);\ | |
2028 \ | |
2029 JavaValue jvalue(Tag); \ | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
2030 JNI_ArgumentPusherArray ap(methodID, args); \ |
0 | 2031 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \ |
2032 ret = jvalue.get_##ResultType(); \ | |
2033 return ret;\ | |
2034 JNI_END | |
2035 | |
2036 // the runtime type of subword integral basic types is integer | |
2037 DEFINE_CALLNONVIRTUALMETHOD(jboolean, Boolean, T_BOOLEAN) | |
2038 DEFINE_CALLNONVIRTUALMETHOD(jbyte, Byte, T_BYTE) | |
2039 DEFINE_CALLNONVIRTUALMETHOD(jchar, Char, T_CHAR) | |
2040 DEFINE_CALLNONVIRTUALMETHOD(jshort, Short, T_SHORT) | |
2041 | |
2042 DEFINE_CALLNONVIRTUALMETHOD(jobject, Object, T_OBJECT) | |
2043 DEFINE_CALLNONVIRTUALMETHOD(jint, Int, T_INT) | |
2044 DEFINE_CALLNONVIRTUALMETHOD(jlong, Long, T_LONG) | |
2045 DEFINE_CALLNONVIRTUALMETHOD(jfloat, Float, T_FLOAT) | |
2046 DEFINE_CALLNONVIRTUALMETHOD(jdouble, Double, T_DOUBLE) | |
2047 | |
2048 | |
2049 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethod); | |
2050 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodV); | |
2051 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodA); | |
2052 | |
4006 | 2053 #else /* USDT2 */ |
2054 | |
2055 #define DEFINE_CALLNONVIRTUALMETHOD(ResultType, Result, Tag \ | |
2056 , EntryProbe, ReturnProbe) \ | |
2057 \ | |
2058 DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##Method, ResultType \ | |
2059 , ReturnProbe);\ | |
2060 \ | |
2061 JNI_ENTRY(ResultType, \ | |
2062 jni_CallNonvirtual##Result##Method(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...)) \ | |
2063 JNIWrapper("CallNonvitual" XSTR(Result) "Method"); \ | |
2064 \ | |
2065 EntryProbe;\ | |
2066 ResultType ret;\ | |
2067 DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##Method, ResultType, \ | |
2068 (const ResultType&)ret);\ | |
2069 \ | |
2070 va_list args; \ | |
2071 va_start(args, methodID); \ | |
2072 JavaValue jvalue(Tag); \ | |
2073 JNI_ArgumentPusherVaArg ap(methodID, args); \ | |
2074 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \ | |
2075 va_end(args); \ | |
2076 ret = jvalue.get_##ResultType(); \ | |
2077 return ret;\ | |
2078 JNI_END | |
2079 | |
2080 // the runtime type of subword integral basic types is integer | |
2081 DEFINE_CALLNONVIRTUALMETHOD(jboolean, Boolean, T_BOOLEAN | |
2082 , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2083 HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_RETURN(_ret_ref)) | |
2084 DEFINE_CALLNONVIRTUALMETHOD(jbyte, Byte, T_BYTE | |
2085 , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2086 HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_RETURN(_ret_ref)) | |
2087 DEFINE_CALLNONVIRTUALMETHOD(jchar, Char, T_CHAR | |
2088 , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2089 HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_RETURN(_ret_ref)) | |
2090 DEFINE_CALLNONVIRTUALMETHOD(jshort, Short, T_SHORT | |
2091 , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2092 HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_RETURN(_ret_ref)) | |
2093 | |
2094 DEFINE_CALLNONVIRTUALMETHOD(jobject, Object, T_OBJECT | |
2095 , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2096 HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_RETURN(_ret_ref)) | |
2097 DEFINE_CALLNONVIRTUALMETHOD(jint, Int, T_INT | |
2098 , HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2099 HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_RETURN(_ret_ref)) | |
2100 DEFINE_CALLNONVIRTUALMETHOD(jlong, Long, T_LONG | |
2101 , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2102 // Float and double probes don't return value because dtrace doesn't currently support it | |
2103 HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_RETURN(_ret_ref)) | |
2104 DEFINE_CALLNONVIRTUALMETHOD(jfloat, Float, T_FLOAT | |
2105 , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2106 HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_RETURN()) | |
2107 DEFINE_CALLNONVIRTUALMETHOD(jdouble, Double, T_DOUBLE | |
2108 , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2109 HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_RETURN()) | |
2110 | |
2111 #define DEFINE_CALLNONVIRTUALMETHODV(ResultType, Result, Tag \ | |
2112 , EntryProbe, ReturnProbe) \ | |
2113 \ | |
2114 DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodV, ResultType \ | |
2115 , ReturnProbe);\ | |
2116 \ | |
2117 JNI_ENTRY(ResultType, \ | |
2118 jni_CallNonvirtual##Result##MethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args)) \ | |
2119 JNIWrapper("CallNonvitual" XSTR(Result) "MethodV"); \ | |
2120 \ | |
2121 EntryProbe;\ | |
2122 ResultType ret;\ | |
2123 DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodV, ResultType, \ | |
2124 (const ResultType&)ret);\ | |
2125 \ | |
2126 JavaValue jvalue(Tag); \ | |
2127 JNI_ArgumentPusherVaArg ap(methodID, args); \ | |
2128 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \ | |
2129 ret = jvalue.get_##ResultType(); \ | |
2130 return ret;\ | |
2131 JNI_END | |
2132 | |
2133 // the runtime type of subword integral basic types is integer | |
2134 DEFINE_CALLNONVIRTUALMETHODV(jboolean, Boolean, T_BOOLEAN | |
2135 , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2136 HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_RETURN(_ret_ref)) | |
2137 DEFINE_CALLNONVIRTUALMETHODV(jbyte, Byte, T_BYTE | |
2138 , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2139 HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_RETURN(_ret_ref)) | |
2140 DEFINE_CALLNONVIRTUALMETHODV(jchar, Char, T_CHAR | |
2141 , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2142 HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_RETURN(_ret_ref)) | |
2143 DEFINE_CALLNONVIRTUALMETHODV(jshort, Short, T_SHORT | |
2144 , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2145 HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_RETURN(_ret_ref)) | |
2146 | |
2147 DEFINE_CALLNONVIRTUALMETHODV(jobject, Object, T_OBJECT | |
2148 , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2149 HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_RETURN(_ret_ref)) | |
2150 DEFINE_CALLNONVIRTUALMETHODV(jint, Int, T_INT | |
2151 , HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2152 HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_RETURN(_ret_ref)) | |
2153 DEFINE_CALLNONVIRTUALMETHODV(jlong, Long, T_LONG | |
2154 , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2155 // Float and double probes don't return value because dtrace doesn't currently support it | |
2156 HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_RETURN(_ret_ref)) | |
2157 DEFINE_CALLNONVIRTUALMETHODV(jfloat, Float, T_FLOAT | |
2158 , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2159 HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_RETURN()) | |
2160 DEFINE_CALLNONVIRTUALMETHODV(jdouble, Double, T_DOUBLE | |
2161 , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2162 HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_RETURN()) | |
2163 | |
2164 #define DEFINE_CALLNONVIRTUALMETHODA(ResultType, Result, Tag \ | |
2165 , EntryProbe, ReturnProbe) \ | |
2166 \ | |
2167 DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodA, ResultType \ | |
2168 , ReturnProbe);\ | |
2169 \ | |
2170 JNI_ENTRY(ResultType, \ | |
2171 jni_CallNonvirtual##Result##MethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args)) \ | |
2172 JNIWrapper("CallNonvitual" XSTR(Result) "MethodA"); \ | |
2173 \ | |
2174 EntryProbe;\ | |
2175 ResultType ret;\ | |
2176 DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodA, ResultType, \ | |
2177 (const ResultType&)ret);\ | |
2178 \ | |
2179 JavaValue jvalue(Tag); \ | |
2180 JNI_ArgumentPusherArray ap(methodID, args); \ | |
2181 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \ | |
2182 ret = jvalue.get_##ResultType(); \ | |
2183 return ret;\ | |
2184 JNI_END | |
2185 | |
2186 // the runtime type of subword integral basic types is integer | |
2187 DEFINE_CALLNONVIRTUALMETHODA(jboolean, Boolean, T_BOOLEAN | |
2188 , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2189 HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_RETURN(_ret_ref)) | |
2190 DEFINE_CALLNONVIRTUALMETHODA(jbyte, Byte, T_BYTE | |
2191 , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2192 HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_RETURN(_ret_ref)) | |
2193 DEFINE_CALLNONVIRTUALMETHODA(jchar, Char, T_CHAR | |
2194 , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2195 HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_RETURN(_ret_ref)) | |
2196 DEFINE_CALLNONVIRTUALMETHODA(jshort, Short, T_SHORT | |
2197 , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2198 HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_RETURN(_ret_ref)) | |
2199 | |
2200 DEFINE_CALLNONVIRTUALMETHODA(jobject, Object, T_OBJECT | |
2201 , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2202 HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_RETURN(_ret_ref)) | |
2203 DEFINE_CALLNONVIRTUALMETHODA(jint, Int, T_INT | |
2204 , HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2205 HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_RETURN(_ret_ref)) | |
2206 DEFINE_CALLNONVIRTUALMETHODA(jlong, Long, T_LONG | |
2207 , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2208 // Float and double probes don't return value because dtrace doesn't currently support it | |
2209 HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_RETURN(_ret_ref)) | |
2210 DEFINE_CALLNONVIRTUALMETHODA(jfloat, Float, T_FLOAT | |
2211 , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2212 HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_RETURN()) | |
2213 DEFINE_CALLNONVIRTUALMETHODA(jdouble, Double, T_DOUBLE | |
2214 , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID), | |
2215 HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_RETURN()) | |
2216 | |
2217 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethod | |
2218 , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_RETURN()); | |
2219 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodV | |
2220 , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_RETURN()); | |
2221 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodA | |
2222 , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_RETURN()); | |
2223 #endif /* USDT2 */ | |
2224 | |
0 | 2225 JNI_ENTRY(void, jni_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...)) |
2226 JNIWrapper("CallNonvirtualVoidMethod"); | |
2227 | |
4006 | 2228 #ifndef USDT2 |
0 | 2229 DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethod__entry, |
2230 env, obj, cls, methodID); | |
4006 | 2231 #else /* USDT2 */ |
2232 HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_ENTRY( | |
2233 env, obj, cls, (uintptr_t) methodID); | |
2234 #endif /* USDT2 */ | |
0 | 2235 DT_VOID_RETURN_MARK(CallNonvirtualVoidMethod); |
2236 | |
2237 va_list args; | |
2238 va_start(args, methodID); | |
2239 JavaValue jvalue(T_VOID); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
2240 JNI_ArgumentPusherVaArg ap(methodID, args); |
0 | 2241 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK); |
2242 va_end(args); | |
2243 JNI_END | |
2244 | |
2245 | |
2246 JNI_ENTRY(void, jni_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args)) | |
2247 JNIWrapper("CallNonvirtualVoidMethodV"); | |
2248 | |
4006 | 2249 #ifndef USDT2 |
0 | 2250 DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethodV__entry, |
2251 env, obj, cls, methodID); | |
4006 | 2252 #else /* USDT2 */ |
2253 HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_ENTRY( | |
2254 env, obj, cls, (uintptr_t) methodID); | |
2255 #endif /* USDT2 */ | |
0 | 2256 DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodV); |
2257 | |
2258 JavaValue jvalue(T_VOID); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
2259 JNI_ArgumentPusherVaArg ap(methodID, args); |
0 | 2260 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK); |
2261 JNI_END | |
2262 | |
2263 | |
2264 JNI_ENTRY(void, jni_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args)) | |
2265 JNIWrapper("CallNonvirtualVoidMethodA"); | |
4006 | 2266 #ifndef USDT2 |
0 | 2267 DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethodA__entry, |
2268 env, obj, cls, methodID); | |
4006 | 2269 #else /* USDT2 */ |
2270 HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_ENTRY( | |
2271 env, obj, cls, (uintptr_t) methodID); | |
2272 #endif /* USDT2 */ | |
0 | 2273 DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodA); |
2274 JavaValue jvalue(T_VOID); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
2275 JNI_ArgumentPusherArray ap(methodID, args); |
0 | 2276 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK); |
2277 JNI_END | |
2278 | |
2279 | |
4006 | 2280 #ifndef USDT2 |
0 | 2281 #define DEFINE_CALLSTATICMETHOD(ResultType, Result, Tag) \ |
2282 \ | |
2283 DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##Method, ResultType);\ | |
2284 DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodV, ResultType);\ | |
2285 DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodA, ResultType);\ | |
2286 \ | |
2287 JNI_ENTRY(ResultType, \ | |
2288 jni_CallStatic##Result##Method(JNIEnv *env, jclass cls, jmethodID methodID, ...)) \ | |
2289 JNIWrapper("CallStatic" XSTR(Result) "Method"); \ | |
2290 \ | |
2291 DTRACE_PROBE3(hotspot_jni, CallStatic##Result##Method__entry, env, cls, methodID);\ | |
2292 ResultType ret = 0;\ | |
2293 DT_RETURN_MARK_FOR(Result, CallStatic##Result##Method, ResultType, \ | |
2294 (const ResultType&)ret);\ | |
2295 \ | |
2296 va_list args; \ | |
2297 va_start(args, methodID); \ | |
2298 JavaValue jvalue(Tag); \ | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
2299 JNI_ArgumentPusherVaArg ap(methodID, args); \ |
0 | 2300 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \ |
2301 va_end(args); \ | |
2302 ret = jvalue.get_##ResultType(); \ | |
2303 return ret;\ | |
2304 JNI_END \ | |
2305 \ | |
2306 JNI_ENTRY(ResultType, \ | |
2307 jni_CallStatic##Result##MethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)) \ | |
2308 JNIWrapper("CallStatic" XSTR(Result) "MethodV"); \ | |
2309 DTRACE_PROBE3(hotspot_jni, CallStatic##Result##MethodV__entry, env, cls, methodID);\ | |
2310 ResultType ret = 0;\ | |
2311 DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodV, ResultType, \ | |
2312 (const ResultType&)ret);\ | |
2313 \ | |
2314 JavaValue jvalue(Tag); \ | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
2315 JNI_ArgumentPusherVaArg ap(methodID, args); \ |
0 | 2316 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \ |
2317 ret = jvalue.get_##ResultType(); \ | |
2318 return ret;\ | |
2319 JNI_END \ | |
2320 \ | |
2321 JNI_ENTRY(ResultType, \ | |
2322 jni_CallStatic##Result##MethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args)) \ | |
2323 JNIWrapper("CallStatic" XSTR(Result) "MethodA"); \ | |
2324 DTRACE_PROBE3(hotspot_jni, CallStatic##Result##MethodA__entry, env, cls, methodID);\ | |
2325 ResultType ret = 0;\ | |
2326 DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodA, ResultType, \ | |
2327 (const ResultType&)ret);\ | |
2328 \ | |
2329 JavaValue jvalue(Tag); \ | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
2330 JNI_ArgumentPusherArray ap(methodID, args); \ |
0 | 2331 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \ |
2332 ret = jvalue.get_##ResultType(); \ | |
2333 return ret;\ | |
2334 JNI_END | |
2335 | |
2336 // the runtime type of subword integral basic types is integer | |
2337 DEFINE_CALLSTATICMETHOD(jboolean, Boolean, T_BOOLEAN) | |
2338 DEFINE_CALLSTATICMETHOD(jbyte, Byte, T_BYTE) | |
2339 DEFINE_CALLSTATICMETHOD(jchar, Char, T_CHAR) | |
2340 DEFINE_CALLSTATICMETHOD(jshort, Short, T_SHORT) | |
2341 | |
2342 DEFINE_CALLSTATICMETHOD(jobject, Object, T_OBJECT) | |
2343 DEFINE_CALLSTATICMETHOD(jint, Int, T_INT) | |
2344 DEFINE_CALLSTATICMETHOD(jlong, Long, T_LONG) | |
2345 DEFINE_CALLSTATICMETHOD(jfloat, Float, T_FLOAT) | |
2346 DEFINE_CALLSTATICMETHOD(jdouble, Double, T_DOUBLE) | |
2347 | |
2348 | |
2349 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethod); | |
2350 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodV); | |
2351 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodA); | |
2352 | |
4006 | 2353 #else /* USDT2 */ |
2354 | |
2355 #define DEFINE_CALLSTATICMETHOD(ResultType, Result, Tag \ | |
2356 , EntryProbe, ResultProbe) \ | |
2357 \ | |
2358 DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##Method, ResultType \ | |
2359 , ResultProbe); \ | |
2360 \ | |
2361 JNI_ENTRY(ResultType, \ | |
2362 jni_CallStatic##Result##Method(JNIEnv *env, jclass cls, jmethodID methodID, ...)) \ | |
2363 JNIWrapper("CallStatic" XSTR(Result) "Method"); \ | |
2364 \ | |
2365 EntryProbe; \ | |
2366 ResultType ret = 0;\ | |
2367 DT_RETURN_MARK_FOR(Result, CallStatic##Result##Method, ResultType, \ | |
2368 (const ResultType&)ret);\ | |
2369 \ | |
2370 va_list args; \ | |
2371 va_start(args, methodID); \ | |
2372 JavaValue jvalue(Tag); \ | |
2373 JNI_ArgumentPusherVaArg ap(methodID, args); \ | |
2374 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \ | |
2375 va_end(args); \ | |
2376 ret = jvalue.get_##ResultType(); \ | |
2377 return ret;\ | |
2378 JNI_END | |
2379 | |
2380 // the runtime type of subword integral basic types is integer | |
2381 DEFINE_CALLSTATICMETHOD(jboolean, Boolean, T_BOOLEAN | |
2382 , HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_ENTRY(env, cls, (uintptr_t)methodID), | |
2383 HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_RETURN(_ret_ref)); | |
2384 DEFINE_CALLSTATICMETHOD(jbyte, Byte, T_BYTE | |
2385 , HOTSPOT_JNI_CALLSTATICBYTEMETHOD_ENTRY(env, cls, (uintptr_t)methodID), | |
2386 HOTSPOT_JNI_CALLSTATICBYTEMETHOD_RETURN(_ret_ref)); | |
2387 DEFINE_CALLSTATICMETHOD(jchar, Char, T_CHAR | |
2388 , HOTSPOT_JNI_CALLSTATICCHARMETHOD_ENTRY(env, cls, (uintptr_t)methodID), | |
2389 HOTSPOT_JNI_CALLSTATICCHARMETHOD_RETURN(_ret_ref)); | |
2390 DEFINE_CALLSTATICMETHOD(jshort, Short, T_SHORT | |
2391 , HOTSPOT_JNI_CALLSTATICSHORTMETHOD_ENTRY(env, cls, (uintptr_t)methodID), | |
2392 HOTSPOT_JNI_CALLSTATICSHORTMETHOD_RETURN(_ret_ref)); | |
2393 | |
2394 DEFINE_CALLSTATICMETHOD(jobject, Object, T_OBJECT | |
2395 , HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_ENTRY(env, cls, (uintptr_t)methodID), | |
2396 HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_RETURN(_ret_ref)); | |
2397 DEFINE_CALLSTATICMETHOD(jint, Int, T_INT | |
2398 , HOTSPOT_JNI_CALLSTATICINTMETHOD_ENTRY(env, cls, (uintptr_t)methodID), | |
2399 HOTSPOT_JNI_CALLSTATICINTMETHOD_RETURN(_ret_ref)); | |
2400 DEFINE_CALLSTATICMETHOD(jlong, Long, T_LONG | |
2401 , HOTSPOT_JNI_CALLSTATICLONGMETHOD_ENTRY(env, cls, (uintptr_t)methodID), | |
2402 HOTSPOT_JNI_CALLSTATICLONGMETHOD_RETURN(_ret_ref)); | |
2403 // Float and double probes don't return value because dtrace doesn't currently support it | |
2404 DEFINE_CALLSTATICMETHOD(jfloat, Float, T_FLOAT | |
2405 , HOTSPOT_JNI_CALLSTATICFLOATMETHOD_ENTRY(env, cls, (uintptr_t)methodID), | |
2406 HOTSPOT_JNI_CALLSTATICFLOATMETHOD_RETURN()); | |
2407 DEFINE_CALLSTATICMETHOD(jdouble, Double, T_DOUBLE | |
2408 , HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_ENTRY(env, cls, (uintptr_t)methodID), | |
2409 HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_RETURN()); | |
2410 | |
2411 #define DEFINE_CALLSTATICMETHODV(ResultType, Result, Tag \ | |
2412 , EntryProbe, ResultProbe) \ | |
2413 \ | |
2414 DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodV, ResultType \ | |
2415 , ResultProbe); \ | |
2416 \ | |
2417 JNI_ENTRY(ResultType, \ | |
2418 jni_CallStatic##Result##MethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)) \ | |
2419 JNIWrapper("CallStatic" XSTR(Result) "MethodV"); \ | |
2420 \ | |
2421 EntryProbe; \ | |
2422 ResultType ret = 0;\ | |
2423 DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodV, ResultType, \ | |
2424 (const ResultType&)ret);\ | |
2425 \ | |
2426 JavaValue jvalue(Tag); \ | |
2427 JNI_ArgumentPusherVaArg ap(methodID, args); \ | |
2428 /* Make sure class is initialized before trying to invoke its method */ \ | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2429 KlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls))); \ |
4006 | 2430 Klass::cast(k())->initialize(CHECK_0); \ |
2431 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \ | |
2432 va_end(args); \ | |
2433 ret = jvalue.get_##ResultType(); \ | |
2434 return ret;\ | |
2435 JNI_END | |
2436 | |
2437 // the runtime type of subword integral basic types is integer | |
2438 DEFINE_CALLSTATICMETHODV(jboolean, Boolean, T_BOOLEAN | |
2439 , HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_ENTRY(env, cls, (uintptr_t)methodID), | |
2440 HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_RETURN(_ret_ref)); | |
2441 DEFINE_CALLSTATICMETHODV(jbyte, Byte, T_BYTE | |
2442 , HOTSPOT_JNI_CALLSTATICBYTEMETHODV_ENTRY(env, cls, (uintptr_t)methodID), | |
2443 HOTSPOT_JNI_CALLSTATICBYTEMETHODV_RETURN(_ret_ref)); | |
2444 DEFINE_CALLSTATICMETHODV(jchar, Char, T_CHAR | |
2445 , HOTSPOT_JNI_CALLSTATICCHARMETHODV_ENTRY(env, cls, (uintptr_t)methodID), | |
2446 HOTSPOT_JNI_CALLSTATICCHARMETHODV_RETURN(_ret_ref)); | |
2447 DEFINE_CALLSTATICMETHODV(jshort, Short, T_SHORT | |
2448 , HOTSPOT_JNI_CALLSTATICSHORTMETHODV_ENTRY(env, cls, (uintptr_t)methodID), | |
2449 HOTSPOT_JNI_CALLSTATICSHORTMETHODV_RETURN(_ret_ref)); | |
2450 | |
2451 DEFINE_CALLSTATICMETHODV(jobject, Object, T_OBJECT | |
2452 , HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_ENTRY(env, cls, (uintptr_t)methodID), | |
2453 HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_RETURN(_ret_ref)); | |
2454 DEFINE_CALLSTATICMETHODV(jint, Int, T_INT | |
2455 , HOTSPOT_JNI_CALLSTATICINTMETHODV_ENTRY(env, cls, (uintptr_t)methodID), | |
2456 HOTSPOT_JNI_CALLSTATICINTMETHODV_RETURN(_ret_ref)); | |
2457 DEFINE_CALLSTATICMETHODV(jlong, Long, T_LONG | |
2458 , HOTSPOT_JNI_CALLSTATICLONGMETHODV_ENTRY(env, cls, (uintptr_t)methodID), | |
2459 HOTSPOT_JNI_CALLSTATICLONGMETHODV_RETURN(_ret_ref)); | |
2460 // Float and double probes don't return value because dtrace doesn't currently support it | |
2461 DEFINE_CALLSTATICMETHODV(jfloat, Float, T_FLOAT | |
2462 , HOTSPOT_JNI_CALLSTATICFLOATMETHODV_ENTRY(env, cls, (uintptr_t)methodID), | |
2463 HOTSPOT_JNI_CALLSTATICFLOATMETHODV_RETURN()); | |
2464 DEFINE_CALLSTATICMETHODV(jdouble, Double, T_DOUBLE | |
2465 , HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_ENTRY(env, cls, (uintptr_t)methodID), | |
2466 HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_RETURN()); | |
2467 | |
2468 #define DEFINE_CALLSTATICMETHODA(ResultType, Result, Tag \ | |
2469 , EntryProbe, ResultProbe) \ | |
2470 \ | |
2471 DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodA, ResultType \ | |
2472 , ResultProbe); \ | |
2473 \ | |
2474 JNI_ENTRY(ResultType, \ | |
2475 jni_CallStatic##Result##MethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args)) \ | |
2476 JNIWrapper("CallStatic" XSTR(Result) "MethodA"); \ | |
2477 \ | |
2478 EntryProbe; \ | |
2479 ResultType ret = 0;\ | |
2480 DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodA, ResultType, \ | |
2481 (const ResultType&)ret);\ | |
2482 \ | |
2483 JavaValue jvalue(Tag); \ | |
2484 JNI_ArgumentPusherArray ap(methodID, args); \ | |
2485 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \ | |
2486 ret = jvalue.get_##ResultType(); \ | |
2487 return ret;\ | |
2488 JNI_END | |
2489 | |
2490 // the runtime type of subword integral basic types is integer | |
2491 DEFINE_CALLSTATICMETHODA(jboolean, Boolean, T_BOOLEAN | |
2492 , HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_ENTRY(env, cls, (uintptr_t)methodID), | |
2493 HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_RETURN(_ret_ref)); | |
2494 DEFINE_CALLSTATICMETHODA(jbyte, Byte, T_BYTE | |
2495 , HOTSPOT_JNI_CALLSTATICBYTEMETHODA_ENTRY(env, cls, (uintptr_t)methodID), | |
2496 HOTSPOT_JNI_CALLSTATICBYTEMETHODA_RETURN(_ret_ref)); | |
2497 DEFINE_CALLSTATICMETHODA(jchar, Char, T_CHAR | |
2498 , HOTSPOT_JNI_CALLSTATICCHARMETHODA_ENTRY(env, cls, (uintptr_t)methodID), | |
2499 HOTSPOT_JNI_CALLSTATICCHARMETHODA_RETURN(_ret_ref)); | |
2500 DEFINE_CALLSTATICMETHODA(jshort, Short, T_SHORT | |
2501 , HOTSPOT_JNI_CALLSTATICSHORTMETHODA_ENTRY(env, cls, (uintptr_t)methodID), | |
2502 HOTSPOT_JNI_CALLSTATICSHORTMETHODA_RETURN(_ret_ref)); | |
2503 | |
2504 DEFINE_CALLSTATICMETHODA(jobject, Object, T_OBJECT | |
2505 , HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_ENTRY(env, cls, (uintptr_t)methodID), | |
2506 HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_RETURN(_ret_ref)); | |
2507 DEFINE_CALLSTATICMETHODA(jint, Int, T_INT | |
2508 , HOTSPOT_JNI_CALLSTATICINTMETHODA_ENTRY(env, cls, (uintptr_t)methodID), | |
2509 HOTSPOT_JNI_CALLSTATICINTMETHODA_RETURN(_ret_ref)); | |
2510 DEFINE_CALLSTATICMETHODA(jlong, Long, T_LONG | |
2511 , HOTSPOT_JNI_CALLSTATICLONGMETHODA_ENTRY(env, cls, (uintptr_t)methodID), | |
2512 HOTSPOT_JNI_CALLSTATICLONGMETHODA_RETURN(_ret_ref)); | |
2513 // Float and double probes don't return value because dtrace doesn't currently support it | |
2514 DEFINE_CALLSTATICMETHODA(jfloat, Float, T_FLOAT | |
2515 , HOTSPOT_JNI_CALLSTATICFLOATMETHODA_ENTRY(env, cls, (uintptr_t)methodID), | |
2516 HOTSPOT_JNI_CALLSTATICFLOATMETHODA_RETURN()); | |
2517 DEFINE_CALLSTATICMETHODA(jdouble, Double, T_DOUBLE | |
2518 , HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_ENTRY(env, cls, (uintptr_t)methodID), | |
2519 HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_RETURN()); | |
2520 | |
2521 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethod | |
2522 , HOTSPOT_JNI_CALLSTATICVOIDMETHOD_RETURN()); | |
2523 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodV | |
2524 , HOTSPOT_JNI_CALLSTATICVOIDMETHODV_RETURN()); | |
2525 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodA | |
2526 , HOTSPOT_JNI_CALLSTATICVOIDMETHODA_RETURN()); | |
2527 #endif /* USDT2 */ | |
2528 | |
0 | 2529 JNI_ENTRY(void, jni_CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)) |
2530 JNIWrapper("CallStaticVoidMethod"); | |
4006 | 2531 #ifndef USDT2 |
0 | 2532 DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethod__entry, env, cls, methodID); |
4006 | 2533 #else /* USDT2 */ |
2534 HOTSPOT_JNI_CALLSTATICVOIDMETHOD_ENTRY( | |
2535 env, cls, (uintptr_t) methodID); | |
2536 #endif /* USDT2 */ | |
0 | 2537 DT_VOID_RETURN_MARK(CallStaticVoidMethod); |
2538 | |
2539 va_list args; | |
2540 va_start(args, methodID); | |
2541 JavaValue jvalue(T_VOID); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
2542 JNI_ArgumentPusherVaArg ap(methodID, args); |
0 | 2543 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK); |
2544 va_end(args); | |
2545 JNI_END | |
2546 | |
2547 | |
2548 JNI_ENTRY(void, jni_CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)) | |
2549 JNIWrapper("CallStaticVoidMethodV"); | |
4006 | 2550 #ifndef USDT2 |
0 | 2551 DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethodV__entry, env, cls, methodID); |
4006 | 2552 #else /* USDT2 */ |
2553 HOTSPOT_JNI_CALLSTATICVOIDMETHODV_ENTRY( | |
2554 env, cls, (uintptr_t) methodID); | |
2555 #endif /* USDT2 */ | |
0 | 2556 DT_VOID_RETURN_MARK(CallStaticVoidMethodV); |
2557 | |
2558 JavaValue jvalue(T_VOID); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
2559 JNI_ArgumentPusherVaArg ap(methodID, args); |
0 | 2560 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK); |
2561 JNI_END | |
2562 | |
2563 | |
2564 JNI_ENTRY(void, jni_CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args)) | |
2565 JNIWrapper("CallStaticVoidMethodA"); | |
4006 | 2566 #ifndef USDT2 |
0 | 2567 DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethodA__entry, env, cls, methodID); |
4006 | 2568 #else /* USDT2 */ |
2569 HOTSPOT_JNI_CALLSTATICVOIDMETHODA_ENTRY( | |
2570 env, cls, (uintptr_t) methodID); | |
2571 #endif /* USDT2 */ | |
0 | 2572 DT_VOID_RETURN_MARK(CallStaticVoidMethodA); |
2573 | |
2574 JavaValue jvalue(T_VOID); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
2575 JNI_ArgumentPusherArray ap(methodID, args); |
0 | 2576 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK); |
2577 JNI_END | |
2578 | |
2579 | |
2580 // | |
2581 // Accessing Fields | |
2582 // | |
2583 | |
2584 | |
4006 | 2585 #ifndef USDT2 |
0 | 2586 DT_RETURN_MARK_DECL(GetFieldID, jfieldID); |
4006 | 2587 #else /* USDT2 */ |
2588 DT_RETURN_MARK_DECL(GetFieldID, jfieldID | |
2589 , HOTSPOT_JNI_GETFIELDID_RETURN((uintptr_t)_ret_ref)); | |
2590 #endif /* USDT2 */ | |
0 | 2591 |
2592 JNI_ENTRY(jfieldID, jni_GetFieldID(JNIEnv *env, jclass clazz, | |
2593 const char *name, const char *sig)) | |
2594 JNIWrapper("GetFieldID"); | |
4006 | 2595 #ifndef USDT2 |
0 | 2596 DTRACE_PROBE4(hotspot_jni, GetFieldID__entry, env, clazz, name, sig); |
4006 | 2597 #else /* USDT2 */ |
2598 HOTSPOT_JNI_GETFIELDID_ENTRY( | |
2599 env, clazz, (char *) name, (char *) sig); | |
2600 #endif /* USDT2 */ | |
0 | 2601 jfieldID ret = 0; |
2602 DT_RETURN_MARK(GetFieldID, jfieldID, (const jfieldID&)ret); | |
2603 | |
2604 // The class should have been loaded (we have an instance of the class | |
2605 // passed in) so the field and signature should already be in the symbol | |
2606 // table. If they're not there, the field doesn't exist. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
2607 TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name)); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
2608 TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig)); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
2609 if (fieldname == NULL || signame == NULL) { |
0 | 2610 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name); |
2611 } | |
2612 KlassHandle k(THREAD, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2613 java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); |
0 | 2614 // Make sure class is initialized before handing id's out to fields |
2615 Klass::cast(k())->initialize(CHECK_NULL); | |
2616 | |
2617 fieldDescriptor fd; | |
2618 if (!Klass::cast(k())->oop_is_instance() || | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2619 !InstanceKlass::cast(k())->find_field(fieldname, signame, false, &fd)) { |
0 | 2620 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name); |
2621 } | |
2622 | |
2623 // A jfieldID for a non-static field is simply the offset of the field within the instanceOop | |
2624 // It may also have hash bits for k, if VerifyJNIFields is turned on. | |
2625 ret = jfieldIDWorkaround::to_instance_jfieldID(k(), fd.offset()); | |
2626 return ret; | |
2627 JNI_END | |
2628 | |
2629 | |
2630 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)) | |
2631 JNIWrapper("GetObjectField"); | |
4006 | 2632 #ifndef USDT2 |
0 | 2633 DTRACE_PROBE3(hotspot_jni, GetObjectField__entry, env, obj, fieldID); |
4006 | 2634 #else /* USDT2 */ |
2635 HOTSPOT_JNI_GETOBJECTFIELD_ENTRY( | |
2636 env, obj, (uintptr_t) fieldID); | |
2637 #endif /* USDT2 */ | |
0 | 2638 oop o = JNIHandles::resolve_non_null(obj); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2639 Klass* k = o->klass(); |
0 | 2640 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); |
2641 // Keep JVMTI addition small and only check enabled flag here. | |
2642 // jni_GetField_probe() assumes that is okay to create handles. | |
2643 if (JvmtiExport::should_post_field_access()) { | |
2644 o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false); | |
2645 } | |
2646 jobject ret = JNIHandles::make_local(env, o->obj_field(offset)); | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2647 #ifndef SERIALGC |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2648 // If G1 is enabled and we are accessing the value of the referent |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2649 // field in a reference object then we need to register a non-null |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2650 // referent with the SATB barrier. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2651 if (UseG1GC) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2652 bool needs_barrier = false; |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2653 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2654 if (ret != NULL && |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2655 offset == java_lang_ref_Reference::referent_offset && |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2656 InstanceKlass::cast(k)->reference_type() != REF_NONE) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2657 assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity"); |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2658 needs_barrier = true; |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2659 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2660 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2661 if (needs_barrier) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2662 oop referent = JNIHandles::resolve(ret); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2663 G1SATBCardTableModRefBS::enqueue(referent); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2664 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2665 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
2666 #endif // SERIALGC |
4006 | 2667 #ifndef USDT2 |
0 | 2668 DTRACE_PROBE1(hotspot_jni, GetObjectField__return, ret); |
4006 | 2669 #else /* USDT2 */ |
2670 HOTSPOT_JNI_GETOBJECTFIELD_RETURN( | |
2671 ret); | |
2672 #endif /* USDT2 */ | |
0 | 2673 return ret; |
2674 JNI_END | |
2675 | |
2676 | |
4006 | 2677 #ifndef USDT2 |
0 | 2678 #define DEFINE_GETFIELD(Return,Fieldname,Result) \ |
2679 \ | |
2680 DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return);\ | |
2681 \ | |
2682 JNI_QUICK_ENTRY(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \ | |
2683 JNIWrapper("Get" XSTR(Result) "Field"); \ | |
2684 \ | |
2685 DTRACE_PROBE3(hotspot_jni, Get##Result##Field__entry, env, obj, fieldID);\ | |
2686 Return ret = 0;\ | |
2687 DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\ | |
2688 \ | |
2689 oop o = JNIHandles::resolve_non_null(obj); \ | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2690 Klass* k = o->klass(); \ |
0 | 2691 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \ |
2692 /* Keep JVMTI addition small and only check enabled flag here. */ \ | |
2693 /* jni_GetField_probe_nh() assumes that is not okay to create handles */ \ | |
2694 /* and creates a ResetNoHandleMark. */ \ | |
2695 if (JvmtiExport::should_post_field_access()) { \ | |
2696 o = JvmtiExport::jni_GetField_probe_nh(thread, obj, o, k, fieldID, false); \ | |
2697 } \ | |
2698 ret = o->Fieldname##_field(offset); \ | |
2699 return ret; \ | |
2700 JNI_END | |
2701 | |
2702 DEFINE_GETFIELD(jboolean, bool, Boolean) | |
2703 DEFINE_GETFIELD(jbyte, byte, Byte) | |
2704 DEFINE_GETFIELD(jchar, char, Char) | |
2705 DEFINE_GETFIELD(jshort, short, Short) | |
2706 DEFINE_GETFIELD(jint, int, Int) | |
2707 DEFINE_GETFIELD(jlong, long, Long) | |
2708 DEFINE_GETFIELD(jfloat, float, Float) | |
2709 DEFINE_GETFIELD(jdouble, double, Double) | |
2710 | |
4006 | 2711 #else /* USDT2 */ |
2712 | |
2713 #define DEFINE_GETFIELD(Return,Fieldname,Result \ | |
2714 , EntryProbe, ReturnProbe) \ | |
2715 \ | |
2716 DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \ | |
2717 , ReturnProbe); \ | |
2718 \ | |
2719 JNI_QUICK_ENTRY(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \ | |
2720 JNIWrapper("Get" XSTR(Result) "Field"); \ | |
2721 \ | |
2722 EntryProbe; \ | |
2723 Return ret = 0;\ | |
2724 DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\ | |
2725 \ | |
2726 oop o = JNIHandles::resolve_non_null(obj); \ | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2727 Klass* k = o->klass(); \ |
4006 | 2728 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \ |
2729 /* Keep JVMTI addition small and only check enabled flag here. */ \ | |
2730 /* jni_GetField_probe_nh() assumes that is not okay to create handles */ \ | |
2731 /* and creates a ResetNoHandleMark. */ \ | |
2732 if (JvmtiExport::should_post_field_access()) { \ | |
2733 o = JvmtiExport::jni_GetField_probe_nh(thread, obj, o, k, fieldID, false); \ | |
2734 } \ | |
2735 ret = o->Fieldname##_field(offset); \ | |
2736 return ret; \ | |
2737 JNI_END | |
2738 | |
2739 DEFINE_GETFIELD(jboolean, bool, Boolean | |
2740 , HOTSPOT_JNI_GETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID), | |
2741 HOTSPOT_JNI_GETBOOLEANFIELD_RETURN(_ret_ref)) | |
2742 DEFINE_GETFIELD(jbyte, byte, Byte | |
2743 , HOTSPOT_JNI_GETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID), | |
2744 HOTSPOT_JNI_GETBYTEFIELD_RETURN(_ret_ref)) | |
2745 DEFINE_GETFIELD(jchar, char, Char | |
2746 , HOTSPOT_JNI_GETCHARFIELD_ENTRY(env, obj, (uintptr_t)fieldID), | |
2747 HOTSPOT_JNI_GETCHARFIELD_RETURN(_ret_ref)) | |
2748 DEFINE_GETFIELD(jshort, short, Short | |
2749 , HOTSPOT_JNI_GETSHORTFIELD_ENTRY(env, obj, (uintptr_t)fieldID), | |
2750 HOTSPOT_JNI_GETSHORTFIELD_RETURN(_ret_ref)) | |
2751 DEFINE_GETFIELD(jint, int, Int | |
2752 , HOTSPOT_JNI_GETINTFIELD_ENTRY(env, obj, (uintptr_t)fieldID), | |
2753 HOTSPOT_JNI_GETINTFIELD_RETURN(_ret_ref)) | |
2754 DEFINE_GETFIELD(jlong, long, Long | |
2755 , HOTSPOT_JNI_GETLONGFIELD_ENTRY(env, obj, (uintptr_t)fieldID), | |
2756 HOTSPOT_JNI_GETLONGFIELD_RETURN(_ret_ref)) | |
2757 // Float and double probes don't return value because dtrace doesn't currently support it | |
2758 DEFINE_GETFIELD(jfloat, float, Float | |
2759 , HOTSPOT_JNI_GETFLOATFIELD_ENTRY(env, obj, (uintptr_t)fieldID), | |
2760 HOTSPOT_JNI_GETFLOATFIELD_RETURN()) | |
2761 DEFINE_GETFIELD(jdouble, double, Double | |
2762 , HOTSPOT_JNI_GETDOUBLEFIELD_ENTRY(env, obj, (uintptr_t)fieldID), | |
2763 HOTSPOT_JNI_GETDOUBLEFIELD_RETURN()) | |
2764 #endif /* USDT2 */ | |
2765 | |
0 | 2766 address jni_GetBooleanField_addr() { |
2767 return (address)jni_GetBooleanField; | |
2768 } | |
2769 address jni_GetByteField_addr() { | |
2770 return (address)jni_GetByteField; | |
2771 } | |
2772 address jni_GetCharField_addr() { | |
2773 return (address)jni_GetCharField; | |
2774 } | |
2775 address jni_GetShortField_addr() { | |
2776 return (address)jni_GetShortField; | |
2777 } | |
2778 address jni_GetIntField_addr() { | |
2779 return (address)jni_GetIntField; | |
2780 } | |
2781 address jni_GetLongField_addr() { | |
2782 return (address)jni_GetLongField; | |
2783 } | |
2784 address jni_GetFloatField_addr() { | |
2785 return (address)jni_GetFloatField; | |
2786 } | |
2787 address jni_GetDoubleField_addr() { | |
2788 return (address)jni_GetDoubleField; | |
2789 } | |
2790 | |
2791 JNI_QUICK_ENTRY(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value)) | |
2792 JNIWrapper("SetObjectField"); | |
4006 | 2793 #ifndef USDT2 |
0 | 2794 DTRACE_PROBE4(hotspot_jni, SetObjectField__entry, env, obj, fieldID, value); |
4006 | 2795 #else /* USDT2 */ |
2796 HOTSPOT_JNI_SETOBJECTFIELD_ENTRY( | |
2797 env, obj, (uintptr_t) fieldID, value); | |
2798 #endif /* USDT2 */ | |
0 | 2799 oop o = JNIHandles::resolve_non_null(obj); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2800 Klass* k = o->klass(); |
0 | 2801 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); |
2802 // Keep JVMTI addition small and only check enabled flag here. | |
2803 // jni_SetField_probe_nh() assumes that is not okay to create handles | |
2804 // and creates a ResetNoHandleMark. | |
2805 if (JvmtiExport::should_post_field_modification()) { | |
2806 jvalue field_value; | |
2807 field_value.l = value; | |
2808 o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, 'L', (jvalue *)&field_value); | |
2809 } | |
2810 o->obj_field_put(offset, JNIHandles::resolve(value)); | |
4006 | 2811 #ifndef USDT2 |
0 | 2812 DTRACE_PROBE(hotspot_jni, SetObjectField__return); |
4006 | 2813 #else /* USDT2 */ |
2814 HOTSPOT_JNI_SETOBJECTFIELD_RETURN( | |
2815 ); | |
2816 #endif /* USDT2 */ | |
0 | 2817 JNI_END |
2818 | |
4006 | 2819 #ifndef USDT2 |
0 | 2820 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType) \ |
2821 \ | |
2822 JNI_QUICK_ENTRY(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \ | |
2823 JNIWrapper("Set" XSTR(Result) "Field"); \ | |
2824 \ | |
6837
75982791ddb6
7170638: Use DTRACE_PROBE[N] in JNI Set and SetStatic Field.
coleenp
parents:
6831
diff
changeset
|
2825 FP_SELECT_##Result( \ |
75982791ddb6
7170638: Use DTRACE_PROBE[N] in JNI Set and SetStatic Field.
coleenp
parents:
6831
diff
changeset
|
2826 DTRACE_PROBE4(hotspot_jni, Set##Result##Field__entry, env, obj, fieldID, value), \ |
75982791ddb6
7170638: Use DTRACE_PROBE[N] in JNI Set and SetStatic Field.
coleenp
parents:
6831
diff
changeset
|
2827 DTRACE_PROBE3(hotspot_jni, Set##Result##Field__entry, env, obj, fieldID)); \ |
0 | 2828 \ |
2829 oop o = JNIHandles::resolve_non_null(obj); \ | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2830 Klass* k = o->klass(); \ |
0 | 2831 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \ |
2832 /* Keep JVMTI addition small and only check enabled flag here. */ \ | |
2833 /* jni_SetField_probe_nh() assumes that is not okay to create handles */ \ | |
2834 /* and creates a ResetNoHandleMark. */ \ | |
2835 if (JvmtiExport::should_post_field_modification()) { \ | |
2836 jvalue field_value; \ | |
2837 field_value.unionType = value; \ | |
2838 o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \ | |
2839 } \ | |
2840 o->Fieldname##_field_put(offset, value); \ | |
2841 DTRACE_PROBE(hotspot_jni, Set##Result##Field__return);\ | |
2842 JNI_END | |
2843 | |
2844 DEFINE_SETFIELD(jboolean, bool, Boolean, 'Z', z) | |
2845 DEFINE_SETFIELD(jbyte, byte, Byte, 'B', b) | |
2846 DEFINE_SETFIELD(jchar, char, Char, 'C', c) | |
2847 DEFINE_SETFIELD(jshort, short, Short, 'S', s) | |
2848 DEFINE_SETFIELD(jint, int, Int, 'I', i) | |
2849 DEFINE_SETFIELD(jlong, long, Long, 'J', j) | |
2850 DEFINE_SETFIELD(jfloat, float, Float, 'F', f) | |
2851 DEFINE_SETFIELD(jdouble, double, Double, 'D', d) | |
2852 | |
4006 | 2853 #else /* USDT2 */ |
2854 | |
2855 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \ | |
2856 , EntryProbe, ReturnProbe) \ | |
2857 \ | |
2858 JNI_QUICK_ENTRY(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \ | |
2859 JNIWrapper("Set" XSTR(Result) "Field"); \ | |
2860 \ | |
2861 EntryProbe; \ | |
2862 \ | |
2863 oop o = JNIHandles::resolve_non_null(obj); \ | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2864 Klass* k = o->klass(); \ |
4006 | 2865 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \ |
2866 /* Keep JVMTI addition small and only check enabled flag here. */ \ | |
2867 /* jni_SetField_probe_nh() assumes that is not okay to create handles */ \ | |
2868 /* and creates a ResetNoHandleMark. */ \ | |
2869 if (JvmtiExport::should_post_field_modification()) { \ | |
2870 jvalue field_value; \ | |
2871 field_value.unionType = value; \ | |
2872 o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \ | |
2873 } \ | |
2874 o->Fieldname##_field_put(offset, value); \ | |
2875 ReturnProbe; \ | |
2876 JNI_END | |
2877 | |
2878 DEFINE_SETFIELD(jboolean, bool, Boolean, 'Z', z | |
2879 , HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value), | |
2880 HOTSPOT_JNI_SETBOOLEANFIELD_RETURN()) | |
2881 DEFINE_SETFIELD(jbyte, byte, Byte, 'B', b | |
2882 , HOTSPOT_JNI_SETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value), | |
2883 HOTSPOT_JNI_SETBYTEFIELD_RETURN()) | |
2884 DEFINE_SETFIELD(jchar, char, Char, 'C', c | |
2885 , HOTSPOT_JNI_SETCHARFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value), | |
2886 HOTSPOT_JNI_SETCHARFIELD_RETURN()) | |
2887 DEFINE_SETFIELD(jshort, short, Short, 'S', s | |
2888 , HOTSPOT_JNI_SETSHORTFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value), | |
2889 HOTSPOT_JNI_SETSHORTFIELD_RETURN()) | |
2890 DEFINE_SETFIELD(jint, int, Int, 'I', i | |
2891 , HOTSPOT_JNI_SETINTFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value), | |
2892 HOTSPOT_JNI_SETINTFIELD_RETURN()) | |
2893 DEFINE_SETFIELD(jlong, long, Long, 'J', j | |
2894 , HOTSPOT_JNI_SETLONGFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value), | |
2895 HOTSPOT_JNI_SETLONGFIELD_RETURN()) | |
2896 // Float and double probes don't return value because dtrace doesn't currently support it | |
2897 DEFINE_SETFIELD(jfloat, float, Float, 'F', f | |
2898 , HOTSPOT_JNI_SETFLOATFIELD_ENTRY(env, obj, (uintptr_t)fieldID), | |
2899 HOTSPOT_JNI_SETFLOATFIELD_RETURN()) | |
2900 DEFINE_SETFIELD(jdouble, double, Double, 'D', d | |
2901 , HOTSPOT_JNI_SETDOUBLEFIELD_ENTRY(env, obj, (uintptr_t)fieldID), | |
2902 HOTSPOT_JNI_SETDOUBLEFIELD_RETURN()) | |
2903 #endif /* USDT2 */ | |
2904 | |
2905 #ifndef USDT2 | |
0 | 2906 DT_RETURN_MARK_DECL(ToReflectedField, jobject); |
4006 | 2907 #else /* USDT2 */ |
2908 DT_RETURN_MARK_DECL(ToReflectedField, jobject | |
2909 , HOTSPOT_JNI_TOREFLECTEDFIELD_RETURN(_ret_ref)); | |
2910 #endif /* USDT2 */ | |
0 | 2911 |
2912 JNI_ENTRY(jobject, jni_ToReflectedField(JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic)) | |
2913 JNIWrapper("ToReflectedField"); | |
4006 | 2914 #ifndef USDT2 |
0 | 2915 DTRACE_PROBE4(hotspot_jni, ToReflectedField__entry, |
2916 env, cls, fieldID, isStatic); | |
4006 | 2917 #else /* USDT2 */ |
2918 HOTSPOT_JNI_TOREFLECTEDFIELD_ENTRY( | |
2919 env, cls, (uintptr_t) fieldID, isStatic); | |
2920 #endif /* USDT2 */ | |
0 | 2921 jobject ret = NULL; |
2922 DT_RETURN_MARK(ToReflectedField, jobject, (const jobject&)ret); | |
2923 | |
2924 fieldDescriptor fd; | |
2925 bool found = false; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2926 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); |
0 | 2927 |
2928 assert(jfieldIDWorkaround::is_static_jfieldID(fieldID) == (isStatic != 0), "invalid fieldID"); | |
2929 | |
2930 if (isStatic) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2931 // Static field. The fieldID a JNIid specifying the field holder and the offset within the Klass*. |
0 | 2932 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); |
2933 assert(id->is_static_field_id(), "invalid static field id"); | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2177
diff
changeset
|
2934 found = id->find_local_field(&fd); |
0 | 2935 } else { |
2936 // Non-static field. The fieldID is really the offset of the field within the instanceOop. | |
2937 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2938 found = InstanceKlass::cast(k)->find_field_from_offset(offset, false, &fd); |
0 | 2939 } |
2940 assert(found, "bad fieldID passed into jni_ToReflectedField"); | |
2941 oop reflected = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL); | |
2942 ret = JNIHandles::make_local(env, reflected); | |
2943 return ret; | |
2944 JNI_END | |
2945 | |
2946 | |
2947 // | |
2948 // Accessing Static Fields | |
2949 // | |
4006 | 2950 #ifndef USDT2 |
0 | 2951 DT_RETURN_MARK_DECL(GetStaticFieldID, jfieldID); |
4006 | 2952 #else /* USDT2 */ |
2953 DT_RETURN_MARK_DECL(GetStaticFieldID, jfieldID | |
2954 , HOTSPOT_JNI_GETSTATICFIELDID_RETURN((uintptr_t)_ret_ref)); | |
2955 #endif /* USDT2 */ | |
0 | 2956 |
2957 JNI_ENTRY(jfieldID, jni_GetStaticFieldID(JNIEnv *env, jclass clazz, | |
2958 const char *name, const char *sig)) | |
2959 JNIWrapper("GetStaticFieldID"); | |
4006 | 2960 #ifndef USDT2 |
0 | 2961 DTRACE_PROBE4(hotspot_jni, GetStaticFieldID__entry, env, clazz, name, sig); |
4006 | 2962 #else /* USDT2 */ |
2963 HOTSPOT_JNI_GETSTATICFIELDID_ENTRY( | |
2964 env, clazz, (char *) name, (char *) sig); | |
2965 #endif /* USDT2 */ | |
0 | 2966 jfieldID ret = NULL; |
2967 DT_RETURN_MARK(GetStaticFieldID, jfieldID, (const jfieldID&)ret); | |
2968 | |
2969 // The class should have been loaded (we have an instance of the class | |
2970 // passed in) so the field and signature should already be in the symbol | |
2971 // table. If they're not there, the field doesn't exist. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
2972 TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name)); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
2973 TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig)); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
2974 if (fieldname == NULL || signame == NULL) { |
0 | 2975 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name); |
2976 } | |
2977 KlassHandle k(THREAD, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2978 java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); |
0 | 2979 // Make sure class is initialized before handing id's out to static fields |
2980 Klass::cast(k())->initialize(CHECK_NULL); | |
2981 | |
2982 fieldDescriptor fd; | |
2983 if (!Klass::cast(k())->oop_is_instance() || | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2984 !InstanceKlass::cast(k())->find_field(fieldname, signame, true, &fd)) { |
0 | 2985 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name); |
2986 } | |
2987 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2988 // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass* |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6856
diff
changeset
|
2989 JNIid* id = fd.field_holder()->jni_id_for(fd.offset()); |
0 | 2990 debug_only(id->set_is_static_field_id();) |
2991 | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2177
diff
changeset
|
2992 debug_only(id->verify(fd.field_holder())); |
0 | 2993 |
2994 ret = jfieldIDWorkaround::to_static_jfieldID(id); | |
2995 return ret; | |
2996 JNI_END | |
2997 | |
2998 | |
2999 JNI_ENTRY(jobject, jni_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)) | |
3000 JNIWrapper("GetStaticObjectField"); | |
4006 | 3001 #ifndef USDT2 |
0 | 3002 DTRACE_PROBE3(hotspot_jni, GetStaticObjectField__entry, env, clazz, fieldID); |
4006 | 3003 #else /* USDT2 */ |
3004 HOTSPOT_JNI_GETSTATICOBJECTFIELD_ENTRY( | |
3005 env, clazz, (uintptr_t) fieldID); | |
3006 #endif /* USDT2 */ | |
6854
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6725
diff
changeset
|
3007 #if INCLUDE_JNI_CHECK |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
3008 DEBUG_ONLY(Klass* param_k = jniCheck::validate_class(thread, clazz);) |
6854
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6725
diff
changeset
|
3009 #endif // INCLUDE_JNI_CHECK |
0 | 3010 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); |
3011 assert(id->is_static_field_id(), "invalid static field id"); | |
3012 // Keep JVMTI addition small and only check enabled flag here. | |
3013 // jni_GetField_probe() assumes that is okay to create handles. | |
3014 if (JvmtiExport::should_post_field_access()) { | |
3015 JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true); | |
3016 } | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2177
diff
changeset
|
3017 jobject ret = JNIHandles::make_local(id->holder()->java_mirror()->obj_field(id->offset())); |
4006 | 3018 #ifndef USDT2 |
0 | 3019 DTRACE_PROBE1(hotspot_jni, GetStaticObjectField__return, ret); |
4006 | 3020 #else /* USDT2 */ |
3021 HOTSPOT_JNI_GETSTATICOBJECTFIELD_RETURN( | |
3022 ret); | |
3023 #endif /* USDT2 */ | |
0 | 3024 return ret; |
3025 JNI_END | |
3026 | |
4006 | 3027 #ifndef USDT2 |
0 | 3028 #define DEFINE_GETSTATICFIELD(Return,Fieldname,Result) \ |
3029 \ | |
3030 DT_RETURN_MARK_DECL_FOR(Result, GetStatic##Result##Field, Return);\ | |
3031 \ | |
3032 JNI_ENTRY(Return, jni_GetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID)) \ | |
3033 JNIWrapper("GetStatic" XSTR(Result) "Field"); \ | |
3034 DTRACE_PROBE3(hotspot_jni, GetStatic##Result##Field__entry, env, clazz, fieldID);\ | |
3035 Return ret = 0;\ | |
3036 DT_RETURN_MARK_FOR(Result, GetStatic##Result##Field, Return, \ | |
3037 (const Return&)ret);\ | |
3038 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \ | |
3039 assert(id->is_static_field_id(), "invalid static field id"); \ | |
3040 /* Keep JVMTI addition small and only check enabled flag here. */ \ | |
3041 /* jni_GetField_probe() assumes that is okay to create handles. */ \ | |
3042 if (JvmtiExport::should_post_field_access()) { \ | |
3043 JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true); \ | |
3044 } \ | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2177
diff
changeset
|
3045 ret = id->holder()->java_mirror()-> Fieldname##_field (id->offset()); \ |
0 | 3046 return ret;\ |
3047 JNI_END | |
3048 | |
3049 DEFINE_GETSTATICFIELD(jboolean, bool, Boolean) | |
3050 DEFINE_GETSTATICFIELD(jbyte, byte, Byte) | |
3051 DEFINE_GETSTATICFIELD(jchar, char, Char) | |
3052 DEFINE_GETSTATICFIELD(jshort, short, Short) | |
3053 DEFINE_GETSTATICFIELD(jint, int, Int) | |
3054 DEFINE_GETSTATICFIELD(jlong, long, Long) | |
3055 DEFINE_GETSTATICFIELD(jfloat, float, Float) | |
3056 DEFINE_GETSTATICFIELD(jdouble, double, Double) | |
3057 | |
4006 | 3058 #else /* USDT2 */ |
3059 | |
3060 #define DEFINE_GETSTATICFIELD(Return,Fieldname,Result \ | |
3061 , EntryProbe, ReturnProbe) \ | |
3062 \ | |
3063 DT_RETURN_MARK_DECL_FOR(Result, GetStatic##Result##Field, Return \ | |
3064 , ReturnProbe); \ | |
3065 \ | |
3066 JNI_ENTRY(Return, jni_GetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID)) \ | |
3067 JNIWrapper("GetStatic" XSTR(Result) "Field"); \ | |
3068 EntryProbe; \ | |
3069 Return ret = 0;\ | |
3070 DT_RETURN_MARK_FOR(Result, GetStatic##Result##Field, Return, \ | |
3071 (const Return&)ret);\ | |
3072 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \ | |
3073 assert(id->is_static_field_id(), "invalid static field id"); \ | |
3074 /* Keep JVMTI addition small and only check enabled flag here. */ \ | |
3075 /* jni_GetField_probe() assumes that is okay to create handles. */ \ | |
3076 if (JvmtiExport::should_post_field_access()) { \ | |
3077 JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true); \ | |
3078 } \ | |
3079 ret = id->holder()->java_mirror()-> Fieldname##_field (id->offset()); \ | |
3080 return ret;\ | |
3081 JNI_END | |
3082 | |
3083 DEFINE_GETSTATICFIELD(jboolean, bool, Boolean | |
3084 , HOTSPOT_JNI_GETSTATICBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICBOOLEANFIELD_RETURN(_ret_ref)) | |
3085 DEFINE_GETSTATICFIELD(jbyte, byte, Byte | |
3086 , HOTSPOT_JNI_GETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICBYTEFIELD_RETURN(_ret_ref) ) | |
3087 DEFINE_GETSTATICFIELD(jchar, char, Char | |
3088 , HOTSPOT_JNI_GETSTATICCHARFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICCHARFIELD_RETURN(_ret_ref) ) | |
3089 DEFINE_GETSTATICFIELD(jshort, short, Short | |
3090 , HOTSPOT_JNI_GETSTATICSHORTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICSHORTFIELD_RETURN(_ret_ref) ) | |
3091 DEFINE_GETSTATICFIELD(jint, int, Int | |
3092 , HOTSPOT_JNI_GETSTATICINTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICINTFIELD_RETURN(_ret_ref) ) | |
3093 DEFINE_GETSTATICFIELD(jlong, long, Long | |
3094 , HOTSPOT_JNI_GETSTATICLONGFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICLONGFIELD_RETURN(_ret_ref) ) | |
3095 // Float and double probes don't return value because dtrace doesn't currently support it | |
3096 DEFINE_GETSTATICFIELD(jfloat, float, Float | |
3097 , HOTSPOT_JNI_GETSTATICFLOATFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICFLOATFIELD_RETURN() ) | |
3098 DEFINE_GETSTATICFIELD(jdouble, double, Double | |
3099 , HOTSPOT_JNI_GETSTATICDOUBLEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICDOUBLEFIELD_RETURN() ) | |
3100 #endif /* USDT2 */ | |
0 | 3101 |
3102 JNI_ENTRY(void, jni_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)) | |
3103 JNIWrapper("SetStaticObjectField"); | |
4006 | 3104 #ifndef USDT2 |
0 | 3105 DTRACE_PROBE4(hotspot_jni, SetStaticObjectField__entry, env, clazz, fieldID, value); |
4006 | 3106 #else /* USDT2 */ |
3107 HOTSPOT_JNI_SETSTATICOBJECTFIELD_ENTRY( | |
3108 env, clazz, (uintptr_t) fieldID, value); | |
3109 #endif /* USDT2 */ | |
0 | 3110 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); |
3111 assert(id->is_static_field_id(), "invalid static field id"); | |
3112 // Keep JVMTI addition small and only check enabled flag here. | |
3113 // jni_SetField_probe() assumes that is okay to create handles. | |
3114 if (JvmtiExport::should_post_field_modification()) { | |
3115 jvalue field_value; | |
3116 field_value.l = value; | |
3117 JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, 'L', (jvalue *)&field_value); | |
3118 } | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2177
diff
changeset
|
3119 id->holder()->java_mirror()->obj_field_put(id->offset(), JNIHandles::resolve(value)); |
4006 | 3120 #ifndef USDT2 |
0 | 3121 DTRACE_PROBE(hotspot_jni, SetStaticObjectField__return); |
4006 | 3122 #else /* USDT2 */ |
3123 HOTSPOT_JNI_SETSTATICOBJECTFIELD_RETURN( | |
3124 ); | |
3125 #endif /* USDT2 */ | |
0 | 3126 JNI_END |
3127 | |
3128 | |
4006 | 3129 #ifndef USDT2 |
0 | 3130 #define DEFINE_SETSTATICFIELD(Argument,Fieldname,Result,SigType,unionType) \ |
3131 \ | |
3132 JNI_ENTRY(void, jni_SetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID, Argument value)) \ | |
3133 JNIWrapper("SetStatic" XSTR(Result) "Field"); \ | |
6837
75982791ddb6
7170638: Use DTRACE_PROBE[N] in JNI Set and SetStatic Field.
coleenp
parents:
6831
diff
changeset
|
3134 FP_SELECT_##Result( \ |
75982791ddb6
7170638: Use DTRACE_PROBE[N] in JNI Set and SetStatic Field.
coleenp
parents:
6831
diff
changeset
|
3135 DTRACE_PROBE4(hotspot_jni, SetStatic##Result##Field__entry, env, clazz, fieldID, value), \ |
75982791ddb6
7170638: Use DTRACE_PROBE[N] in JNI Set and SetStatic Field.
coleenp
parents:
6831
diff
changeset
|
3136 DTRACE_PROBE3(hotspot_jni, SetStatic##Result##Field__entry, env, clazz, fieldID)); \ |
0 | 3137 \ |
3138 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \ | |
3139 assert(id->is_static_field_id(), "invalid static field id"); \ | |
3140 /* Keep JVMTI addition small and only check enabled flag here. */ \ | |
3141 /* jni_SetField_probe() assumes that is okay to create handles. */ \ | |
3142 if (JvmtiExport::should_post_field_modification()) { \ | |
3143 jvalue field_value; \ | |
3144 field_value.unionType = value; \ | |
3145 JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \ | |
3146 } \ | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2177
diff
changeset
|
3147 id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \ |
0 | 3148 DTRACE_PROBE(hotspot_jni, SetStatic##Result##Field__return);\ |
3149 JNI_END | |
3150 | |
3151 DEFINE_SETSTATICFIELD(jboolean, bool, Boolean, 'Z', z) | |
3152 DEFINE_SETSTATICFIELD(jbyte, byte, Byte, 'B', b) | |
3153 DEFINE_SETSTATICFIELD(jchar, char, Char, 'C', c) | |
3154 DEFINE_SETSTATICFIELD(jshort, short, Short, 'S', s) | |
3155 DEFINE_SETSTATICFIELD(jint, int, Int, 'I', i) | |
3156 DEFINE_SETSTATICFIELD(jlong, long, Long, 'J', j) | |
3157 DEFINE_SETSTATICFIELD(jfloat, float, Float, 'F', f) | |
3158 DEFINE_SETSTATICFIELD(jdouble, double, Double, 'D', d) | |
3159 | |
4006 | 3160 #else /* USDT2 */ |
3161 | |
3162 #define DEFINE_SETSTATICFIELD(Argument,Fieldname,Result,SigType,unionType \ | |
3163 , EntryProbe, ReturnProbe) \ | |
3164 \ | |
3165 JNI_ENTRY(void, jni_SetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID, Argument value)) \ | |
3166 JNIWrapper("SetStatic" XSTR(Result) "Field"); \ | |
3167 EntryProbe; \ | |
3168 \ | |
3169 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \ | |
3170 assert(id->is_static_field_id(), "invalid static field id"); \ | |
3171 /* Keep JVMTI addition small and only check enabled flag here. */ \ | |
3172 /* jni_SetField_probe() assumes that is okay to create handles. */ \ | |
3173 if (JvmtiExport::should_post_field_modification()) { \ | |
3174 jvalue field_value; \ | |
3175 field_value.unionType = value; \ | |
3176 JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \ | |
3177 } \ | |
3178 id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \ | |
3179 ReturnProbe;\ | |
3180 JNI_END | |
3181 | |
3182 DEFINE_SETSTATICFIELD(jboolean, bool, Boolean, 'Z', z | |
3183 , HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t)fieldID, value), | |
3184 HOTSPOT_JNI_SETBOOLEANFIELD_RETURN()) | |
3185 DEFINE_SETSTATICFIELD(jbyte, byte, Byte, 'B', b | |
3186 , HOTSPOT_JNI_SETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value), | |
3187 HOTSPOT_JNI_SETSTATICBYTEFIELD_RETURN()) | |
3188 DEFINE_SETSTATICFIELD(jchar, char, Char, 'C', c | |
3189 , HOTSPOT_JNI_SETSTATICCHARFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value), | |
3190 HOTSPOT_JNI_SETSTATICCHARFIELD_RETURN()) | |
3191 DEFINE_SETSTATICFIELD(jshort, short, Short, 'S', s | |
3192 , HOTSPOT_JNI_SETSTATICSHORTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value), | |
3193 HOTSPOT_JNI_SETSTATICSHORTFIELD_RETURN()) | |
3194 DEFINE_SETSTATICFIELD(jint, int, Int, 'I', i | |
3195 , HOTSPOT_JNI_SETSTATICINTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value), | |
3196 HOTSPOT_JNI_SETSTATICINTFIELD_RETURN()) | |
3197 DEFINE_SETSTATICFIELD(jlong, long, Long, 'J', j | |
3198 , HOTSPOT_JNI_SETSTATICLONGFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value), | |
3199 HOTSPOT_JNI_SETSTATICLONGFIELD_RETURN()) | |
3200 // Float and double probes don't return value because dtrace doesn't currently support it | |
3201 DEFINE_SETSTATICFIELD(jfloat, float, Float, 'F', f | |
3202 , HOTSPOT_JNI_SETSTATICFLOATFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), | |
3203 HOTSPOT_JNI_SETSTATICFLOATFIELD_RETURN()) | |
3204 DEFINE_SETSTATICFIELD(jdouble, double, Double, 'D', d | |
3205 , HOTSPOT_JNI_SETSTATICDOUBLEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), | |
3206 HOTSPOT_JNI_SETSTATICDOUBLEFIELD_RETURN()) | |
3207 #endif /* USDT2 */ | |
0 | 3208 |
3209 // | |
3210 // String Operations | |
3211 // | |
3212 | |
3213 // Unicode Interface | |
3214 | |
4006 | 3215 #ifndef USDT2 |
0 | 3216 DT_RETURN_MARK_DECL(NewString, jstring); |
4006 | 3217 #else /* USDT2 */ |
3218 DT_RETURN_MARK_DECL(NewString, jstring | |
3219 , HOTSPOT_JNI_NEWSTRING_RETURN(_ret_ref)); | |
3220 #endif /* USDT2 */ | |
0 | 3221 |
3222 JNI_ENTRY(jstring, jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len)) | |
3223 JNIWrapper("NewString"); | |
4006 | 3224 #ifndef USDT2 |
0 | 3225 DTRACE_PROBE3(hotspot_jni, NewString__entry, env, unicodeChars, len); |
4006 | 3226 #else /* USDT2 */ |
3227 HOTSPOT_JNI_NEWSTRING_ENTRY( | |
3228 env, (uint16_t *) unicodeChars, len); | |
3229 #endif /* USDT2 */ | |
0 | 3230 jstring ret = NULL; |
3231 DT_RETURN_MARK(NewString, jstring, (const jstring&)ret); | |
3232 oop string=java_lang_String::create_oop_from_unicode((jchar*) unicodeChars, len, CHECK_NULL); | |
3233 ret = (jstring) JNIHandles::make_local(env, string); | |
3234 return ret; | |
3235 JNI_END | |
3236 | |
3237 | |
3238 JNI_QUICK_ENTRY(jsize, jni_GetStringLength(JNIEnv *env, jstring string)) | |
3239 JNIWrapper("GetStringLength"); | |
4006 | 3240 #ifndef USDT2 |
0 | 3241 DTRACE_PROBE2(hotspot_jni, GetStringLength__entry, env, string); |
4006 | 3242 #else /* USDT2 */ |
3243 HOTSPOT_JNI_GETSTRINGLENGTH_ENTRY( | |
3244 env, string); | |
3245 #endif /* USDT2 */ | |
0 | 3246 jsize ret = java_lang_String::length(JNIHandles::resolve_non_null(string)); |
4006 | 3247 #ifndef USDT2 |
0 | 3248 DTRACE_PROBE1(hotspot_jni, GetStringLength__return, ret); |
4006 | 3249 #else /* USDT2 */ |
3250 HOTSPOT_JNI_GETSTRINGLENGTH_RETURN( | |
3251 ret); | |
3252 #endif /* USDT2 */ | |
0 | 3253 return ret; |
3254 JNI_END | |
3255 | |
3256 | |
3257 JNI_QUICK_ENTRY(const jchar*, jni_GetStringChars( | |
3258 JNIEnv *env, jstring string, jboolean *isCopy)) | |
3259 JNIWrapper("GetStringChars"); | |
4006 | 3260 #ifndef USDT2 |
0 | 3261 DTRACE_PROBE3(hotspot_jni, GetStringChars__entry, env, string, isCopy); |
4006 | 3262 #else /* USDT2 */ |
3263 HOTSPOT_JNI_GETSTRINGCHARS_ENTRY( | |
3264 env, string, (uintptr_t *) isCopy); | |
3265 #endif /* USDT2 */ | |
0 | 3266 //%note jni_5 |
3267 if (isCopy != NULL) { | |
3268 *isCopy = JNI_TRUE; | |
3269 } | |
3270 oop s = JNIHandles::resolve_non_null(string); | |
3271 int s_len = java_lang_String::length(s); | |
3272 typeArrayOop s_value = java_lang_String::value(s); | |
3273 int s_offset = java_lang_String::offset(s); | |
6197 | 3274 jchar* buf = NEW_C_HEAP_ARRAY(jchar, s_len + 1, mtInternal); // add one for zero termination |
0 | 3275 if (s_len > 0) { |
3276 memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len); | |
3277 } | |
3278 buf[s_len] = 0; | |
4006 | 3279 #ifndef USDT2 |
0 | 3280 DTRACE_PROBE1(hotspot_jni, GetStringChars__return, buf); |
4006 | 3281 #else /* USDT2 */ |
3282 HOTSPOT_JNI_GETSTRINGCHARS_RETURN( | |
3283 buf); | |
3284 #endif /* USDT2 */ | |
0 | 3285 return buf; |
3286 JNI_END | |
3287 | |
3288 | |
3289 JNI_QUICK_ENTRY(void, jni_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)) | |
3290 JNIWrapper("ReleaseStringChars"); | |
4006 | 3291 #ifndef USDT2 |
0 | 3292 DTRACE_PROBE3(hotspot_jni, ReleaseStringChars__entry, env, str, chars); |
4006 | 3293 #else /* USDT2 */ |
3294 HOTSPOT_JNI_RELEASESTRINGCHARS_ENTRY( | |
3295 env, str, (uint16_t *) chars); | |
3296 #endif /* USDT2 */ | |
0 | 3297 //%note jni_6 |
3298 if (chars != NULL) { | |
3299 // Since String objects are supposed to be immutable, don't copy any | |
3300 // new data back. A bad user will have to go after the char array. | |
3301 FreeHeap((void*) chars); | |
3302 } | |
4006 | 3303 #ifndef USDT2 |
0 | 3304 DTRACE_PROBE(hotspot_jni, ReleaseStringChars__return); |
4006 | 3305 #else /* USDT2 */ |
3306 HOTSPOT_JNI_RELEASESTRINGCHARS_RETURN( | |
3307 ); | |
3308 #endif /* USDT2 */ | |
0 | 3309 JNI_END |
3310 | |
3311 | |
3312 // UTF Interface | |
3313 | |
4006 | 3314 #ifndef USDT2 |
0 | 3315 DT_RETURN_MARK_DECL(NewStringUTF, jstring); |
4006 | 3316 #else /* USDT2 */ |
3317 DT_RETURN_MARK_DECL(NewStringUTF, jstring | |
3318 , HOTSPOT_JNI_NEWSTRINGUTF_RETURN(_ret_ref)); | |
3319 #endif /* USDT2 */ | |
0 | 3320 |
3321 JNI_ENTRY(jstring, jni_NewStringUTF(JNIEnv *env, const char *bytes)) | |
3322 JNIWrapper("NewStringUTF"); | |
4006 | 3323 #ifndef USDT2 |
0 | 3324 DTRACE_PROBE2(hotspot_jni, NewStringUTF__entry, env, bytes); |
4006 | 3325 #else /* USDT2 */ |
3326 HOTSPOT_JNI_NEWSTRINGUTF_ENTRY( | |
3327 env, (char *) bytes); | |
3328 #endif /* USDT2 */ | |
0 | 3329 jstring ret; |
3330 DT_RETURN_MARK(NewStringUTF, jstring, (const jstring&)ret); | |
3331 | |
3332 oop result = java_lang_String::create_oop_from_str((char*) bytes, CHECK_NULL); | |
3333 ret = (jstring) JNIHandles::make_local(env, result); | |
3334 return ret; | |
3335 JNI_END | |
3336 | |
3337 | |
3338 JNI_ENTRY(jsize, jni_GetStringUTFLength(JNIEnv *env, jstring string)) | |
3339 JNIWrapper("GetStringUTFLength"); | |
4006 | 3340 #ifndef USDT2 |
0 | 3341 DTRACE_PROBE2(hotspot_jni, GetStringUTFLength__entry, env, string); |
4006 | 3342 #else /* USDT2 */ |
3343 HOTSPOT_JNI_GETSTRINGUTFLENGTH_ENTRY( | |
3344 env, string); | |
3345 #endif /* USDT2 */ | |
0 | 3346 jsize ret = java_lang_String::utf8_length(JNIHandles::resolve_non_null(string)); |
4006 | 3347 #ifndef USDT2 |
0 | 3348 DTRACE_PROBE1(hotspot_jni, GetStringUTFLength__return, ret); |
4006 | 3349 #else /* USDT2 */ |
3350 HOTSPOT_JNI_GETSTRINGUTFLENGTH_RETURN( | |
3351 ret); | |
3352 #endif /* USDT2 */ | |
0 | 3353 return ret; |
3354 JNI_END | |
3355 | |
3356 | |
3357 JNI_ENTRY(const char*, jni_GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)) | |
3358 JNIWrapper("GetStringUTFChars"); | |
4006 | 3359 #ifndef USDT2 |
0 | 3360 DTRACE_PROBE3(hotspot_jni, GetStringUTFChars__entry, env, string, isCopy); |
4006 | 3361 #else /* USDT2 */ |
3362 HOTSPOT_JNI_GETSTRINGUTFCHARS_ENTRY( | |
3363 env, string, (uintptr_t *) isCopy); | |
3364 #endif /* USDT2 */ | |
1989
017cd8bce8a8
6539281: -Xcheck:jni should validate char* argument to ReleaseStringUTFChars
sla
parents:
1980
diff
changeset
|
3365 oop java_string = JNIHandles::resolve_non_null(string); |
017cd8bce8a8
6539281: -Xcheck:jni should validate char* argument to ReleaseStringUTFChars
sla
parents:
1980
diff
changeset
|
3366 size_t length = java_lang_String::utf8_length(java_string); |
6197 | 3367 char* result = AllocateHeap(length + 1, mtInternal); |
1989
017cd8bce8a8
6539281: -Xcheck:jni should validate char* argument to ReleaseStringUTFChars
sla
parents:
1980
diff
changeset
|
3368 java_lang_String::as_utf8_string(java_string, result, (int) length + 1); |
0 | 3369 if (isCopy != NULL) *isCopy = JNI_TRUE; |
4006 | 3370 #ifndef USDT2 |
0 | 3371 DTRACE_PROBE1(hotspot_jni, GetStringUTFChars__return, result); |
4006 | 3372 #else /* USDT2 */ |
3373 HOTSPOT_JNI_GETSTRINGUTFCHARS_RETURN( | |
3374 result); | |
3375 #endif /* USDT2 */ | |
0 | 3376 return result; |
3377 JNI_END | |
3378 | |
3379 | |
3380 JNI_LEAF(void, jni_ReleaseStringUTFChars(JNIEnv *env, jstring str, const char *chars)) | |
3381 JNIWrapper("ReleaseStringUTFChars"); | |
4006 | 3382 #ifndef USDT2 |
0 | 3383 DTRACE_PROBE3(hotspot_jni, ReleaseStringUTFChars__entry, env, str, chars); |
4006 | 3384 #else /* USDT2 */ |
3385 HOTSPOT_JNI_RELEASESTRINGUTFCHARS_ENTRY( | |
3386 env, str, (char *) chars); | |
3387 #endif /* USDT2 */ | |
0 | 3388 if (chars != NULL) { |
3389 FreeHeap((char*) chars); | |
3390 } | |
4006 | 3391 #ifndef USDT2 |
0 | 3392 DTRACE_PROBE(hotspot_jni, ReleaseStringUTFChars__return); |
4006 | 3393 #else /* USDT2 */ |
3394 HOTSPOT_JNI_RELEASESTRINGUTFCHARS_RETURN( | |
3395 ); | |
3396 #endif /* USDT2 */ | |
0 | 3397 JNI_END |
3398 | |
3399 | |
3400 JNI_QUICK_ENTRY(jsize, jni_GetArrayLength(JNIEnv *env, jarray array)) | |
3401 JNIWrapper("GetArrayLength"); | |
4006 | 3402 #ifndef USDT2 |
0 | 3403 DTRACE_PROBE2(hotspot_jni, GetArrayLength__entry, env, array); |
4006 | 3404 #else /* USDT2 */ |
3405 HOTSPOT_JNI_GETARRAYLENGTH_ENTRY( | |
3406 env, array); | |
3407 #endif /* USDT2 */ | |
0 | 3408 arrayOop a = arrayOop(JNIHandles::resolve_non_null(array)); |
3409 assert(a->is_array(), "must be array"); | |
3410 jsize ret = a->length(); | |
4006 | 3411 #ifndef USDT2 |
0 | 3412 DTRACE_PROBE1(hotspot_jni, GetArrayLength__return, ret); |
4006 | 3413 #else /* USDT2 */ |
3414 HOTSPOT_JNI_GETARRAYLENGTH_RETURN( | |
3415 ret); | |
3416 #endif /* USDT2 */ | |
0 | 3417 return ret; |
3418 JNI_END | |
3419 | |
3420 | |
3421 // | |
3422 // Object Array Operations | |
3423 // | |
3424 | |
4006 | 3425 #ifndef USDT2 |
0 | 3426 DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray); |
4006 | 3427 #else /* USDT2 */ |
3428 DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray | |
3429 , HOTSPOT_JNI_NEWOBJECTARRAY_RETURN(_ret_ref)); | |
3430 #endif /* USDT2 */ | |
0 | 3431 |
3432 JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)) | |
3433 JNIWrapper("NewObjectArray"); | |
4006 | 3434 #ifndef USDT2 |
0 | 3435 DTRACE_PROBE4(hotspot_jni, NewObjectArray__entry, env, length, elementClass, initialElement); |
4006 | 3436 #else /* USDT2 */ |
3437 HOTSPOT_JNI_NEWOBJECTARRAY_ENTRY( | |
3438 env, length, elementClass, initialElement); | |
3439 #endif /* USDT2 */ | |
0 | 3440 jobjectArray ret = NULL; |
3441 DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
3442 KlassHandle ek(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(elementClass))); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
3443 Klass* ako = Klass::cast(ek())->array_klass(CHECK_NULL); |
0 | 3444 KlassHandle ak = KlassHandle(THREAD, ako); |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
3445 ObjArrayKlass::cast(ak())->initialize(CHECK_NULL); |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
3446 objArrayOop result = ObjArrayKlass::cast(ak())->allocate(length, CHECK_NULL); |
0 | 3447 oop initial_value = JNIHandles::resolve(initialElement); |
3448 if (initial_value != NULL) { // array already initialized with NULL | |
3449 for (int index = 0; index < length; index++) { | |
3450 result->obj_at_put(index, initial_value); | |
3451 } | |
3452 } | |
3453 ret = (jobjectArray) JNIHandles::make_local(env, result); | |
3454 return ret; | |
3455 JNI_END | |
3456 | |
4006 | 3457 #ifndef USDT2 |
0 | 3458 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject); |
4006 | 3459 #else /* USDT2 */ |
3460 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject | |
3461 , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref)); | |
3462 #endif /* USDT2 */ | |
0 | 3463 |
3464 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)) | |
3465 JNIWrapper("GetObjectArrayElement"); | |
4006 | 3466 #ifndef USDT2 |
0 | 3467 DTRACE_PROBE3(hotspot_jni, GetObjectArrayElement__entry, env, array, index); |
4006 | 3468 #else /* USDT2 */ |
3469 HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY( | |
3470 env, array, index); | |
3471 #endif /* USDT2 */ | |
0 | 3472 jobject ret = NULL; |
3473 DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret); | |
3474 objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array)); | |
3475 if (a->is_within_bounds(index)) { | |
1034
08780c8a9f04
6893483: DTrace probe return values for a couple JNI methods are wrong
kamg
parents:
973
diff
changeset
|
3476 ret = JNIHandles::make_local(env, a->obj_at(index)); |
0 | 3477 return ret; |
3478 } else { | |
3479 char buf[jintAsStringSize]; | |
3480 sprintf(buf, "%d", index); | |
3481 THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), buf); | |
3482 } | |
3483 JNI_END | |
3484 | |
4006 | 3485 #ifndef USDT2 |
0 | 3486 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement); |
4006 | 3487 #else /* USDT2 */ |
3488 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement | |
3489 , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN()); | |
3490 #endif /* USDT2 */ | |
0 | 3491 |
3492 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value)) | |
3493 JNIWrapper("SetObjectArrayElement"); | |
4006 | 3494 #ifndef USDT2 |
0 | 3495 DTRACE_PROBE4(hotspot_jni, SetObjectArrayElement__entry, env, array, index, value); |
4006 | 3496 #else /* USDT2 */ |
3497 HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY( | |
3498 env, array, index, value); | |
3499 #endif /* USDT2 */ | |
0 | 3500 DT_VOID_RETURN_MARK(SetObjectArrayElement); |
3501 | |
3502 objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array)); | |
3503 oop v = JNIHandles::resolve(value); | |
3504 if (a->is_within_bounds(index)) { | |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
3505 if (v == NULL || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) { |
0 | 3506 a->obj_at_put(index, v); |
3507 } else { | |
3508 THROW(vmSymbols::java_lang_ArrayStoreException()); | |
3509 } | |
3510 } else { | |
3511 char buf[jintAsStringSize]; | |
3512 sprintf(buf, "%d", index); | |
3513 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), buf); | |
3514 } | |
3515 JNI_END | |
3516 | |
3517 | |
4006 | 3518 #ifndef USDT2 |
0 | 3519 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result) \ |
3520 \ | |
4006 | 3521 DT_RETURN_MARK_DECL(New##Result##Array, Return); \ |
0 | 3522 \ |
3523 JNI_ENTRY(Return, \ | |
3524 jni_New##Result##Array(JNIEnv *env, jsize len)) \ | |
3525 JNIWrapper("New" XSTR(Result) "Array"); \ | |
3526 DTRACE_PROBE2(hotspot_jni, New##Result##Array__entry, env, len);\ | |
3527 Return ret = NULL;\ | |
1034
08780c8a9f04
6893483: DTrace probe return values for a couple JNI methods are wrong
kamg
parents:
973
diff
changeset
|
3528 DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\ |
0 | 3529 \ |
3530 oop obj= oopFactory::Allocator(len, CHECK_0); \ | |
3531 ret = (Return) JNIHandles::make_local(env, obj); \ | |
3532 return ret;\ | |
3533 JNI_END | |
3534 | |
3535 DEFINE_NEWSCALARARRAY(jbooleanArray, new_boolArray, Boolean) | |
3536 DEFINE_NEWSCALARARRAY(jbyteArray, new_byteArray, Byte) | |
3537 DEFINE_NEWSCALARARRAY(jshortArray, new_shortArray, Short) | |
3538 DEFINE_NEWSCALARARRAY(jcharArray, new_charArray, Char) | |
3539 DEFINE_NEWSCALARARRAY(jintArray, new_intArray, Int) | |
3540 DEFINE_NEWSCALARARRAY(jlongArray, new_longArray, Long) | |
3541 DEFINE_NEWSCALARARRAY(jfloatArray, new_singleArray, Float) | |
3542 DEFINE_NEWSCALARARRAY(jdoubleArray, new_doubleArray, Double) | |
3543 | |
4006 | 3544 #else /* USDT2 */ |
3545 | |
3546 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \ | |
3547 ,EntryProbe,ReturnProbe) \ | |
3548 \ | |
3549 DT_RETURN_MARK_DECL(New##Result##Array, Return \ | |
3550 , ReturnProbe); \ | |
3551 \ | |
3552 JNI_ENTRY(Return, \ | |
3553 jni_New##Result##Array(JNIEnv *env, jsize len)) \ | |
3554 JNIWrapper("New" XSTR(Result) "Array"); \ | |
3555 EntryProbe; \ | |
3556 Return ret = NULL;\ | |
3557 DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\ | |
3558 \ | |
3559 oop obj= oopFactory::Allocator(len, CHECK_0); \ | |
3560 ret = (Return) JNIHandles::make_local(env, obj); \ | |
3561 return ret;\ | |
3562 JNI_END | |
3563 | |
3564 DEFINE_NEWSCALARARRAY(jbooleanArray, new_boolArray, Boolean, | |
3565 HOTSPOT_JNI_NEWBOOLEANARRAY_ENTRY(env, len), | |
3566 HOTSPOT_JNI_NEWBOOLEANARRAY_RETURN(_ret_ref)) | |
3567 DEFINE_NEWSCALARARRAY(jbyteArray, new_byteArray, Byte, | |
3568 HOTSPOT_JNI_NEWBYTEARRAY_ENTRY(env, len), | |
3569 HOTSPOT_JNI_NEWBYTEARRAY_RETURN(_ret_ref)) | |
3570 DEFINE_NEWSCALARARRAY(jshortArray, new_shortArray, Short, | |
3571 HOTSPOT_JNI_NEWSHORTARRAY_ENTRY(env, len), | |
3572 HOTSPOT_JNI_NEWSHORTARRAY_RETURN(_ret_ref)) | |
3573 DEFINE_NEWSCALARARRAY(jcharArray, new_charArray, Char, | |
3574 HOTSPOT_JNI_NEWCHARARRAY_ENTRY(env, len), | |
3575 HOTSPOT_JNI_NEWCHARARRAY_RETURN(_ret_ref)) | |
3576 DEFINE_NEWSCALARARRAY(jintArray, new_intArray, Int, | |
3577 HOTSPOT_JNI_NEWINTARRAY_ENTRY(env, len), | |
3578 HOTSPOT_JNI_NEWINTARRAY_RETURN(_ret_ref)) | |
3579 DEFINE_NEWSCALARARRAY(jlongArray, new_longArray, Long, | |
3580 HOTSPOT_JNI_NEWLONGARRAY_ENTRY(env, len), | |
3581 HOTSPOT_JNI_NEWLONGARRAY_RETURN(_ret_ref)) | |
3582 DEFINE_NEWSCALARARRAY(jfloatArray, new_singleArray, Float, | |
3583 HOTSPOT_JNI_NEWFLOATARRAY_ENTRY(env, len), | |
3584 HOTSPOT_JNI_NEWFLOATARRAY_RETURN(_ret_ref)) | |
3585 DEFINE_NEWSCALARARRAY(jdoubleArray, new_doubleArray, Double, | |
3586 HOTSPOT_JNI_NEWDOUBLEARRAY_ENTRY(env, len), | |
3587 HOTSPOT_JNI_NEWDOUBLEARRAY_RETURN(_ret_ref)) | |
3588 #endif /* USDT2 */ | |
0 | 3589 |
3590 // Return an address which will fault if the caller writes to it. | |
3591 | |
3592 static char* get_bad_address() { | |
3593 static char* bad_address = NULL; | |
3594 if (bad_address == NULL) { | |
3595 size_t size = os::vm_allocation_granularity(); | |
3596 bad_address = os::reserve_memory(size); | |
3597 if (bad_address != NULL) { | |
477
24fda36852ce
6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents:
237
diff
changeset
|
3598 os::protect_memory(bad_address, size, os::MEM_PROT_READ, |
24fda36852ce
6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents:
237
diff
changeset
|
3599 /*is_committed*/false); |
0 | 3600 } |
3601 } | |
3602 return bad_address; | |
3603 } | |
3604 | |
3605 | |
4006 | 3606 #ifndef USDT2 |
0 | 3607 #define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag) \ |
3608 \ | |
3609 JNI_QUICK_ENTRY(ElementType*, \ | |
3610 jni_Get##Result##ArrayElements(JNIEnv *env, ElementType##Array array, jboolean *isCopy)) \ | |
3611 JNIWrapper("Get" XSTR(Result) "ArrayElements"); \ | |
3612 DTRACE_PROBE3(hotspot_jni, Get##Result##ArrayElements__entry, env, array, isCopy);\ | |
3613 /* allocate an chunk of memory in c land */ \ | |
3614 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \ | |
3615 ElementType* result; \ | |
3616 int len = a->length(); \ | |
3617 if (len == 0) { \ | |
3618 /* Empty array: legal but useless, can't return NULL. \ | |
3619 * Return a pointer to something useless. \ | |
3620 * Avoid asserts in typeArrayOop. */ \ | |
3621 result = (ElementType*)get_bad_address(); \ | |
3622 } else { \ | |
6197 | 3623 result = NEW_C_HEAP_ARRAY(ElementType, len, mtInternal); \ |
0 | 3624 /* copy the array to the c chunk */ \ |
3625 memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \ | |
3626 } \ | |
3627 if (isCopy) *isCopy = JNI_TRUE; \ | |
3628 DTRACE_PROBE1(hotspot_jni, Get##Result##ArrayElements__return, result);\ | |
3629 return result; \ | |
3630 JNI_END | |
3631 | |
3632 DEFINE_GETSCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool) | |
3633 DEFINE_GETSCALARARRAYELEMENTS(T_BYTE, jbyte, Byte, byte) | |
3634 DEFINE_GETSCALARARRAYELEMENTS(T_SHORT, jshort, Short, short) | |
3635 DEFINE_GETSCALARARRAYELEMENTS(T_CHAR, jchar, Char, char) | |
3636 DEFINE_GETSCALARARRAYELEMENTS(T_INT, jint, Int, int) | |
3637 DEFINE_GETSCALARARRAYELEMENTS(T_LONG, jlong, Long, long) | |
3638 DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float) | |
3639 DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double) | |
3640 | |
4006 | 3641 #else /* USDT2 */ |
3642 | |
3643 #define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag \ | |
3644 , EntryProbe, ReturnProbe) \ | |
3645 \ | |
3646 JNI_QUICK_ENTRY(ElementType*, \ | |
3647 jni_Get##Result##ArrayElements(JNIEnv *env, ElementType##Array array, jboolean *isCopy)) \ | |
3648 JNIWrapper("Get" XSTR(Result) "ArrayElements"); \ | |
3649 EntryProbe; \ | |
3650 /* allocate an chunk of memory in c land */ \ | |
3651 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \ | |
3652 ElementType* result; \ | |
3653 int len = a->length(); \ | |
3654 if (len == 0) { \ | |
3655 /* Empty array: legal but useless, can't return NULL. \ | |
3656 * Return a pointer to something useless. \ | |
3657 * Avoid asserts in typeArrayOop. */ \ | |
3658 result = (ElementType*)get_bad_address(); \ | |
3659 } else { \ | |
6197 | 3660 result = NEW_C_HEAP_ARRAY(ElementType, len, mtInternal); \ |
4006 | 3661 /* copy the array to the c chunk */ \ |
3662 memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \ | |
3663 } \ | |
3664 if (isCopy) *isCopy = JNI_TRUE; \ | |
3665 ReturnProbe; \ | |
3666 return result; \ | |
3667 JNI_END | |
3668 | |
3669 DEFINE_GETSCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool | |
3670 , HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy), | |
3671 HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_RETURN((uintptr_t*)result)) | |
3672 DEFINE_GETSCALARARRAYELEMENTS(T_BYTE, jbyte, Byte, byte | |
3673 , HOTSPOT_JNI_GETBYTEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy), | |
3674 HOTSPOT_JNI_GETBYTEARRAYELEMENTS_RETURN((char*)result)) | |
3675 DEFINE_GETSCALARARRAYELEMENTS(T_SHORT, jshort, Short, short | |
3676 , HOTSPOT_JNI_GETSHORTARRAYELEMENTS_ENTRY(env, (uint16_t*) array, (uintptr_t *) isCopy), | |
3677 HOTSPOT_JNI_GETSHORTARRAYELEMENTS_RETURN((uint16_t*)result)) | |
3678 DEFINE_GETSCALARARRAYELEMENTS(T_CHAR, jchar, Char, char | |
3679 , HOTSPOT_JNI_GETCHARARRAYELEMENTS_ENTRY(env, (uint16_t*) array, (uintptr_t *) isCopy), | |
3680 HOTSPOT_JNI_GETCHARARRAYELEMENTS_RETURN(result)) | |
3681 DEFINE_GETSCALARARRAYELEMENTS(T_INT, jint, Int, int | |
3682 , HOTSPOT_JNI_GETINTARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy), | |
3683 HOTSPOT_JNI_GETINTARRAYELEMENTS_RETURN((uint32_t*)result)) | |
3684 DEFINE_GETSCALARARRAYELEMENTS(T_LONG, jlong, Long, long | |
3685 , HOTSPOT_JNI_GETLONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy), | |
3686 HOTSPOT_JNI_GETLONGARRAYELEMENTS_RETURN(((uintptr_t*)result))) | |
3687 // Float and double probes don't return value because dtrace doesn't currently support it | |
3688 DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float | |
3689 , HOTSPOT_JNI_GETFLOATARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy), | |
3690 HOTSPOT_JNI_GETFLOATARRAYELEMENTS_RETURN(result)) | |
3691 DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double | |
3692 , HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy), | |
3693 HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_RETURN(result)) | |
3694 #endif /* USDT2 */ | |
3695 | |
3696 #ifndef USDT2 | |
0 | 3697 #define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag) \ |
3698 \ | |
3699 JNI_QUICK_ENTRY(void, \ | |
3700 jni_Release##Result##ArrayElements(JNIEnv *env, ElementType##Array array, \ | |
3701 ElementType *buf, jint mode)) \ | |
3702 JNIWrapper("Release" XSTR(Result) "ArrayElements"); \ | |
3703 DTRACE_PROBE4(hotspot_jni, Release##Result##ArrayElements__entry, env, array, buf, mode);\ | |
3704 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \ | |
3705 int len = a->length(); \ | |
3706 if (len != 0) { /* Empty array: nothing to free or copy. */ \ | |
3707 if ((mode == 0) || (mode == JNI_COMMIT)) { \ | |
3708 memcpy(a->Tag##_at_addr(0), buf, sizeof(ElementType)*len); \ | |
3709 } \ | |
3710 if ((mode == 0) || (mode == JNI_ABORT)) { \ | |
3711 FreeHeap(buf); \ | |
3712 } \ | |
3713 } \ | |
3714 DTRACE_PROBE(hotspot_jni, Release##Result##ArrayElements__return);\ | |
3715 JNI_END | |
3716 | |
3717 DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool) | |
3718 DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE, jbyte, Byte, byte) | |
3719 DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT, jshort, Short, short) | |
3720 DEFINE_RELEASESCALARARRAYELEMENTS(T_CHAR, jchar, Char, char) | |
3721 DEFINE_RELEASESCALARARRAYELEMENTS(T_INT, jint, Int, int) | |
3722 DEFINE_RELEASESCALARARRAYELEMENTS(T_LONG, jlong, Long, long) | |
3723 DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float) | |
3724 DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double) | |
3725 | |
4006 | 3726 #else /* USDT2 */ |
3727 | |
3728 #define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag \ | |
3729 , EntryProbe, ReturnProbe);\ | |
3730 \ | |
3731 JNI_QUICK_ENTRY(void, \ | |
3732 jni_Release##Result##ArrayElements(JNIEnv *env, ElementType##Array array, \ | |
3733 ElementType *buf, jint mode)) \ | |
3734 JNIWrapper("Release" XSTR(Result) "ArrayElements"); \ | |
3735 EntryProbe; \ | |
3736 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \ | |
3737 int len = a->length(); \ | |
3738 if (len != 0) { /* Empty array: nothing to free or copy. */ \ | |
3739 if ((mode == 0) || (mode == JNI_COMMIT)) { \ | |
3740 memcpy(a->Tag##_at_addr(0), buf, sizeof(ElementType)*len); \ | |
3741 } \ | |
3742 if ((mode == 0) || (mode == JNI_ABORT)) { \ | |
3743 FreeHeap(buf); \ | |
3744 } \ | |
3745 } \ | |
3746 ReturnProbe; \ | |
3747 JNI_END | |
3748 | |
3749 DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool | |
3750 , HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode), | |
3751 HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_RETURN()) | |
3752 DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE, jbyte, Byte, byte | |
3753 , HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_ENTRY(env, array, (char *) buf, mode), | |
3754 HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_RETURN()) | |
3755 DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT, jshort, Short, short | |
3756 , HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode), | |
3757 HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_RETURN()) | |
3758 DEFINE_RELEASESCALARARRAYELEMENTS(T_CHAR, jchar, Char, char | |
3759 , HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode), | |
3760 HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_RETURN()) | |
3761 DEFINE_RELEASESCALARARRAYELEMENTS(T_INT, jint, Int, int | |
3762 , HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_ENTRY(env, array, (uint32_t *) buf, mode), | |
3763 HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_RETURN()) | |
3764 DEFINE_RELEASESCALARARRAYELEMENTS(T_LONG, jlong, Long, long | |
3765 , HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode), | |
3766 HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_RETURN()) | |
3767 DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float | |
3768 , HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_ENTRY(env, array, (float *) buf, mode), | |
3769 HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_RETURN()) | |
3770 DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double | |
3771 , HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_ENTRY(env, array, (double *) buf, mode), | |
3772 HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_RETURN()) | |
3773 #endif /* USDT2 */ | |
3774 | |
3775 #ifndef USDT2 | |
0 | 3776 #define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag) \ |
3777 DT_VOID_RETURN_MARK_DECL(Get##Result##ArrayRegion);\ | |
3778 \ | |
3779 JNI_ENTRY(void, \ | |
3780 jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \ | |
3781 jsize len, ElementType *buf)) \ | |
3782 JNIWrapper("Get" XSTR(Result) "ArrayRegion"); \ | |
3783 DTRACE_PROBE5(hotspot_jni, Get##Result##ArrayRegion__entry, env, array, start, len, buf);\ | |
3784 DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \ | |
3785 typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \ | |
3786 if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)src->length())) { \ | |
3787 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \ | |
3788 } else { \ | |
3789 if (len > 0) { \ | |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
3790 int sc = TypeArrayKlass::cast(src->klass())->log2_element_size(); \ |
0 | 3791 memcpy((u_char*) buf, \ |
3792 (u_char*) src->Tag##_at_addr(start), \ | |
3793 len << sc); \ | |
3794 } \ | |
3795 } \ | |
3796 JNI_END | |
3797 | |
3798 DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool) | |
3799 DEFINE_GETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte) | |
3800 DEFINE_GETSCALARARRAYREGION(T_SHORT, jshort, Short, short) | |
3801 DEFINE_GETSCALARARRAYREGION(T_CHAR, jchar, Char, char) | |
3802 DEFINE_GETSCALARARRAYREGION(T_INT, jint, Int, int) | |
3803 DEFINE_GETSCALARARRAYREGION(T_LONG, jlong, Long, long) | |
3804 DEFINE_GETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float) | |
3805 DEFINE_GETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double) | |
3806 | |
4006 | 3807 #else /* USDT2 */ |
3808 | |
3809 #define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \ | |
3810 , EntryProbe, ReturnProbe); \ | |
3811 DT_VOID_RETURN_MARK_DECL(Get##Result##ArrayRegion \ | |
3812 , ReturnProbe); \ | |
3813 \ | |
3814 JNI_ENTRY(void, \ | |
3815 jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \ | |
3816 jsize len, ElementType *buf)) \ | |
3817 JNIWrapper("Get" XSTR(Result) "ArrayRegion"); \ | |
3818 EntryProbe; \ | |
3819 DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \ | |
3820 typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \ | |
3821 if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)src->length())) { \ | |
3822 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \ | |
3823 } else { \ | |
3824 if (len > 0) { \ | |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
3825 int sc = TypeArrayKlass::cast(src->klass())->log2_element_size(); \ |
4006 | 3826 memcpy((u_char*) buf, \ |
3827 (u_char*) src->Tag##_at_addr(start), \ | |
3828 len << sc); \ | |
3829 } \ | |
3830 } \ | |
3831 JNI_END | |
3832 | |
3833 DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool | |
3834 , HOTSPOT_JNI_GETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf), | |
3835 HOTSPOT_JNI_GETBOOLEANARRAYREGION_RETURN()); | |
3836 DEFINE_GETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte | |
3837 , HOTSPOT_JNI_GETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf), | |
3838 HOTSPOT_JNI_GETBYTEARRAYREGION_RETURN()); | |
3839 DEFINE_GETSCALARARRAYREGION(T_SHORT, jshort, Short, short | |
3840 , HOTSPOT_JNI_GETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf), | |
3841 HOTSPOT_JNI_GETSHORTARRAYREGION_RETURN()); | |
3842 DEFINE_GETSCALARARRAYREGION(T_CHAR, jchar, Char, char | |
3843 , HOTSPOT_JNI_GETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t*) buf), | |
3844 HOTSPOT_JNI_GETCHARARRAYREGION_RETURN()); | |
3845 DEFINE_GETSCALARARRAYREGION(T_INT, jint, Int, int | |
3846 , HOTSPOT_JNI_GETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t*) buf), | |
3847 HOTSPOT_JNI_GETINTARRAYREGION_RETURN()); | |
3848 DEFINE_GETSCALARARRAYREGION(T_LONG, jlong, Long, long | |
3849 , HOTSPOT_JNI_GETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf), | |
3850 HOTSPOT_JNI_GETLONGARRAYREGION_RETURN()); | |
3851 DEFINE_GETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float | |
3852 , HOTSPOT_JNI_GETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf), | |
3853 HOTSPOT_JNI_GETFLOATARRAYREGION_RETURN()); | |
3854 DEFINE_GETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double | |
3855 , HOTSPOT_JNI_GETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf), | |
3856 HOTSPOT_JNI_GETDOUBLEARRAYREGION_RETURN()); | |
3857 #endif /* USDT2 */ | |
3858 | |
3859 #ifndef USDT2 | |
0 | 3860 #define DEFINE_SETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag) \ |
3861 DT_VOID_RETURN_MARK_DECL(Set##Result##ArrayRegion);\ | |
3862 \ | |
3863 JNI_ENTRY(void, \ | |
3864 jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \ | |
3865 jsize len, const ElementType *buf)) \ | |
3866 JNIWrapper("Set" XSTR(Result) "ArrayRegion"); \ | |
3867 DTRACE_PROBE5(hotspot_jni, Set##Result##ArrayRegion__entry, env, array, start, len, buf);\ | |
3868 DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \ | |
3869 typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \ | |
3870 if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)dst->length())) { \ | |
3871 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \ | |
3872 } else { \ | |
3873 if (len > 0) { \ | |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
3874 int sc = TypeArrayKlass::cast(dst->klass())->log2_element_size(); \ |
0 | 3875 memcpy((u_char*) dst->Tag##_at_addr(start), \ |
3876 (u_char*) buf, \ | |
3877 len << sc); \ | |
3878 } \ | |
3879 } \ | |
3880 JNI_END | |
3881 | |
3882 DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool) | |
3883 DEFINE_SETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte) | |
3884 DEFINE_SETSCALARARRAYREGION(T_SHORT, jshort, Short, short) | |
3885 DEFINE_SETSCALARARRAYREGION(T_CHAR, jchar, Char, char) | |
3886 DEFINE_SETSCALARARRAYREGION(T_INT, jint, Int, int) | |
3887 DEFINE_SETSCALARARRAYREGION(T_LONG, jlong, Long, long) | |
3888 DEFINE_SETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float) | |
3889 DEFINE_SETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double) | |
3890 | |
4006 | 3891 #else /* USDT2 */ |
3892 | |
3893 #define DEFINE_SETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \ | |
3894 , EntryProbe, ReturnProbe); \ | |
3895 DT_VOID_RETURN_MARK_DECL(Set##Result##ArrayRegion \ | |
3896 ,ReturnProbe); \ | |
3897 \ | |
3898 JNI_ENTRY(void, \ | |
3899 jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \ | |
3900 jsize len, const ElementType *buf)) \ | |
3901 JNIWrapper("Set" XSTR(Result) "ArrayRegion"); \ | |
3902 EntryProbe; \ | |
3903 DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \ | |
3904 typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \ | |
3905 if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)dst->length())) { \ | |
3906 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \ | |
3907 } else { \ | |
3908 if (len > 0) { \ | |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
3909 int sc = TypeArrayKlass::cast(dst->klass())->log2_element_size(); \ |
4006 | 3910 memcpy((u_char*) dst->Tag##_at_addr(start), \ |
3911 (u_char*) buf, \ | |
3912 len << sc); \ | |
3913 } \ | |
3914 } \ | |
3915 JNI_END | |
3916 | |
3917 DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool | |
3918 , HOTSPOT_JNI_SETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *)buf), | |
3919 HOTSPOT_JNI_SETBOOLEANARRAYREGION_RETURN()) | |
3920 DEFINE_SETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte | |
3921 , HOTSPOT_JNI_SETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf), | |
3922 HOTSPOT_JNI_SETBYTEARRAYREGION_RETURN()) | |
3923 DEFINE_SETSCALARARRAYREGION(T_SHORT, jshort, Short, short | |
3924 , HOTSPOT_JNI_SETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf), | |
3925 HOTSPOT_JNI_SETSHORTARRAYREGION_RETURN()) | |
3926 DEFINE_SETSCALARARRAYREGION(T_CHAR, jchar, Char, char | |
3927 , HOTSPOT_JNI_SETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf), | |
3928 HOTSPOT_JNI_SETCHARARRAYREGION_RETURN()) | |
3929 DEFINE_SETSCALARARRAYREGION(T_INT, jint, Int, int | |
3930 , HOTSPOT_JNI_SETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t *) buf), | |
3931 HOTSPOT_JNI_SETINTARRAYREGION_RETURN()) | |
3932 DEFINE_SETSCALARARRAYREGION(T_LONG, jlong, Long, long | |
3933 , HOTSPOT_JNI_SETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf), | |
3934 HOTSPOT_JNI_SETLONGARRAYREGION_RETURN()) | |
3935 DEFINE_SETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float | |
3936 , HOTSPOT_JNI_SETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf), | |
3937 HOTSPOT_JNI_SETFLOATARRAYREGION_RETURN()) | |
3938 DEFINE_SETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double | |
3939 , HOTSPOT_JNI_SETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf), | |
3940 HOTSPOT_JNI_SETDOUBLEARRAYREGION_RETURN()) | |
3941 #endif /* USDT2 */ | |
3942 | |
0 | 3943 |
3944 // | |
3945 // Interception of natives | |
3946 // | |
3947 | |
3948 // The RegisterNatives call being attempted tried to register with a method that | |
3949 // is not native. Ask JVM TI what prefixes have been specified. Then check | |
3950 // to see if the native method is now wrapped with the prefixes. See the | |
3951 // SetNativeMethodPrefix(es) functions in the JVM TI Spec for details. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
3952 static Method* find_prefixed_native(KlassHandle k, |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
3953 Symbol* name, Symbol* signature, TRAPS) { |
6854
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6725
diff
changeset
|
3954 #if INCLUDE_JVMTI |
0 | 3955 ResourceMark rm(THREAD); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
3956 Method* method; |
0 | 3957 int name_len = name->utf8_length(); |
3958 char* name_str = name->as_utf8(); | |
3959 int prefix_count; | |
3960 char** prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count); | |
3961 for (int i = 0; i < prefix_count; i++) { | |
3962 char* prefix = prefixes[i]; | |
3963 int prefix_len = (int)strlen(prefix); | |
3964 | |
3965 // try adding this prefix to the method name and see if it matches another method name | |
3966 int trial_len = name_len + prefix_len; | |
3967 char* trial_name_str = NEW_RESOURCE_ARRAY(char, trial_len + 1); | |
3968 strcpy(trial_name_str, prefix); | |
3969 strcat(trial_name_str, name_str); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
3970 TempNewSymbol trial_name = SymbolTable::probe(trial_name_str, trial_len); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
3971 if (trial_name == NULL) { |
0 | 3972 continue; // no such symbol, so this prefix wasn't used, try the next prefix |
3973 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
3974 method = Klass::cast(k())->lookup_method(trial_name, signature); |
0 | 3975 if (method == NULL) { |
3976 continue; // signature doesn't match, try the next prefix | |
3977 } | |
3978 if (method->is_native()) { | |
3979 method->set_is_prefixed_native(); | |
3980 return method; // wahoo, we found a prefixed version of the method, return it | |
3981 } | |
3982 // found as non-native, so prefix is good, add it, probably just need more prefixes | |
3983 name_len = trial_len; | |
3984 name_str = trial_name_str; | |
3985 } | |
6854
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6725
diff
changeset
|
3986 #endif // INCLUDE_JVMTI |
0 | 3987 return NULL; // not found |
3988 } | |
3989 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
3990 static bool register_native(KlassHandle k, Symbol* name, Symbol* signature, address entry, TRAPS) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
3991 Method* method = Klass::cast(k())->lookup_method(name, signature); |
0 | 3992 if (method == NULL) { |
3993 ResourceMark rm; | |
3994 stringStream st; | |
3995 st.print("Method %s name or signature does not match", | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
3996 Method::name_and_sig_as_C_string(Klass::cast(k()), name, signature)); |
0 | 3997 THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false); |
3998 } | |
3999 if (!method->is_native()) { | |
4000 // trying to register to a non-native method, see if a JVM TI agent has added prefix(es) | |
4001 method = find_prefixed_native(k, name, signature, THREAD); | |
4002 if (method == NULL) { | |
4003 ResourceMark rm; | |
4004 stringStream st; | |
4005 st.print("Method %s is not declared as native", | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
4006 Method::name_and_sig_as_C_string(Klass::cast(k()), name, signature)); |
0 | 4007 THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false); |
4008 } | |
4009 } | |
4010 | |
4011 if (entry != NULL) { | |
4012 method->set_native_function(entry, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
4013 Method::native_bind_event_is_interesting); |
0 | 4014 } else { |
4015 method->clear_native_function(); | |
4016 } | |
4017 if (PrintJNIResolving) { | |
4018 ResourceMark rm(THREAD); | |
4019 tty->print_cr("[Registering JNI native method %s.%s]", | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6856
diff
changeset
|
4020 method->method_holder()->external_name(), |
0 | 4021 method->name()->as_C_string()); |
4022 } | |
4023 return true; | |
4024 } | |
4025 | |
4006 | 4026 #ifndef USDT2 |
0 | 4027 DT_RETURN_MARK_DECL(RegisterNatives, jint); |
4006 | 4028 #else /* USDT2 */ |
4029 DT_RETURN_MARK_DECL(RegisterNatives, jint | |
4030 , HOTSPOT_JNI_REGISTERNATIVES_RETURN(_ret_ref)); | |
4031 #endif /* USDT2 */ | |
0 | 4032 |
4033 JNI_ENTRY(jint, jni_RegisterNatives(JNIEnv *env, jclass clazz, | |
4034 const JNINativeMethod *methods, | |
4035 jint nMethods)) | |
4036 JNIWrapper("RegisterNatives"); | |
4006 | 4037 #ifndef USDT2 |
0 | 4038 DTRACE_PROBE4(hotspot_jni, RegisterNatives__entry, env, clazz, methods, nMethods); |
4006 | 4039 #else /* USDT2 */ |
4040 HOTSPOT_JNI_REGISTERNATIVES_ENTRY( | |
4041 env, clazz, (void *) methods, nMethods); | |
4042 #endif /* USDT2 */ | |
0 | 4043 jint ret = 0; |
4044 DT_RETURN_MARK(RegisterNatives, jint, (const jint&)ret); | |
4045 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
4046 KlassHandle h_k(thread, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); |
0 | 4047 |
4048 for (int index = 0; index < nMethods; index++) { | |
4049 const char* meth_name = methods[index].name; | |
4050 const char* meth_sig = methods[index].signature; | |
4051 int meth_name_len = (int)strlen(meth_name); | |
4052 | |
4053 // The class should have been loaded (we have an instance of the class | |
4054 // passed in) so the method and signature should already be in the symbol | |
4055 // table. If they're not there, the method doesn't exist. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
4056 TempNewSymbol name = SymbolTable::probe(meth_name, meth_name_len); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
4057 TempNewSymbol signature = SymbolTable::probe(meth_sig, (int)strlen(meth_sig)); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
4058 |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
4059 if (name == NULL || signature == NULL) { |
0 | 4060 ResourceMark rm; |
4061 stringStream st; | |
4062 st.print("Method %s.%s%s not found", Klass::cast(h_k())->external_name(), meth_name, meth_sig); | |
4063 // Must return negative value on failure | |
4064 THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1); | |
4065 } | |
4066 | |
4067 bool res = register_native(h_k, name, signature, | |
4068 (address) methods[index].fnPtr, THREAD); | |
4069 if (!res) { | |
4070 ret = -1; | |
4071 break; | |
4072 } | |
4073 } | |
4074 return ret; | |
4075 JNI_END | |
4076 | |
4077 | |
4078 JNI_ENTRY(jint, jni_UnregisterNatives(JNIEnv *env, jclass clazz)) | |
4079 JNIWrapper("UnregisterNatives"); | |
4006 | 4080 #ifndef USDT2 |
0 | 4081 DTRACE_PROBE2(hotspot_jni, UnregisterNatives__entry, env, clazz); |
4006 | 4082 #else /* USDT2 */ |
4083 HOTSPOT_JNI_UNREGISTERNATIVES_ENTRY( | |
4084 env, clazz); | |
4085 #endif /* USDT2 */ | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
4086 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)); |
0 | 4087 //%note jni_2 |
4088 if (Klass::cast(k)->oop_is_instance()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
4089 for (int index = 0; index < InstanceKlass::cast(k)->methods()->length(); index++) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
4090 Method* m = InstanceKlass::cast(k)->methods()->at(index); |
0 | 4091 if (m->is_native()) { |
4092 m->clear_native_function(); | |
4093 m->set_signature_handler(NULL); | |
4094 } | |
4095 } | |
4096 } | |
4006 | 4097 #ifndef USDT2 |
0 | 4098 DTRACE_PROBE1(hotspot_jni, UnregisterNatives__return, 0); |
4006 | 4099 #else /* USDT2 */ |
4100 HOTSPOT_JNI_UNREGISTERNATIVES_RETURN( | |
4101 0); | |
4102 #endif /* USDT2 */ | |
0 | 4103 return 0; |
4104 JNI_END | |
4105 | |
4106 // | |
4107 // Monitor functions | |
4108 // | |
4109 | |
4006 | 4110 #ifndef USDT2 |
0 | 4111 DT_RETURN_MARK_DECL(MonitorEnter, jint); |
4006 | 4112 #else /* USDT2 */ |
4113 DT_RETURN_MARK_DECL(MonitorEnter, jint | |
4114 , HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref)); | |
4115 #endif /* USDT2 */ | |
0 | 4116 |
4117 JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj)) | |
4006 | 4118 #ifndef USDT2 |
0 | 4119 DTRACE_PROBE2(hotspot_jni, MonitorEnter__entry, env, jobj); |
4006 | 4120 #else /* USDT2 */ |
4121 HOTSPOT_JNI_MONITORENTER_ENTRY( | |
4122 env, jobj); | |
4123 #endif /* USDT2 */ | |
0 | 4124 jint ret = JNI_ERR; |
4125 DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret); | |
4126 | |
4127 // If the object is null, we can't do anything with it | |
4128 if (jobj == NULL) { | |
4129 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR); | |
4130 } | |
4131 | |
4132 Handle obj(thread, JNIHandles::resolve_non_null(jobj)); | |
4133 ObjectSynchronizer::jni_enter(obj, CHECK_(JNI_ERR)); | |
4134 ret = JNI_OK; | |
4135 return ret; | |
4136 JNI_END | |
4137 | |
4006 | 4138 #ifndef USDT2 |
0 | 4139 DT_RETURN_MARK_DECL(MonitorExit, jint); |
4006 | 4140 #else /* USDT2 */ |
4141 DT_RETURN_MARK_DECL(MonitorExit, jint | |
4142 , HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref)); | |
4143 #endif /* USDT2 */ | |
0 | 4144 |
4145 JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj)) | |
4006 | 4146 #ifndef USDT2 |
0 | 4147 DTRACE_PROBE2(hotspot_jni, MonitorExit__entry, env, jobj); |
4006 | 4148 #else /* USDT2 */ |
4149 HOTSPOT_JNI_MONITOREXIT_ENTRY( | |
4150 env, jobj); | |
4151 #endif /* USDT2 */ | |
0 | 4152 jint ret = JNI_ERR; |
4153 DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret); | |
4154 | |
4155 // Don't do anything with a null object | |
4156 if (jobj == NULL) { | |
4157 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR); | |
4158 } | |
4159 | |
4160 Handle obj(THREAD, JNIHandles::resolve_non_null(jobj)); | |
4161 ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR)); | |
4162 | |
4163 ret = JNI_OK; | |
4164 return ret; | |
4165 JNI_END | |
4166 | |
4167 // | |
4168 // Extensions | |
4169 // | |
4170 | |
4006 | 4171 #ifndef USDT2 |
0 | 4172 DT_VOID_RETURN_MARK_DECL(GetStringRegion); |
4006 | 4173 #else /* USDT2 */ |
4174 DT_VOID_RETURN_MARK_DECL(GetStringRegion | |
4175 , HOTSPOT_JNI_GETSTRINGREGION_RETURN()); | |
4176 #endif /* USDT2 */ | |
0 | 4177 |
4178 JNI_ENTRY(void, jni_GetStringRegion(JNIEnv *env, jstring string, jsize start, jsize len, jchar *buf)) | |
4179 JNIWrapper("GetStringRegion"); | |
4006 | 4180 #ifndef USDT2 |
0 | 4181 DTRACE_PROBE5(hotspot_jni, GetStringRegion__entry, env, string, start, len, buf); |
4006 | 4182 #else /* USDT2 */ |
4183 HOTSPOT_JNI_GETSTRINGREGION_ENTRY( | |
4184 env, string, start, len, buf); | |
4185 #endif /* USDT2 */ | |
0 | 4186 DT_VOID_RETURN_MARK(GetStringRegion); |
4187 oop s = JNIHandles::resolve_non_null(string); | |
4188 int s_len = java_lang_String::length(s); | |
4189 if (start < 0 || len < 0 || start + len > s_len) { | |
4190 THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException()); | |
4191 } else { | |
4192 if (len > 0) { | |
4193 int s_offset = java_lang_String::offset(s); | |
4194 typeArrayOop s_value = java_lang_String::value(s); | |
4195 memcpy(buf, s_value->char_at_addr(s_offset+start), sizeof(jchar)*len); | |
4196 } | |
4197 } | |
4198 JNI_END | |
4199 | |
4006 | 4200 #ifndef USDT2 |
0 | 4201 DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion); |
4006 | 4202 #else /* USDT2 */ |
4203 DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion | |
4204 , HOTSPOT_JNI_GETSTRINGUTFREGION_RETURN()); | |
4205 #endif /* USDT2 */ | |
0 | 4206 |
4207 JNI_ENTRY(void, jni_GetStringUTFRegion(JNIEnv *env, jstring string, jsize start, jsize len, char *buf)) | |
4208 JNIWrapper("GetStringUTFRegion"); | |
4006 | 4209 #ifndef USDT2 |
0 | 4210 DTRACE_PROBE5(hotspot_jni, GetStringUTFRegion__entry, env, string, start, len, buf); |
4006 | 4211 #else /* USDT2 */ |
4212 HOTSPOT_JNI_GETSTRINGUTFREGION_ENTRY( | |
4213 env, string, start, len, buf); | |
4214 #endif /* USDT2 */ | |
0 | 4215 DT_VOID_RETURN_MARK(GetStringUTFRegion); |
4216 oop s = JNIHandles::resolve_non_null(string); | |
4217 int s_len = java_lang_String::length(s); | |
4218 if (start < 0 || len < 0 || start + len > s_len) { | |
4219 THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException()); | |
4220 } else { | |
4221 //%note jni_7 | |
4222 if (len > 0) { | |
4223 ResourceMark rm(THREAD); | |
4224 char *utf_region = java_lang_String::as_utf8_string(s, start, len); | |
4225 int utf_len = (int)strlen(utf_region); | |
4226 memcpy(buf, utf_region, utf_len); | |
4227 buf[utf_len] = 0; | |
4228 } else { | |
4229 // JDK null-terminates the buffer even in len is zero | |
4230 if (buf != NULL) { | |
4231 buf[0] = 0; | |
4232 } | |
4233 } | |
4234 } | |
4235 JNI_END | |
4236 | |
4237 | |
4238 JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)) | |
4239 JNIWrapper("GetPrimitiveArrayCritical"); | |
4006 | 4240 #ifndef USDT2 |
0 | 4241 DTRACE_PROBE3(hotspot_jni, GetPrimitiveArrayCritical__entry, env, array, isCopy); |
4006 | 4242 #else /* USDT2 */ |
4243 HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY( | |
4244 env, array, (uintptr_t *) isCopy); | |
4245 #endif /* USDT2 */ | |
0 | 4246 GC_locker::lock_critical(thread); |
4247 if (isCopy != NULL) { | |
4248 *isCopy = JNI_FALSE; | |
4249 } | |
4250 oop a = JNIHandles::resolve_non_null(array); | |
4251 assert(a->is_array(), "just checking"); | |
4252 BasicType type; | |
4253 if (a->is_objArray()) { | |
4254 type = T_OBJECT; | |
4255 } else { | |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
4256 type = TypeArrayKlass::cast(a->klass())->element_type(); |
0 | 4257 } |
4258 void* ret = arrayOop(a)->base(type); | |
4006 | 4259 #ifndef USDT2 |
0 | 4260 DTRACE_PROBE1(hotspot_jni, GetPrimitiveArrayCritical__return, ret); |
4006 | 4261 #else /* USDT2 */ |
4262 HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN( | |
4263 ret); | |
4264 #endif /* USDT2 */ | |
0 | 4265 return ret; |
4266 JNI_END | |
4267 | |
4268 | |
4269 JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode)) | |
4270 JNIWrapper("ReleasePrimitiveArrayCritical"); | |
4006 | 4271 #ifndef USDT2 |
0 | 4272 DTRACE_PROBE4(hotspot_jni, ReleasePrimitiveArrayCritical__entry, env, array, carray, mode); |
4006 | 4273 #else /* USDT2 */ |
4274 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY( | |
4275 env, array, carray, mode); | |
4276 #endif /* USDT2 */ | |
0 | 4277 // The array, carray and mode arguments are ignored |
4278 GC_locker::unlock_critical(thread); | |
4006 | 4279 #ifndef USDT2 |
0 | 4280 DTRACE_PROBE(hotspot_jni, ReleasePrimitiveArrayCritical__return); |
4006 | 4281 #else /* USDT2 */ |
4282 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN( | |
4283 ); | |
4284 #endif /* USDT2 */ | |
0 | 4285 JNI_END |
4286 | |
4287 | |
4288 JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)) | |
4289 JNIWrapper("GetStringCritical"); | |
4006 | 4290 #ifndef USDT2 |
0 | 4291 DTRACE_PROBE3(hotspot_jni, GetStringCritical__entry, env, string, isCopy); |
4006 | 4292 #else /* USDT2 */ |
4293 HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY( | |
4294 env, string, (uintptr_t *) isCopy); | |
4295 #endif /* USDT2 */ | |
0 | 4296 GC_locker::lock_critical(thread); |
4297 if (isCopy != NULL) { | |
4298 *isCopy = JNI_FALSE; | |
4299 } | |
4300 oop s = JNIHandles::resolve_non_null(string); | |
4301 int s_len = java_lang_String::length(s); | |
4302 typeArrayOop s_value = java_lang_String::value(s); | |
4303 int s_offset = java_lang_String::offset(s); | |
4304 const jchar* ret; | |
4305 if (s_len > 0) { | |
4306 ret = s_value->char_at_addr(s_offset); | |
4307 } else { | |
4308 ret = (jchar*) s_value->base(T_CHAR); | |
4309 } | |
4006 | 4310 #ifndef USDT2 |
0 | 4311 DTRACE_PROBE1(hotspot_jni, GetStringCritical__return, ret); |
4006 | 4312 #else /* USDT2 */ |
4313 HOTSPOT_JNI_GETSTRINGCRITICAL_RETURN( | |
4314 (uint16_t *) ret); | |
4315 #endif /* USDT2 */ | |
0 | 4316 return ret; |
4317 JNI_END | |
4318 | |
4319 | |
4320 JNI_ENTRY(void, jni_ReleaseStringCritical(JNIEnv *env, jstring str, const jchar *chars)) | |
4321 JNIWrapper("ReleaseStringCritical"); | |
4006 | 4322 #ifndef USDT2 |
0 | 4323 DTRACE_PROBE3(hotspot_jni, ReleaseStringCritical__entry, env, str, chars); |
4006 | 4324 #else /* USDT2 */ |
4325 HOTSPOT_JNI_RELEASESTRINGCRITICAL_ENTRY( | |
4326 env, str, (uint16_t *) chars); | |
4327 #endif /* USDT2 */ | |
0 | 4328 // The str and chars arguments are ignored |
4329 GC_locker::unlock_critical(thread); | |
4006 | 4330 #ifndef USDT2 |
0 | 4331 DTRACE_PROBE(hotspot_jni, ReleaseStringCritical__return); |
4006 | 4332 #else /* USDT2 */ |
4333 HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN( | |
4334 ); | |
4335 #endif /* USDT2 */ | |
0 | 4336 JNI_END |
4337 | |
4338 | |
4339 JNI_ENTRY(jweak, jni_NewWeakGlobalRef(JNIEnv *env, jobject ref)) | |
4340 JNIWrapper("jni_NewWeakGlobalRef"); | |
4006 | 4341 #ifndef USDT2 |
0 | 4342 DTRACE_PROBE2(hotspot_jni, NewWeakGlobalRef__entry, env, ref); |
4006 | 4343 #else /* USDT2 */ |
4344 HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY( | |
4345 env, ref); | |
4346 #endif /* USDT2 */ | |
0 | 4347 Handle ref_handle(thread, JNIHandles::resolve(ref)); |
4348 jweak ret = JNIHandles::make_weak_global(ref_handle); | |
4006 | 4349 #ifndef USDT2 |
0 | 4350 DTRACE_PROBE1(hotspot_jni, NewWeakGlobalRef__return, ret); |
4006 | 4351 #else /* USDT2 */ |
4352 HOTSPOT_JNI_NEWWEAKGLOBALREF_RETURN( | |
4353 ret); | |
4354 #endif /* USDT2 */ | |
0 | 4355 return ret; |
4356 JNI_END | |
4357 | |
4358 // Must be JNI_ENTRY (with HandleMark) | |
4359 JNI_ENTRY(void, jni_DeleteWeakGlobalRef(JNIEnv *env, jweak ref)) | |
4360 JNIWrapper("jni_DeleteWeakGlobalRef"); | |
4006 | 4361 #ifndef USDT2 |
0 | 4362 DTRACE_PROBE2(hotspot_jni, DeleteWeakGlobalRef__entry, env, ref); |
4006 | 4363 #else /* USDT2 */ |
4364 HOTSPOT_JNI_DELETEWEAKGLOBALREF_ENTRY( | |
4365 env, ref); | |
4366 #endif /* USDT2 */ | |
0 | 4367 JNIHandles::destroy_weak_global(ref); |
4006 | 4368 #ifndef USDT2 |
0 | 4369 DTRACE_PROBE(hotspot_jni, DeleteWeakGlobalRef__return); |
4006 | 4370 #else /* USDT2 */ |
4371 HOTSPOT_JNI_DELETEWEAKGLOBALREF_RETURN( | |
4372 ); | |
4373 #endif /* USDT2 */ | |
0 | 4374 JNI_END |
4375 | |
4376 | |
4377 JNI_QUICK_ENTRY(jboolean, jni_ExceptionCheck(JNIEnv *env)) | |
4378 JNIWrapper("jni_ExceptionCheck"); | |
4006 | 4379 #ifndef USDT2 |
0 | 4380 DTRACE_PROBE1(hotspot_jni, ExceptionCheck__entry, env); |
4006 | 4381 #else /* USDT2 */ |
4382 HOTSPOT_JNI_EXCEPTIONCHECK_ENTRY( | |
4383 env); | |
4384 #endif /* USDT2 */ | |
0 | 4385 jni_check_async_exceptions(thread); |
4386 jboolean ret = (thread->has_pending_exception()) ? JNI_TRUE : JNI_FALSE; | |
4006 | 4387 #ifndef USDT2 |
0 | 4388 DTRACE_PROBE1(hotspot_jni, ExceptionCheck__return, ret); |
4006 | 4389 #else /* USDT2 */ |
4390 HOTSPOT_JNI_EXCEPTIONCHECK_RETURN( | |
4391 ret); | |
4392 #endif /* USDT2 */ | |
0 | 4393 return ret; |
4394 JNI_END | |
4395 | |
4396 | |
4397 // Initialization state for three routines below relating to | |
4398 // java.nio.DirectBuffers | |
4399 static jint directBufferSupportInitializeStarted = 0; | |
4400 static volatile jint directBufferSupportInitializeEnded = 0; | |
4401 static volatile jint directBufferSupportInitializeFailed = 0; | |
4402 static jclass bufferClass = NULL; | |
4403 static jclass directBufferClass = NULL; | |
4404 static jclass directByteBufferClass = NULL; | |
4405 static jmethodID directByteBufferConstructor = NULL; | |
4406 static jfieldID directBufferAddressField = NULL; | |
4407 static jfieldID bufferCapacityField = NULL; | |
4408 | |
4409 static jclass lookupOne(JNIEnv* env, const char* name, TRAPS) { | |
4410 Handle loader; // null (bootstrap) loader | |
4411 Handle protection_domain; // null protection domain | |
4412 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1989
diff
changeset
|
4413 TempNewSymbol sym = SymbolTable::new_symbol(name, CHECK_NULL); |
657
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
4414 jclass result = find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL); |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
4415 |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
4416 if (TraceClassResolution && result != NULL) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
4417 trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result))); |
657
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
4418 } |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
4419 return result; |
0 | 4420 } |
4421 | |
4422 // These lookups are done with the NULL (bootstrap) ClassLoader to | |
4423 // circumvent any security checks that would be done by jni_FindClass. | |
4424 JNI_ENTRY(bool, lookupDirectBufferClasses(JNIEnv* env)) | |
4425 { | |
4426 if ((bufferClass = lookupOne(env, "java/nio/Buffer", thread)) == NULL) { return false; } | |
4427 if ((directBufferClass = lookupOne(env, "sun/nio/ch/DirectBuffer", thread)) == NULL) { return false; } | |
4428 if ((directByteBufferClass = lookupOne(env, "java/nio/DirectByteBuffer", thread)) == NULL) { return false; } | |
4429 return true; | |
4430 } | |
4431 JNI_END | |
4432 | |
4433 | |
4434 static bool initializeDirectBufferSupport(JNIEnv* env, JavaThread* thread) { | |
4435 if (directBufferSupportInitializeFailed) { | |
4436 return false; | |
4437 } | |
4438 | |
4439 if (Atomic::cmpxchg(1, &directBufferSupportInitializeStarted, 0) == 0) { | |
4440 if (!lookupDirectBufferClasses(env)) { | |
4441 directBufferSupportInitializeFailed = 1; | |
4442 return false; | |
4443 } | |
4444 | |
4445 // Make global references for these | |
4446 bufferClass = (jclass) env->NewGlobalRef(bufferClass); | |
4447 directBufferClass = (jclass) env->NewGlobalRef(directBufferClass); | |
4448 directByteBufferClass = (jclass) env->NewGlobalRef(directByteBufferClass); | |
4449 | |
4450 // Get needed field and method IDs | |
4451 directByteBufferConstructor = env->GetMethodID(directByteBufferClass, "<init>", "(JI)V"); | |
4452 directBufferAddressField = env->GetFieldID(bufferClass, "address", "J"); | |
4453 bufferCapacityField = env->GetFieldID(bufferClass, "capacity", "I"); | |
4454 | |
4455 if ((directByteBufferConstructor == NULL) || | |
4456 (directBufferAddressField == NULL) || | |
4457 (bufferCapacityField == NULL)) { | |
4458 directBufferSupportInitializeFailed = 1; | |
4459 return false; | |
4460 } | |
4461 | |
4462 directBufferSupportInitializeEnded = 1; | |
4463 } else { | |
4464 while (!directBufferSupportInitializeEnded && !directBufferSupportInitializeFailed) { | |
521
4db4e58c16bd
6791815: Fix for 6471657 can cause deadlock on non-Solaris platforms when initializing direct buffer support
xlu
parents:
477
diff
changeset
|
4465 // Set state as yield_all can call os:sleep. On Solaris, yield_all calls |
4db4e58c16bd
6791815: Fix for 6471657 can cause deadlock on non-Solaris platforms when initializing direct buffer support
xlu
parents:
477
diff
changeset
|
4466 // os::sleep which requires the VM state transition. On other platforms, it |
4db4e58c16bd
6791815: Fix for 6471657 can cause deadlock on non-Solaris platforms when initializing direct buffer support
xlu
parents:
477
diff
changeset
|
4467 // is not necessary. The following call to change the VM state is purposely |
4db4e58c16bd
6791815: Fix for 6471657 can cause deadlock on non-Solaris platforms when initializing direct buffer support
xlu
parents:
477
diff
changeset
|
4468 // put inside the loop to avoid potential deadlock when multiple threads |
4db4e58c16bd
6791815: Fix for 6471657 can cause deadlock on non-Solaris platforms when initializing direct buffer support
xlu
parents:
477
diff
changeset
|
4469 // try to call this method. See 6791815 for more details. |
4db4e58c16bd
6791815: Fix for 6471657 can cause deadlock on non-Solaris platforms when initializing direct buffer support
xlu
parents:
477
diff
changeset
|
4470 ThreadInVMfromNative tivn(thread); |
0 | 4471 os::yield_all(); |
4472 } | |
4473 } | |
4474 | |
4475 return !directBufferSupportInitializeFailed; | |
4476 } | |
4477 | |
4478 extern "C" jobject JNICALL jni_NewDirectByteBuffer(JNIEnv *env, void* address, jlong capacity) | |
4479 { | |
4480 // thread_from_jni_environment() will block if VM is gone. | |
4481 JavaThread* thread = JavaThread::thread_from_jni_environment(env); | |
4482 | |
4483 JNIWrapper("jni_NewDirectByteBuffer"); | |
4006 | 4484 #ifndef USDT2 |
0 | 4485 DTRACE_PROBE3(hotspot_jni, NewDirectByteBuffer__entry, env, address, capacity); |
4006 | 4486 #else /* USDT2 */ |
4487 HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_ENTRY( | |
4488 env, address, capacity); | |
4489 #endif /* USDT2 */ | |
0 | 4490 |
4491 if (!directBufferSupportInitializeEnded) { | |
4492 if (!initializeDirectBufferSupport(env, thread)) { | |
4006 | 4493 #ifndef USDT2 |
0 | 4494 DTRACE_PROBE1(hotspot_jni, NewDirectByteBuffer__return, NULL); |
4006 | 4495 #else /* USDT2 */ |
4496 HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN( | |
4497 NULL); | |
4498 #endif /* USDT2 */ | |
0 | 4499 return NULL; |
4500 } | |
4501 } | |
4502 | |
4503 // Being paranoid about accidental sign extension on address | |
4504 jlong addr = (jlong) ((uintptr_t) address); | |
4505 // NOTE that package-private DirectByteBuffer constructor currently | |
4506 // takes int capacity | |
4507 jint cap = (jint) capacity; | |
4508 jobject ret = env->NewObject(directByteBufferClass, directByteBufferConstructor, addr, cap); | |
4006 | 4509 #ifndef USDT2 |
0 | 4510 DTRACE_PROBE1(hotspot_jni, NewDirectByteBuffer__return, ret); |
4006 | 4511 #else /* USDT2 */ |
4512 HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN( | |
4513 ret); | |
4514 #endif /* USDT2 */ | |
0 | 4515 return ret; |
4516 } | |
4517 | |
4006 | 4518 #ifndef USDT2 |
0 | 4519 DT_RETURN_MARK_DECL(GetDirectBufferAddress, void*); |
4006 | 4520 #else /* USDT2 */ |
4521 DT_RETURN_MARK_DECL(GetDirectBufferAddress, void* | |
4522 , HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_RETURN((void*) _ret_ref)); | |
4523 #endif /* USDT2 */ | |
0 | 4524 |
4525 extern "C" void* JNICALL jni_GetDirectBufferAddress(JNIEnv *env, jobject buf) | |
4526 { | |
4527 // thread_from_jni_environment() will block if VM is gone. | |
4528 JavaThread* thread = JavaThread::thread_from_jni_environment(env); | |
4529 | |
4530 JNIWrapper("jni_GetDirectBufferAddress"); | |
4006 | 4531 #ifndef USDT2 |
0 | 4532 DTRACE_PROBE2(hotspot_jni, GetDirectBufferAddress__entry, env, buf); |
4006 | 4533 #else /* USDT2 */ |
4534 HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_ENTRY( | |
4535 env, buf); | |
4536 #endif /* USDT2 */ | |
0 | 4537 void* ret = NULL; |
4538 DT_RETURN_MARK(GetDirectBufferAddress, void*, (const void*&)ret); | |
4539 | |
4540 if (!directBufferSupportInitializeEnded) { | |
4541 if (!initializeDirectBufferSupport(env, thread)) { | |
4542 return 0; | |
4543 } | |
4544 } | |
4545 | |
4546 if ((buf != NULL) && (!env->IsInstanceOf(buf, directBufferClass))) { | |
4547 return 0; | |
4548 } | |
4549 | |
4550 ret = (void*)(intptr_t)env->GetLongField(buf, directBufferAddressField); | |
4551 return ret; | |
4552 } | |
4553 | |
4006 | 4554 #ifndef USDT2 |
0 | 4555 DT_RETURN_MARK_DECL(GetDirectBufferCapacity, jlong); |
4006 | 4556 #else /* USDT2 */ |
4557 DT_RETURN_MARK_DECL(GetDirectBufferCapacity, jlong | |
4558 , HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_RETURN(_ret_ref)); | |
4559 #endif /* USDT2 */ | |
0 | 4560 |
4561 extern "C" jlong JNICALL jni_GetDirectBufferCapacity(JNIEnv *env, jobject buf) | |
4562 { | |
4563 // thread_from_jni_environment() will block if VM is gone. | |
4564 JavaThread* thread = JavaThread::thread_from_jni_environment(env); | |
4565 | |
4566 JNIWrapper("jni_GetDirectBufferCapacity"); | |
4006 | 4567 #ifndef USDT2 |
0 | 4568 DTRACE_PROBE2(hotspot_jni, GetDirectBufferCapacity__entry, env, buf); |
4006 | 4569 #else /* USDT2 */ |
4570 HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_ENTRY( | |
4571 env, buf); | |
4572 #endif /* USDT2 */ | |
0 | 4573 jlong ret = -1; |
4574 DT_RETURN_MARK(GetDirectBufferCapacity, jlong, (const jlong&)ret); | |
4575 | |
4576 if (!directBufferSupportInitializeEnded) { | |
4577 if (!initializeDirectBufferSupport(env, thread)) { | |
4578 ret = 0; | |
4579 return ret; | |
4580 } | |
4581 } | |
4582 | |
4583 if (buf == NULL) { | |
4584 return -1; | |
4585 } | |
4586 | |
4587 if (!env->IsInstanceOf(buf, directBufferClass)) { | |
4588 return -1; | |
4589 } | |
4590 | |
4591 // NOTE that capacity is currently an int in the implementation | |
4592 ret = env->GetIntField(buf, bufferCapacityField); | |
4593 return ret; | |
4594 } | |
4595 | |
4596 | |
4597 JNI_LEAF(jint, jni_GetVersion(JNIEnv *env)) | |
4598 JNIWrapper("GetVersion"); | |
4006 | 4599 #ifndef USDT2 |
0 | 4600 DTRACE_PROBE1(hotspot_jni, GetVersion__entry, env); |
4006 | 4601 #else /* USDT2 */ |
4602 HOTSPOT_JNI_GETVERSION_ENTRY( | |
4603 env); | |
4604 #endif /* USDT2 */ | |
4605 #ifndef USDT2 | |
0 | 4606 DTRACE_PROBE1(hotspot_jni, GetVersion__return, CurrentVersion); |
4006 | 4607 #else /* USDT2 */ |
4608 HOTSPOT_JNI_GETVERSION_RETURN( | |
4609 CurrentVersion); | |
4610 #endif /* USDT2 */ | |
0 | 4611 return CurrentVersion; |
4612 JNI_END | |
4613 | |
4614 extern struct JavaVM_ main_vm; | |
4615 | |
4616 JNI_LEAF(jint, jni_GetJavaVM(JNIEnv *env, JavaVM **vm)) | |
4617 JNIWrapper("jni_GetJavaVM"); | |
4006 | 4618 #ifndef USDT2 |
0 | 4619 DTRACE_PROBE2(hotspot_jni, GetJavaVM__entry, env, vm); |
4006 | 4620 #else /* USDT2 */ |
4621 HOTSPOT_JNI_GETJAVAVM_ENTRY( | |
4622 env, (void **) vm); | |
4623 #endif /* USDT2 */ | |
0 | 4624 *vm = (JavaVM *)(&main_vm); |
4006 | 4625 #ifndef USDT2 |
0 | 4626 DTRACE_PROBE1(hotspot_jni, GetJavaVM__return, JNI_OK); |
4006 | 4627 #else /* USDT2 */ |
4628 HOTSPOT_JNI_GETJAVAVM_RETURN( | |
4629 JNI_OK); | |
4630 #endif /* USDT2 */ | |
0 | 4631 return JNI_OK; |
4632 JNI_END | |
4633 | |
4634 // Structure containing all jni functions | |
4635 struct JNINativeInterface_ jni_NativeInterface = { | |
4636 NULL, | |
4637 NULL, | |
4638 NULL, | |
4639 | |
4640 NULL, | |
4641 | |
4642 jni_GetVersion, | |
4643 | |
4644 jni_DefineClass, | |
4645 jni_FindClass, | |
4646 | |
4647 jni_FromReflectedMethod, | |
4648 jni_FromReflectedField, | |
4649 | |
4650 jni_ToReflectedMethod, | |
4651 | |
4652 jni_GetSuperclass, | |
4653 jni_IsAssignableFrom, | |
4654 | |
4655 jni_ToReflectedField, | |
4656 | |
4657 jni_Throw, | |
4658 jni_ThrowNew, | |
4659 jni_ExceptionOccurred, | |
4660 jni_ExceptionDescribe, | |
4661 jni_ExceptionClear, | |
4662 jni_FatalError, | |
4663 | |
4664 jni_PushLocalFrame, | |
4665 jni_PopLocalFrame, | |
4666 | |
4667 jni_NewGlobalRef, | |
4668 jni_DeleteGlobalRef, | |
4669 jni_DeleteLocalRef, | |
4670 jni_IsSameObject, | |
4671 | |
4672 jni_NewLocalRef, | |
4673 jni_EnsureLocalCapacity, | |
4674 | |
4675 jni_AllocObject, | |
4676 jni_NewObject, | |
4677 jni_NewObjectV, | |
4678 jni_NewObjectA, | |
4679 | |
4680 jni_GetObjectClass, | |
4681 jni_IsInstanceOf, | |
4682 | |
4683 jni_GetMethodID, | |
4684 | |
4685 jni_CallObjectMethod, | |
4686 jni_CallObjectMethodV, | |
4687 jni_CallObjectMethodA, | |
4688 jni_CallBooleanMethod, | |
4689 jni_CallBooleanMethodV, | |
4690 jni_CallBooleanMethodA, | |
4691 jni_CallByteMethod, | |
4692 jni_CallByteMethodV, | |
4693 jni_CallByteMethodA, | |
4694 jni_CallCharMethod, | |
4695 jni_CallCharMethodV, | |
4696 jni_CallCharMethodA, | |
4697 jni_CallShortMethod, | |
4698 jni_CallShortMethodV, | |
4699 jni_CallShortMethodA, | |
4700 jni_CallIntMethod, | |
4701 jni_CallIntMethodV, | |
4702 jni_CallIntMethodA, | |
4703 jni_CallLongMethod, | |
4704 jni_CallLongMethodV, | |
4705 jni_CallLongMethodA, | |
4706 jni_CallFloatMethod, | |
4707 jni_CallFloatMethodV, | |
4708 jni_CallFloatMethodA, | |
4709 jni_CallDoubleMethod, | |
4710 jni_CallDoubleMethodV, | |
4711 jni_CallDoubleMethodA, | |
4712 jni_CallVoidMethod, | |
4713 jni_CallVoidMethodV, | |
4714 jni_CallVoidMethodA, | |
4715 | |
4716 jni_CallNonvirtualObjectMethod, | |
4717 jni_CallNonvirtualObjectMethodV, | |
4718 jni_CallNonvirtualObjectMethodA, | |
4719 jni_CallNonvirtualBooleanMethod, | |
4720 jni_CallNonvirtualBooleanMethodV, | |
4721 jni_CallNonvirtualBooleanMethodA, | |
4722 jni_CallNonvirtualByteMethod, | |
4723 jni_CallNonvirtualByteMethodV, | |
4724 jni_CallNonvirtualByteMethodA, | |
4725 jni_CallNonvirtualCharMethod, | |
4726 jni_CallNonvirtualCharMethodV, | |
4727 jni_CallNonvirtualCharMethodA, | |
4728 jni_CallNonvirtualShortMethod, | |
4729 jni_CallNonvirtualShortMethodV, | |
4730 jni_CallNonvirtualShortMethodA, | |
4731 jni_CallNonvirtualIntMethod, | |
4732 jni_CallNonvirtualIntMethodV, | |
4733 jni_CallNonvirtualIntMethodA, | |
4734 jni_CallNonvirtualLongMethod, | |
4735 jni_CallNonvirtualLongMethodV, | |
4736 jni_CallNonvirtualLongMethodA, | |
4737 jni_CallNonvirtualFloatMethod, | |
4738 jni_CallNonvirtualFloatMethodV, | |
4739 jni_CallNonvirtualFloatMethodA, | |
4740 jni_CallNonvirtualDoubleMethod, | |
4741 jni_CallNonvirtualDoubleMethodV, | |
4742 jni_CallNonvirtualDoubleMethodA, | |
4743 jni_CallNonvirtualVoidMethod, | |
4744 jni_CallNonvirtualVoidMethodV, | |
4745 jni_CallNonvirtualVoidMethodA, | |
4746 | |
4747 jni_GetFieldID, | |
4748 | |
4749 jni_GetObjectField, | |
4750 jni_GetBooleanField, | |
4751 jni_GetByteField, | |
4752 jni_GetCharField, | |
4753 jni_GetShortField, | |
4754 jni_GetIntField, | |
4755 jni_GetLongField, | |
4756 jni_GetFloatField, | |
4757 jni_GetDoubleField, | |
4758 | |
4759 jni_SetObjectField, | |
4760 jni_SetBooleanField, | |
4761 jni_SetByteField, | |
4762 jni_SetCharField, | |
4763 jni_SetShortField, | |
4764 jni_SetIntField, | |
4765 jni_SetLongField, | |
4766 jni_SetFloatField, | |
4767 jni_SetDoubleField, | |
4768 | |
4769 jni_GetStaticMethodID, | |
4770 | |
4771 jni_CallStaticObjectMethod, | |
4772 jni_CallStaticObjectMethodV, | |
4773 jni_CallStaticObjectMethodA, | |
4774 jni_CallStaticBooleanMethod, | |
4775 jni_CallStaticBooleanMethodV, | |
4776 jni_CallStaticBooleanMethodA, | |
4777 jni_CallStaticByteMethod, | |
4778 jni_CallStaticByteMethodV, | |
4779 jni_CallStaticByteMethodA, | |
4780 jni_CallStaticCharMethod, | |
4781 jni_CallStaticCharMethodV, | |
4782 jni_CallStaticCharMethodA, | |
4783 jni_CallStaticShortMethod, | |
4784 jni_CallStaticShortMethodV, | |
4785 jni_CallStaticShortMethodA, | |
4786 jni_CallStaticIntMethod, | |
4787 jni_CallStaticIntMethodV, | |
4788 jni_CallStaticIntMethodA, | |
4789 jni_CallStaticLongMethod, | |
4790 jni_CallStaticLongMethodV, | |
4791 jni_CallStaticLongMethodA, | |
4792 jni_CallStaticFloatMethod, | |
4793 jni_CallStaticFloatMethodV, | |
4794 jni_CallStaticFloatMethodA, | |
4795 jni_CallStaticDoubleMethod, | |
4796 jni_CallStaticDoubleMethodV, | |
4797 jni_CallStaticDoubleMethodA, | |
4798 jni_CallStaticVoidMethod, | |
4799 jni_CallStaticVoidMethodV, | |
4800 jni_CallStaticVoidMethodA, | |
4801 | |
4802 jni_GetStaticFieldID, | |
4803 | |
4804 jni_GetStaticObjectField, | |
4805 jni_GetStaticBooleanField, | |
4806 jni_GetStaticByteField, | |
4807 jni_GetStaticCharField, | |
4808 jni_GetStaticShortField, | |
4809 jni_GetStaticIntField, | |
4810 jni_GetStaticLongField, | |
4811 jni_GetStaticFloatField, | |
4812 jni_GetStaticDoubleField, | |
4813 | |
4814 jni_SetStaticObjectField, | |
4815 jni_SetStaticBooleanField, | |
4816 jni_SetStaticByteField, | |
4817 jni_SetStaticCharField, | |
4818 jni_SetStaticShortField, | |
4819 jni_SetStaticIntField, | |
4820 jni_SetStaticLongField, | |
4821 jni_SetStaticFloatField, | |
4822 jni_SetStaticDoubleField, | |
4823 | |
4824 jni_NewString, | |
4825 jni_GetStringLength, | |
4826 jni_GetStringChars, | |
4827 jni_ReleaseStringChars, | |
4828 | |
4829 jni_NewStringUTF, | |
4830 jni_GetStringUTFLength, | |
4831 jni_GetStringUTFChars, | |
4832 jni_ReleaseStringUTFChars, | |
4833 | |
4834 jni_GetArrayLength, | |
4835 | |
4836 jni_NewObjectArray, | |
4837 jni_GetObjectArrayElement, | |
4838 jni_SetObjectArrayElement, | |
4839 | |
4840 jni_NewBooleanArray, | |
4841 jni_NewByteArray, | |
4842 jni_NewCharArray, | |
4843 jni_NewShortArray, | |
4844 jni_NewIntArray, | |
4845 jni_NewLongArray, | |
4846 jni_NewFloatArray, | |
4847 jni_NewDoubleArray, | |
4848 | |
4849 jni_GetBooleanArrayElements, | |
4850 jni_GetByteArrayElements, | |
4851 jni_GetCharArrayElements, | |
4852 jni_GetShortArrayElements, | |
4853 jni_GetIntArrayElements, | |
4854 jni_GetLongArrayElements, | |
4855 jni_GetFloatArrayElements, | |
4856 jni_GetDoubleArrayElements, | |
4857 | |
4858 jni_ReleaseBooleanArrayElements, | |
4859 jni_ReleaseByteArrayElements, | |
4860 jni_ReleaseCharArrayElements, | |
4861 jni_ReleaseShortArrayElements, | |
4862 jni_ReleaseIntArrayElements, | |
4863 jni_ReleaseLongArrayElements, | |
4864 jni_ReleaseFloatArrayElements, | |
4865 jni_ReleaseDoubleArrayElements, | |
4866 | |
4867 jni_GetBooleanArrayRegion, | |
4868 jni_GetByteArrayRegion, | |
4869 jni_GetCharArrayRegion, | |
4870 jni_GetShortArrayRegion, | |
4871 jni_GetIntArrayRegion, | |
4872 jni_GetLongArrayRegion, | |
4873 jni_GetFloatArrayRegion, | |
4874 jni_GetDoubleArrayRegion, | |
4875 | |
4876 jni_SetBooleanArrayRegion, | |
4877 jni_SetByteArrayRegion, | |
4878 jni_SetCharArrayRegion, | |
4879 jni_SetShortArrayRegion, | |
4880 jni_SetIntArrayRegion, | |
4881 jni_SetLongArrayRegion, | |
4882 jni_SetFloatArrayRegion, | |
4883 jni_SetDoubleArrayRegion, | |
4884 | |
4885 jni_RegisterNatives, | |
4886 jni_UnregisterNatives, | |
4887 | |
4888 jni_MonitorEnter, | |
4889 jni_MonitorExit, | |
4890 | |
4891 jni_GetJavaVM, | |
4892 | |
4893 jni_GetStringRegion, | |
4894 jni_GetStringUTFRegion, | |
4895 | |
4896 jni_GetPrimitiveArrayCritical, | |
4897 jni_ReleasePrimitiveArrayCritical, | |
4898 | |
4899 jni_GetStringCritical, | |
4900 jni_ReleaseStringCritical, | |
4901 | |
4902 jni_NewWeakGlobalRef, | |
4903 jni_DeleteWeakGlobalRef, | |
4904 | |
4905 jni_ExceptionCheck, | |
4906 | |
4907 jni_NewDirectByteBuffer, | |
4908 jni_GetDirectBufferAddress, | |
4909 jni_GetDirectBufferCapacity, | |
4910 | |
4911 // New 1_6 features | |
4912 | |
4913 jni_GetObjectRefType | |
4914 }; | |
4915 | |
4916 | |
4917 // For jvmti use to modify jni function table. | |
4918 // Java threads in native contiues to run until it is transitioned | |
4919 // to VM at safepoint. Before the transition or before it is blocked | |
4920 // for safepoint it may access jni function table. VM could crash if | |
4921 // any java thread access the jni function table in the middle of memcpy. | |
4922 // To avoid this each function pointers are copied automically. | |
4923 void copy_jni_function_table(const struct JNINativeInterface_ *new_jni_NativeInterface) { | |
4924 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); | |
4925 intptr_t *a = (intptr_t *) jni_functions(); | |
4926 intptr_t *b = (intptr_t *) new_jni_NativeInterface; | |
4927 for (uint i=0; i < sizeof(struct JNINativeInterface_)/sizeof(void *); i++) { | |
4928 Atomic::store_ptr(*b++, a++); | |
4929 } | |
4930 } | |
4931 | |
4932 void quicken_jni_functions() { | |
4933 // Replace Get<Primitive>Field with fast versions | |
4934 if (UseFastJNIAccessors && !JvmtiExport::can_post_field_access() | |
4935 && !VerifyJNIFields && !TraceJNICalls && !CountJNICalls && !CheckJNICalls | |
4936 #if defined(_WINDOWS) && defined(IA32) && defined(COMPILER2) | |
4937 // windows x86 currently needs SEH wrapper and the gain of the fast | |
4938 // versions currently isn't certain for server vm on uniprocessor. | |
4939 && os::is_MP() | |
4940 #endif | |
4941 ) { | |
4942 address func; | |
4943 func = JNI_FastGetField::generate_fast_get_boolean_field(); | |
4944 if (func != (address)-1) { | |
4945 jni_NativeInterface.GetBooleanField = (GetBooleanField_t)func; | |
4946 } | |
4947 func = JNI_FastGetField::generate_fast_get_byte_field(); | |
4948 if (func != (address)-1) { | |
4949 jni_NativeInterface.GetByteField = (GetByteField_t)func; | |
4950 } | |
4951 func = JNI_FastGetField::generate_fast_get_char_field(); | |
4952 if (func != (address)-1) { | |
4953 jni_NativeInterface.GetCharField = (GetCharField_t)func; | |
4954 } | |
4955 func = JNI_FastGetField::generate_fast_get_short_field(); | |
4956 if (func != (address)-1) { | |
4957 jni_NativeInterface.GetShortField = (GetShortField_t)func; | |
4958 } | |
4959 func = JNI_FastGetField::generate_fast_get_int_field(); | |
4960 if (func != (address)-1) { | |
4961 jni_NativeInterface.GetIntField = (GetIntField_t)func; | |
4962 } | |
4963 func = JNI_FastGetField::generate_fast_get_long_field(); | |
4964 if (func != (address)-1) { | |
4965 jni_NativeInterface.GetLongField = (GetLongField_t)func; | |
4966 } | |
4967 func = JNI_FastGetField::generate_fast_get_float_field(); | |
4968 if (func != (address)-1) { | |
4969 jni_NativeInterface.GetFloatField = (GetFloatField_t)func; | |
4970 } | |
4971 func = JNI_FastGetField::generate_fast_get_double_field(); | |
4972 if (func != (address)-1) { | |
4973 jni_NativeInterface.GetDoubleField = (GetDoubleField_t)func; | |
4974 } | |
4975 } | |
4976 } | |
4977 | |
4978 // Returns the function structure | |
4979 struct JNINativeInterface_* jni_functions() { | |
6854
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6725
diff
changeset
|
4980 #if INCLUDE_JNI_CHECK |
0 | 4981 if (CheckJNICalls) return jni_functions_check(); |
6854
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6725
diff
changeset
|
4982 #endif // INCLUDE_JNI_CHECK |
0 | 4983 return &jni_NativeInterface; |
4984 } | |
4985 | |
4986 // Returns the function structure | |
4987 struct JNINativeInterface_* jni_functions_nocheck() { | |
4988 return &jni_NativeInterface; | |
4989 } | |
4990 | |
4991 | |
4992 // Invocation API | |
4993 | |
4994 | |
4995 // Forward declaration | |
4996 extern const struct JNIInvokeInterface_ jni_InvokeInterface; | |
4997 | |
4998 // Global invocation API vars | |
4999 volatile jint vm_created = 0; | |
5000 // Indicate whether it is safe to recreate VM | |
5001 volatile jint safe_to_recreate_vm = 1; | |
5002 struct JavaVM_ main_vm = {&jni_InvokeInterface}; | |
5003 | |
5004 | |
5005 #define JAVASTACKSIZE (400 * 1024) /* Default size of a thread java stack */ | |
5006 enum { VERIFY_NONE, VERIFY_REMOTE, VERIFY_ALL }; | |
5007 | |
4006 | 5008 #ifndef USDT2 |
0 | 5009 HS_DTRACE_PROBE_DECL1(hotspot_jni, GetDefaultJavaVMInitArgs__entry, void*); |
5010 DT_RETURN_MARK_DECL(GetDefaultJavaVMInitArgs, jint); | |
4006 | 5011 #else /* USDT2 */ |
5012 DT_RETURN_MARK_DECL(GetDefaultJavaVMInitArgs, jint | |
5013 , HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_RETURN(_ret_ref)); | |
5014 #endif /* USDT2 */ | |
0 | 5015 |
5016 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) { | |
4006 | 5017 #ifndef USDT2 |
0 | 5018 HS_DTRACE_PROBE1(hotspot_jni, GetDefaultJavaVMInitArgs__entry, args_); |
4006 | 5019 #else /* USDT2 */ |
5020 HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_ENTRY( | |
5021 args_); | |
5022 #endif /* USDT2 */ | |
0 | 5023 JDK1_1InitArgs *args = (JDK1_1InitArgs *)args_; |
5024 jint ret = JNI_ERR; | |
5025 DT_RETURN_MARK(GetDefaultJavaVMInitArgs, jint, (const jint&)ret); | |
5026 | |
5027 if (Threads::is_supported_jni_version(args->version)) { | |
5028 ret = JNI_OK; | |
5029 } | |
5030 // 1.1 style no longer supported in hotspot. | |
5031 // According the JNI spec, we should update args->version on return. | |
5032 // We also use the structure to communicate with launcher about default | |
5033 // stack size. | |
5034 if (args->version == JNI_VERSION_1_1) { | |
5035 args->version = JNI_VERSION_1_2; | |
5036 // javaStackSize is int in arguments structure | |
5037 assert(jlong(ThreadStackSize) * K < INT_MAX, "integer overflow"); | |
5038 args->javaStackSize = (jint)(ThreadStackSize * K); | |
5039 } | |
5040 return ret; | |
5041 } | |
5042 | |
3779 | 5043 #ifndef PRODUCT |
5044 | |
4708 | 5045 #include "gc_interface/collectedHeap.hpp" |
3779 | 5046 #include "utilities/quickSort.hpp" |
5047 | |
4708 | 5048 #define run_unit_test(unit_test_function_call) \ |
5049 tty->print_cr("Running test: " #unit_test_function_call); \ | |
5050 unit_test_function_call | |
5051 | |
3779 | 5052 void execute_internal_vm_tests() { |
5053 if (ExecuteInternalVMTests) { | |
4708 | 5054 tty->print_cr("Running internal VM tests"); |
5055 run_unit_test(arrayOopDesc::test_max_array_length()); | |
5056 run_unit_test(CollectedHeap::test_is_in()); | |
5057 run_unit_test(QuickSort::test_quick_sort()); | |
6162 | 5058 run_unit_test(AltHashing::test_alt_hash()); |
4070
6fd81579526f
7102044: G1: VM crashes with assert(old_end != new_end) failed: don't call this otherwise
brutisso
parents:
4006
diff
changeset
|
5059 tty->print_cr("All internal VM tests passed"); |
3779 | 5060 } |
5061 } | |
5062 | |
4708 | 5063 #undef run_unit_test |
5064 | |
3779 | 5065 #endif |
5066 | |
4006 | 5067 #ifndef USDT2 |
0 | 5068 HS_DTRACE_PROBE_DECL3(hotspot_jni, CreateJavaVM__entry, vm, penv, args); |
5069 DT_RETURN_MARK_DECL(CreateJavaVM, jint); | |
4006 | 5070 #else /* USDT2 */ |
5071 DT_RETURN_MARK_DECL(CreateJavaVM, jint | |
5072 , HOTSPOT_JNI_CREATEJAVAVM_RETURN(_ret_ref)); | |
5073 #endif /* USDT2 */ | |
0 | 5074 |
5075 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) { | |
4006 | 5076 #ifndef USDT2 |
0 | 5077 HS_DTRACE_PROBE3(hotspot_jni, CreateJavaVM__entry, vm, penv, args); |
4006 | 5078 #else /* USDT2 */ |
5079 HOTSPOT_JNI_CREATEJAVAVM_ENTRY( | |
5080 (void **) vm, penv, args); | |
5081 #endif /* USDT2 */ | |
0 | 5082 |
5083 jint result = JNI_ERR; | |
5084 DT_RETURN_MARK(CreateJavaVM, jint, (const jint&)result); | |
5085 | |
1078 | 5086 // We're about to use Atomic::xchg for synchronization. Some Zero |
5087 // platforms use the GCC builtin __sync_lock_test_and_set for this, | |
5088 // but __sync_lock_test_and_set is not guaranteed to do what we want | |
5089 // on all architectures. So we check it works before relying on it. | |
5090 #if defined(ZERO) && defined(ASSERT) | |
5091 { | |
5092 jint a = 0xcafebabe; | |
5093 jint b = Atomic::xchg(0xdeadbeef, &a); | |
5094 void *c = &a; | |
5095 void *d = Atomic::xchg_ptr(&b, &c); | |
1132 | 5096 assert(a == (jint) 0xdeadbeef && b == (jint) 0xcafebabe, "Atomic::xchg() works"); |
1078 | 5097 assert(c == &b && d == &a, "Atomic::xchg_ptr() works"); |
5098 } | |
5099 #endif // ZERO && ASSERT | |
5100 | |
0 | 5101 // At the moment it's only possible to have one Java VM, |
5102 // since some of the runtime state is in global variables. | |
5103 | |
5104 // We cannot use our mutex locks here, since they only work on | |
5105 // Threads. We do an atomic compare and exchange to ensure only | |
5106 // one thread can call this method at a time | |
5107 | |
5108 // We use Atomic::xchg rather than Atomic::add/dec since on some platforms | |
5109 // the add/dec implementations are dependent on whether we are running | |
5110 // on a multiprocessor, and at this stage of initialization the os::is_MP | |
5111 // function used to determine this will always return false. Atomic::xchg | |
5112 // does not have this problem. | |
5113 if (Atomic::xchg(1, &vm_created) == 1) { | |
5114 return JNI_ERR; // already created, or create attempt in progress | |
5115 } | |
5116 if (Atomic::xchg(0, &safe_to_recreate_vm) == 0) { | |
5117 return JNI_ERR; // someone tried and failed and retry not allowed. | |
5118 } | |
5119 | |
5120 assert(vm_created == 1, "vm_created is true during the creation"); | |
5121 | |
5122 /** | |
5123 * Certain errors during initialization are recoverable and do not | |
5124 * prevent this method from being called again at a later time | |
5125 * (perhaps with different arguments). However, at a certain | |
5126 * point during initialization if an error occurs we cannot allow | |
5127 * this function to be called again (or it will crash). In those | |
5128 * situations, the 'canTryAgain' flag is set to false, which atomically | |
5129 * sets safe_to_recreate_vm to 1, such that any new call to | |
5130 * JNI_CreateJavaVM will immediately fail using the above logic. | |
5131 */ | |
5132 bool can_try_again = true; | |
5133 | |
5134 result = Threads::create_vm((JavaVMInitArgs*) args, &can_try_again); | |
5135 if (result == JNI_OK) { | |
5136 JavaThread *thread = JavaThread::current(); | |
5137 /* thread is thread_in_vm here */ | |
5138 *vm = (JavaVM *)(&main_vm); | |
5139 *(JNIEnv**)penv = thread->jni_environment(); | |
5140 | |
5141 // Tracks the time application was running before GC | |
5142 RuntimeService::record_application_start(); | |
5143 | |
5144 // Notify JVMTI | |
5145 if (JvmtiExport::should_post_thread_life()) { | |
5146 JvmtiExport::post_thread_start(thread); | |
5147 } | |
4800
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
4708
diff
changeset
|
5148 |
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
4708
diff
changeset
|
5149 EVENT_BEGIN(TraceEventThreadStart, event); |
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
4708
diff
changeset
|
5150 EVENT_COMMIT(event, |
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
4708
diff
changeset
|
5151 EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(thread->threadObj()))); |
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
4708
diff
changeset
|
5152 |
0 | 5153 // Check if we should compile all classes on bootclasspath |
5154 NOT_PRODUCT(if (CompileTheWorld) ClassLoader::compile_the_world();) | |
6972
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
5155 NOT_PRODUCT(if (ReplayCompiles) ciReplay::replay(thread);) |
0 | 5156 // Since this is not a JVM_ENTRY we have to set the thread state manually before leaving. |
5157 ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native); | |
5158 } else { | |
5159 if (can_try_again) { | |
5160 // reset safe_to_recreate_vm to 1 so that retrial would be possible | |
5161 safe_to_recreate_vm = 1; | |
5162 } | |
5163 | |
5164 // Creation failed. We must reset vm_created | |
5165 *vm = 0; | |
5166 *(JNIEnv**)penv = 0; | |
5167 // reset vm_created last to avoid race condition. Use OrderAccess to | |
5168 // control both compiler and architectural-based reordering. | |
5169 OrderAccess::release_store(&vm_created, 0); | |
5170 } | |
5171 | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1290
diff
changeset
|
5172 NOT_PRODUCT(test_error_handler(ErrorHandlerTest)); |
3779 | 5173 NOT_PRODUCT(execute_internal_vm_tests()); |
0 | 5174 return result; |
5175 } | |
5176 | |
4006 | 5177 #ifndef USDT2 |
0 | 5178 HS_DTRACE_PROBE_DECL3(hotspot_jni, GetCreatedJavaVMs__entry, \ |
5179 JavaVM**, jsize, jsize*); | |
5180 HS_DTRACE_PROBE_DECL1(hotspot_jni, GetCreatedJavaVMs__return, jint); | |
4006 | 5181 #endif /* !USDT2 */ |
0 | 5182 |
5183 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetCreatedJavaVMs(JavaVM **vm_buf, jsize bufLen, jsize *numVMs) { | |
5184 // See bug 4367188, the wrapper can sometimes cause VM crashes | |
5185 // JNIWrapper("GetCreatedJavaVMs"); | |
4006 | 5186 #ifndef USDT2 |
0 | 5187 HS_DTRACE_PROBE3(hotspot_jni, GetCreatedJavaVMs__entry, \ |
5188 vm_buf, bufLen, numVMs); | |
4006 | 5189 #else /* USDT2 */ |
5190 HOTSPOT_JNI_GETCREATEDJAVAVMS_ENTRY( | |
5191 (void **) vm_buf, bufLen, (uintptr_t *) numVMs); | |
5192 #endif /* USDT2 */ | |
0 | 5193 if (vm_created) { |
5194 if (numVMs != NULL) *numVMs = 1; | |
5195 if (bufLen > 0) *vm_buf = (JavaVM *)(&main_vm); | |
5196 } else { | |
5197 if (numVMs != NULL) *numVMs = 0; | |
5198 } | |
4006 | 5199 #ifndef USDT2 |
0 | 5200 HS_DTRACE_PROBE1(hotspot_jni, GetCreatedJavaVMs__return, JNI_OK); |
4006 | 5201 #else /* USDT2 */ |
5202 HOTSPOT_JNI_GETCREATEDJAVAVMS_RETURN( | |
5203 JNI_OK); | |
5204 #endif /* USDT2 */ | |
0 | 5205 return JNI_OK; |
5206 } | |
5207 | |
5208 extern "C" { | |
5209 | |
4006 | 5210 #ifndef USDT2 |
0 | 5211 DT_RETURN_MARK_DECL(DestroyJavaVM, jint); |
4006 | 5212 #else /* USDT2 */ |
5213 DT_RETURN_MARK_DECL(DestroyJavaVM, jint | |
5214 , HOTSPOT_JNI_DESTROYJAVAVM_RETURN(_ret_ref)); | |
5215 #endif /* USDT2 */ | |
0 | 5216 |
5217 jint JNICALL jni_DestroyJavaVM(JavaVM *vm) { | |
4006 | 5218 #ifndef USDT2 |
0 | 5219 DTRACE_PROBE1(hotspot_jni, DestroyJavaVM__entry, vm); |
4006 | 5220 #else /* USDT2 */ |
5221 HOTSPOT_JNI_DESTROYJAVAVM_ENTRY( | |
5222 vm); | |
5223 #endif /* USDT2 */ | |
0 | 5224 jint res = JNI_ERR; |
5225 DT_RETURN_MARK(DestroyJavaVM, jint, (const jint&)res); | |
5226 | |
5227 if (!vm_created) { | |
5228 res = JNI_ERR; | |
5229 return res; | |
5230 } | |
5231 | |
5232 JNIWrapper("DestroyJavaVM"); | |
5233 JNIEnv *env; | |
5234 JavaVMAttachArgs destroyargs; | |
5235 destroyargs.version = CurrentVersion; | |
5236 destroyargs.name = (char *)"DestroyJavaVM"; | |
5237 destroyargs.group = NULL; | |
5238 res = vm->AttachCurrentThread((void **)&env, (void *)&destroyargs); | |
5239 if (res != JNI_OK) { | |
5240 return res; | |
5241 } | |
5242 | |
5243 // Since this is not a JVM_ENTRY we have to set the thread state manually before entering. | |
5244 JavaThread* thread = JavaThread::current(); | |
5245 ThreadStateTransition::transition_from_native(thread, _thread_in_vm); | |
5246 if (Threads::destroy_vm()) { | |
5247 // Should not change thread state, VM is gone | |
5248 vm_created = false; | |
5249 res = JNI_OK; | |
5250 return res; | |
5251 } else { | |
5252 ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native); | |
5253 res = JNI_ERR; | |
5254 return res; | |
5255 } | |
5256 } | |
5257 | |
5258 | |
5259 static jint attach_current_thread(JavaVM *vm, void **penv, void *_args, bool daemon) { | |
5260 JavaVMAttachArgs *args = (JavaVMAttachArgs *) _args; | |
5261 | |
5262 // Check below commented out from JDK1.2fcs as well | |
5263 /* | |
5264 if (args && (args->version != JNI_VERSION_1_1 || args->version != JNI_VERSION_1_2)) { | |
5265 return JNI_EVERSION; | |
5266 } | |
5267 */ | |
5268 | |
5269 Thread* t = ThreadLocalStorage::get_thread_slow(); | |
5270 if (t != NULL) { | |
5271 // If the thread has been attached this operation is a no-op | |
5272 *(JNIEnv**)penv = ((JavaThread*) t)->jni_environment(); | |
5273 return JNI_OK; | |
5274 } | |
5275 | |
5276 // Create a thread and mark it as attaching so it will be skipped by the | |
5277 // ThreadsListEnumerator - see CR 6404306 | |
5278 JavaThread* thread = new JavaThread(true); | |
5279 | |
5280 // Set correct safepoint info. The thread is going to call into Java when | |
5281 // initializing the Java level thread object. Hence, the correct state must | |
5282 // be set in order for the Safepoint code to deal with it correctly. | |
5283 thread->set_thread_state(_thread_in_vm); | |
5284 // Must do this before initialize_thread_local_storage | |
5285 thread->record_stack_base_and_size(); | |
1290
c8a467bf56ad
6914050: jvm assertion "guard pages must be in use" in -Xcomp mode
coleenp
parents:
1142
diff
changeset
|
5286 |
0 | 5287 thread->initialize_thread_local_storage(); |
5288 | |
5289 if (!os::create_attached_thread(thread)) { | |
5290 delete thread; | |
5291 return JNI_ERR; | |
5292 } | |
1290
c8a467bf56ad
6914050: jvm assertion "guard pages must be in use" in -Xcomp mode
coleenp
parents:
1142
diff
changeset
|
5293 // Enable stack overflow checks |
c8a467bf56ad
6914050: jvm assertion "guard pages must be in use" in -Xcomp mode
coleenp
parents:
1142
diff
changeset
|
5294 thread->create_stack_guard_pages(); |
c8a467bf56ad
6914050: jvm assertion "guard pages must be in use" in -Xcomp mode
coleenp
parents:
1142
diff
changeset
|
5295 |
0 | 5296 thread->initialize_tlab(); |
5297 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
5298 thread->cache_global_variables(); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
5299 |
0 | 5300 // Crucial that we do not have a safepoint check for this thread, since it has |
5301 // not been added to the Thread list yet. | |
5302 { Threads_lock->lock_without_safepoint_check(); | |
5303 // This must be inside this lock in order to get FullGCALot to work properly, i.e., to | |
5304 // avoid this thread trying to do a GC before it is added to the thread-list | |
5305 thread->set_active_handles(JNIHandleBlock::allocate_block()); | |
5306 Threads::add(thread, daemon); | |
5307 Threads_lock->unlock(); | |
5308 } | |
5309 // Create thread group and name info from attach arguments | |
5310 oop group = NULL; | |
5311 char* thread_name = NULL; | |
5312 if (args != NULL && Threads::is_supported_jni_version(args->version)) { | |
5313 group = JNIHandles::resolve(args->group); | |
5314 thread_name = args->name; // may be NULL | |
5315 } | |
5316 if (group == NULL) group = Universe::main_thread_group(); | |
5317 | |
5318 // Create Java level thread object and attach it to this thread | |
5319 bool attach_failed = false; | |
5320 { | |
5321 EXCEPTION_MARK; | |
5322 HandleMark hm(THREAD); | |
5323 Handle thread_group(THREAD, group); | |
5324 thread->allocate_threadObj(thread_group, thread_name, daemon, THREAD); | |
5325 if (HAS_PENDING_EXCEPTION) { | |
5326 CLEAR_PENDING_EXCEPTION; | |
5327 // cleanup outside the handle mark. | |
5328 attach_failed = true; | |
5329 } | |
5330 } | |
5331 | |
5332 if (attach_failed) { | |
5333 // Added missing cleanup | |
5334 thread->cleanup_failed_attach_current_thread(); | |
5335 return JNI_ERR; | |
5336 } | |
5337 | |
5338 // mark the thread as no longer attaching | |
5339 // this uses a fence to push the change through so we don't have | |
5340 // to regrab the threads_lock | |
4006 | 5341 thread->set_done_attaching_via_jni(); |
0 | 5342 |
5343 // Set java thread status. | |
5344 java_lang_Thread::set_thread_status(thread->threadObj(), | |
5345 java_lang_Thread::RUNNABLE); | |
5346 | |
5347 // Notify the debugger | |
5348 if (JvmtiExport::should_post_thread_life()) { | |
5349 JvmtiExport::post_thread_start(thread); | |
5350 } | |
5351 | |
4800
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
4708
diff
changeset
|
5352 EVENT_BEGIN(TraceEventThreadStart, event); |
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
4708
diff
changeset
|
5353 EVENT_COMMIT(event, |
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
4708
diff
changeset
|
5354 EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(thread->threadObj()))); |
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
4708
diff
changeset
|
5355 |
0 | 5356 *(JNIEnv**)penv = thread->jni_environment(); |
5357 | |
5358 // Now leaving the VM, so change thread_state. This is normally automatically taken care | |
5359 // of in the JVM_ENTRY. But in this situation we have to do it manually. Notice, that by | |
5360 // using ThreadStateTransition::transition, we do a callback to the safepoint code if | |
5361 // needed. | |
5362 | |
5363 ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native); | |
5364 | |
5365 // Perform any platform dependent FPU setup | |
5366 os::setup_fpu(); | |
5367 | |
5368 return JNI_OK; | |
5369 } | |
5370 | |
5371 | |
5372 jint JNICALL jni_AttachCurrentThread(JavaVM *vm, void **penv, void *_args) { | |
4006 | 5373 #ifndef USDT2 |
0 | 5374 DTRACE_PROBE3(hotspot_jni, AttachCurrentThread__entry, vm, penv, _args); |
4006 | 5375 #else /* USDT2 */ |
5376 HOTSPOT_JNI_ATTACHCURRENTTHREAD_ENTRY( | |
5377 vm, penv, _args); | |
5378 #endif /* USDT2 */ | |
0 | 5379 if (!vm_created) { |
4006 | 5380 #ifndef USDT2 |
0 | 5381 DTRACE_PROBE1(hotspot_jni, AttachCurrentThread__return, JNI_ERR); |
4006 | 5382 #else /* USDT2 */ |
5383 HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN( | |
5384 (uint32_t) JNI_ERR); | |
5385 #endif /* USDT2 */ | |
0 | 5386 return JNI_ERR; |
5387 } | |
5388 | |
5389 JNIWrapper("AttachCurrentThread"); | |
5390 jint ret = attach_current_thread(vm, penv, _args, false); | |
4006 | 5391 #ifndef USDT2 |
0 | 5392 DTRACE_PROBE1(hotspot_jni, AttachCurrentThread__return, ret); |
4006 | 5393 #else /* USDT2 */ |
5394 HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN( | |
5395 ret); | |
5396 #endif /* USDT2 */ | |
0 | 5397 return ret; |
5398 } | |
5399 | |
5400 | |
5401 jint JNICALL jni_DetachCurrentThread(JavaVM *vm) { | |
4006 | 5402 #ifndef USDT2 |
0 | 5403 DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__entry, vm); |
4006 | 5404 #else /* USDT2 */ |
5405 HOTSPOT_JNI_DETACHCURRENTTHREAD_ENTRY( | |
5406 vm); | |
5407 #endif /* USDT2 */ | |
0 | 5408 VM_Exit::block_if_vm_exited(); |
5409 | |
5410 JNIWrapper("DetachCurrentThread"); | |
5411 | |
5412 // If the thread has been deattacted the operations is a no-op | |
5413 if (ThreadLocalStorage::thread() == NULL) { | |
4006 | 5414 #ifndef USDT2 |
0 | 5415 DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_OK); |
4006 | 5416 #else /* USDT2 */ |
5417 HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN( | |
5418 JNI_OK); | |
5419 #endif /* USDT2 */ | |
0 | 5420 return JNI_OK; |
5421 } | |
5422 | |
5423 JavaThread* thread = JavaThread::current(); | |
5424 if (thread->has_last_Java_frame()) { | |
4006 | 5425 #ifndef USDT2 |
0 | 5426 DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_ERR); |
4006 | 5427 #else /* USDT2 */ |
5428 HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN( | |
5429 (uint32_t) JNI_ERR); | |
5430 #endif /* USDT2 */ | |
0 | 5431 // Can't detach a thread that's running java, that can't work. |
5432 return JNI_ERR; | |
5433 } | |
5434 | |
5435 // Safepoint support. Have to do call-back to safepoint code, if in the | |
5436 // middel of a safepoint operation | |
5437 ThreadStateTransition::transition_from_native(thread, _thread_in_vm); | |
5438 | |
5439 // XXX: Note that JavaThread::exit() call below removes the guards on the | |
5440 // stack pages set up via enable_stack_{red,yellow}_zone() calls | |
5441 // above in jni_AttachCurrentThread. Unfortunately, while the setting | |
5442 // of the guards is visible in jni_AttachCurrentThread above, | |
5443 // the removal of the guards is buried below in JavaThread::exit() | |
5444 // here. The abstraction should be more symmetrically either exposed | |
5445 // or hidden (e.g. it could probably be hidden in the same | |
5446 // (platform-dependent) methods where we do alternate stack | |
5447 // maintenance work?) | |
5448 thread->exit(false, JavaThread::jni_detach); | |
5449 delete thread; | |
5450 | |
4006 | 5451 #ifndef USDT2 |
0 | 5452 DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_OK); |
4006 | 5453 #else /* USDT2 */ |
5454 HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN( | |
5455 JNI_OK); | |
5456 #endif /* USDT2 */ | |
0 | 5457 return JNI_OK; |
5458 } | |
5459 | |
4006 | 5460 #ifndef USDT2 |
0 | 5461 DT_RETURN_MARK_DECL(GetEnv, jint); |
4006 | 5462 #else /* USDT2 */ |
5463 DT_RETURN_MARK_DECL(GetEnv, jint | |
5464 , HOTSPOT_JNI_GETENV_RETURN(_ret_ref)); | |
5465 #endif /* USDT2 */ | |
0 | 5466 |
5467 jint JNICALL jni_GetEnv(JavaVM *vm, void **penv, jint version) { | |
4006 | 5468 #ifndef USDT2 |
0 | 5469 DTRACE_PROBE3(hotspot_jni, GetEnv__entry, vm, penv, version); |
4006 | 5470 #else /* USDT2 */ |
5471 HOTSPOT_JNI_GETENV_ENTRY( | |
5472 vm, penv, version); | |
5473 #endif /* USDT2 */ | |
0 | 5474 jint ret = JNI_ERR; |
5475 DT_RETURN_MARK(GetEnv, jint, (const jint&)ret); | |
5476 | |
5477 if (!vm_created) { | |
5478 *penv = NULL; | |
5479 ret = JNI_EDETACHED; | |
5480 return ret; | |
5481 } | |
5482 | |
4800
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
4708
diff
changeset
|
5483 if (JniExportedInterface::GetExportedInterface(vm, penv, version, &ret)) { |
0 | 5484 return ret; |
5485 } | |
5486 | |
5487 #ifndef JVMPI_VERSION_1 | |
5488 // need these in order to be polite about older agents | |
5489 #define JVMPI_VERSION_1 ((jint)0x10000001) | |
5490 #define JVMPI_VERSION_1_1 ((jint)0x10000002) | |
5491 #define JVMPI_VERSION_1_2 ((jint)0x10000003) | |
5492 #endif // !JVMPI_VERSION_1 | |
5493 | |
5494 Thread* thread = ThreadLocalStorage::thread(); | |
5495 if (thread != NULL && thread->is_Java_thread()) { | |
5496 if (Threads::is_supported_jni_version_including_1_1(version)) { | |
5497 *(JNIEnv**)penv = ((JavaThread*) thread)->jni_environment(); | |
5498 ret = JNI_OK; | |
5499 return ret; | |
5500 | |
5501 } else if (version == JVMPI_VERSION_1 || | |
5502 version == JVMPI_VERSION_1_1 || | |
5503 version == JVMPI_VERSION_1_2) { | |
5504 tty->print_cr("ERROR: JVMPI, an experimental interface, is no longer supported."); | |
5505 tty->print_cr("Please use the supported interface: the JVM Tool Interface (JVM TI)."); | |
5506 ret = JNI_EVERSION; | |
5507 return ret; | |
5508 } else if (JvmtiExport::is_jvmdi_version(version)) { | |
5509 tty->print_cr("FATAL ERROR: JVMDI is no longer supported."); | |
5510 tty->print_cr("Please use the supported interface: the JVM Tool Interface (JVM TI)."); | |
5511 ret = JNI_EVERSION; | |
5512 return ret; | |
5513 } else { | |
5514 *penv = NULL; | |
5515 ret = JNI_EVERSION; | |
5516 return ret; | |
5517 } | |
5518 } else { | |
5519 *penv = NULL; | |
5520 ret = JNI_EDETACHED; | |
5521 return ret; | |
5522 } | |
5523 } | |
5524 | |
5525 | |
5526 jint JNICALL jni_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *_args) { | |
4006 | 5527 #ifndef USDT2 |
0 | 5528 DTRACE_PROBE3(hotspot_jni, AttachCurrentThreadAsDaemon__entry, vm, penv, _args); |
4006 | 5529 #else /* USDT2 */ |
5530 HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_ENTRY( | |
5531 vm, penv, _args); | |
5532 #endif /* USDT2 */ | |
0 | 5533 if (!vm_created) { |
4006 | 5534 #ifndef USDT2 |
0 | 5535 DTRACE_PROBE1(hotspot_jni, AttachCurrentThreadAsDaemon__return, JNI_ERR); |
4006 | 5536 #else /* USDT2 */ |
5537 HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN( | |
5538 (uint32_t) JNI_ERR); | |
5539 #endif /* USDT2 */ | |
0 | 5540 return JNI_ERR; |
5541 } | |
5542 | |
5543 JNIWrapper("AttachCurrentThreadAsDaemon"); | |
5544 jint ret = attach_current_thread(vm, penv, _args, true); | |
4006 | 5545 #ifndef USDT2 |
0 | 5546 DTRACE_PROBE1(hotspot_jni, AttachCurrentThreadAsDaemon__return, ret); |
4006 | 5547 #else /* USDT2 */ |
5548 HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN( | |
5549 ret); | |
5550 #endif /* USDT2 */ | |
0 | 5551 return ret; |
5552 } | |
5553 | |
5554 | |
5555 } // End extern "C" | |
5556 | |
5557 const struct JNIInvokeInterface_ jni_InvokeInterface = { | |
5558 NULL, | |
5559 NULL, | |
5560 NULL, | |
5561 | |
5562 jni_DestroyJavaVM, | |
5563 jni_AttachCurrentThread, | |
5564 jni_DetachCurrentThread, | |
5565 jni_GetEnv, | |
5566 jni_AttachCurrentThreadAsDaemon | |
5567 }; |