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