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