Mercurial > hg > graal-compiler
annotate src/share/vm/prims/jvm.cpp @ 3992:d1bdeef3e3e2
7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76
Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing.
Reviewed-by: tonyp, brutisso, ysr
author | johnc |
---|---|
date | Wed, 12 Oct 2011 10:25:51 -0700 |
parents | f08d439fab8c |
children | 436b4a3231bf |
rev | line source |
---|---|
0 | 1 /* |
2162
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1324
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1324
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1324
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/classLoader.hpp" | |
27 #include "classfile/javaAssertions.hpp" | |
28 #include "classfile/javaClasses.hpp" | |
29 #include "classfile/symbolTable.hpp" | |
30 #include "classfile/systemDictionary.hpp" | |
31 #include "classfile/vmSymbols.hpp" | |
32 #include "gc_interface/collectedHeap.inline.hpp" | |
33 #include "memory/oopFactory.hpp" | |
34 #include "memory/universe.inline.hpp" | |
3938 | 35 #include "oops/fieldStreams.hpp" |
1972 | 36 #include "oops/instanceKlass.hpp" |
37 #include "oops/objArrayKlass.hpp" | |
38 #include "prims/jvm.h" | |
39 #include "prims/jvm_misc.hpp" | |
40 #include "prims/jvmtiExport.hpp" | |
41 #include "prims/jvmtiThreadState.hpp" | |
42 #include "prims/nativeLookup.hpp" | |
43 #include "prims/privilegedStack.hpp" | |
44 #include "runtime/arguments.hpp" | |
45 #include "runtime/dtraceJSDT.hpp" | |
46 #include "runtime/handles.inline.hpp" | |
47 #include "runtime/init.hpp" | |
48 #include "runtime/interfaceSupport.hpp" | |
49 #include "runtime/java.hpp" | |
50 #include "runtime/javaCalls.hpp" | |
51 #include "runtime/jfieldIDWorkaround.hpp" | |
52 #include "runtime/os.hpp" | |
53 #include "runtime/perfData.hpp" | |
54 #include "runtime/reflection.hpp" | |
55 #include "runtime/vframe.hpp" | |
56 #include "runtime/vm_operations.hpp" | |
57 #include "services/attachListener.hpp" | |
58 #include "services/management.hpp" | |
59 #include "services/threadService.hpp" | |
60 #include "utilities/copy.hpp" | |
61 #include "utilities/defaultStream.hpp" | |
62 #include "utilities/dtrace.hpp" | |
63 #include "utilities/events.hpp" | |
64 #include "utilities/histogram.hpp" | |
65 #include "utilities/top.hpp" | |
66 #include "utilities/utf8.hpp" | |
67 #ifdef TARGET_OS_FAMILY_linux | |
68 # include "jvm_linux.h" | |
69 #endif | |
70 #ifdef TARGET_OS_FAMILY_solaris | |
71 # include "jvm_solaris.h" | |
72 #endif | |
73 #ifdef TARGET_OS_FAMILY_windows | |
74 # include "jvm_windows.h" | |
75 #endif | |
3960 | 76 #ifdef TARGET_OS_FAMILY_bsd |
77 # include "jvm_bsd.h" | |
78 #endif | |
1972 | 79 |
0 | 80 #include <errno.h> |
81 | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1144
diff
changeset
|
82 HS_DTRACE_PROBE_DECL1(hotspot, thread__sleep__begin, long long); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1144
diff
changeset
|
83 HS_DTRACE_PROBE_DECL1(hotspot, thread__sleep__end, int); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1144
diff
changeset
|
84 HS_DTRACE_PROBE_DECL0(hotspot, thread__yield); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1144
diff
changeset
|
85 |
0 | 86 /* |
87 NOTE about use of any ctor or function call that can trigger a safepoint/GC: | |
88 such ctors and calls MUST NOT come between an oop declaration/init and its | |
89 usage because if objects are move this may cause various memory stomps, bus | |
90 errors and segfaults. Here is a cookbook for causing so called "naked oop | |
91 failures": | |
92 | |
93 JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields<etc> { | |
94 JVMWrapper("JVM_GetClassDeclaredFields"); | |
95 | |
96 // Object address to be held directly in mirror & not visible to GC | |
97 oop mirror = JNIHandles::resolve_non_null(ofClass); | |
98 | |
99 // If this ctor can hit a safepoint, moving objects around, then | |
100 ComplexConstructor foo; | |
101 | |
102 // Boom! mirror may point to JUNK instead of the intended object | |
103 (some dereference of mirror) | |
104 | |
105 // Here's another call that may block for GC, making mirror stale | |
106 MutexLocker ml(some_lock); | |
107 | |
108 // And here's an initializer that can result in a stale oop | |
109 // all in one step. | |
110 oop o = call_that_can_throw_exception(TRAPS); | |
111 | |
112 | |
113 The solution is to keep the oop declaration BELOW the ctor or function | |
114 call that might cause a GC, do another resolve to reassign the oop, or | |
115 consider use of a Handle instead of an oop so there is immunity from object | |
116 motion. But note that the "QUICK" entries below do not have a handlemark | |
117 and thus can only support use of handles passed in. | |
118 */ | |
119 | |
120 static void trace_class_resolution_impl(klassOop to_class, TRAPS) { | |
121 ResourceMark rm; | |
122 int line_number = -1; | |
123 const char * source_file = NULL; | |
657
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
124 const char * trace = "explicit"; |
0 | 125 klassOop caller = NULL; |
126 JavaThread* jthread = JavaThread::current(); | |
127 if (jthread->has_last_Java_frame()) { | |
128 vframeStream vfst(jthread); | |
129 | |
130 // scan up the stack skipping ClassLoader, AccessController and PrivilegedAction frames | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
131 TempNewSymbol access_controller = SymbolTable::new_symbol("java/security/AccessController", CHECK); |
0 | 132 klassOop access_controller_klass = SystemDictionary::resolve_or_fail(access_controller, false, CHECK); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
133 TempNewSymbol privileged_action = SymbolTable::new_symbol("java/security/PrivilegedAction", CHECK); |
0 | 134 klassOop privileged_action_klass = SystemDictionary::resolve_or_fail(privileged_action, false, CHECK); |
135 | |
136 methodOop last_caller = NULL; | |
137 | |
138 while (!vfst.at_end()) { | |
139 methodOop m = vfst.method(); | |
1142 | 140 if (!vfst.method()->method_holder()->klass_part()->is_subclass_of(SystemDictionary::ClassLoader_klass())&& |
0 | 141 !vfst.method()->method_holder()->klass_part()->is_subclass_of(access_controller_klass) && |
142 !vfst.method()->method_holder()->klass_part()->is_subclass_of(privileged_action_klass)) { | |
143 break; | |
144 } | |
145 last_caller = m; | |
146 vfst.next(); | |
147 } | |
148 // if this is called from Class.forName0 and that is called from Class.forName, | |
149 // then print the caller of Class.forName. If this is Class.loadClass, then print | |
150 // that caller, otherwise keep quiet since this should be picked up elsewhere. | |
151 bool found_it = false; | |
152 if (!vfst.at_end() && | |
153 instanceKlass::cast(vfst.method()->method_holder())->name() == vmSymbols::java_lang_Class() && | |
154 vfst.method()->name() == vmSymbols::forName0_name()) { | |
155 vfst.next(); | |
156 if (!vfst.at_end() && | |
157 instanceKlass::cast(vfst.method()->method_holder())->name() == vmSymbols::java_lang_Class() && | |
158 vfst.method()->name() == vmSymbols::forName_name()) { | |
159 vfst.next(); | |
160 found_it = true; | |
161 } | |
162 } else if (last_caller != NULL && | |
163 instanceKlass::cast(last_caller->method_holder())->name() == | |
164 vmSymbols::java_lang_ClassLoader() && | |
165 (last_caller->name() == vmSymbols::loadClassInternal_name() || | |
166 last_caller->name() == vmSymbols::loadClass_name())) { | |
167 found_it = true; | |
657
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
168 } else if (!vfst.at_end()) { |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
169 if (vfst.method()->is_native()) { |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
170 // JNI call |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
171 found_it = true; |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
172 } |
0 | 173 } |
174 if (found_it && !vfst.at_end()) { | |
175 // found the caller | |
176 caller = vfst.method()->method_holder(); | |
177 line_number = vfst.method()->line_number_from_bci(vfst.bci()); | |
657
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
178 if (line_number == -1) { |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
179 // show method name if it's a native method |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
180 trace = vfst.method()->name_and_sig_as_C_string(); |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
181 } |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
182 Symbol* s = instanceKlass::cast(caller)->source_file_name(); |
0 | 183 if (s != NULL) { |
184 source_file = s->as_C_string(); | |
185 } | |
186 } | |
187 } | |
188 if (caller != NULL) { | |
189 if (to_class != caller) { | |
190 const char * from = Klass::cast(caller)->external_name(); | |
191 const char * to = Klass::cast(to_class)->external_name(); | |
192 // print in a single call to reduce interleaving between threads | |
193 if (source_file != NULL) { | |
657
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
194 tty->print("RESOLVE %s %s %s:%d (%s)\n", from, to, source_file, line_number, trace); |
0 | 195 } else { |
657
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
196 tty->print("RESOLVE %s %s (%s)\n", from, to, trace); |
0 | 197 } |
198 } | |
199 } | |
200 } | |
201 | |
657
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
202 void trace_class_resolution(klassOop to_class) { |
0 | 203 EXCEPTION_MARK; |
204 trace_class_resolution_impl(to_class, THREAD); | |
205 if (HAS_PENDING_EXCEPTION) { | |
206 CLEAR_PENDING_EXCEPTION; | |
207 } | |
208 } | |
209 | |
210 // Wrapper to trace JVM functions | |
211 | |
212 #ifdef ASSERT | |
213 class JVMTraceWrapper : public StackObj { | |
214 public: | |
215 JVMTraceWrapper(const char* format, ...) { | |
216 if (TraceJVMCalls) { | |
217 va_list ap; | |
218 va_start(ap, format); | |
219 tty->print("JVM "); | |
220 tty->vprint_cr(format, ap); | |
221 va_end(ap); | |
222 } | |
223 } | |
224 }; | |
225 | |
226 Histogram* JVMHistogram; | |
227 volatile jint JVMHistogram_lock = 0; | |
228 | |
229 class JVMHistogramElement : public HistogramElement { | |
230 public: | |
231 JVMHistogramElement(const char* name); | |
232 }; | |
233 | |
234 JVMHistogramElement::JVMHistogramElement(const char* elementName) { | |
235 _name = elementName; | |
236 uintx count = 0; | |
237 | |
238 while (Atomic::cmpxchg(1, &JVMHistogram_lock, 0) != 0) { | |
239 while (OrderAccess::load_acquire(&JVMHistogram_lock) != 0) { | |
240 count +=1; | |
241 if ( (WarnOnStalledSpinLock > 0) | |
242 && (count % WarnOnStalledSpinLock == 0)) { | |
243 warning("JVMHistogram_lock seems to be stalled"); | |
244 } | |
245 } | |
246 } | |
247 | |
248 if(JVMHistogram == NULL) | |
249 JVMHistogram = new Histogram("JVM Call Counts",100); | |
250 | |
251 JVMHistogram->add_element(this); | |
252 Atomic::dec(&JVMHistogram_lock); | |
253 } | |
254 | |
255 #define JVMCountWrapper(arg) \ | |
256 static JVMHistogramElement* e = new JVMHistogramElement(arg); \ | |
257 if (e != NULL) e->increment_count(); // Due to bug in VC++, we need a NULL check here eventhough it should never happen! | |
258 | |
259 #define JVMWrapper(arg1) JVMCountWrapper(arg1); JVMTraceWrapper(arg1) | |
260 #define JVMWrapper2(arg1, arg2) JVMCountWrapper(arg1); JVMTraceWrapper(arg1, arg2) | |
261 #define JVMWrapper3(arg1, arg2, arg3) JVMCountWrapper(arg1); JVMTraceWrapper(arg1, arg2, arg3) | |
262 #define JVMWrapper4(arg1, arg2, arg3, arg4) JVMCountWrapper(arg1); JVMTraceWrapper(arg1, arg2, arg3, arg4) | |
263 #else | |
264 #define JVMWrapper(arg1) | |
265 #define JVMWrapper2(arg1, arg2) | |
266 #define JVMWrapper3(arg1, arg2, arg3) | |
267 #define JVMWrapper4(arg1, arg2, arg3, arg4) | |
268 #endif | |
269 | |
270 | |
271 // Interface version ///////////////////////////////////////////////////////////////////// | |
272 | |
273 | |
274 JVM_LEAF(jint, JVM_GetInterfaceVersion()) | |
275 return JVM_INTERFACE_VERSION; | |
276 JVM_END | |
277 | |
278 | |
279 // java.lang.System ////////////////////////////////////////////////////////////////////// | |
280 | |
281 | |
282 JVM_LEAF(jlong, JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored)) | |
283 JVMWrapper("JVM_CurrentTimeMillis"); | |
284 return os::javaTimeMillis(); | |
285 JVM_END | |
286 | |
287 JVM_LEAF(jlong, JVM_NanoTime(JNIEnv *env, jclass ignored)) | |
288 JVMWrapper("JVM_NanoTime"); | |
289 return os::javaTimeNanos(); | |
290 JVM_END | |
291 | |
292 | |
293 JVM_ENTRY(void, JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos, | |
294 jobject dst, jint dst_pos, jint length)) | |
295 JVMWrapper("JVM_ArrayCopy"); | |
296 // Check if we have null pointers | |
297 if (src == NULL || dst == NULL) { | |
298 THROW(vmSymbols::java_lang_NullPointerException()); | |
299 } | |
300 arrayOop s = arrayOop(JNIHandles::resolve_non_null(src)); | |
301 arrayOop d = arrayOop(JNIHandles::resolve_non_null(dst)); | |
302 assert(s->is_oop(), "JVM_ArrayCopy: src not an oop"); | |
303 assert(d->is_oop(), "JVM_ArrayCopy: dst not an oop"); | |
304 // Do copy | |
305 Klass::cast(s->klass())->copy_array(s, src_pos, d, dst_pos, length, thread); | |
306 JVM_END | |
307 | |
308 | |
309 static void set_property(Handle props, const char* key, const char* value, TRAPS) { | |
310 JavaValue r(T_OBJECT); | |
311 // public synchronized Object put(Object key, Object value); | |
312 HandleMark hm(THREAD); | |
313 Handle key_str = java_lang_String::create_from_platform_dependent_str(key, CHECK); | |
314 Handle value_str = java_lang_String::create_from_platform_dependent_str((value != NULL ? value : ""), CHECK); | |
315 JavaCalls::call_virtual(&r, | |
316 props, | |
1142 | 317 KlassHandle(THREAD, SystemDictionary::Properties_klass()), |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
318 vmSymbols::put_name(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
319 vmSymbols::object_object_object_signature(), |
0 | 320 key_str, |
321 value_str, | |
322 THREAD); | |
323 } | |
324 | |
325 | |
326 #define PUTPROP(props, name, value) set_property((props), (name), (value), CHECK_(properties)); | |
327 | |
328 | |
329 JVM_ENTRY(jobject, JVM_InitProperties(JNIEnv *env, jobject properties)) | |
330 JVMWrapper("JVM_InitProperties"); | |
331 ResourceMark rm; | |
332 | |
333 Handle props(THREAD, JNIHandles::resolve_non_null(properties)); | |
334 | |
335 // System property list includes both user set via -D option and | |
336 // jvm system specific properties. | |
337 for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) { | |
338 PUTPROP(props, p->key(), p->value()); | |
339 } | |
340 | |
341 // Convert the -XX:MaxDirectMemorySize= command line flag | |
342 // to the sun.nio.MaxDirectMemorySize property. | |
343 // Do this after setting user properties to prevent people | |
344 // from setting the value with a -D option, as requested. | |
345 { | |
346 char as_chars[256]; | |
347 jio_snprintf(as_chars, sizeof(as_chars), INTX_FORMAT, MaxDirectMemorySize); | |
348 PUTPROP(props, "sun.nio.MaxDirectMemorySize", as_chars); | |
349 } | |
350 | |
351 // JVM monitoring and management support | |
352 // Add the sun.management.compiler property for the compiler's name | |
353 { | |
354 #undef CSIZE | |
355 #if defined(_LP64) || defined(_WIN64) | |
356 #define CSIZE "64-Bit " | |
357 #else | |
358 #define CSIZE | |
359 #endif // 64bit | |
360 | |
361 #ifdef TIERED | |
362 const char* compiler_name = "HotSpot " CSIZE "Tiered Compilers"; | |
363 #else | |
364 #if defined(COMPILER1) | |
365 const char* compiler_name = "HotSpot " CSIZE "Client Compiler"; | |
366 #elif defined(COMPILER2) | |
367 const char* compiler_name = "HotSpot " CSIZE "Server Compiler"; | |
368 #else | |
369 const char* compiler_name = ""; | |
370 #endif // compilers | |
371 #endif // TIERED | |
372 | |
373 if (*compiler_name != '\0' && | |
374 (Arguments::mode() != Arguments::_int)) { | |
375 PUTPROP(props, "sun.management.compiler", compiler_name); | |
376 } | |
377 } | |
378 | |
379 return properties; | |
380 JVM_END | |
381 | |
382 | |
383 // java.lang.Runtime ///////////////////////////////////////////////////////////////////////// | |
384 | |
385 extern volatile jint vm_created; | |
386 | |
387 JVM_ENTRY_NO_ENV(void, JVM_Exit(jint code)) | |
388 if (vm_created != 0 && (code == 0)) { | |
389 // The VM is about to exit. We call back into Java to check whether finalizers should be run | |
390 Universe::run_finalizers_on_exit(); | |
391 } | |
392 before_exit(thread); | |
393 vm_exit(code); | |
394 JVM_END | |
395 | |
396 | |
397 JVM_ENTRY_NO_ENV(void, JVM_Halt(jint code)) | |
398 before_exit(thread); | |
399 vm_exit(code); | |
400 JVM_END | |
401 | |
402 | |
403 JVM_LEAF(void, JVM_OnExit(void (*func)(void))) | |
404 register_on_exit_function(func); | |
405 JVM_END | |
406 | |
407 | |
408 JVM_ENTRY_NO_ENV(void, JVM_GC(void)) | |
409 JVMWrapper("JVM_GC"); | |
410 if (!DisableExplicitGC) { | |
411 Universe::heap()->collect(GCCause::_java_lang_system_gc); | |
412 } | |
413 JVM_END | |
414 | |
415 | |
416 JVM_LEAF(jlong, JVM_MaxObjectInspectionAge(void)) | |
417 JVMWrapper("JVM_MaxObjectInspectionAge"); | |
418 return Universe::heap()->millis_since_last_gc(); | |
419 JVM_END | |
420 | |
421 | |
422 JVM_LEAF(void, JVM_TraceInstructions(jboolean on)) | |
423 if (PrintJVMWarnings) warning("JVM_TraceInstructions not supported"); | |
424 JVM_END | |
425 | |
426 | |
427 JVM_LEAF(void, JVM_TraceMethodCalls(jboolean on)) | |
428 if (PrintJVMWarnings) warning("JVM_TraceMethodCalls not supported"); | |
429 JVM_END | |
430 | |
431 static inline jlong convert_size_t_to_jlong(size_t val) { | |
432 // In the 64-bit vm, a size_t can overflow a jlong (which is signed). | |
433 NOT_LP64 (return (jlong)val;) | |
434 LP64_ONLY(return (jlong)MIN2(val, (size_t)max_jlong);) | |
435 } | |
436 | |
437 JVM_ENTRY_NO_ENV(jlong, JVM_TotalMemory(void)) | |
438 JVMWrapper("JVM_TotalMemory"); | |
439 size_t n = Universe::heap()->capacity(); | |
440 return convert_size_t_to_jlong(n); | |
441 JVM_END | |
442 | |
443 | |
444 JVM_ENTRY_NO_ENV(jlong, JVM_FreeMemory(void)) | |
445 JVMWrapper("JVM_FreeMemory"); | |
446 CollectedHeap* ch = Universe::heap(); | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
116
diff
changeset
|
447 size_t n; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
116
diff
changeset
|
448 { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
116
diff
changeset
|
449 MutexLocker x(Heap_lock); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
116
diff
changeset
|
450 n = ch->capacity() - ch->used(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
116
diff
changeset
|
451 } |
0 | 452 return convert_size_t_to_jlong(n); |
453 JVM_END | |
454 | |
455 | |
456 JVM_ENTRY_NO_ENV(jlong, JVM_MaxMemory(void)) | |
457 JVMWrapper("JVM_MaxMemory"); | |
458 size_t n = Universe::heap()->max_capacity(); | |
459 return convert_size_t_to_jlong(n); | |
460 JVM_END | |
461 | |
462 | |
463 JVM_ENTRY_NO_ENV(jint, JVM_ActiveProcessorCount(void)) | |
464 JVMWrapper("JVM_ActiveProcessorCount"); | |
465 return os::active_processor_count(); | |
466 JVM_END | |
467 | |
468 | |
469 | |
470 // java.lang.Throwable ////////////////////////////////////////////////////// | |
471 | |
472 | |
473 JVM_ENTRY(void, JVM_FillInStackTrace(JNIEnv *env, jobject receiver)) | |
474 JVMWrapper("JVM_FillInStackTrace"); | |
475 Handle exception(thread, JNIHandles::resolve_non_null(receiver)); | |
476 java_lang_Throwable::fill_in_stack_trace(exception); | |
477 JVM_END | |
478 | |
479 | |
480 JVM_ENTRY(void, JVM_PrintStackTrace(JNIEnv *env, jobject receiver, jobject printable)) | |
481 JVMWrapper("JVM_PrintStackTrace"); | |
482 // Note: This is no longer used in Merlin, but we still support it for compatibility. | |
483 oop exception = JNIHandles::resolve_non_null(receiver); | |
484 oop stream = JNIHandles::resolve_non_null(printable); | |
485 java_lang_Throwable::print_stack_trace(exception, stream); | |
486 JVM_END | |
487 | |
488 | |
489 JVM_ENTRY(jint, JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable)) | |
490 JVMWrapper("JVM_GetStackTraceDepth"); | |
491 oop exception = JNIHandles::resolve(throwable); | |
492 return java_lang_Throwable::get_stack_trace_depth(exception, THREAD); | |
493 JVM_END | |
494 | |
495 | |
496 JVM_ENTRY(jobject, JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)) | |
497 JVMWrapper("JVM_GetStackTraceElement"); | |
498 JvmtiVMObjectAllocEventCollector oam; // This ctor (throughout this module) may trigger a safepoint/GC | |
499 oop exception = JNIHandles::resolve(throwable); | |
500 oop element = java_lang_Throwable::get_stack_trace_element(exception, index, CHECK_NULL); | |
501 return JNIHandles::make_local(env, element); | |
502 JVM_END | |
503 | |
504 | |
505 // java.lang.Object /////////////////////////////////////////////// | |
506 | |
507 | |
508 JVM_ENTRY(jint, JVM_IHashCode(JNIEnv* env, jobject handle)) | |
509 JVMWrapper("JVM_IHashCode"); | |
510 // as implemented in the classic virtual machine; return 0 if object is NULL | |
511 return handle == NULL ? 0 : ObjectSynchronizer::FastHashCode (THREAD, JNIHandles::resolve_non_null(handle)) ; | |
512 JVM_END | |
513 | |
514 | |
515 JVM_ENTRY(void, JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms)) | |
516 JVMWrapper("JVM_MonitorWait"); | |
517 Handle obj(THREAD, JNIHandles::resolve_non_null(handle)); | |
518 assert(obj->is_instance() || obj->is_array(), "JVM_MonitorWait must apply to an object"); | |
519 JavaThreadInObjectWaitState jtiows(thread, ms != 0); | |
520 if (JvmtiExport::should_post_monitor_wait()) { | |
521 JvmtiExport::post_monitor_wait((JavaThread *)THREAD, (oop)obj(), ms); | |
522 } | |
523 ObjectSynchronizer::wait(obj, ms, CHECK); | |
524 JVM_END | |
525 | |
526 | |
527 JVM_ENTRY(void, JVM_MonitorNotify(JNIEnv* env, jobject handle)) | |
528 JVMWrapper("JVM_MonitorNotify"); | |
529 Handle obj(THREAD, JNIHandles::resolve_non_null(handle)); | |
530 assert(obj->is_instance() || obj->is_array(), "JVM_MonitorNotify must apply to an object"); | |
531 ObjectSynchronizer::notify(obj, CHECK); | |
532 JVM_END | |
533 | |
534 | |
535 JVM_ENTRY(void, JVM_MonitorNotifyAll(JNIEnv* env, jobject handle)) | |
536 JVMWrapper("JVM_MonitorNotifyAll"); | |
537 Handle obj(THREAD, JNIHandles::resolve_non_null(handle)); | |
538 assert(obj->is_instance() || obj->is_array(), "JVM_MonitorNotifyAll must apply to an object"); | |
539 ObjectSynchronizer::notifyall(obj, CHECK); | |
540 JVM_END | |
541 | |
542 | |
543 JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle)) | |
544 JVMWrapper("JVM_Clone"); | |
545 Handle obj(THREAD, JNIHandles::resolve_non_null(handle)); | |
546 const KlassHandle klass (THREAD, obj->klass()); | |
547 JvmtiVMObjectAllocEventCollector oam; | |
548 | |
549 #ifdef ASSERT | |
550 // Just checking that the cloneable flag is set correct | |
551 if (obj->is_javaArray()) { | |
552 guarantee(klass->is_cloneable(), "all arrays are cloneable"); | |
553 } else { | |
554 guarantee(obj->is_instance(), "should be instanceOop"); | |
1142 | 555 bool cloneable = klass->is_subtype_of(SystemDictionary::Cloneable_klass()); |
0 | 556 guarantee(cloneable == klass->is_cloneable(), "incorrect cloneable flag"); |
557 } | |
558 #endif | |
559 | |
560 // Check if class of obj supports the Cloneable interface. | |
561 // All arrays are considered to be cloneable (See JLS 20.1.5) | |
562 if (!klass->is_cloneable()) { | |
563 ResourceMark rm(THREAD); | |
564 THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name()); | |
565 } | |
566 | |
567 // Make shallow object copy | |
568 const int size = obj->size(); | |
569 oop new_obj = NULL; | |
570 if (obj->is_javaArray()) { | |
571 const int length = ((arrayOop)obj())->length(); | |
572 new_obj = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL); | |
573 } else { | |
574 new_obj = CollectedHeap::obj_allocate(klass, size, CHECK_NULL); | |
575 } | |
576 // 4839641 (4840070): We must do an oop-atomic copy, because if another thread | |
577 // is modifying a reference field in the clonee, a non-oop-atomic copy might | |
578 // be suspended in the middle of copying the pointer and end up with parts | |
579 // of two different pointers in the field. Subsequent dereferences will crash. | |
580 // 4846409: an oop-copy of objects with long or double fields or arrays of same | |
581 // won't copy the longs/doubles atomically in 32-bit vm's, so we copy jlongs instead | |
582 // of oops. We know objects are aligned on a minimum of an jlong boundary. | |
583 // The same is true of StubRoutines::object_copy and the various oop_copy | |
584 // variants, and of the code generated by the inline_native_clone intrinsic. | |
585 assert(MinObjAlignmentInBytes >= BytesPerLong, "objects misaligned"); | |
586 Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj, | |
587 (size_t)align_object_size(size) / HeapWordsPerLong); | |
588 // Clear the header | |
589 new_obj->init_mark(); | |
590 | |
591 // Store check (mark entire object and let gc sort it out) | |
592 BarrierSet* bs = Universe::heap()->barrier_set(); | |
593 assert(bs->has_write_region_opt(), "Barrier set does not have write_region"); | |
594 bs->write_region(MemRegion((HeapWord*)new_obj, size)); | |
595 | |
596 // Caution: this involves a java upcall, so the clone should be | |
597 // "gc-robust" by this stage. | |
598 if (klass->has_finalizer()) { | |
599 assert(obj->is_instance(), "should be instanceOop"); | |
600 new_obj = instanceKlass::register_finalizer(instanceOop(new_obj), CHECK_NULL); | |
601 } | |
602 | |
603 return JNIHandles::make_local(env, oop(new_obj)); | |
604 JVM_END | |
605 | |
606 // java.lang.Compiler //////////////////////////////////////////////////// | |
607 | |
608 // The initial cuts of the HotSpot VM will not support JITs, and all existing | |
609 // JITs would need extensive changes to work with HotSpot. The JIT-related JVM | |
610 // functions are all silently ignored unless JVM warnings are printed. | |
611 | |
612 JVM_LEAF(void, JVM_InitializeCompiler (JNIEnv *env, jclass compCls)) | |
613 if (PrintJVMWarnings) warning("JVM_InitializeCompiler not supported"); | |
614 JVM_END | |
615 | |
616 | |
617 JVM_LEAF(jboolean, JVM_IsSilentCompiler(JNIEnv *env, jclass compCls)) | |
618 if (PrintJVMWarnings) warning("JVM_IsSilentCompiler not supported"); | |
619 return JNI_FALSE; | |
620 JVM_END | |
621 | |
622 | |
623 JVM_LEAF(jboolean, JVM_CompileClass(JNIEnv *env, jclass compCls, jclass cls)) | |
624 if (PrintJVMWarnings) warning("JVM_CompileClass not supported"); | |
625 return JNI_FALSE; | |
626 JVM_END | |
627 | |
628 | |
629 JVM_LEAF(jboolean, JVM_CompileClasses(JNIEnv *env, jclass cls, jstring jname)) | |
630 if (PrintJVMWarnings) warning("JVM_CompileClasses not supported"); | |
631 return JNI_FALSE; | |
632 JVM_END | |
633 | |
634 | |
635 JVM_LEAF(jobject, JVM_CompilerCommand(JNIEnv *env, jclass compCls, jobject arg)) | |
636 if (PrintJVMWarnings) warning("JVM_CompilerCommand not supported"); | |
637 return NULL; | |
638 JVM_END | |
639 | |
640 | |
641 JVM_LEAF(void, JVM_EnableCompiler(JNIEnv *env, jclass compCls)) | |
642 if (PrintJVMWarnings) warning("JVM_EnableCompiler not supported"); | |
643 JVM_END | |
644 | |
645 | |
646 JVM_LEAF(void, JVM_DisableCompiler(JNIEnv *env, jclass compCls)) | |
647 if (PrintJVMWarnings) warning("JVM_DisableCompiler not supported"); | |
648 JVM_END | |
649 | |
650 | |
651 | |
652 // Error message support ////////////////////////////////////////////////////// | |
653 | |
654 JVM_LEAF(jint, JVM_GetLastErrorString(char *buf, int len)) | |
655 JVMWrapper("JVM_GetLastErrorString"); | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
656 return (jint)os::lasterror(buf, len); |
0 | 657 JVM_END |
658 | |
659 | |
660 // java.io.File /////////////////////////////////////////////////////////////// | |
661 | |
662 JVM_LEAF(char*, JVM_NativePath(char* path)) | |
663 JVMWrapper2("JVM_NativePath (%s)", path); | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
664 return os::native_path(path); |
0 | 665 JVM_END |
666 | |
667 | |
668 // Misc. class handling /////////////////////////////////////////////////////////// | |
669 | |
670 | |
671 JVM_ENTRY(jclass, JVM_GetCallerClass(JNIEnv* env, int depth)) | |
672 JVMWrapper("JVM_GetCallerClass"); | |
673 klassOop k = thread->security_get_caller_class(depth); | |
674 return (k == NULL) ? NULL : (jclass) JNIHandles::make_local(env, Klass::cast(k)->java_mirror()); | |
675 JVM_END | |
676 | |
677 | |
678 JVM_ENTRY(jclass, JVM_FindPrimitiveClass(JNIEnv* env, const char* utf)) | |
679 JVMWrapper("JVM_FindPrimitiveClass"); | |
680 oop mirror = NULL; | |
681 BasicType t = name2type(utf); | |
682 if (t != T_ILLEGAL && t != T_OBJECT && t != T_ARRAY) { | |
683 mirror = Universe::java_mirror(t); | |
684 } | |
685 if (mirror == NULL) { | |
686 THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), (char*) utf); | |
687 } else { | |
688 return (jclass) JNIHandles::make_local(env, mirror); | |
689 } | |
690 JVM_END | |
691 | |
692 | |
693 JVM_ENTRY(void, JVM_ResolveClass(JNIEnv* env, jclass cls)) | |
694 JVMWrapper("JVM_ResolveClass"); | |
695 if (PrintJVMWarnings) warning("JVM_ResolveClass not implemented"); | |
696 JVM_END | |
697 | |
878
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
698 |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
699 // Returns a class loaded by the bootstrap class loader; or null |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
700 // if not found. ClassNotFoundException is not thrown. |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
701 // |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
702 // Rationale behind JVM_FindClassFromBootLoader |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
703 // a> JVM_FindClassFromClassLoader was never exported in the export tables. |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
704 // b> because of (a) java.dll has a direct dependecy on the unexported |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
705 // private symbol "_JVM_FindClassFromClassLoader@20". |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
706 // c> the launcher cannot use the private symbol as it dynamically opens |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
707 // the entry point, so if something changes, the launcher will fail |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
708 // unexpectedly at runtime, it is safest for the launcher to dlopen a |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
709 // stable exported interface. |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
710 // d> re-exporting JVM_FindClassFromClassLoader as public, will cause its |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
711 // signature to change from _JVM_FindClassFromClassLoader@20 to |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
712 // JVM_FindClassFromClassLoader and will not be backward compatible |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
713 // with older JDKs. |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
714 // Thus a public/stable exported entry point is the right solution, |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
715 // public here means public in linker semantics, and is exported only |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
716 // to the JDK, and is not intended to be a public API. |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
717 |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
718 JVM_ENTRY(jclass, JVM_FindClassFromBootLoader(JNIEnv* env, |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
719 const char* name)) |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
720 JVMWrapper2("JVM_FindClassFromBootLoader %s", name); |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
721 |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
722 // Java libraries should ensure that name is never null... |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
723 if (name == NULL || (int)strlen(name) > Symbol::max_length()) { |
878
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
724 // It's impossible to create this class; the name cannot fit |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
725 // into the constant pool. |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
726 return NULL; |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
727 } |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
728 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
729 TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL); |
878
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
730 klassOop k = SystemDictionary::resolve_or_null(h_name, CHECK_NULL); |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
731 if (k == NULL) { |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
732 return NULL; |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
733 } |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
734 |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
735 if (TraceClassResolution) { |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
736 trace_class_resolution(k); |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
737 } |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
738 return (jclass) JNIHandles::make_local(env, Klass::cast(k)->java_mirror()); |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
739 JVM_END |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
740 |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
741 JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name, |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
742 jboolean init, jobject loader, |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
743 jboolean throwError)) |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
744 JVMWrapper3("JVM_FindClassFromClassLoader %s throw %s", name, |
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
745 throwError ? "error" : "exception"); |
388 | 746 // Java libraries should ensure that name is never null... |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
747 if (name == NULL || (int)strlen(name) > Symbol::max_length()) { |
388 | 748 // It's impossible to create this class; the name cannot fit |
749 // into the constant pool. | |
750 if (throwError) { | |
751 THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name); | |
752 } else { | |
753 THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name); | |
754 } | |
755 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
756 TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL); |
388 | 757 Handle h_loader(THREAD, JNIHandles::resolve(loader)); |
758 jclass result = find_class_from_class_loader(env, h_name, init, h_loader, | |
759 Handle(), throwError, THREAD); | |
760 | |
761 if (TraceClassResolution && result != NULL) { | |
762 trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result))); | |
763 } | |
764 return result; | |
0 | 765 JVM_END |
766 | |
767 | |
768 JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name, | |
769 jboolean init, jclass from)) | |
770 JVMWrapper2("JVM_FindClassFromClass %s", name); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
771 if (name == NULL || (int)strlen(name) > Symbol::max_length()) { |
0 | 772 // It's impossible to create this class; the name cannot fit |
773 // into the constant pool. | |
774 THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name); | |
775 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
776 TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL); |
0 | 777 oop from_class_oop = JNIHandles::resolve(from); |
778 klassOop from_class = (from_class_oop == NULL) | |
779 ? (klassOop)NULL | |
780 : java_lang_Class::as_klassOop(from_class_oop); | |
781 oop class_loader = NULL; | |
782 oop protection_domain = NULL; | |
783 if (from_class != NULL) { | |
784 class_loader = Klass::cast(from_class)->class_loader(); | |
785 protection_domain = Klass::cast(from_class)->protection_domain(); | |
786 } | |
787 Handle h_loader(THREAD, class_loader); | |
788 Handle h_prot (THREAD, protection_domain); | |
789 jclass result = find_class_from_class_loader(env, h_name, init, h_loader, | |
790 h_prot, true, thread); | |
791 | |
792 if (TraceClassResolution && result != NULL) { | |
793 // this function is generally only used for class loading during verification. | |
794 ResourceMark rm; | |
795 oop from_mirror = JNIHandles::resolve_non_null(from); | |
796 klassOop from_class = java_lang_Class::as_klassOop(from_mirror); | |
797 const char * from_name = Klass::cast(from_class)->external_name(); | |
798 | |
799 oop mirror = JNIHandles::resolve_non_null(result); | |
800 klassOop to_class = java_lang_Class::as_klassOop(mirror); | |
801 const char * to = Klass::cast(to_class)->external_name(); | |
802 tty->print("RESOLVE %s %s (verification)\n", from_name, to); | |
803 } | |
804 | |
805 return result; | |
806 JVM_END | |
807 | |
808 static void is_lock_held_by_thread(Handle loader, PerfCounter* counter, TRAPS) { | |
809 if (loader.is_null()) { | |
810 return; | |
811 } | |
812 | |
813 // check whether the current caller thread holds the lock or not. | |
814 // If not, increment the corresponding counter | |
815 if (ObjectSynchronizer::query_lock_ownership((JavaThread*)THREAD, loader) != | |
816 ObjectSynchronizer::owner_self) { | |
817 counter->inc(); | |
818 } | |
819 } | |
820 | |
821 // common code for JVM_DefineClass() and JVM_DefineClassWithSource() | |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
822 // and JVM_DefineClassWithSourceCond() |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
823 static jclass jvm_define_class_common(JNIEnv *env, const char *name, |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
824 jobject loader, const jbyte *buf, |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
825 jsize len, jobject pd, const char *source, |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
826 jboolean verify, TRAPS) { |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
388
diff
changeset
|
827 if (source == NULL) source = "__JVM_DefineClass__"; |
0 | 828 |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
726
diff
changeset
|
829 assert(THREAD->is_Java_thread(), "must be a JavaThread"); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
726
diff
changeset
|
830 JavaThread* jt = (JavaThread*) THREAD; |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
726
diff
changeset
|
831 |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
726
diff
changeset
|
832 PerfClassTraceTime vmtimer(ClassLoader::perf_define_appclass_time(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
726
diff
changeset
|
833 ClassLoader::perf_define_appclass_selftime(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
726
diff
changeset
|
834 ClassLoader::perf_define_appclasses(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
726
diff
changeset
|
835 jt->get_thread_stat()->perf_recursion_counts_addr(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
726
diff
changeset
|
836 jt->get_thread_stat()->perf_timers_addr(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
726
diff
changeset
|
837 PerfClassTraceTime::DEFINE_CLASS); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
726
diff
changeset
|
838 |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
726
diff
changeset
|
839 if (UsePerfData) { |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
726
diff
changeset
|
840 ClassLoader::perf_app_classfile_bytes_read()->inc(len); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
726
diff
changeset
|
841 } |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
726
diff
changeset
|
842 |
0 | 843 // Since exceptions can be thrown, class initialization can take place |
844 // if name is NULL no check for class name in .class stream has to be made. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
845 TempNewSymbol class_name = NULL; |
0 | 846 if (name != NULL) { |
847 const int str_len = (int)strlen(name); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
848 if (str_len > Symbol::max_length()) { |
0 | 849 // It's impossible to create this class; the name cannot fit |
850 // into the constant pool. | |
851 THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name); | |
852 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
853 class_name = SymbolTable::new_symbol(name, str_len, CHECK_NULL); |
0 | 854 } |
855 | |
856 ResourceMark rm(THREAD); | |
857 ClassFileStream st((u1*) buf, len, (char *)source); | |
858 Handle class_loader (THREAD, JNIHandles::resolve(loader)); | |
859 if (UsePerfData) { | |
860 is_lock_held_by_thread(class_loader, | |
861 ClassLoader::sync_JVMDefineClassLockFreeCounter(), | |
862 THREAD); | |
863 } | |
864 Handle protection_domain (THREAD, JNIHandles::resolve(pd)); | |
865 klassOop k = SystemDictionary::resolve_from_stream(class_name, class_loader, | |
866 protection_domain, &st, | |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
867 verify != 0, |
0 | 868 CHECK_NULL); |
869 | |
870 if (TraceClassResolution && k != NULL) { | |
871 trace_class_resolution(k); | |
872 } | |
873 | |
874 return (jclass) JNIHandles::make_local(env, Klass::cast(k)->java_mirror()); | |
875 } | |
876 | |
877 | |
878 JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd)) | |
879 JVMWrapper2("JVM_DefineClass %s", name); | |
880 | |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
881 return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, true, THREAD); |
0 | 882 JVM_END |
883 | |
884 | |
885 JVM_ENTRY(jclass, JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source)) | |
886 JVMWrapper2("JVM_DefineClassWithSource %s", name); | |
887 | |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
888 return jvm_define_class_common(env, name, loader, buf, len, pd, source, true, THREAD); |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
889 JVM_END |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
890 |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
891 JVM_ENTRY(jclass, JVM_DefineClassWithSourceCond(JNIEnv *env, const char *name, |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
892 jobject loader, const jbyte *buf, |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
893 jsize len, jobject pd, |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
894 const char *source, jboolean verify)) |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
895 JVMWrapper2("JVM_DefineClassWithSourceCond %s", name); |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
896 |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
897 return jvm_define_class_common(env, name, loader, buf, len, pd, source, verify, THREAD); |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
878
diff
changeset
|
898 JVM_END |
0 | 899 |
900 JVM_ENTRY(jclass, JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name)) | |
901 JVMWrapper("JVM_FindLoadedClass"); | |
902 ResourceMark rm(THREAD); | |
903 | |
904 Handle h_name (THREAD, JNIHandles::resolve_non_null(name)); | |
905 Handle string = java_lang_String::internalize_classname(h_name, CHECK_NULL); | |
906 | |
907 const char* str = java_lang_String::as_utf8_string(string()); | |
908 // Sanity check, don't expect null | |
909 if (str == NULL) return NULL; | |
910 | |
911 const int str_len = (int)strlen(str); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
912 if (str_len > Symbol::max_length()) { |
0 | 913 // It's impossible to create this class; the name cannot fit |
914 // into the constant pool. | |
915 return NULL; | |
916 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
917 TempNewSymbol klass_name = SymbolTable::new_symbol(str, str_len, CHECK_NULL); |
0 | 918 |
919 // Security Note: | |
920 // The Java level wrapper will perform the necessary security check allowing | |
921 // us to pass the NULL as the initiating class loader. | |
922 Handle h_loader(THREAD, JNIHandles::resolve(loader)); | |
923 if (UsePerfData) { | |
924 is_lock_held_by_thread(h_loader, | |
925 ClassLoader::sync_JVMFindLoadedClassLockFreeCounter(), | |
926 THREAD); | |
927 } | |
928 | |
929 klassOop k = SystemDictionary::find_instance_or_array_klass(klass_name, | |
930 h_loader, | |
931 Handle(), | |
932 CHECK_NULL); | |
933 | |
934 return (k == NULL) ? NULL : | |
935 (jclass) JNIHandles::make_local(env, Klass::cast(k)->java_mirror()); | |
936 JVM_END | |
937 | |
938 | |
939 // Reflection support ////////////////////////////////////////////////////////////////////////////// | |
940 | |
941 JVM_ENTRY(jstring, JVM_GetClassName(JNIEnv *env, jclass cls)) | |
942 assert (cls != NULL, "illegal class"); | |
943 JVMWrapper("JVM_GetClassName"); | |
944 JvmtiVMObjectAllocEventCollector oam; | |
945 ResourceMark rm(THREAD); | |
946 const char* name; | |
947 if (java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { | |
948 name = type2name(java_lang_Class::primitive_type(JNIHandles::resolve(cls))); | |
949 } else { | |
950 // Consider caching interned string in Klass | |
951 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve(cls)); | |
952 assert(k->is_klass(), "just checking"); | |
953 name = Klass::cast(k)->external_name(); | |
954 } | |
955 oop result = StringTable::intern((char*) name, CHECK_NULL); | |
956 return (jstring) JNIHandles::make_local(env, result); | |
957 JVM_END | |
958 | |
959 | |
960 JVM_ENTRY(jobjectArray, JVM_GetClassInterfaces(JNIEnv *env, jclass cls)) | |
961 JVMWrapper("JVM_GetClassInterfaces"); | |
962 JvmtiVMObjectAllocEventCollector oam; | |
963 oop mirror = JNIHandles::resolve_non_null(cls); | |
964 | |
965 // Special handling for primitive objects | |
966 if (java_lang_Class::is_primitive(mirror)) { | |
967 // Primitive objects does not have any interfaces | |
1142 | 968 objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_NULL); |
0 | 969 return (jobjectArray) JNIHandles::make_local(env, r); |
970 } | |
971 | |
972 KlassHandle klass(thread, java_lang_Class::as_klassOop(mirror)); | |
973 // Figure size of result array | |
974 int size; | |
975 if (klass->oop_is_instance()) { | |
976 size = instanceKlass::cast(klass())->local_interfaces()->length(); | |
977 } else { | |
978 assert(klass->oop_is_objArray() || klass->oop_is_typeArray(), "Illegal mirror klass"); | |
979 size = 2; | |
980 } | |
981 | |
982 // Allocate result array | |
1142 | 983 objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), size, CHECK_NULL); |
0 | 984 objArrayHandle result (THREAD, r); |
985 // Fill in result | |
986 if (klass->oop_is_instance()) { | |
987 // Regular instance klass, fill in all local interfaces | |
988 for (int index = 0; index < size; index++) { | |
989 klassOop k = klassOop(instanceKlass::cast(klass())->local_interfaces()->obj_at(index)); | |
990 result->obj_at_put(index, Klass::cast(k)->java_mirror()); | |
991 } | |
992 } else { | |
993 // All arrays implement java.lang.Cloneable and java.io.Serializable | |
1142 | 994 result->obj_at_put(0, Klass::cast(SystemDictionary::Cloneable_klass())->java_mirror()); |
995 result->obj_at_put(1, Klass::cast(SystemDictionary::Serializable_klass())->java_mirror()); | |
0 | 996 } |
997 return (jobjectArray) JNIHandles::make_local(env, result()); | |
998 JVM_END | |
999 | |
1000 | |
1001 JVM_ENTRY(jobject, JVM_GetClassLoader(JNIEnv *env, jclass cls)) | |
1002 JVMWrapper("JVM_GetClassLoader"); | |
1003 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) { | |
1004 return NULL; | |
1005 } | |
1006 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
1007 oop loader = Klass::cast(k)->class_loader(); | |
1008 return JNIHandles::make_local(env, loader); | |
1009 JVM_END | |
1010 | |
1011 | |
1012 JVM_QUICK_ENTRY(jboolean, JVM_IsInterface(JNIEnv *env, jclass cls)) | |
1013 JVMWrapper("JVM_IsInterface"); | |
1014 oop mirror = JNIHandles::resolve_non_null(cls); | |
1015 if (java_lang_Class::is_primitive(mirror)) { | |
1016 return JNI_FALSE; | |
1017 } | |
1018 klassOop k = java_lang_Class::as_klassOop(mirror); | |
1019 jboolean result = Klass::cast(k)->is_interface(); | |
1020 assert(!result || Klass::cast(k)->oop_is_instance(), | |
1021 "all interfaces are instance types"); | |
1022 // The compiler intrinsic for isInterface tests the | |
1023 // Klass::_access_flags bits in the same way. | |
1024 return result; | |
1025 JVM_END | |
1026 | |
1027 | |
1028 JVM_ENTRY(jobjectArray, JVM_GetClassSigners(JNIEnv *env, jclass cls)) | |
1029 JVMWrapper("JVM_GetClassSigners"); | |
1030 JvmtiVMObjectAllocEventCollector oam; | |
1031 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) { | |
1032 // There are no signers for primitive types | |
1033 return NULL; | |
1034 } | |
1035 | |
1036 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
1037 objArrayOop signers = NULL; | |
1038 if (Klass::cast(k)->oop_is_instance()) { | |
1039 signers = instanceKlass::cast(k)->signers(); | |
1040 } | |
1041 | |
1042 // If there are no signers set in the class, or if the class | |
1043 // is an array, return NULL. | |
1044 if (signers == NULL) return NULL; | |
1045 | |
1046 // copy of the signers array | |
1047 klassOop element = objArrayKlass::cast(signers->klass())->element_klass(); | |
1048 objArrayOop signers_copy = oopFactory::new_objArray(element, signers->length(), CHECK_NULL); | |
1049 for (int index = 0; index < signers->length(); index++) { | |
1050 signers_copy->obj_at_put(index, signers->obj_at(index)); | |
1051 } | |
1052 | |
1053 // return the copy | |
1054 return (jobjectArray) JNIHandles::make_local(env, signers_copy); | |
1055 JVM_END | |
1056 | |
1057 | |
1058 JVM_ENTRY(void, JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers)) | |
1059 JVMWrapper("JVM_SetClassSigners"); | |
1060 if (!java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) { | |
1061 // This call is ignored for primitive types and arrays. | |
1062 // Signers are only set once, ClassLoader.java, and thus shouldn't | |
1063 // be called with an array. Only the bootstrap loader creates arrays. | |
1064 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
1065 if (Klass::cast(k)->oop_is_instance()) { | |
1066 instanceKlass::cast(k)->set_signers(objArrayOop(JNIHandles::resolve(signers))); | |
1067 } | |
1068 } | |
1069 JVM_END | |
1070 | |
1071 | |
1072 JVM_ENTRY(jobject, JVM_GetProtectionDomain(JNIEnv *env, jclass cls)) | |
1073 JVMWrapper("JVM_GetProtectionDomain"); | |
1074 if (JNIHandles::resolve(cls) == NULL) { | |
1075 THROW_(vmSymbols::java_lang_NullPointerException(), NULL); | |
1076 } | |
1077 | |
1078 if (java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { | |
1079 // Primitive types does not have a protection domain. | |
1080 return NULL; | |
1081 } | |
1082 | |
1083 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve(cls)); | |
1084 return (jobject) JNIHandles::make_local(env, Klass::cast(k)->protection_domain()); | |
1085 JVM_END | |
1086 | |
1087 | |
1088 // Obsolete since 1.2 (Class.setProtectionDomain removed), although | |
1089 // still defined in core libraries as of 1.5. | |
1090 JVM_ENTRY(void, JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protection_domain)) | |
1091 JVMWrapper("JVM_SetProtectionDomain"); | |
1092 if (JNIHandles::resolve(cls) == NULL) { | |
1093 THROW(vmSymbols::java_lang_NullPointerException()); | |
1094 } | |
1095 if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { | |
1096 // Call is ignored for primitive types | |
1097 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve(cls)); | |
1098 | |
1099 // cls won't be an array, as this called only from ClassLoader.defineClass | |
1100 if (Klass::cast(k)->oop_is_instance()) { | |
1101 oop pd = JNIHandles::resolve(protection_domain); | |
1102 assert(pd == NULL || pd->is_oop(), "just checking"); | |
1103 instanceKlass::cast(k)->set_protection_domain(pd); | |
1104 } | |
1105 } | |
1106 JVM_END | |
1107 | |
1108 | |
1109 JVM_ENTRY(jobject, JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject context, jboolean wrapException)) | |
1110 JVMWrapper("JVM_DoPrivileged"); | |
1111 | |
1112 if (action == NULL) { | |
1113 THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), "Null action"); | |
1114 } | |
1115 | |
1116 // Stack allocated list of privileged stack elements | |
1117 PrivilegedElement pi; | |
1118 | |
1119 // Check that action object understands "Object run()" | |
1120 Handle object (THREAD, JNIHandles::resolve(action)); | |
1121 | |
1122 // get run() method | |
1123 methodOop m_oop = Klass::cast(object->klass())->uncached_lookup_method( | |
1124 vmSymbols::run_method_name(), | |
1125 vmSymbols::void_object_signature()); | |
1126 methodHandle m (THREAD, m_oop); | |
1127 if (m.is_null() || !m->is_method() || !methodOop(m())->is_public() || methodOop(m())->is_static()) { | |
1128 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "No run method"); | |
1129 } | |
1130 | |
1131 // Compute the frame initiating the do privileged operation and setup the privileged stack | |
1132 vframeStream vfst(thread); | |
1133 vfst.security_get_caller_frame(1); | |
1134 | |
1135 if (!vfst.at_end()) { | |
1136 pi.initialize(&vfst, JNIHandles::resolve(context), thread->privileged_stack_top(), CHECK_NULL); | |
1137 thread->set_privileged_stack_top(&pi); | |
1138 } | |
1139 | |
1140 | |
1141 // invoke the Object run() in the action object. We cannot use call_interface here, since the static type | |
1142 // is not really known - it is either java.security.PrivilegedAction or java.security.PrivilegedExceptionAction | |
1143 Handle pending_exception; | |
1144 JavaValue result(T_OBJECT); | |
1145 JavaCallArguments args(object); | |
1146 JavaCalls::call(&result, m, &args, THREAD); | |
1147 | |
1148 // done with action, remove ourselves from the list | |
1149 if (!vfst.at_end()) { | |
1150 assert(thread->privileged_stack_top() != NULL && thread->privileged_stack_top() == &pi, "wrong top element"); | |
1151 thread->set_privileged_stack_top(thread->privileged_stack_top()->next()); | |
1152 } | |
1153 | |
1154 if (HAS_PENDING_EXCEPTION) { | |
1155 pending_exception = Handle(THREAD, PENDING_EXCEPTION); | |
1156 CLEAR_PENDING_EXCEPTION; | |
1157 | |
1142 | 1158 if ( pending_exception->is_a(SystemDictionary::Exception_klass()) && |
1159 !pending_exception->is_a(SystemDictionary::RuntimeException_klass())) { | |
0 | 1160 // Throw a java.security.PrivilegedActionException(Exception e) exception |
1161 JavaCallArguments args(pending_exception); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
1162 THROW_ARG_0(vmSymbols::java_security_PrivilegedActionException(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
1163 vmSymbols::exception_void_signature(), |
0 | 1164 &args); |
1165 } | |
1166 } | |
1167 | |
1168 if (pending_exception.not_null()) THROW_OOP_0(pending_exception()); | |
1169 return JNIHandles::make_local(env, (oop) result.get_jobject()); | |
1170 JVM_END | |
1171 | |
1172 | |
1173 // Returns the inherited_access_control_context field of the running thread. | |
1174 JVM_ENTRY(jobject, JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls)) | |
1175 JVMWrapper("JVM_GetInheritedAccessControlContext"); | |
1176 oop result = java_lang_Thread::inherited_access_control_context(thread->threadObj()); | |
1177 return JNIHandles::make_local(env, result); | |
1178 JVM_END | |
1179 | |
1180 class RegisterArrayForGC { | |
1181 private: | |
1182 JavaThread *_thread; | |
1183 public: | |
1184 RegisterArrayForGC(JavaThread *thread, GrowableArray<oop>* array) { | |
1185 _thread = thread; | |
1186 _thread->register_array_for_gc(array); | |
1187 } | |
1188 | |
1189 ~RegisterArrayForGC() { | |
1190 _thread->register_array_for_gc(NULL); | |
1191 } | |
1192 }; | |
1193 | |
1194 | |
1195 JVM_ENTRY(jobject, JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls)) | |
1196 JVMWrapper("JVM_GetStackAccessControlContext"); | |
1197 if (!UsePrivilegedStack) return NULL; | |
1198 | |
1199 ResourceMark rm(THREAD); | |
1200 GrowableArray<oop>* local_array = new GrowableArray<oop>(12); | |
1201 JvmtiVMObjectAllocEventCollector oam; | |
1202 | |
1203 // count the protection domains on the execution stack. We collapse | |
1204 // duplicate consecutive protection domains into a single one, as | |
1205 // well as stopping when we hit a privileged frame. | |
1206 | |
1207 // Use vframeStream to iterate through Java frames | |
1208 vframeStream vfst(thread); | |
1209 | |
1210 oop previous_protection_domain = NULL; | |
1211 Handle privileged_context(thread, NULL); | |
1212 bool is_privileged = false; | |
1213 oop protection_domain = NULL; | |
1214 | |
1215 for(; !vfst.at_end(); vfst.next()) { | |
1216 // get method of frame | |
1217 methodOop method = vfst.method(); | |
1218 intptr_t* frame_id = vfst.frame_id(); | |
1219 | |
1220 // check the privileged frames to see if we have a match | |
1221 if (thread->privileged_stack_top() && thread->privileged_stack_top()->frame_id() == frame_id) { | |
1222 // this frame is privileged | |
1223 is_privileged = true; | |
1224 privileged_context = Handle(thread, thread->privileged_stack_top()->privileged_context()); | |
1225 protection_domain = thread->privileged_stack_top()->protection_domain(); | |
1226 } else { | |
1227 protection_domain = instanceKlass::cast(method->method_holder())->protection_domain(); | |
1228 } | |
1229 | |
1230 if ((previous_protection_domain != protection_domain) && (protection_domain != NULL)) { | |
1231 local_array->push(protection_domain); | |
1232 previous_protection_domain = protection_domain; | |
1233 } | |
1234 | |
1235 if (is_privileged) break; | |
1236 } | |
1237 | |
1238 | |
1239 // either all the domains on the stack were system domains, or | |
1240 // we had a privileged system domain | |
1241 if (local_array->is_empty()) { | |
1242 if (is_privileged && privileged_context.is_null()) return NULL; | |
1243 | |
1244 oop result = java_security_AccessControlContext::create(objArrayHandle(), is_privileged, privileged_context, CHECK_NULL); | |
1245 return JNIHandles::make_local(env, result); | |
1246 } | |
1247 | |
1248 // the resource area must be registered in case of a gc | |
1249 RegisterArrayForGC ragc(thread, local_array); | |
1142 | 1250 objArrayOop context = oopFactory::new_objArray(SystemDictionary::ProtectionDomain_klass(), |
0 | 1251 local_array->length(), CHECK_NULL); |
1252 objArrayHandle h_context(thread, context); | |
1253 for (int index = 0; index < local_array->length(); index++) { | |
1254 h_context->obj_at_put(index, local_array->at(index)); | |
1255 } | |
1256 | |
1257 oop result = java_security_AccessControlContext::create(h_context, is_privileged, privileged_context, CHECK_NULL); | |
1258 | |
1259 return JNIHandles::make_local(env, result); | |
1260 JVM_END | |
1261 | |
1262 | |
1263 JVM_QUICK_ENTRY(jboolean, JVM_IsArrayClass(JNIEnv *env, jclass cls)) | |
1264 JVMWrapper("JVM_IsArrayClass"); | |
1265 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
1266 return (k != NULL) && Klass::cast(k)->oop_is_javaArray() ? true : false; | |
1267 JVM_END | |
1268 | |
1269 | |
1270 JVM_QUICK_ENTRY(jboolean, JVM_IsPrimitiveClass(JNIEnv *env, jclass cls)) | |
1271 JVMWrapper("JVM_IsPrimitiveClass"); | |
1272 oop mirror = JNIHandles::resolve_non_null(cls); | |
1273 return (jboolean) java_lang_Class::is_primitive(mirror); | |
1274 JVM_END | |
1275 | |
1276 | |
1277 JVM_ENTRY(jclass, JVM_GetComponentType(JNIEnv *env, jclass cls)) | |
1278 JVMWrapper("JVM_GetComponentType"); | |
1279 oop mirror = JNIHandles::resolve_non_null(cls); | |
1280 oop result = Reflection::array_component_type(mirror, CHECK_NULL); | |
1281 return (jclass) JNIHandles::make_local(env, result); | |
1282 JVM_END | |
1283 | |
1284 | |
1285 JVM_ENTRY(jint, JVM_GetClassModifiers(JNIEnv *env, jclass cls)) | |
1286 JVMWrapper("JVM_GetClassModifiers"); | |
1287 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) { | |
1288 // Primitive type | |
1289 return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC; | |
1290 } | |
1291 | |
1292 Klass* k = Klass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls))); | |
1293 debug_only(int computed_modifiers = k->compute_modifier_flags(CHECK_0)); | |
1294 assert(k->modifier_flags() == computed_modifiers, "modifiers cache is OK"); | |
1295 return k->modifier_flags(); | |
1296 JVM_END | |
1297 | |
1298 | |
1299 // Inner class reflection /////////////////////////////////////////////////////////////////////////////// | |
1300 | |
1301 JVM_ENTRY(jobjectArray, JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass)) | |
1302 const int inner_class_info_index = 0; | |
1303 const int outer_class_info_index = 1; | |
1304 | |
1305 JvmtiVMObjectAllocEventCollector oam; | |
1306 // ofClass is a reference to a java_lang_Class object. The mirror object | |
1307 // of an instanceKlass | |
1308 | |
1309 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) || | |
1310 ! Klass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass)))->oop_is_instance()) { | |
1142 | 1311 oop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_NULL); |
0 | 1312 return (jobjectArray)JNIHandles::make_local(env, result); |
1313 } | |
1314 | |
1315 instanceKlassHandle k(thread, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass))); | |
1316 | |
1317 if (k->inner_classes()->length() == 0) { | |
1318 // Neither an inner nor outer class | |
1142 | 1319 oop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_NULL); |
0 | 1320 return (jobjectArray)JNIHandles::make_local(env, result); |
1321 } | |
1322 | |
1323 // find inner class info | |
1324 typeArrayHandle icls(thread, k->inner_classes()); | |
1325 constantPoolHandle cp(thread, k->constants()); | |
1326 int length = icls->length(); | |
1327 | |
1328 // Allocate temp. result array | |
1142 | 1329 objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), length/4, CHECK_NULL); |
0 | 1330 objArrayHandle result (THREAD, r); |
1331 int members = 0; | |
1332 | |
1333 for(int i = 0; i < length; i += 4) { | |
1334 int ioff = icls->ushort_at(i + inner_class_info_index); | |
1335 int ooff = icls->ushort_at(i + outer_class_info_index); | |
1336 | |
1337 if (ioff != 0 && ooff != 0) { | |
1338 // Check to see if the name matches the class we're looking for | |
1339 // before attempting to find the class. | |
1340 if (cp->klass_name_at_matches(k, ooff)) { | |
1341 klassOop outer_klass = cp->klass_at(ooff, CHECK_NULL); | |
1342 if (outer_klass == k()) { | |
1343 klassOop ik = cp->klass_at(ioff, CHECK_NULL); | |
1344 instanceKlassHandle inner_klass (THREAD, ik); | |
1345 | |
1346 // Throws an exception if outer klass has not declared k as | |
1347 // an inner klass | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1348 Reflection::check_for_inner_class(k, inner_klass, true, CHECK_NULL); |
0 | 1349 |
1350 result->obj_at_put(members, inner_klass->java_mirror()); | |
1351 members++; | |
1352 } | |
1353 } | |
1354 } | |
1355 } | |
1356 | |
1357 if (members != length) { | |
1358 // Return array of right length | |
1142 | 1359 objArrayOop res = oopFactory::new_objArray(SystemDictionary::Class_klass(), members, CHECK_NULL); |
0 | 1360 for(int i = 0; i < members; i++) { |
1361 res->obj_at_put(i, result->obj_at(i)); | |
1362 } | |
1363 return (jobjectArray)JNIHandles::make_local(env, res); | |
1364 } | |
1365 | |
1366 return (jobjectArray)JNIHandles::make_local(env, result()); | |
1367 JVM_END | |
1368 | |
1369 | |
1370 JVM_ENTRY(jclass, JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass)) | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1371 { |
0 | 1372 // ofClass is a reference to a java_lang_Class object. |
1373 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) || | |
1374 ! Klass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass)))->oop_is_instance()) { | |
1375 return NULL; | |
1376 } | |
1377 | |
1126
933a3e806ce6
6895168: JCK api/signaturetest/sigtest.basic.html#basic test fails for jdk 5.0 with HS 16 in nightly build
xlu
parents:
1059
diff
changeset
|
1378 bool inner_is_member = false; |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1379 klassOop outer_klass |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1380 = instanceKlass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass)) |
1126
933a3e806ce6
6895168: JCK api/signaturetest/sigtest.basic.html#basic test fails for jdk 5.0 with HS 16 in nightly build
xlu
parents:
1059
diff
changeset
|
1381 )->compute_enclosing_class(&inner_is_member, CHECK_NULL); |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1382 if (outer_klass == NULL) return NULL; // already a top-level class |
1126
933a3e806ce6
6895168: JCK api/signaturetest/sigtest.basic.html#basic test fails for jdk 5.0 with HS 16 in nightly build
xlu
parents:
1059
diff
changeset
|
1383 if (!inner_is_member) return NULL; // an anonymous class (inside a method) |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1384 return (jclass) JNIHandles::make_local(env, Klass::cast(outer_klass)->java_mirror()); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1385 } |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1386 JVM_END |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1387 |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1388 // should be in instanceKlass.cpp, but is here for historical reasons |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1389 klassOop instanceKlass::compute_enclosing_class_impl(instanceKlassHandle k, |
1126
933a3e806ce6
6895168: JCK api/signaturetest/sigtest.basic.html#basic test fails for jdk 5.0 with HS 16 in nightly build
xlu
parents:
1059
diff
changeset
|
1390 bool* inner_is_member, |
933a3e806ce6
6895168: JCK api/signaturetest/sigtest.basic.html#basic test fails for jdk 5.0 with HS 16 in nightly build
xlu
parents:
1059
diff
changeset
|
1391 TRAPS) { |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1392 Thread* thread = THREAD; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1393 const int inner_class_info_index = inner_class_inner_class_info_offset; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1394 const int outer_class_info_index = inner_class_outer_class_info_offset; |
0 | 1395 |
1396 if (k->inner_classes()->length() == 0) { | |
1397 // No inner class info => no declaring class | |
1398 return NULL; | |
1399 } | |
1400 | |
1401 typeArrayHandle i_icls(thread, k->inner_classes()); | |
1402 constantPoolHandle i_cp(thread, k->constants()); | |
1403 int i_length = i_icls->length(); | |
1404 | |
1405 bool found = false; | |
1406 klassOop ok; | |
1407 instanceKlassHandle outer_klass; | |
1126
933a3e806ce6
6895168: JCK api/signaturetest/sigtest.basic.html#basic test fails for jdk 5.0 with HS 16 in nightly build
xlu
parents:
1059
diff
changeset
|
1408 *inner_is_member = false; |
0 | 1409 |
1410 // Find inner_klass attribute | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1411 for (int i = 0; i < i_length && !found; i += inner_class_next_offset) { |
0 | 1412 int ioff = i_icls->ushort_at(i + inner_class_info_index); |
1413 int ooff = i_icls->ushort_at(i + outer_class_info_index); | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1414 int noff = i_icls->ushort_at(i + inner_class_inner_name_offset); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1415 if (ioff != 0) { |
0 | 1416 // Check to see if the name matches the class we're looking for |
1417 // before attempting to find the class. | |
1418 if (i_cp->klass_name_at_matches(k, ioff)) { | |
1419 klassOop inner_klass = i_cp->klass_at(ioff, CHECK_NULL); | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1420 found = (k() == inner_klass); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1421 if (found && ooff != 0) { |
0 | 1422 ok = i_cp->klass_at(ooff, CHECK_NULL); |
1423 outer_klass = instanceKlassHandle(thread, ok); | |
1126
933a3e806ce6
6895168: JCK api/signaturetest/sigtest.basic.html#basic test fails for jdk 5.0 with HS 16 in nightly build
xlu
parents:
1059
diff
changeset
|
1424 *inner_is_member = true; |
0 | 1425 } |
1426 } | |
1427 } | |
1428 } | |
1429 | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1430 if (found && outer_klass.is_null()) { |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1431 // It may be anonymous; try for that. |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1432 int encl_method_class_idx = k->enclosing_method_class_index(); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1433 if (encl_method_class_idx != 0) { |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1434 ok = i_cp->klass_at(encl_method_class_idx, CHECK_NULL); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1435 outer_klass = instanceKlassHandle(thread, ok); |
1126
933a3e806ce6
6895168: JCK api/signaturetest/sigtest.basic.html#basic test fails for jdk 5.0 with HS 16 in nightly build
xlu
parents:
1059
diff
changeset
|
1436 *inner_is_member = false; |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1437 } |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1438 } |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1439 |
0 | 1440 // If no inner class attribute found for this class. |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1441 if (outer_klass.is_null()) return NULL; |
0 | 1442 |
1443 // Throws an exception if outer klass has not declared k as an inner klass | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1444 // We need evidence that each klass knows about the other, or else |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1445 // the system could allow a spoof of an inner class to gain access rights. |
1126
933a3e806ce6
6895168: JCK api/signaturetest/sigtest.basic.html#basic test fails for jdk 5.0 with HS 16 in nightly build
xlu
parents:
1059
diff
changeset
|
1446 Reflection::check_for_inner_class(outer_klass, k, *inner_is_member, CHECK_NULL); |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1447 return outer_klass(); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
579
diff
changeset
|
1448 } |
0 | 1449 |
1450 JVM_ENTRY(jstring, JVM_GetClassSignature(JNIEnv *env, jclass cls)) | |
1451 assert (cls != NULL, "illegal class"); | |
1452 JVMWrapper("JVM_GetClassSignature"); | |
1453 JvmtiVMObjectAllocEventCollector oam; | |
1454 ResourceMark rm(THREAD); | |
1455 // Return null for arrays and primatives | |
1456 if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { | |
1457 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve(cls)); | |
1458 if (Klass::cast(k)->oop_is_instance()) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
1459 Symbol* sym = instanceKlass::cast(k)->generic_signature(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
1460 if (sym == NULL) return NULL; |
0 | 1461 Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL); |
1462 return (jstring) JNIHandles::make_local(env, str()); | |
1463 } | |
1464 } | |
1465 return NULL; | |
1466 JVM_END | |
1467 | |
1468 | |
1469 JVM_ENTRY(jbyteArray, JVM_GetClassAnnotations(JNIEnv *env, jclass cls)) | |
1470 assert (cls != NULL, "illegal class"); | |
1471 JVMWrapper("JVM_GetClassAnnotations"); | |
1472 ResourceMark rm(THREAD); | |
1473 // Return null for arrays and primitives | |
1474 if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { | |
1475 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve(cls)); | |
1476 if (Klass::cast(k)->oop_is_instance()) { | |
1477 return (jbyteArray) JNIHandles::make_local(env, | |
1478 instanceKlass::cast(k)->class_annotations()); | |
1479 } | |
1480 } | |
1481 return NULL; | |
1482 JVM_END | |
1483 | |
1484 | |
1485 JVM_ENTRY(jbyteArray, JVM_GetFieldAnnotations(JNIEnv *env, jobject field)) | |
1486 assert(field != NULL, "illegal field"); | |
1487 JVMWrapper("JVM_GetFieldAnnotations"); | |
1488 | |
1489 // some of this code was adapted from from jni_FromReflectedField | |
1490 | |
1491 // field is a handle to a java.lang.reflect.Field object | |
1492 oop reflected = JNIHandles::resolve_non_null(field); | |
1493 oop mirror = java_lang_reflect_Field::clazz(reflected); | |
1494 klassOop k = java_lang_Class::as_klassOop(mirror); | |
1495 int slot = java_lang_reflect_Field::slot(reflected); | |
1496 int modifiers = java_lang_reflect_Field::modifiers(reflected); | |
1497 | |
1498 fieldDescriptor fd; | |
1499 KlassHandle kh(THREAD, k); | |
3938 | 1500 intptr_t offset = instanceKlass::cast(kh())->field_offset(slot); |
0 | 1501 |
1502 if (modifiers & JVM_ACC_STATIC) { | |
1503 // for static fields we only look in the current class | |
1504 if (!instanceKlass::cast(kh())->find_local_field_from_offset(offset, | |
1505 true, &fd)) { | |
1506 assert(false, "cannot find static field"); | |
1507 return NULL; // robustness | |
1508 } | |
1509 } else { | |
1510 // for instance fields we start with the current class and work | |
1511 // our way up through the superclass chain | |
1512 if (!instanceKlass::cast(kh())->find_field_from_offset(offset, false, | |
1513 &fd)) { | |
1514 assert(false, "cannot find instance field"); | |
1515 return NULL; // robustness | |
1516 } | |
1517 } | |
1518 | |
1519 return (jbyteArray) JNIHandles::make_local(env, fd.annotations()); | |
1520 JVM_END | |
1521 | |
1522 | |
1523 static methodOop jvm_get_method_common(jobject method, TRAPS) { | |
1524 // some of this code was adapted from from jni_FromReflectedMethod | |
1525 | |
1526 oop reflected = JNIHandles::resolve_non_null(method); | |
1527 oop mirror = NULL; | |
1528 int slot = 0; | |
1529 | |
1142 | 1530 if (reflected->klass() == SystemDictionary::reflect_Constructor_klass()) { |
0 | 1531 mirror = java_lang_reflect_Constructor::clazz(reflected); |
1532 slot = java_lang_reflect_Constructor::slot(reflected); | |
1533 } else { | |
1142 | 1534 assert(reflected->klass() == SystemDictionary::reflect_Method_klass(), |
0 | 1535 "wrong type"); |
1536 mirror = java_lang_reflect_Method::clazz(reflected); | |
1537 slot = java_lang_reflect_Method::slot(reflected); | |
1538 } | |
1539 klassOop k = java_lang_Class::as_klassOop(mirror); | |
1540 | |
1541 KlassHandle kh(THREAD, k); | |
1542 methodOop m = instanceKlass::cast(kh())->method_with_idnum(slot); | |
1543 if (m == NULL) { | |
1544 assert(false, "cannot find method"); | |
1545 return NULL; // robustness | |
1546 } | |
1547 | |
1548 return m; | |
1549 } | |
1550 | |
1551 | |
1552 JVM_ENTRY(jbyteArray, JVM_GetMethodAnnotations(JNIEnv *env, jobject method)) | |
1553 JVMWrapper("JVM_GetMethodAnnotations"); | |
1554 | |
1555 // method is a handle to a java.lang.reflect.Method object | |
1556 methodOop m = jvm_get_method_common(method, CHECK_NULL); | |
1557 return (jbyteArray) JNIHandles::make_local(env, m->annotations()); | |
1558 JVM_END | |
1559 | |
1560 | |
1561 JVM_ENTRY(jbyteArray, JVM_GetMethodDefaultAnnotationValue(JNIEnv *env, jobject method)) | |
1562 JVMWrapper("JVM_GetMethodDefaultAnnotationValue"); | |
1563 | |
1564 // method is a handle to a java.lang.reflect.Method object | |
1565 methodOop m = jvm_get_method_common(method, CHECK_NULL); | |
1566 return (jbyteArray) JNIHandles::make_local(env, m->annotation_default()); | |
1567 JVM_END | |
1568 | |
1569 | |
1570 JVM_ENTRY(jbyteArray, JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject method)) | |
1571 JVMWrapper("JVM_GetMethodParameterAnnotations"); | |
1572 | |
1573 // method is a handle to a java.lang.reflect.Method object | |
1574 methodOop m = jvm_get_method_common(method, CHECK_NULL); | |
1575 return (jbyteArray) JNIHandles::make_local(env, m->parameter_annotations()); | |
1576 JVM_END | |
1577 | |
1578 | |
1579 // New (JDK 1.4) reflection implementation ///////////////////////////////////// | |
1580 | |
1581 JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly)) | |
1582 { | |
1583 JVMWrapper("JVM_GetClassDeclaredFields"); | |
1584 JvmtiVMObjectAllocEventCollector oam; | |
1585 | |
1586 // Exclude primitive types and array types | |
1587 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) || | |
1588 Klass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass)))->oop_is_javaArray()) { | |
1589 // Return empty array | |
1142 | 1590 oop res = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), 0, CHECK_NULL); |
0 | 1591 return (jobjectArray) JNIHandles::make_local(env, res); |
1592 } | |
1593 | |
1594 instanceKlassHandle k(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass))); | |
1595 constantPoolHandle cp(THREAD, k->constants()); | |
1596 | |
1597 // Ensure class is linked | |
1598 k->link_class(CHECK_NULL); | |
1599 | |
1600 // 4496456 We need to filter out java.lang.Throwable.backtrace | |
1601 bool skip_backtrace = false; | |
1602 | |
1603 // Allocate result | |
1604 int num_fields; | |
1605 | |
1606 if (publicOnly) { | |
1607 num_fields = 0; | |
3938 | 1608 for (JavaFieldStream fs(k()); !fs.done(); fs.next()) { |
1609 if (fs.access_flags().is_public()) ++num_fields; | |
0 | 1610 } |
1611 } else { | |
3938 | 1612 num_fields = k->java_fields_count(); |
0 | 1613 |
1142 | 1614 if (k() == SystemDictionary::Throwable_klass()) { |
0 | 1615 num_fields--; |
1616 skip_backtrace = true; | |
1617 } | |
1618 } | |
1619 | |
1142 | 1620 objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), num_fields, CHECK_NULL); |
0 | 1621 objArrayHandle result (THREAD, r); |
1622 | |
1623 int out_idx = 0; | |
1624 fieldDescriptor fd; | |
3938 | 1625 for (JavaFieldStream fs(k); !fs.done(); fs.next()) { |
0 | 1626 if (skip_backtrace) { |
1627 // 4496456 skip java.lang.Throwable.backtrace | |
3938 | 1628 int offset = fs.offset(); |
0 | 1629 if (offset == java_lang_Throwable::get_backtrace_offset()) continue; |
1630 } | |
1631 | |
3938 | 1632 if (!publicOnly || fs.access_flags().is_public()) { |
1633 fd.initialize(k(), fs.index()); | |
0 | 1634 oop field = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL); |
1635 result->obj_at_put(out_idx, field); | |
1636 ++out_idx; | |
1637 } | |
1638 } | |
1639 assert(out_idx == num_fields, "just checking"); | |
1640 return (jobjectArray) JNIHandles::make_local(env, result()); | |
1641 } | |
1642 JVM_END | |
1643 | |
1644 JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly)) | |
1645 { | |
1646 JVMWrapper("JVM_GetClassDeclaredMethods"); | |
1647 JvmtiVMObjectAllocEventCollector oam; | |
1648 | |
1649 // Exclude primitive types and array types | |
1650 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) | |
1651 || Klass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass)))->oop_is_javaArray()) { | |
1652 // Return empty array | |
1142 | 1653 oop res = oopFactory::new_objArray(SystemDictionary::reflect_Method_klass(), 0, CHECK_NULL); |
0 | 1654 return (jobjectArray) JNIHandles::make_local(env, res); |
1655 } | |
1656 | |
1657 instanceKlassHandle k(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass))); | |
1658 | |
1659 // Ensure class is linked | |
1660 k->link_class(CHECK_NULL); | |
1661 | |
1662 objArrayHandle methods (THREAD, k->methods()); | |
1663 int methods_length = methods->length(); | |
1664 int num_methods = 0; | |
1665 | |
1666 int i; | |
1667 for (i = 0; i < methods_length; i++) { | |
1668 methodHandle method(THREAD, (methodOop) methods->obj_at(i)); | |
1669 if (!method->is_initializer()) { | |
1670 if (!publicOnly || method->is_public()) { | |
1671 ++num_methods; | |
1672 } | |
1673 } | |
1674 } | |
1675 | |
1676 // Allocate result | |
1142 | 1677 objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Method_klass(), num_methods, CHECK_NULL); |
0 | 1678 objArrayHandle result (THREAD, r); |
1679 | |
1680 int out_idx = 0; | |
1681 for (i = 0; i < methods_length; i++) { | |
1682 methodHandle method(THREAD, (methodOop) methods->obj_at(i)); | |
1683 if (!method->is_initializer()) { | |
1684 if (!publicOnly || method->is_public()) { | |
1685 oop m = Reflection::new_method(method, UseNewReflection, false, CHECK_NULL); | |
1686 result->obj_at_put(out_idx, m); | |
1687 ++out_idx; | |
1688 } | |
1689 } | |
1690 } | |
1691 assert(out_idx == num_methods, "just checking"); | |
1692 return (jobjectArray) JNIHandles::make_local(env, result()); | |
1693 } | |
1694 JVM_END | |
1695 | |
1696 JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly)) | |
1697 { | |
1698 JVMWrapper("JVM_GetClassDeclaredConstructors"); | |
1699 JvmtiVMObjectAllocEventCollector oam; | |
1700 | |
1701 // Exclude primitive types and array types | |
1702 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) | |
1703 || Klass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass)))->oop_is_javaArray()) { | |
1704 // Return empty array | |
1142 | 1705 oop res = oopFactory::new_objArray(SystemDictionary::reflect_Constructor_klass(), 0 , CHECK_NULL); |
0 | 1706 return (jobjectArray) JNIHandles::make_local(env, res); |
1707 } | |
1708 | |
1709 instanceKlassHandle k(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass))); | |
1710 | |
1711 // Ensure class is linked | |
1712 k->link_class(CHECK_NULL); | |
1713 | |
1714 objArrayHandle methods (THREAD, k->methods()); | |
1715 int methods_length = methods->length(); | |
1716 int num_constructors = 0; | |
1717 | |
1718 int i; | |
1719 for (i = 0; i < methods_length; i++) { | |
1720 methodHandle method(THREAD, (methodOop) methods->obj_at(i)); | |
1721 if (method->is_initializer() && !method->is_static()) { | |
1722 if (!publicOnly || method->is_public()) { | |
1723 ++num_constructors; | |
1724 } | |
1725 } | |
1726 } | |
1727 | |
1728 // Allocate result | |
1142 | 1729 objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Constructor_klass(), num_constructors, CHECK_NULL); |
0 | 1730 objArrayHandle result(THREAD, r); |
1731 | |
1732 int out_idx = 0; | |
1733 for (i = 0; i < methods_length; i++) { | |
1734 methodHandle method(THREAD, (methodOop) methods->obj_at(i)); | |
1735 if (method->is_initializer() && !method->is_static()) { | |
1736 if (!publicOnly || method->is_public()) { | |
1737 oop m = Reflection::new_constructor(method, CHECK_NULL); | |
1738 result->obj_at_put(out_idx, m); | |
1739 ++out_idx; | |
1740 } | |
1741 } | |
1742 } | |
1743 assert(out_idx == num_constructors, "just checking"); | |
1744 return (jobjectArray) JNIHandles::make_local(env, result()); | |
1745 } | |
1746 JVM_END | |
1747 | |
1748 JVM_ENTRY(jint, JVM_GetClassAccessFlags(JNIEnv *env, jclass cls)) | |
1749 { | |
1750 JVMWrapper("JVM_GetClassAccessFlags"); | |
1751 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) { | |
1752 // Primitive type | |
1753 return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC; | |
1754 } | |
1755 | |
1756 Klass* k = Klass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls))); | |
1757 return k->access_flags().as_int() & JVM_ACC_WRITTEN_FLAGS; | |
1758 } | |
1759 JVM_END | |
1760 | |
1761 | |
1762 // Constant pool access ////////////////////////////////////////////////////////// | |
1763 | |
1764 JVM_ENTRY(jobject, JVM_GetClassConstantPool(JNIEnv *env, jclass cls)) | |
1765 { | |
1766 JVMWrapper("JVM_GetClassConstantPool"); | |
1767 JvmtiVMObjectAllocEventCollector oam; | |
1768 | |
1769 // Return null for primitives and arrays | |
1770 if (!java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) { | |
1771 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
1772 if (Klass::cast(k)->oop_is_instance()) { | |
1773 instanceKlassHandle k_h(THREAD, k); | |
1774 Handle jcp = sun_reflect_ConstantPool::create(CHECK_NULL); | |
1775 sun_reflect_ConstantPool::set_cp_oop(jcp(), k_h->constants()); | |
1776 return JNIHandles::make_local(jcp()); | |
1777 } | |
1778 } | |
1779 return NULL; | |
1780 } | |
1781 JVM_END | |
1782 | |
1783 | |
1784 JVM_ENTRY(jint, JVM_ConstantPoolGetSize(JNIEnv *env, jobject unused, jobject jcpool)) | |
1785 { | |
1786 JVMWrapper("JVM_ConstantPoolGetSize"); | |
1787 constantPoolHandle cp = constantPoolHandle(THREAD, constantPoolOop(JNIHandles::resolve_non_null(jcpool))); | |
1788 return cp->length(); | |
1789 } | |
1790 JVM_END | |
1791 | |
1792 | |
1793 static void bounds_check(constantPoolHandle cp, jint index, TRAPS) { | |
1794 if (!cp->is_within_bounds(index)) { | |
1795 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Constant pool index out of bounds"); | |
1796 } | |
1797 } | |
1798 | |
1799 | |
1800 JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)) | |
1801 { | |
1802 JVMWrapper("JVM_ConstantPoolGetClassAt"); | |
1803 constantPoolHandle cp = constantPoolHandle(THREAD, constantPoolOop(JNIHandles::resolve_non_null(jcpool))); | |
1804 bounds_check(cp, index, CHECK_NULL); | |
1805 constantTag tag = cp->tag_at(index); | |
1806 if (!tag.is_klass() && !tag.is_unresolved_klass()) { | |
1807 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index"); | |
1808 } | |
1809 klassOop k = cp->klass_at(index, CHECK_NULL); | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2191
diff
changeset
|
1810 return (jclass) JNIHandles::make_local(k->java_mirror()); |
0 | 1811 } |
1812 JVM_END | |
1813 | |
1814 | |
1815 JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject unused, jobject jcpool, jint index)) | |
1816 { | |
1817 JVMWrapper("JVM_ConstantPoolGetClassAtIfLoaded"); | |
1818 constantPoolHandle cp = constantPoolHandle(THREAD, constantPoolOop(JNIHandles::resolve_non_null(jcpool))); | |
1819 bounds_check(cp, index, CHECK_NULL); | |
1820 constantTag tag = cp->tag_at(index); | |
1821 if (!tag.is_klass() && !tag.is_unresolved_klass()) { | |
1822 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index"); | |
1823 } | |
1824 klassOop k = constantPoolOopDesc::klass_at_if_loaded(cp, index); | |
1825 if (k == NULL) return NULL; | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2191
diff
changeset
|
1826 return (jclass) JNIHandles::make_local(k->java_mirror()); |
0 | 1827 } |
1828 JVM_END | |
1829 | |
1830 static jobject get_method_at_helper(constantPoolHandle cp, jint index, bool force_resolution, TRAPS) { | |
1831 constantTag tag = cp->tag_at(index); | |
1832 if (!tag.is_method() && !tag.is_interface_method()) { | |
1833 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index"); | |
1834 } | |
1835 int klass_ref = cp->uncached_klass_ref_index_at(index); | |
1836 klassOop k_o; | |
1837 if (force_resolution) { | |
1838 k_o = cp->klass_at(klass_ref, CHECK_NULL); | |
1839 } else { | |
1840 k_o = constantPoolOopDesc::klass_at_if_loaded(cp, klass_ref); | |
1841 if (k_o == NULL) return NULL; | |
1842 } | |
1843 instanceKlassHandle k(THREAD, k_o); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
1844 Symbol* name = cp->uncached_name_ref_at(index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
1845 Symbol* sig = cp->uncached_signature_ref_at(index); |
0 | 1846 methodHandle m (THREAD, k->find_method(name, sig)); |
1847 if (m.is_null()) { | |
1848 THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "Unable to look up method in target class"); | |
1849 } | |
1850 oop method; | |
1851 if (!m->is_initializer() || m->is_static()) { | |
1852 method = Reflection::new_method(m, true, true, CHECK_NULL); | |
1853 } else { | |
1854 method = Reflection::new_constructor(m, CHECK_NULL); | |
1855 } | |
1856 return JNIHandles::make_local(method); | |
1857 } | |
1858 | |
1859 JVM_ENTRY(jobject, JVM_ConstantPoolGetMethodAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)) | |
1860 { | |
1861 JVMWrapper("JVM_ConstantPoolGetMethodAt"); | |
1862 JvmtiVMObjectAllocEventCollector oam; | |
1863 constantPoolHandle cp = constantPoolHandle(THREAD, constantPoolOop(JNIHandles::resolve_non_null(jcpool))); | |
1864 bounds_check(cp, index, CHECK_NULL); | |
1865 jobject res = get_method_at_helper(cp, index, true, CHECK_NULL); | |
1866 return res; | |
1867 } | |
1868 JVM_END | |
1869 | |
1870 JVM_ENTRY(jobject, JVM_ConstantPoolGetMethodAtIfLoaded(JNIEnv *env, jobject unused, jobject jcpool, jint index)) | |
1871 { | |
1872 JVMWrapper("JVM_ConstantPoolGetMethodAtIfLoaded"); | |
1873 JvmtiVMObjectAllocEventCollector oam; | |
1874 constantPoolHandle cp = constantPoolHandle(THREAD, constantPoolOop(JNIHandles::resolve_non_null(jcpool))); | |
1875 bounds_check(cp, index, CHECK_NULL); | |
1876 jobject res = get_method_at_helper(cp, index, false, CHECK_NULL); | |
1877 return res; | |
1878 } | |
1879 JVM_END | |
1880 | |
1881 static jobject get_field_at_helper(constantPoolHandle cp, jint index, bool force_resolution, TRAPS) { | |
1882 constantTag tag = cp->tag_at(index); | |
1883 if (!tag.is_field()) { | |
1884 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index"); | |
1885 } | |
1886 int klass_ref = cp->uncached_klass_ref_index_at(index); | |
1887 klassOop k_o; | |
1888 if (force_resolution) { | |
1889 k_o = cp->klass_at(klass_ref, CHECK_NULL); | |
1890 } else { | |
1891 k_o = constantPoolOopDesc::klass_at_if_loaded(cp, klass_ref); | |
1892 if (k_o == NULL) return NULL; | |
1893 } | |
1894 instanceKlassHandle k(THREAD, k_o); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
1895 Symbol* name = cp->uncached_name_ref_at(index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
1896 Symbol* sig = cp->uncached_signature_ref_at(index); |
0 | 1897 fieldDescriptor fd; |
1898 klassOop target_klass = k->find_field(name, sig, &fd); | |
1899 if (target_klass == NULL) { | |
1900 THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "Unable to look up field in target class"); | |
1901 } | |
1902 oop field = Reflection::new_field(&fd, true, CHECK_NULL); | |
1903 return JNIHandles::make_local(field); | |
1904 } | |
1905 | |
1906 JVM_ENTRY(jobject, JVM_ConstantPoolGetFieldAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)) | |
1907 { | |
1908 JVMWrapper("JVM_ConstantPoolGetFieldAt"); | |
1909 JvmtiVMObjectAllocEventCollector oam; | |
1910 constantPoolHandle cp = constantPoolHandle(THREAD, constantPoolOop(JNIHandles::resolve_non_null(jcpool))); | |
1911 bounds_check(cp, index, CHECK_NULL); | |
1912 jobject res = get_field_at_helper(cp, index, true, CHECK_NULL); | |
1913 return res; | |
1914 } | |
1915 JVM_END | |
1916 | |
1917 JVM_ENTRY(jobject, JVM_ConstantPoolGetFieldAtIfLoaded(JNIEnv *env, jobject unused, jobject jcpool, jint index)) | |
1918 { | |
1919 JVMWrapper("JVM_ConstantPoolGetFieldAtIfLoaded"); | |
1920 JvmtiVMObjectAllocEventCollector oam; | |
1921 constantPoolHandle cp = constantPoolHandle(THREAD, constantPoolOop(JNIHandles::resolve_non_null(jcpool))); | |
1922 bounds_check(cp, index, CHECK_NULL); | |
1923 jobject res = get_field_at_helper(cp, index, false, CHECK_NULL); | |
1924 return res; | |
1925 } | |
1926 JVM_END | |
1927 | |
1928 JVM_ENTRY(jobjectArray, JVM_ConstantPoolGetMemberRefInfoAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)) | |
1929 { | |
1930 JVMWrapper("JVM_ConstantPoolGetMemberRefInfoAt"); | |
1931 JvmtiVMObjectAllocEventCollector oam; | |
1932 constantPoolHandle cp = constantPoolHandle(THREAD, constantPoolOop(JNIHandles::resolve_non_null(jcpool))); | |
1933 bounds_check(cp, index, CHECK_NULL); | |
1934 constantTag tag = cp->tag_at(index); | |
1935 if (!tag.is_field_or_method()) { | |
1936 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index"); | |
1937 } | |
1938 int klass_ref = cp->uncached_klass_ref_index_at(index); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
1939 Symbol* klass_name = cp->klass_name_at(klass_ref); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
1940 Symbol* member_name = cp->uncached_name_ref_at(index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
1941 Symbol* member_sig = cp->uncached_signature_ref_at(index); |
1142 | 1942 objArrayOop dest_o = oopFactory::new_objArray(SystemDictionary::String_klass(), 3, CHECK_NULL); |
0 | 1943 objArrayHandle dest(THREAD, dest_o); |
1944 Handle str = java_lang_String::create_from_symbol(klass_name, CHECK_NULL); | |
1945 dest->obj_at_put(0, str()); | |
1946 str = java_lang_String::create_from_symbol(member_name, CHECK_NULL); | |
1947 dest->obj_at_put(1, str()); | |
1948 str = java_lang_String::create_from_symbol(member_sig, CHECK_NULL); | |
1949 dest->obj_at_put(2, str()); | |
1950 return (jobjectArray) JNIHandles::make_local(dest()); | |
1951 } | |
1952 JVM_END | |
1953 | |
1954 JVM_ENTRY(jint, JVM_ConstantPoolGetIntAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)) | |
1955 { | |
1956 JVMWrapper("JVM_ConstantPoolGetIntAt"); | |
1957 constantPoolHandle cp = constantPoolHandle(THREAD, constantPoolOop(JNIHandles::resolve_non_null(jcpool))); | |
1958 bounds_check(cp, index, CHECK_0); | |
1959 constantTag tag = cp->tag_at(index); | |
1960 if (!tag.is_int()) { | |
1961 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index"); | |
1962 } | |
1963 return cp->int_at(index); | |
1964 } | |
1965 JVM_END | |
1966 | |
1967 JVM_ENTRY(jlong, JVM_ConstantPoolGetLongAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)) | |
1968 { | |
1969 JVMWrapper("JVM_ConstantPoolGetLongAt"); | |
1970 constantPoolHandle cp = constantPoolHandle(THREAD, constantPoolOop(JNIHandles::resolve_non_null(jcpool))); | |
1971 bounds_check(cp, index, CHECK_(0L)); | |
1972 constantTag tag = cp->tag_at(index); | |
1973 if (!tag.is_long()) { | |
1974 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index"); | |
1975 } | |
1976 return cp->long_at(index); | |
1977 } | |
1978 JVM_END | |
1979 | |
1980 JVM_ENTRY(jfloat, JVM_ConstantPoolGetFloatAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)) | |
1981 { | |
1982 JVMWrapper("JVM_ConstantPoolGetFloatAt"); | |
1983 constantPoolHandle cp = constantPoolHandle(THREAD, constantPoolOop(JNIHandles::resolve_non_null(jcpool))); | |
1984 bounds_check(cp, index, CHECK_(0.0f)); | |
1985 constantTag tag = cp->tag_at(index); | |
1986 if (!tag.is_float()) { | |
1987 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index"); | |
1988 } | |
1989 return cp->float_at(index); | |
1990 } | |
1991 JVM_END | |
1992 | |
1993 JVM_ENTRY(jdouble, JVM_ConstantPoolGetDoubleAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)) | |
1994 { | |
1995 JVMWrapper("JVM_ConstantPoolGetDoubleAt"); | |
1996 constantPoolHandle cp = constantPoolHandle(THREAD, constantPoolOop(JNIHandles::resolve_non_null(jcpool))); | |
1997 bounds_check(cp, index, CHECK_(0.0)); | |
1998 constantTag tag = cp->tag_at(index); | |
1999 if (!tag.is_double()) { | |
2000 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index"); | |
2001 } | |
2002 return cp->double_at(index); | |
2003 } | |
2004 JVM_END | |
2005 | |
2006 JVM_ENTRY(jstring, JVM_ConstantPoolGetStringAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)) | |
2007 { | |
2008 JVMWrapper("JVM_ConstantPoolGetStringAt"); | |
2009 constantPoolHandle cp = constantPoolHandle(THREAD, constantPoolOop(JNIHandles::resolve_non_null(jcpool))); | |
2010 bounds_check(cp, index, CHECK_NULL); | |
2011 constantTag tag = cp->tag_at(index); | |
2012 if (!tag.is_string() && !tag.is_unresolved_string()) { | |
2013 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index"); | |
2014 } | |
2015 oop str = cp->string_at(index, CHECK_NULL); | |
2016 return (jstring) JNIHandles::make_local(str); | |
2017 } | |
2018 JVM_END | |
2019 | |
2020 JVM_ENTRY(jstring, JVM_ConstantPoolGetUTF8At(JNIEnv *env, jobject unused, jobject jcpool, jint index)) | |
2021 { | |
2022 JVMWrapper("JVM_ConstantPoolGetUTF8At"); | |
2023 JvmtiVMObjectAllocEventCollector oam; | |
2024 constantPoolHandle cp = constantPoolHandle(THREAD, constantPoolOop(JNIHandles::resolve_non_null(jcpool))); | |
2025 bounds_check(cp, index, CHECK_NULL); | |
2026 constantTag tag = cp->tag_at(index); | |
2027 if (!tag.is_symbol()) { | |
2028 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index"); | |
2029 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
2030 Symbol* sym = cp->symbol_at(index); |
0 | 2031 Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL); |
2032 return (jstring) JNIHandles::make_local(str()); | |
2033 } | |
2034 JVM_END | |
2035 | |
2036 | |
2037 // Assertion support. ////////////////////////////////////////////////////////// | |
2038 | |
2039 JVM_ENTRY(jboolean, JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls)) | |
2040 JVMWrapper("JVM_DesiredAssertionStatus"); | |
2041 assert(cls != NULL, "bad class"); | |
2042 | |
2043 oop r = JNIHandles::resolve(cls); | |
2044 assert(! java_lang_Class::is_primitive(r), "primitive classes not allowed"); | |
2045 if (java_lang_Class::is_primitive(r)) return false; | |
2046 | |
2047 klassOop k = java_lang_Class::as_klassOop(r); | |
2048 assert(Klass::cast(k)->oop_is_instance(), "must be an instance klass"); | |
2049 if (! Klass::cast(k)->oop_is_instance()) return false; | |
2050 | |
2051 ResourceMark rm(THREAD); | |
2052 const char* name = Klass::cast(k)->name()->as_C_string(); | |
2053 bool system_class = Klass::cast(k)->class_loader() == NULL; | |
2054 return JavaAssertions::enabled(name, system_class); | |
2055 | |
2056 JVM_END | |
2057 | |
2058 | |
2059 // Return a new AssertionStatusDirectives object with the fields filled in with | |
2060 // command-line assertion arguments (i.e., -ea, -da). | |
2061 JVM_ENTRY(jobject, JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused)) | |
2062 JVMWrapper("JVM_AssertionStatusDirectives"); | |
2063 JvmtiVMObjectAllocEventCollector oam; | |
2064 oop asd = JavaAssertions::createAssertionStatusDirectives(CHECK_NULL); | |
2065 return JNIHandles::make_local(env, asd); | |
2066 JVM_END | |
2067 | |
2068 // Verification //////////////////////////////////////////////////////////////////////////////// | |
2069 | |
2070 // Reflection for the verifier ///////////////////////////////////////////////////////////////// | |
2071 | |
2072 // RedefineClasses support: bug 6214132 caused verification to fail. | |
2073 // All functions from this section should call the jvmtiThreadSate function: | |
2074 // klassOop class_to_verify_considering_redefinition(klassOop klass). | |
2075 // The function returns a klassOop of the _scratch_class if the verifier | |
2076 // was invoked in the middle of the class redefinition. | |
2077 // Otherwise it returns its argument value which is the _the_class klassOop. | |
2078 // Please, refer to the description in the jvmtiThreadSate.hpp. | |
2079 | |
2080 JVM_ENTRY(const char*, JVM_GetClassNameUTF(JNIEnv *env, jclass cls)) | |
2081 JVMWrapper("JVM_GetClassNameUTF"); | |
2082 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2083 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2084 return Klass::cast(k)->name()->as_utf8(); | |
2085 JVM_END | |
2086 | |
2087 | |
2088 JVM_QUICK_ENTRY(void, JVM_GetClassCPTypes(JNIEnv *env, jclass cls, unsigned char *types)) | |
2089 JVMWrapper("JVM_GetClassCPTypes"); | |
2090 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2091 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2092 // types will have length zero if this is not an instanceKlass | |
2093 // (length is determined by call to JVM_GetClassCPEntriesCount) | |
2094 if (Klass::cast(k)->oop_is_instance()) { | |
2095 constantPoolOop cp = instanceKlass::cast(k)->constants(); | |
2096 for (int index = cp->length() - 1; index >= 0; index--) { | |
2097 constantTag tag = cp->tag_at(index); | |
2098 types[index] = (tag.is_unresolved_klass()) ? JVM_CONSTANT_Class : | |
2099 (tag.is_unresolved_string()) ? JVM_CONSTANT_String : tag.value(); | |
2100 } | |
2101 } | |
2102 JVM_END | |
2103 | |
2104 | |
2105 JVM_QUICK_ENTRY(jint, JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cls)) | |
2106 JVMWrapper("JVM_GetClassCPEntriesCount"); | |
2107 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2108 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2109 if (!Klass::cast(k)->oop_is_instance()) | |
2110 return 0; | |
2111 return instanceKlass::cast(k)->constants()->length(); | |
2112 JVM_END | |
2113 | |
2114 | |
2115 JVM_QUICK_ENTRY(jint, JVM_GetClassFieldsCount(JNIEnv *env, jclass cls)) | |
2116 JVMWrapper("JVM_GetClassFieldsCount"); | |
2117 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2118 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2119 if (!Klass::cast(k)->oop_is_instance()) | |
2120 return 0; | |
3938 | 2121 return instanceKlass::cast(k)->java_fields_count(); |
0 | 2122 JVM_END |
2123 | |
2124 | |
2125 JVM_QUICK_ENTRY(jint, JVM_GetClassMethodsCount(JNIEnv *env, jclass cls)) | |
2126 JVMWrapper("JVM_GetClassMethodsCount"); | |
2127 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2128 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2129 if (!Klass::cast(k)->oop_is_instance()) | |
2130 return 0; | |
2131 return instanceKlass::cast(k)->methods()->length(); | |
2132 JVM_END | |
2133 | |
2134 | |
2135 // The following methods, used for the verifier, are never called with | |
2136 // array klasses, so a direct cast to instanceKlass is safe. | |
2137 // Typically, these methods are called in a loop with bounds determined | |
2138 // by the results of JVM_GetClass{Fields,Methods}Count, which return | |
2139 // zero for arrays. | |
2140 JVM_QUICK_ENTRY(void, JVM_GetMethodIxExceptionIndexes(JNIEnv *env, jclass cls, jint method_index, unsigned short *exceptions)) | |
2141 JVMWrapper("JVM_GetMethodIxExceptionIndexes"); | |
2142 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2143 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2144 oop method = instanceKlass::cast(k)->methods()->obj_at(method_index); | |
2145 int length = methodOop(method)->checked_exceptions_length(); | |
2146 if (length > 0) { | |
2147 CheckedExceptionElement* table= methodOop(method)->checked_exceptions_start(); | |
2148 for (int i = 0; i < length; i++) { | |
2149 exceptions[i] = table[i].class_cp_index; | |
2150 } | |
2151 } | |
2152 JVM_END | |
2153 | |
2154 | |
2155 JVM_QUICK_ENTRY(jint, JVM_GetMethodIxExceptionsCount(JNIEnv *env, jclass cls, jint method_index)) | |
2156 JVMWrapper("JVM_GetMethodIxExceptionsCount"); | |
2157 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2158 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2159 oop method = instanceKlass::cast(k)->methods()->obj_at(method_index); | |
2160 return methodOop(method)->checked_exceptions_length(); | |
2161 JVM_END | |
2162 | |
2163 | |
2164 JVM_QUICK_ENTRY(void, JVM_GetMethodIxByteCode(JNIEnv *env, jclass cls, jint method_index, unsigned char *code)) | |
2165 JVMWrapper("JVM_GetMethodIxByteCode"); | |
2166 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2167 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2168 oop method = instanceKlass::cast(k)->methods()->obj_at(method_index); | |
2169 memcpy(code, methodOop(method)->code_base(), methodOop(method)->code_size()); | |
2170 JVM_END | |
2171 | |
2172 | |
2173 JVM_QUICK_ENTRY(jint, JVM_GetMethodIxByteCodeLength(JNIEnv *env, jclass cls, jint method_index)) | |
2174 JVMWrapper("JVM_GetMethodIxByteCodeLength"); | |
2175 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2176 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2177 oop method = instanceKlass::cast(k)->methods()->obj_at(method_index); | |
2178 return methodOop(method)->code_size(); | |
2179 JVM_END | |
2180 | |
2181 | |
2182 JVM_QUICK_ENTRY(void, JVM_GetMethodIxExceptionTableEntry(JNIEnv *env, jclass cls, jint method_index, jint entry_index, JVM_ExceptionTableEntryType *entry)) | |
2183 JVMWrapper("JVM_GetMethodIxExceptionTableEntry"); | |
2184 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2185 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2186 oop method = instanceKlass::cast(k)->methods()->obj_at(method_index); | |
2187 typeArrayOop extable = methodOop(method)->exception_table(); | |
2188 entry->start_pc = extable->int_at(entry_index * 4); | |
2189 entry->end_pc = extable->int_at(entry_index * 4 + 1); | |
2190 entry->handler_pc = extable->int_at(entry_index * 4 + 2); | |
2191 entry->catchType = extable->int_at(entry_index * 4 + 3); | |
2192 JVM_END | |
2193 | |
2194 | |
2195 JVM_QUICK_ENTRY(jint, JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cls, int method_index)) | |
2196 JVMWrapper("JVM_GetMethodIxExceptionTableLength"); | |
2197 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2198 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2199 oop method = instanceKlass::cast(k)->methods()->obj_at(method_index); | |
2200 return methodOop(method)->exception_table()->length() / 4; | |
2201 JVM_END | |
2202 | |
2203 | |
2204 JVM_QUICK_ENTRY(jint, JVM_GetMethodIxModifiers(JNIEnv *env, jclass cls, int method_index)) | |
2205 JVMWrapper("JVM_GetMethodIxModifiers"); | |
2206 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2207 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2208 oop method = instanceKlass::cast(k)->methods()->obj_at(method_index); | |
2209 return methodOop(method)->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; | |
2210 JVM_END | |
2211 | |
2212 | |
2213 JVM_QUICK_ENTRY(jint, JVM_GetFieldIxModifiers(JNIEnv *env, jclass cls, int field_index)) | |
2214 JVMWrapper("JVM_GetFieldIxModifiers"); | |
2215 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2216 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
3938 | 2217 return instanceKlass::cast(k)->field_access_flags(field_index) & JVM_RECOGNIZED_FIELD_MODIFIERS; |
0 | 2218 JVM_END |
2219 | |
2220 | |
2221 JVM_QUICK_ENTRY(jint, JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cls, int method_index)) | |
2222 JVMWrapper("JVM_GetMethodIxLocalsCount"); | |
2223 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2224 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2225 oop method = instanceKlass::cast(k)->methods()->obj_at(method_index); | |
2226 return methodOop(method)->max_locals(); | |
2227 JVM_END | |
2228 | |
2229 | |
2230 JVM_QUICK_ENTRY(jint, JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cls, int method_index)) | |
2231 JVMWrapper("JVM_GetMethodIxArgsSize"); | |
2232 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2233 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2234 oop method = instanceKlass::cast(k)->methods()->obj_at(method_index); | |
2235 return methodOop(method)->size_of_parameters(); | |
2236 JVM_END | |
2237 | |
2238 | |
2239 JVM_QUICK_ENTRY(jint, JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cls, int method_index)) | |
2240 JVMWrapper("JVM_GetMethodIxMaxStack"); | |
2241 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2242 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2243 oop method = instanceKlass::cast(k)->methods()->obj_at(method_index); | |
2244 return methodOop(method)->max_stack(); | |
2245 JVM_END | |
2246 | |
2247 | |
2248 JVM_QUICK_ENTRY(jboolean, JVM_IsConstructorIx(JNIEnv *env, jclass cls, int method_index)) | |
2249 JVMWrapper("JVM_IsConstructorIx"); | |
2250 ResourceMark rm(THREAD); | |
2251 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2252 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2253 oop method = instanceKlass::cast(k)->methods()->obj_at(method_index); | |
2254 return methodOop(method)->name() == vmSymbols::object_initializer_name(); | |
2255 JVM_END | |
2256 | |
2257 | |
2258 JVM_ENTRY(const char*, JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cls, jint method_index)) | |
2259 JVMWrapper("JVM_GetMethodIxIxUTF"); | |
2260 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2261 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2262 oop method = instanceKlass::cast(k)->methods()->obj_at(method_index); | |
2263 return methodOop(method)->name()->as_utf8(); | |
2264 JVM_END | |
2265 | |
2266 | |
2267 JVM_ENTRY(const char*, JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cls, jint method_index)) | |
2268 JVMWrapper("JVM_GetMethodIxSignatureUTF"); | |
2269 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2270 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2271 oop method = instanceKlass::cast(k)->methods()->obj_at(method_index); | |
2272 return methodOop(method)->signature()->as_utf8(); | |
2273 JVM_END | |
2274 | |
2275 /** | |
2276 * All of these JVM_GetCP-xxx methods are used by the old verifier to | |
2277 * read entries in the constant pool. Since the old verifier always | |
2278 * works on a copy of the code, it will not see any rewriting that | |
2279 * may possibly occur in the middle of verification. So it is important | |
2280 * that nothing it calls tries to use the cpCache instead of the raw | |
2281 * constant pool, so we must use cp->uncached_x methods when appropriate. | |
2282 */ | |
2283 JVM_ENTRY(const char*, JVM_GetCPFieldNameUTF(JNIEnv *env, jclass cls, jint cp_index)) | |
2284 JVMWrapper("JVM_GetCPFieldNameUTF"); | |
2285 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2286 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2287 constantPoolOop cp = instanceKlass::cast(k)->constants(); | |
2288 switch (cp->tag_at(cp_index).value()) { | |
2289 case JVM_CONSTANT_Fieldref: | |
2290 return cp->uncached_name_ref_at(cp_index)->as_utf8(); | |
2291 default: | |
2292 fatal("JVM_GetCPFieldNameUTF: illegal constant"); | |
2293 } | |
2294 ShouldNotReachHere(); | |
2295 return NULL; | |
2296 JVM_END | |
2297 | |
2298 | |
2299 JVM_ENTRY(const char*, JVM_GetCPMethodNameUTF(JNIEnv *env, jclass cls, jint cp_index)) | |
2300 JVMWrapper("JVM_GetCPMethodNameUTF"); | |
2301 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2302 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2303 constantPoolOop cp = instanceKlass::cast(k)->constants(); | |
2304 switch (cp->tag_at(cp_index).value()) { | |
2305 case JVM_CONSTANT_InterfaceMethodref: | |
2306 case JVM_CONSTANT_Methodref: | |
1059
389049f3f393
6858164: invokedynamic code needs some cleanup (post-6655638)
jrose
parents:
973
diff
changeset
|
2307 case JVM_CONSTANT_NameAndType: // for invokedynamic |
0 | 2308 return cp->uncached_name_ref_at(cp_index)->as_utf8(); |
2309 default: | |
2310 fatal("JVM_GetCPMethodNameUTF: illegal constant"); | |
2311 } | |
2312 ShouldNotReachHere(); | |
2313 return NULL; | |
2314 JVM_END | |
2315 | |
2316 | |
2317 JVM_ENTRY(const char*, JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cls, jint cp_index)) | |
2318 JVMWrapper("JVM_GetCPMethodSignatureUTF"); | |
2319 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2320 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2321 constantPoolOop cp = instanceKlass::cast(k)->constants(); | |
2322 switch (cp->tag_at(cp_index).value()) { | |
2323 case JVM_CONSTANT_InterfaceMethodref: | |
2324 case JVM_CONSTANT_Methodref: | |
1059
389049f3f393
6858164: invokedynamic code needs some cleanup (post-6655638)
jrose
parents:
973
diff
changeset
|
2325 case JVM_CONSTANT_NameAndType: // for invokedynamic |
0 | 2326 return cp->uncached_signature_ref_at(cp_index)->as_utf8(); |
2327 default: | |
2328 fatal("JVM_GetCPMethodSignatureUTF: illegal constant"); | |
2329 } | |
2330 ShouldNotReachHere(); | |
2331 return NULL; | |
2332 JVM_END | |
2333 | |
2334 | |
2335 JVM_ENTRY(const char*, JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cls, jint cp_index)) | |
2336 JVMWrapper("JVM_GetCPFieldSignatureUTF"); | |
2337 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2338 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2339 constantPoolOop cp = instanceKlass::cast(k)->constants(); | |
2340 switch (cp->tag_at(cp_index).value()) { | |
2341 case JVM_CONSTANT_Fieldref: | |
2342 return cp->uncached_signature_ref_at(cp_index)->as_utf8(); | |
2343 default: | |
2344 fatal("JVM_GetCPFieldSignatureUTF: illegal constant"); | |
2345 } | |
2346 ShouldNotReachHere(); | |
2347 return NULL; | |
2348 JVM_END | |
2349 | |
2350 | |
2351 JVM_ENTRY(const char*, JVM_GetCPClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)) | |
2352 JVMWrapper("JVM_GetCPClassNameUTF"); | |
2353 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2354 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2355 constantPoolOop cp = instanceKlass::cast(k)->constants(); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
2356 Symbol* classname = cp->klass_name_at(cp_index); |
0 | 2357 return classname->as_utf8(); |
2358 JVM_END | |
2359 | |
2360 | |
2361 JVM_ENTRY(const char*, JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)) | |
2362 JVMWrapper("JVM_GetCPFieldClassNameUTF"); | |
2363 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2364 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2365 constantPoolOop cp = instanceKlass::cast(k)->constants(); | |
2366 switch (cp->tag_at(cp_index).value()) { | |
2367 case JVM_CONSTANT_Fieldref: { | |
2368 int class_index = cp->uncached_klass_ref_index_at(cp_index); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
2369 Symbol* classname = cp->klass_name_at(class_index); |
0 | 2370 return classname->as_utf8(); |
2371 } | |
2372 default: | |
2373 fatal("JVM_GetCPFieldClassNameUTF: illegal constant"); | |
2374 } | |
2375 ShouldNotReachHere(); | |
2376 return NULL; | |
2377 JVM_END | |
2378 | |
2379 | |
2380 JVM_ENTRY(const char*, JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)) | |
2381 JVMWrapper("JVM_GetCPMethodClassNameUTF"); | |
2382 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2383 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2384 constantPoolOop cp = instanceKlass::cast(k)->constants(); | |
2385 switch (cp->tag_at(cp_index).value()) { | |
2386 case JVM_CONSTANT_Methodref: | |
2387 case JVM_CONSTANT_InterfaceMethodref: { | |
2388 int class_index = cp->uncached_klass_ref_index_at(cp_index); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
2389 Symbol* classname = cp->klass_name_at(class_index); |
0 | 2390 return classname->as_utf8(); |
2391 } | |
2392 default: | |
2393 fatal("JVM_GetCPMethodClassNameUTF: illegal constant"); | |
2394 } | |
2395 ShouldNotReachHere(); | |
2396 return NULL; | |
2397 JVM_END | |
2398 | |
2399 | |
3938 | 2400 JVM_ENTRY(jint, JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls)) |
0 | 2401 JVMWrapper("JVM_GetCPFieldModifiers"); |
2402 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2403 klassOop k_called = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(called_cls)); | |
2404 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2405 k_called = JvmtiThreadState::class_to_verify_considering_redefinition(k_called, thread); | |
2406 constantPoolOop cp = instanceKlass::cast(k)->constants(); | |
2407 constantPoolOop cp_called = instanceKlass::cast(k_called)->constants(); | |
2408 switch (cp->tag_at(cp_index).value()) { | |
2409 case JVM_CONSTANT_Fieldref: { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
2410 Symbol* name = cp->uncached_name_ref_at(cp_index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
2411 Symbol* signature = cp->uncached_signature_ref_at(cp_index); |
3938 | 2412 for (JavaFieldStream fs(k_called); !fs.done(); fs.next()) { |
2413 if (fs.name() == name && fs.signature() == signature) { | |
2414 return fs.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS; | |
0 | 2415 } |
2416 } | |
2417 return -1; | |
2418 } | |
2419 default: | |
2420 fatal("JVM_GetCPFieldModifiers: illegal constant"); | |
2421 } | |
2422 ShouldNotReachHere(); | |
2423 return 0; | |
2424 JVM_END | |
2425 | |
2426 | |
2427 JVM_QUICK_ENTRY(jint, JVM_GetCPMethodModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls)) | |
2428 JVMWrapper("JVM_GetCPMethodModifiers"); | |
2429 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); | |
2430 klassOop k_called = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(called_cls)); | |
2431 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); | |
2432 k_called = JvmtiThreadState::class_to_verify_considering_redefinition(k_called, thread); | |
2433 constantPoolOop cp = instanceKlass::cast(k)->constants(); | |
2434 switch (cp->tag_at(cp_index).value()) { | |
2435 case JVM_CONSTANT_Methodref: | |
2436 case JVM_CONSTANT_InterfaceMethodref: { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
2437 Symbol* name = cp->uncached_name_ref_at(cp_index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
2438 Symbol* signature = cp->uncached_signature_ref_at(cp_index); |
0 | 2439 objArrayOop methods = instanceKlass::cast(k_called)->methods(); |
2440 int methods_count = methods->length(); | |
2441 for (int i = 0; i < methods_count; i++) { | |
2442 methodOop method = methodOop(methods->obj_at(i)); | |
2443 if (method->name() == name && method->signature() == signature) { | |
2444 return method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; | |
2445 } | |
2446 } | |
2447 return -1; | |
2448 } | |
2449 default: | |
2450 fatal("JVM_GetCPMethodModifiers: illegal constant"); | |
2451 } | |
2452 ShouldNotReachHere(); | |
2453 return 0; | |
2454 JVM_END | |
2455 | |
2456 | |
2457 // Misc ////////////////////////////////////////////////////////////////////////////////////////////// | |
2458 | |
2459 JVM_LEAF(void, JVM_ReleaseUTF(const char *utf)) | |
2460 // So long as UTF8::convert_to_utf8 returns resource strings, we don't have to do anything | |
2461 JVM_END | |
2462 | |
2463 | |
2464 JVM_ENTRY(jboolean, JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2)) | |
2465 JVMWrapper("JVM_IsSameClassPackage"); | |
2466 oop class1_mirror = JNIHandles::resolve_non_null(class1); | |
2467 oop class2_mirror = JNIHandles::resolve_non_null(class2); | |
2468 klassOop klass1 = java_lang_Class::as_klassOop(class1_mirror); | |
2469 klassOop klass2 = java_lang_Class::as_klassOop(class2_mirror); | |
2470 return (jboolean) Reflection::is_same_class_package(klass1, klass2); | |
2471 JVM_END | |
2472 | |
2473 | |
2474 // IO functions //////////////////////////////////////////////////////////////////////////////////////// | |
2475 | |
2476 JVM_LEAF(jint, JVM_Open(const char *fname, jint flags, jint mode)) | |
2477 JVMWrapper2("JVM_Open (%s)", fname); | |
2478 | |
2479 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2480 int result = os::open(fname, flags, mode); |
0 | 2481 if (result >= 0) { |
2482 return result; | |
2483 } else { | |
2484 switch(errno) { | |
2485 case EEXIST: | |
2486 return JVM_EEXIST; | |
2487 default: | |
2488 return -1; | |
2489 } | |
2490 } | |
2491 JVM_END | |
2492 | |
2493 | |
2494 JVM_LEAF(jint, JVM_Close(jint fd)) | |
2495 JVMWrapper2("JVM_Close (0x%x)", fd); | |
2496 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2497 return os::close(fd); |
0 | 2498 JVM_END |
2499 | |
2500 | |
2501 JVM_LEAF(jint, JVM_Read(jint fd, char *buf, jint nbytes)) | |
2502 JVMWrapper2("JVM_Read (0x%x)", fd); | |
2503 | |
2504 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2505 return (jint)os::restartable_read(fd, buf, nbytes); |
0 | 2506 JVM_END |
2507 | |
2508 | |
2509 JVM_LEAF(jint, JVM_Write(jint fd, char *buf, jint nbytes)) | |
2510 JVMWrapper2("JVM_Write (0x%x)", fd); | |
2511 | |
2512 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2513 return (jint)os::write(fd, buf, nbytes); |
0 | 2514 JVM_END |
2515 | |
2516 | |
2517 JVM_LEAF(jint, JVM_Available(jint fd, jlong *pbytes)) | |
2518 JVMWrapper2("JVM_Available (0x%x)", fd); | |
2519 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2520 return os::available(fd, pbytes); |
0 | 2521 JVM_END |
2522 | |
2523 | |
2524 JVM_LEAF(jlong, JVM_Lseek(jint fd, jlong offset, jint whence)) | |
2525 JVMWrapper4("JVM_Lseek (0x%x, %Ld, %d)", fd, offset, whence); | |
2526 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2527 return os::lseek(fd, offset, whence); |
0 | 2528 JVM_END |
2529 | |
2530 | |
2531 JVM_LEAF(jint, JVM_SetLength(jint fd, jlong length)) | |
2532 JVMWrapper3("JVM_SetLength (0x%x, %Ld)", fd, length); | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2533 return os::ftruncate(fd, length); |
0 | 2534 JVM_END |
2535 | |
2536 | |
2537 JVM_LEAF(jint, JVM_Sync(jint fd)) | |
2538 JVMWrapper2("JVM_Sync (0x%x)", fd); | |
2539 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2540 return os::fsync(fd); |
0 | 2541 JVM_END |
2542 | |
2543 | |
2544 // Printing support ////////////////////////////////////////////////// | |
2545 extern "C" { | |
2546 | |
2547 int jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args) { | |
2548 // see bug 4399518, 4417214 | |
2549 if ((intptr_t)count <= 0) return -1; | |
2550 return vsnprintf(str, count, fmt, args); | |
2551 } | |
2552 | |
2553 | |
2554 int jio_snprintf(char *str, size_t count, const char *fmt, ...) { | |
2555 va_list args; | |
2556 int len; | |
2557 va_start(args, fmt); | |
2558 len = jio_vsnprintf(str, count, fmt, args); | |
2559 va_end(args); | |
2560 return len; | |
2561 } | |
2562 | |
2563 | |
2564 int jio_fprintf(FILE* f, const char *fmt, ...) { | |
2565 int len; | |
2566 va_list args; | |
2567 va_start(args, fmt); | |
2568 len = jio_vfprintf(f, fmt, args); | |
2569 va_end(args); | |
2570 return len; | |
2571 } | |
2572 | |
2573 | |
2574 int jio_vfprintf(FILE* f, const char *fmt, va_list args) { | |
2575 if (Arguments::vfprintf_hook() != NULL) { | |
2576 return Arguments::vfprintf_hook()(f, fmt, args); | |
2577 } else { | |
2578 return vfprintf(f, fmt, args); | |
2579 } | |
2580 } | |
2581 | |
2582 | |
2191 | 2583 JNIEXPORT int jio_printf(const char *fmt, ...) { |
0 | 2584 int len; |
2585 va_list args; | |
2586 va_start(args, fmt); | |
2587 len = jio_vfprintf(defaultStream::output_stream(), fmt, args); | |
2588 va_end(args); | |
2589 return len; | |
2590 } | |
2591 | |
2592 | |
2593 // HotSpot specific jio method | |
2594 void jio_print(const char* s) { | |
2595 // Try to make this function as atomic as possible. | |
2596 if (Arguments::vfprintf_hook() != NULL) { | |
2597 jio_fprintf(defaultStream::output_stream(), "%s", s); | |
2598 } else { | |
513
2328d1d3f8cf
6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents:
431
diff
changeset
|
2599 // Make an unused local variable to avoid warning from gcc 4.x compiler. |
2328d1d3f8cf
6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents:
431
diff
changeset
|
2600 size_t count = ::write(defaultStream::output_fd(), s, (int)strlen(s)); |
0 | 2601 } |
2602 } | |
2603 | |
2604 } // Extern C | |
2605 | |
2606 // java.lang.Thread ////////////////////////////////////////////////////////////////////////////// | |
2607 | |
2608 // In most of the JVM Thread support functions we need to be sure to lock the Threads_lock | |
2609 // to prevent the target thread from exiting after we have a pointer to the C++ Thread or | |
2610 // OSThread objects. The exception to this rule is when the target object is the thread | |
2611 // doing the operation, in which case we know that the thread won't exit until the | |
2612 // operation is done (all exits being voluntary). There are a few cases where it is | |
2613 // rather silly to do operations on yourself, like resuming yourself or asking whether | |
2614 // you are alive. While these can still happen, they are not subject to deadlocks if | |
2615 // the lock is held while the operation occurs (this is not the case for suspend, for | |
2616 // instance), and are very unlikely. Because IsAlive needs to be fast and its | |
2617 // implementation is local to this file, we always lock Threads_lock for that one. | |
2618 | |
2619 static void thread_entry(JavaThread* thread, TRAPS) { | |
2620 HandleMark hm(THREAD); | |
2621 Handle obj(THREAD, thread->threadObj()); | |
2622 JavaValue result(T_VOID); | |
2623 JavaCalls::call_virtual(&result, | |
2624 obj, | |
1142 | 2625 KlassHandle(THREAD, SystemDictionary::Thread_klass()), |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
2626 vmSymbols::run_method_name(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
2627 vmSymbols::void_method_signature(), |
0 | 2628 THREAD); |
2629 } | |
2630 | |
2631 | |
2632 JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread)) | |
2633 JVMWrapper("JVM_StartThread"); | |
2634 JavaThread *native_thread = NULL; | |
2635 | |
2636 // We cannot hold the Threads_lock when we throw an exception, | |
2637 // due to rank ordering issues. Example: we might need to grab the | |
2638 // Heap_lock while we construct the exception. | |
2639 bool throw_illegal_thread_state = false; | |
2640 | |
2641 // We must release the Threads_lock before we can post a jvmti event | |
2642 // in Thread::start. | |
2643 { | |
2644 // Ensure that the C++ Thread and OSThread structures aren't freed before | |
2645 // we operate. | |
2646 MutexLocker mu(Threads_lock); | |
2647 | |
2162
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2648 // Since JDK 5 the java.lang.Thread threadStatus is used to prevent |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2649 // re-starting an already started thread, so we should usually find |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2650 // that the JavaThread is null. However for a JNI attached thread |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2651 // there is a small window between the Thread object being created |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2652 // (with its JavaThread set) and the update to its threadStatus, so we |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2653 // have to check for this |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2654 if (java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) { |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2655 throw_illegal_thread_state = true; |
0 | 2656 } else { |
2162
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2657 // We could also check the stillborn flag to see if this thread was already stopped, but |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2658 // for historical reasons we let the thread detect that itself when it starts running |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2659 |
0 | 2660 jlong size = |
2661 java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread)); | |
2662 // Allocate the C++ Thread structure and create the native thread. The | |
2663 // stack size retrieved from java is signed, but the constructor takes | |
2664 // size_t (an unsigned type), so avoid passing negative values which would | |
2665 // result in really large stacks. | |
2666 size_t sz = size > 0 ? (size_t) size : 0; | |
2667 native_thread = new JavaThread(&thread_entry, sz); | |
2668 | |
2669 // At this point it may be possible that no osthread was created for the | |
2670 // JavaThread due to lack of memory. Check for this situation and throw | |
2671 // an exception if necessary. Eventually we may want to change this so | |
2672 // that we only grab the lock if the thread was created successfully - | |
2673 // then we can also do this check and throw the exception in the | |
2674 // JavaThread constructor. | |
2675 if (native_thread->osthread() != NULL) { | |
2676 // Note: the current thread is not being used within "prepare". | |
2677 native_thread->prepare(jthread); | |
2678 } | |
2679 } | |
2680 } | |
2681 | |
2682 if (throw_illegal_thread_state) { | |
2683 THROW(vmSymbols::java_lang_IllegalThreadStateException()); | |
2684 } | |
2685 | |
2686 assert(native_thread != NULL, "Starting null thread?"); | |
2687 | |
2688 if (native_thread->osthread() == NULL) { | |
2689 // No one should hold a reference to the 'native_thread'. | |
2690 delete native_thread; | |
2691 if (JvmtiExport::should_post_resource_exhausted()) { | |
2692 JvmtiExport::post_resource_exhausted( | |
2693 JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_THREADS, | |
2694 "unable to create new native thread"); | |
2695 } | |
2696 THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), | |
2697 "unable to create new native thread"); | |
2698 } | |
2699 | |
2700 Thread::start(native_thread); | |
2701 | |
2702 JVM_END | |
2703 | |
2704 // JVM_Stop is implemented using a VM_Operation, so threads are forced to safepoints | |
2705 // before the quasi-asynchronous exception is delivered. This is a little obtrusive, | |
2706 // but is thought to be reliable and simple. In the case, where the receiver is the | |
2162
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2707 // same thread as the sender, no safepoint is needed. |
0 | 2708 JVM_ENTRY(void, JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable)) |
2709 JVMWrapper("JVM_StopThread"); | |
2710 | |
2711 oop java_throwable = JNIHandles::resolve(throwable); | |
2712 if (java_throwable == NULL) { | |
2713 THROW(vmSymbols::java_lang_NullPointerException()); | |
2714 } | |
2715 oop java_thread = JNIHandles::resolve_non_null(jthread); | |
2716 JavaThread* receiver = java_lang_Thread::thread(java_thread); | |
2717 Events::log("JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]", receiver, (address)java_thread, throwable); | |
2162
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2718 // First check if thread is alive |
0 | 2719 if (receiver != NULL) { |
2720 // Check if exception is getting thrown at self (use oop equality, since the | |
2721 // target object might exit) | |
2722 if (java_thread == thread->threadObj()) { | |
2723 THROW_OOP(java_throwable); | |
2724 } else { | |
2725 // Enques a VM_Operation to stop all threads and then deliver the exception... | |
2726 Thread::send_async_exception(java_thread, JNIHandles::resolve(throwable)); | |
2727 } | |
2728 } | |
2162
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2729 else { |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2730 // Either: |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2731 // - target thread has not been started before being stopped, or |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2732 // - target thread already terminated |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2733 // We could read the threadStatus to determine which case it is |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2734 // but that is overkill as it doesn't matter. We must set the |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2735 // stillborn flag for the first case, and if the thread has already |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2736 // exited setting this flag has no affect |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2737 java_lang_Thread::set_stillborn(java_thread); |
ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents:
1980
diff
changeset
|
2738 } |
0 | 2739 JVM_END |
2740 | |
2741 | |
2742 JVM_ENTRY(jboolean, JVM_IsThreadAlive(JNIEnv* env, jobject jthread)) | |
2743 JVMWrapper("JVM_IsThreadAlive"); | |
2744 | |
2745 oop thread_oop = JNIHandles::resolve_non_null(jthread); | |
2746 return java_lang_Thread::is_alive(thread_oop); | |
2747 JVM_END | |
2748 | |
2749 | |
2750 JVM_ENTRY(void, JVM_SuspendThread(JNIEnv* env, jobject jthread)) | |
2751 JVMWrapper("JVM_SuspendThread"); | |
2752 oop java_thread = JNIHandles::resolve_non_null(jthread); | |
2753 JavaThread* receiver = java_lang_Thread::thread(java_thread); | |
2754 | |
2755 if (receiver != NULL) { | |
2756 // thread has run and has not exited (still on threads list) | |
2757 | |
2758 { | |
2759 MutexLockerEx ml(receiver->SR_lock(), Mutex::_no_safepoint_check_flag); | |
2760 if (receiver->is_external_suspend()) { | |
2761 // Don't allow nested external suspend requests. We can't return | |
2762 // an error from this interface so just ignore the problem. | |
2763 return; | |
2764 } | |
2765 if (receiver->is_exiting()) { // thread is in the process of exiting | |
2766 return; | |
2767 } | |
2768 receiver->set_external_suspend(); | |
2769 } | |
2770 | |
2771 // java_suspend() will catch threads in the process of exiting | |
2772 // and will ignore them. | |
2773 receiver->java_suspend(); | |
2774 | |
2775 // It would be nice to have the following assertion in all the | |
2776 // time, but it is possible for a racing resume request to have | |
2777 // resumed this thread right after we suspended it. Temporarily | |
2778 // enable this assertion if you are chasing a different kind of | |
2779 // bug. | |
2780 // | |
2781 // assert(java_lang_Thread::thread(receiver->threadObj()) == NULL || | |
2782 // receiver->is_being_ext_suspended(), "thread is not suspended"); | |
2783 } | |
2784 JVM_END | |
2785 | |
2786 | |
2787 JVM_ENTRY(void, JVM_ResumeThread(JNIEnv* env, jobject jthread)) | |
2788 JVMWrapper("JVM_ResumeThread"); | |
2789 // Ensure that the C++ Thread and OSThread structures aren't freed before we operate. | |
2790 // We need to *always* get the threads lock here, since this operation cannot be allowed during | |
2791 // a safepoint. The safepoint code relies on suspending a thread to examine its state. If other | |
2792 // threads randomly resumes threads, then a thread might not be suspended when the safepoint code | |
2793 // looks at it. | |
2794 MutexLocker ml(Threads_lock); | |
2795 JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)); | |
2796 if (thr != NULL) { | |
2797 // the thread has run and is not in the process of exiting | |
2798 thr->java_resume(); | |
2799 } | |
2800 JVM_END | |
2801 | |
2802 | |
2803 JVM_ENTRY(void, JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio)) | |
2804 JVMWrapper("JVM_SetThreadPriority"); | |
2805 // Ensure that the C++ Thread and OSThread structures aren't freed before we operate | |
2806 MutexLocker ml(Threads_lock); | |
2807 oop java_thread = JNIHandles::resolve_non_null(jthread); | |
2808 java_lang_Thread::set_priority(java_thread, (ThreadPriority)prio); | |
2809 JavaThread* thr = java_lang_Thread::thread(java_thread); | |
2810 if (thr != NULL) { // Thread not yet started; priority pushed down when it is | |
2811 Thread::set_priority(thr, (ThreadPriority)prio); | |
2812 } | |
2813 JVM_END | |
2814 | |
2815 | |
2816 JVM_ENTRY(void, JVM_Yield(JNIEnv *env, jclass threadClass)) | |
2817 JVMWrapper("JVM_Yield"); | |
2818 if (os::dont_yield()) return; | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1144
diff
changeset
|
2819 HS_DTRACE_PROBE0(hotspot, thread__yield); |
0 | 2820 // When ConvertYieldToSleep is off (default), this matches the classic VM use of yield. |
2821 // Critical for similar threading behaviour | |
2822 if (ConvertYieldToSleep) { | |
2823 os::sleep(thread, MinSleepInterval, false); | |
2824 } else { | |
2825 os::yield(); | |
2826 } | |
2827 JVM_END | |
2828 | |
2829 | |
2830 JVM_ENTRY(void, JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis)) | |
2831 JVMWrapper("JVM_Sleep"); | |
2832 | |
2833 if (millis < 0) { | |
2834 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative"); | |
2835 } | |
2836 | |
2837 if (Thread::is_interrupted (THREAD, true) && !HAS_PENDING_EXCEPTION) { | |
2838 THROW_MSG(vmSymbols::java_lang_InterruptedException(), "sleep interrupted"); | |
2839 } | |
2840 | |
2841 // Save current thread state and restore it at the end of this block. | |
2842 // And set new thread state to SLEEPING. | |
2843 JavaThreadSleepState jtss(thread); | |
2844 | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1144
diff
changeset
|
2845 HS_DTRACE_PROBE1(hotspot, thread__sleep__begin, millis); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1144
diff
changeset
|
2846 |
0 | 2847 if (millis == 0) { |
2848 // When ConvertSleepToYield is on, this matches the classic VM implementation of | |
2849 // JVM_Sleep. Critical for similar threading behaviour (Win32) | |
2850 // It appears that in certain GUI contexts, it may be beneficial to do a short sleep | |
2851 // for SOLARIS | |
2852 if (ConvertSleepToYield) { | |
2853 os::yield(); | |
2854 } else { | |
2855 ThreadState old_state = thread->osthread()->get_state(); | |
2856 thread->osthread()->set_state(SLEEPING); | |
2857 os::sleep(thread, MinSleepInterval, false); | |
2858 thread->osthread()->set_state(old_state); | |
2859 } | |
2860 } else { | |
2861 ThreadState old_state = thread->osthread()->get_state(); | |
2862 thread->osthread()->set_state(SLEEPING); | |
2863 if (os::sleep(thread, millis, true) == OS_INTRPT) { | |
2864 // An asynchronous exception (e.g., ThreadDeathException) could have been thrown on | |
2865 // us while we were sleeping. We do not overwrite those. | |
2866 if (!HAS_PENDING_EXCEPTION) { | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1144
diff
changeset
|
2867 HS_DTRACE_PROBE1(hotspot, thread__sleep__end,1); |
0 | 2868 // TODO-FIXME: THROW_MSG returns which means we will not call set_state() |
2869 // to properly restore the thread state. That's likely wrong. | |
2870 THROW_MSG(vmSymbols::java_lang_InterruptedException(), "sleep interrupted"); | |
2871 } | |
2872 } | |
2873 thread->osthread()->set_state(old_state); | |
2874 } | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1144
diff
changeset
|
2875 HS_DTRACE_PROBE1(hotspot, thread__sleep__end,0); |
0 | 2876 JVM_END |
2877 | |
2878 JVM_ENTRY(jobject, JVM_CurrentThread(JNIEnv* env, jclass threadClass)) | |
2879 JVMWrapper("JVM_CurrentThread"); | |
2880 oop jthread = thread->threadObj(); | |
2881 assert (thread != NULL, "no current thread!"); | |
2882 return JNIHandles::make_local(env, jthread); | |
2883 JVM_END | |
2884 | |
2885 | |
2886 JVM_ENTRY(jint, JVM_CountStackFrames(JNIEnv* env, jobject jthread)) | |
2887 JVMWrapper("JVM_CountStackFrames"); | |
2888 | |
2889 // Ensure that the C++ Thread and OSThread structures aren't freed before we operate | |
2890 oop java_thread = JNIHandles::resolve_non_null(jthread); | |
2891 bool throw_illegal_thread_state = false; | |
2892 int count = 0; | |
2893 | |
2894 { | |
2895 MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock); | |
2896 // We need to re-resolve the java_thread, since a GC might have happened during the | |
2897 // acquire of the lock | |
2898 JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)); | |
2899 | |
2900 if (thr == NULL) { | |
2901 // do nothing | |
2902 } else if(! thr->is_external_suspend() || ! thr->frame_anchor()->walkable()) { | |
2903 // Check whether this java thread has been suspended already. If not, throws | |
2904 // IllegalThreadStateException. We defer to throw that exception until | |
2905 // Threads_lock is released since loading exception class has to leave VM. | |
2906 // The correct way to test a thread is actually suspended is | |
2907 // wait_for_ext_suspend_completion(), but we can't call that while holding | |
2908 // the Threads_lock. The above tests are sufficient for our purposes | |
2909 // provided the walkability of the stack is stable - which it isn't | |
2910 // 100% but close enough for most practical purposes. | |
2911 throw_illegal_thread_state = true; | |
2912 } else { | |
2913 // Count all java activation, i.e., number of vframes | |
2914 for(vframeStream vfst(thr); !vfst.at_end(); vfst.next()) { | |
2915 // Native frames are not counted | |
2916 if (!vfst.method()->is_native()) count++; | |
2917 } | |
2918 } | |
2919 } | |
2920 | |
2921 if (throw_illegal_thread_state) { | |
2922 THROW_MSG_0(vmSymbols::java_lang_IllegalThreadStateException(), | |
2923 "this thread is not suspended"); | |
2924 } | |
2925 return count; | |
2926 JVM_END | |
2927 | |
2928 // Consider: A better way to implement JVM_Interrupt() is to acquire | |
2929 // Threads_lock to resolve the jthread into a Thread pointer, fetch | |
2930 // Thread->platformevent, Thread->native_thr, Thread->parker, etc., | |
2931 // drop Threads_lock, and the perform the unpark() and thr_kill() operations | |
2932 // outside the critical section. Threads_lock is hot so we want to minimize | |
2933 // the hold-time. A cleaner interface would be to decompose interrupt into | |
2934 // two steps. The 1st phase, performed under Threads_lock, would return | |
2935 // a closure that'd be invoked after Threads_lock was dropped. | |
2936 // This tactic is safe as PlatformEvent and Parkers are type-stable (TSM) and | |
2937 // admit spurious wakeups. | |
2938 | |
2939 JVM_ENTRY(void, JVM_Interrupt(JNIEnv* env, jobject jthread)) | |
2940 JVMWrapper("JVM_Interrupt"); | |
2941 | |
2942 // Ensure that the C++ Thread and OSThread structures aren't freed before we operate | |
2943 oop java_thread = JNIHandles::resolve_non_null(jthread); | |
2944 MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock); | |
2945 // We need to re-resolve the java_thread, since a GC might have happened during the | |
2946 // acquire of the lock | |
2947 JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)); | |
2948 if (thr != NULL) { | |
2949 Thread::interrupt(thr); | |
2950 } | |
2951 JVM_END | |
2952 | |
2953 | |
2954 JVM_QUICK_ENTRY(jboolean, JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrupted)) | |
2955 JVMWrapper("JVM_IsInterrupted"); | |
2956 | |
2957 // Ensure that the C++ Thread and OSThread structures aren't freed before we operate | |
2958 oop java_thread = JNIHandles::resolve_non_null(jthread); | |
2959 MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock); | |
2960 // We need to re-resolve the java_thread, since a GC might have happened during the | |
2961 // acquire of the lock | |
2962 JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)); | |
2963 if (thr == NULL) { | |
2964 return JNI_FALSE; | |
2965 } else { | |
2966 return (jboolean) Thread::is_interrupted(thr, clear_interrupted != 0); | |
2967 } | |
2968 JVM_END | |
2969 | |
2970 | |
2971 // Return true iff the current thread has locked the object passed in | |
2972 | |
2973 JVM_ENTRY(jboolean, JVM_HoldsLock(JNIEnv* env, jclass threadClass, jobject obj)) | |
2974 JVMWrapper("JVM_HoldsLock"); | |
2975 assert(THREAD->is_Java_thread(), "sanity check"); | |
2976 if (obj == NULL) { | |
2977 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE); | |
2978 } | |
2979 Handle h_obj(THREAD, JNIHandles::resolve(obj)); | |
2980 return ObjectSynchronizer::current_thread_holds_lock((JavaThread*)THREAD, h_obj); | |
2981 JVM_END | |
2982 | |
2983 | |
2984 JVM_ENTRY(void, JVM_DumpAllStacks(JNIEnv* env, jclass)) | |
2985 JVMWrapper("JVM_DumpAllStacks"); | |
2986 VM_PrintThreads op; | |
2987 VMThread::execute(&op); | |
2988 if (JvmtiExport::should_post_data_dump()) { | |
2989 JvmtiExport::post_data_dump(); | |
2990 } | |
2991 JVM_END | |
2992 | |
2993 | |
2994 // java.lang.SecurityManager /////////////////////////////////////////////////////////////////////// | |
2995 | |
2996 static bool is_trusted_frame(JavaThread* jthread, vframeStream* vfst) { | |
2997 assert(jthread->is_Java_thread(), "must be a Java thread"); | |
2998 if (jthread->privileged_stack_top() == NULL) return false; | |
2999 if (jthread->privileged_stack_top()->frame_id() == vfst->frame_id()) { | |
3000 oop loader = jthread->privileged_stack_top()->class_loader(); | |
3001 if (loader == NULL) return true; | |
3002 bool trusted = java_lang_ClassLoader::is_trusted_loader(loader); | |
3003 if (trusted) return true; | |
3004 } | |
3005 return false; | |
3006 } | |
3007 | |
3008 JVM_ENTRY(jclass, JVM_CurrentLoadedClass(JNIEnv *env)) | |
3009 JVMWrapper("JVM_CurrentLoadedClass"); | |
3010 ResourceMark rm(THREAD); | |
3011 | |
3012 for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) { | |
3013 // if a method in a class in a trusted loader is in a doPrivileged, return NULL | |
3014 bool trusted = is_trusted_frame(thread, &vfst); | |
3015 if (trusted) return NULL; | |
3016 | |
3017 methodOop m = vfst.method(); | |
3018 if (!m->is_native()) { | |
3019 klassOop holder = m->method_holder(); | |
3020 oop loader = instanceKlass::cast(holder)->class_loader(); | |
3021 if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) { | |
3022 return (jclass) JNIHandles::make_local(env, Klass::cast(holder)->java_mirror()); | |
3023 } | |
3024 } | |
3025 } | |
3026 return NULL; | |
3027 JVM_END | |
3028 | |
3029 | |
3030 JVM_ENTRY(jobject, JVM_CurrentClassLoader(JNIEnv *env)) | |
3031 JVMWrapper("JVM_CurrentClassLoader"); | |
3032 ResourceMark rm(THREAD); | |
3033 | |
3034 for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) { | |
3035 | |
3036 // if a method in a class in a trusted loader is in a doPrivileged, return NULL | |
3037 bool trusted = is_trusted_frame(thread, &vfst); | |
3038 if (trusted) return NULL; | |
3039 | |
3040 methodOop m = vfst.method(); | |
3041 if (!m->is_native()) { | |
3042 klassOop holder = m->method_holder(); | |
3043 assert(holder->is_klass(), "just checking"); | |
3044 oop loader = instanceKlass::cast(holder)->class_loader(); | |
3045 if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) { | |
3046 return JNIHandles::make_local(env, loader); | |
3047 } | |
3048 } | |
3049 } | |
3050 return NULL; | |
3051 JVM_END | |
3052 | |
3053 | |
3054 // Utility object for collecting method holders walking down the stack | |
3055 class KlassLink: public ResourceObj { | |
3056 public: | |
3057 KlassHandle klass; | |
3058 KlassLink* next; | |
3059 | |
3060 KlassLink(KlassHandle k) { klass = k; next = NULL; } | |
3061 }; | |
3062 | |
3063 | |
3064 JVM_ENTRY(jobjectArray, JVM_GetClassContext(JNIEnv *env)) | |
3065 JVMWrapper("JVM_GetClassContext"); | |
3066 ResourceMark rm(THREAD); | |
3067 JvmtiVMObjectAllocEventCollector oam; | |
3068 // Collect linked list of (handles to) method holders | |
3069 KlassLink* first = NULL; | |
3070 KlassLink* last = NULL; | |
3071 int depth = 0; | |
3072 | |
3073 for(vframeStream vfst(thread); !vfst.at_end(); vfst.security_get_caller_frame(1)) { | |
3074 // Native frames are not returned | |
3075 if (!vfst.method()->is_native()) { | |
3076 klassOop holder = vfst.method()->method_holder(); | |
3077 assert(holder->is_klass(), "just checking"); | |
3078 depth++; | |
3079 KlassLink* l = new KlassLink(KlassHandle(thread, holder)); | |
3080 if (first == NULL) { | |
3081 first = last = l; | |
3082 } else { | |
3083 last->next = l; | |
3084 last = l; | |
3085 } | |
3086 } | |
3087 } | |
3088 | |
3089 // Create result array of type [Ljava/lang/Class; | |
1142 | 3090 objArrayOop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), depth, CHECK_NULL); |
0 | 3091 // Fill in mirrors corresponding to method holders |
3092 int index = 0; | |
3093 while (first != NULL) { | |
3094 result->obj_at_put(index++, Klass::cast(first->klass())->java_mirror()); | |
3095 first = first->next; | |
3096 } | |
3097 assert(index == depth, "just checking"); | |
3098 | |
3099 return (jobjectArray) JNIHandles::make_local(env, result); | |
3100 JVM_END | |
3101 | |
3102 | |
3103 JVM_ENTRY(jint, JVM_ClassDepth(JNIEnv *env, jstring name)) | |
3104 JVMWrapper("JVM_ClassDepth"); | |
3105 ResourceMark rm(THREAD); | |
3106 Handle h_name (THREAD, JNIHandles::resolve_non_null(name)); | |
3107 Handle class_name_str = java_lang_String::internalize_classname(h_name, CHECK_0); | |
3108 | |
3109 const char* str = java_lang_String::as_utf8_string(class_name_str()); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
3110 TempNewSymbol class_name_sym = SymbolTable::probe(str, (int)strlen(str)); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
3111 if (class_name_sym == NULL) { |
0 | 3112 return -1; |
3113 } | |
3114 | |
3115 int depth = 0; | |
3116 | |
3117 for(vframeStream vfst(thread); !vfst.at_end(); vfst.next()) { | |
3118 if (!vfst.method()->is_native()) { | |
3119 klassOop holder = vfst.method()->method_holder(); | |
3120 assert(holder->is_klass(), "just checking"); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
3121 if (instanceKlass::cast(holder)->name() == class_name_sym) { |
0 | 3122 return depth; |
3123 } | |
3124 depth++; | |
3125 } | |
3126 } | |
3127 return -1; | |
3128 JVM_END | |
3129 | |
3130 | |
3131 JVM_ENTRY(jint, JVM_ClassLoaderDepth(JNIEnv *env)) | |
3132 JVMWrapper("JVM_ClassLoaderDepth"); | |
3133 ResourceMark rm(THREAD); | |
3134 int depth = 0; | |
3135 for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) { | |
3136 // if a method in a class in a trusted loader is in a doPrivileged, return -1 | |
3137 bool trusted = is_trusted_frame(thread, &vfst); | |
3138 if (trusted) return -1; | |
3139 | |
3140 methodOop m = vfst.method(); | |
3141 if (!m->is_native()) { | |
3142 klassOop holder = m->method_holder(); | |
3143 assert(holder->is_klass(), "just checking"); | |
3144 oop loader = instanceKlass::cast(holder)->class_loader(); | |
3145 if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) { | |
3146 return depth; | |
3147 } | |
3148 depth++; | |
3149 } | |
3150 } | |
3151 return -1; | |
3152 JVM_END | |
3153 | |
3154 | |
3155 // java.lang.Package //////////////////////////////////////////////////////////////// | |
3156 | |
3157 | |
3158 JVM_ENTRY(jstring, JVM_GetSystemPackage(JNIEnv *env, jstring name)) | |
3159 JVMWrapper("JVM_GetSystemPackage"); | |
3160 ResourceMark rm(THREAD); | |
3161 JvmtiVMObjectAllocEventCollector oam; | |
3162 char* str = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name)); | |
3163 oop result = ClassLoader::get_system_package(str, CHECK_NULL); | |
3164 return (jstring) JNIHandles::make_local(result); | |
3165 JVM_END | |
3166 | |
3167 | |
3168 JVM_ENTRY(jobjectArray, JVM_GetSystemPackages(JNIEnv *env)) | |
3169 JVMWrapper("JVM_GetSystemPackages"); | |
3170 JvmtiVMObjectAllocEventCollector oam; | |
3171 objArrayOop result = ClassLoader::get_system_packages(CHECK_NULL); | |
3172 return (jobjectArray) JNIHandles::make_local(result); | |
3173 JVM_END | |
3174 | |
3175 | |
3176 // ObjectInputStream /////////////////////////////////////////////////////////////// | |
3177 | |
3178 bool force_verify_field_access(klassOop current_class, klassOop field_class, AccessFlags access, bool classloader_only) { | |
3179 if (current_class == NULL) { | |
3180 return true; | |
3181 } | |
3182 if ((current_class == field_class) || access.is_public()) { | |
3183 return true; | |
3184 } | |
3185 | |
3186 if (access.is_protected()) { | |
3187 // See if current_class is a subclass of field_class | |
3188 if (Klass::cast(current_class)->is_subclass_of(field_class)) { | |
3189 return true; | |
3190 } | |
3191 } | |
3192 | |
3193 return (!access.is_private() && instanceKlass::cast(current_class)->is_same_class_package(field_class)); | |
3194 } | |
3195 | |
3196 | |
3197 // JVM_AllocateNewObject and JVM_AllocateNewArray are unused as of 1.4 | |
3198 JVM_ENTRY(jobject, JVM_AllocateNewObject(JNIEnv *env, jobject receiver, jclass currClass, jclass initClass)) | |
3199 JVMWrapper("JVM_AllocateNewObject"); | |
3200 JvmtiVMObjectAllocEventCollector oam; | |
3201 // Receiver is not used | |
3202 oop curr_mirror = JNIHandles::resolve_non_null(currClass); | |
3203 oop init_mirror = JNIHandles::resolve_non_null(initClass); | |
3204 | |
3205 // Cannot instantiate primitive types | |
3206 if (java_lang_Class::is_primitive(curr_mirror) || java_lang_Class::is_primitive(init_mirror)) { | |
3207 ResourceMark rm(THREAD); | |
3208 THROW_0(vmSymbols::java_lang_InvalidClassException()); | |
3209 } | |
3210 | |
3211 // Arrays not allowed here, must use JVM_AllocateNewArray | |
3212 if (Klass::cast(java_lang_Class::as_klassOop(curr_mirror))->oop_is_javaArray() || | |
3213 Klass::cast(java_lang_Class::as_klassOop(init_mirror))->oop_is_javaArray()) { | |
3214 ResourceMark rm(THREAD); | |
3215 THROW_0(vmSymbols::java_lang_InvalidClassException()); | |
3216 } | |
3217 | |
3218 instanceKlassHandle curr_klass (THREAD, java_lang_Class::as_klassOop(curr_mirror)); | |
3219 instanceKlassHandle init_klass (THREAD, java_lang_Class::as_klassOop(init_mirror)); | |
3220 | |
3221 assert(curr_klass->is_subclass_of(init_klass()), "just checking"); | |
3222 | |
3223 // Interfaces, abstract classes, and java.lang.Class classes cannot be instantiated directly. | |
3224 curr_klass->check_valid_for_instantiation(false, CHECK_NULL); | |
3225 | |
3226 // Make sure klass is initialized, since we are about to instantiate one of them. | |
3227 curr_klass->initialize(CHECK_NULL); | |
3228 | |
3229 methodHandle m (THREAD, | |
3230 init_klass->find_method(vmSymbols::object_initializer_name(), | |
3231 vmSymbols::void_method_signature())); | |
3232 if (m.is_null()) { | |
3233 ResourceMark rm(THREAD); | |
3234 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), | |
3235 methodOopDesc::name_and_sig_as_C_string(Klass::cast(init_klass()), | |
3236 vmSymbols::object_initializer_name(), | |
3237 vmSymbols::void_method_signature())); | |
3238 } | |
3239 | |
3240 if (curr_klass == init_klass && !m->is_public()) { | |
3241 // Calling the constructor for class 'curr_klass'. | |
3242 // Only allow calls to a public no-arg constructor. | |
3243 // This path corresponds to creating an Externalizable object. | |
3244 THROW_0(vmSymbols::java_lang_IllegalAccessException()); | |
3245 } | |
3246 | |
3247 if (!force_verify_field_access(curr_klass(), init_klass(), m->access_flags(), false)) { | |
3248 // subclass 'curr_klass' does not have access to no-arg constructor of 'initcb' | |
3249 THROW_0(vmSymbols::java_lang_IllegalAccessException()); | |
3250 } | |
3251 | |
3252 Handle obj = curr_klass->allocate_instance_handle(CHECK_NULL); | |
3253 // Call constructor m. This might call a constructor higher up in the hierachy | |
3254 JavaCalls::call_default_constructor(thread, m, obj, CHECK_NULL); | |
3255 | |
3256 return JNIHandles::make_local(obj()); | |
3257 JVM_END | |
3258 | |
3259 | |
3260 JVM_ENTRY(jobject, JVM_AllocateNewArray(JNIEnv *env, jobject obj, jclass currClass, jint length)) | |
3261 JVMWrapper("JVM_AllocateNewArray"); | |
3262 JvmtiVMObjectAllocEventCollector oam; | |
3263 oop mirror = JNIHandles::resolve_non_null(currClass); | |
3264 | |
3265 if (java_lang_Class::is_primitive(mirror)) { | |
3266 THROW_0(vmSymbols::java_lang_InvalidClassException()); | |
3267 } | |
3268 klassOop k = java_lang_Class::as_klassOop(mirror); | |
3269 oop result; | |
3270 | |
3271 if (k->klass_part()->oop_is_typeArray()) { | |
3272 // typeArray | |
3273 result = typeArrayKlass::cast(k)->allocate(length, CHECK_NULL); | |
3274 } else if (k->klass_part()->oop_is_objArray()) { | |
3275 // objArray | |
3276 objArrayKlassHandle oak(THREAD, k); | |
3277 oak->initialize(CHECK_NULL); // make sure class is initialized (matches Classic VM behavior) | |
3278 result = oak->allocate(length, CHECK_NULL); | |
3279 } else { | |
3280 THROW_0(vmSymbols::java_lang_InvalidClassException()); | |
3281 } | |
3282 return JNIHandles::make_local(env, result); | |
3283 JVM_END | |
3284 | |
3285 | |
3286 // Return the first non-null class loader up the execution stack, or null | |
3287 // if only code from the null class loader is on the stack. | |
3288 | |
3289 JVM_ENTRY(jobject, JVM_LatestUserDefinedLoader(JNIEnv *env)) | |
3290 for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) { | |
3291 // UseNewReflection | |
3292 vfst.skip_reflection_related_frames(); // Only needed for 1.4 reflection | |
3293 klassOop holder = vfst.method()->method_holder(); | |
3294 oop loader = instanceKlass::cast(holder)->class_loader(); | |
3295 if (loader != NULL) { | |
3296 return JNIHandles::make_local(env, loader); | |
3297 } | |
3298 } | |
3299 return NULL; | |
3300 JVM_END | |
3301 | |
3302 | |
3303 // Load a class relative to the most recent class on the stack with a non-null | |
3304 // classloader. | |
3305 // This function has been deprecated and should not be considered part of the | |
3306 // specified JVM interface. | |
3307 | |
3308 JVM_ENTRY(jclass, JVM_LoadClass0(JNIEnv *env, jobject receiver, | |
3309 jclass currClass, jstring currClassName)) | |
3310 JVMWrapper("JVM_LoadClass0"); | |
3311 // Receiver is not used | |
3312 ResourceMark rm(THREAD); | |
3313 | |
3314 // Class name argument is not guaranteed to be in internal format | |
3315 Handle classname (THREAD, JNIHandles::resolve_non_null(currClassName)); | |
3316 Handle string = java_lang_String::internalize_classname(classname, CHECK_NULL); | |
3317 | |
3318 const char* str = java_lang_String::as_utf8_string(string()); | |
3319 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
3320 if (str == NULL || (int)strlen(str) > Symbol::max_length()) { |
0 | 3321 // It's impossible to create this class; the name cannot fit |
3322 // into the constant pool. | |
3323 THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), str); | |
3324 } | |
3325 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
3326 TempNewSymbol name = SymbolTable::new_symbol(str, CHECK_NULL); |
0 | 3327 Handle curr_klass (THREAD, JNIHandles::resolve(currClass)); |
3328 // Find the most recent class on the stack with a non-null classloader | |
3329 oop loader = NULL; | |
3330 oop protection_domain = NULL; | |
3331 if (curr_klass.is_null()) { | |
3332 for (vframeStream vfst(thread); | |
3333 !vfst.at_end() && loader == NULL; | |
3334 vfst.next()) { | |
3335 if (!vfst.method()->is_native()) { | |
3336 klassOop holder = vfst.method()->method_holder(); | |
3337 loader = instanceKlass::cast(holder)->class_loader(); | |
3338 protection_domain = instanceKlass::cast(holder)->protection_domain(); | |
3339 } | |
3340 } | |
3341 } else { | |
3342 klassOop curr_klass_oop = java_lang_Class::as_klassOop(curr_klass()); | |
3343 loader = instanceKlass::cast(curr_klass_oop)->class_loader(); | |
3344 protection_domain = instanceKlass::cast(curr_klass_oop)->protection_domain(); | |
3345 } | |
3346 Handle h_loader(THREAD, loader); | |
3347 Handle h_prot (THREAD, protection_domain); | |
657
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
3348 jclass result = find_class_from_class_loader(env, name, true, h_loader, h_prot, |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
3349 false, thread); |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
3350 if (TraceClassResolution && result != NULL) { |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
3351 trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result))); |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
3352 } |
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
579
diff
changeset
|
3353 return result; |
0 | 3354 JVM_END |
3355 | |
3356 | |
3357 // Array /////////////////////////////////////////////////////////////////////////////////////////// | |
3358 | |
3359 | |
3360 // resolve array handle and check arguments | |
3361 static inline arrayOop check_array(JNIEnv *env, jobject arr, bool type_array_only, TRAPS) { | |
3362 if (arr == NULL) { | |
3363 THROW_0(vmSymbols::java_lang_NullPointerException()); | |
3364 } | |
3365 oop a = JNIHandles::resolve_non_null(arr); | |
3366 if (!a->is_javaArray() || (type_array_only && !a->is_typeArray())) { | |
3367 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Argument is not an array"); | |
3368 } | |
3369 return arrayOop(a); | |
3370 } | |
3371 | |
3372 | |
3373 JVM_ENTRY(jint, JVM_GetArrayLength(JNIEnv *env, jobject arr)) | |
3374 JVMWrapper("JVM_GetArrayLength"); | |
3375 arrayOop a = check_array(env, arr, false, CHECK_0); | |
3376 return a->length(); | |
3377 JVM_END | |
3378 | |
3379 | |
3380 JVM_ENTRY(jobject, JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index)) | |
3381 JVMWrapper("JVM_Array_Get"); | |
3382 JvmtiVMObjectAllocEventCollector oam; | |
3383 arrayOop a = check_array(env, arr, false, CHECK_NULL); | |
3384 jvalue value; | |
3385 BasicType type = Reflection::array_get(&value, a, index, CHECK_NULL); | |
3386 oop box = Reflection::box(&value, type, CHECK_NULL); | |
3387 return JNIHandles::make_local(env, box); | |
3388 JVM_END | |
3389 | |
3390 | |
3391 JVM_ENTRY(jvalue, JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint wCode)) | |
3392 JVMWrapper("JVM_GetPrimitiveArrayElement"); | |
3393 jvalue value; | |
3394 value.i = 0; // to initialize value before getting used in CHECK | |
3395 arrayOop a = check_array(env, arr, true, CHECK_(value)); | |
3396 assert(a->is_typeArray(), "just checking"); | |
3397 BasicType type = Reflection::array_get(&value, a, index, CHECK_(value)); | |
3398 BasicType wide_type = (BasicType) wCode; | |
3399 if (type != wide_type) { | |
3400 Reflection::widen(&value, type, wide_type, CHECK_(value)); | |
3401 } | |
3402 return value; | |
3403 JVM_END | |
3404 | |
3405 | |
3406 JVM_ENTRY(void, JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val)) | |
3407 JVMWrapper("JVM_SetArrayElement"); | |
3408 arrayOop a = check_array(env, arr, false, CHECK); | |
3409 oop box = JNIHandles::resolve(val); | |
3410 jvalue value; | |
3411 value.i = 0; // to initialize value before getting used in CHECK | |
3412 BasicType value_type; | |
3413 if (a->is_objArray()) { | |
3414 // Make sure we do no unbox e.g. java/lang/Integer instances when storing into an object array | |
3415 value_type = Reflection::unbox_for_regular_object(box, &value); | |
3416 } else { | |
3417 value_type = Reflection::unbox_for_primitive(box, &value, CHECK); | |
3418 } | |
3419 Reflection::array_set(&value, a, index, value_type, CHECK); | |
3420 JVM_END | |
3421 | |
3422 | |
3423 JVM_ENTRY(void, JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v, unsigned char vCode)) | |
3424 JVMWrapper("JVM_SetPrimitiveArrayElement"); | |
3425 arrayOop a = check_array(env, arr, true, CHECK); | |
3426 assert(a->is_typeArray(), "just checking"); | |
3427 BasicType value_type = (BasicType) vCode; | |
3428 Reflection::array_set(&v, a, index, value_type, CHECK); | |
3429 JVM_END | |
3430 | |
3431 | |
3432 JVM_ENTRY(jobject, JVM_NewArray(JNIEnv *env, jclass eltClass, jint length)) | |
3433 JVMWrapper("JVM_NewArray"); | |
3434 JvmtiVMObjectAllocEventCollector oam; | |
3435 oop element_mirror = JNIHandles::resolve(eltClass); | |
3436 oop result = Reflection::reflect_new_array(element_mirror, length, CHECK_NULL); | |
3437 return JNIHandles::make_local(env, result); | |
3438 JVM_END | |
3439 | |
3440 | |
3441 JVM_ENTRY(jobject, JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim)) | |
3442 JVMWrapper("JVM_NewMultiArray"); | |
3443 JvmtiVMObjectAllocEventCollector oam; | |
3444 arrayOop dim_array = check_array(env, dim, true, CHECK_NULL); | |
3445 oop element_mirror = JNIHandles::resolve(eltClass); | |
3446 assert(dim_array->is_typeArray(), "just checking"); | |
3447 oop result = Reflection::reflect_new_multi_array(element_mirror, typeArrayOop(dim_array), CHECK_NULL); | |
3448 return JNIHandles::make_local(env, result); | |
3449 JVM_END | |
3450 | |
3451 | |
3452 // Networking library support //////////////////////////////////////////////////////////////////// | |
3453 | |
3454 JVM_LEAF(jint, JVM_InitializeSocketLibrary()) | |
3455 JVMWrapper("JVM_InitializeSocketLibrary"); | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3456 return 0; |
0 | 3457 JVM_END |
3458 | |
3459 | |
3460 JVM_LEAF(jint, JVM_Socket(jint domain, jint type, jint protocol)) | |
3461 JVMWrapper("JVM_Socket"); | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3462 return os::socket(domain, type, protocol); |
0 | 3463 JVM_END |
3464 | |
3465 | |
3466 JVM_LEAF(jint, JVM_SocketClose(jint fd)) | |
3467 JVMWrapper2("JVM_SocketClose (0x%x)", fd); | |
3468 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3469 return os::socket_close(fd); |
0 | 3470 JVM_END |
3471 | |
3472 | |
3473 JVM_LEAF(jint, JVM_SocketShutdown(jint fd, jint howto)) | |
3474 JVMWrapper2("JVM_SocketShutdown (0x%x)", fd); | |
3475 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3476 return os::socket_shutdown(fd, howto); |
0 | 3477 JVM_END |
3478 | |
3479 | |
3480 JVM_LEAF(jint, JVM_Recv(jint fd, char *buf, jint nBytes, jint flags)) | |
3481 JVMWrapper2("JVM_Recv (0x%x)", fd); | |
3482 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3483 return os::recv(fd, buf, nBytes, flags); |
0 | 3484 JVM_END |
3485 | |
3486 | |
3487 JVM_LEAF(jint, JVM_Send(jint fd, char *buf, jint nBytes, jint flags)) | |
3488 JVMWrapper2("JVM_Send (0x%x)", fd); | |
3489 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3490 return os::send(fd, buf, nBytes, flags); |
0 | 3491 JVM_END |
3492 | |
3493 | |
3494 JVM_LEAF(jint, JVM_Timeout(int fd, long timeout)) | |
3495 JVMWrapper2("JVM_Timeout (0x%x)", fd); | |
3496 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3497 return os::timeout(fd, timeout); |
0 | 3498 JVM_END |
3499 | |
3500 | |
3501 JVM_LEAF(jint, JVM_Listen(jint fd, jint count)) | |
3502 JVMWrapper2("JVM_Listen (0x%x)", fd); | |
3503 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3504 return os::listen(fd, count); |
0 | 3505 JVM_END |
3506 | |
3507 | |
3508 JVM_LEAF(jint, JVM_Connect(jint fd, struct sockaddr *him, jint len)) | |
3509 JVMWrapper2("JVM_Connect (0x%x)", fd); | |
3510 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3511 return os::connect(fd, him, len); |
0 | 3512 JVM_END |
3513 | |
3514 | |
3515 JVM_LEAF(jint, JVM_Bind(jint fd, struct sockaddr *him, jint len)) | |
3516 JVMWrapper2("JVM_Bind (0x%x)", fd); | |
3517 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3518 return os::bind(fd, him, len); |
0 | 3519 JVM_END |
3520 | |
3521 | |
3522 JVM_LEAF(jint, JVM_Accept(jint fd, struct sockaddr *him, jint *len)) | |
3523 JVMWrapper2("JVM_Accept (0x%x)", fd); | |
3524 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3525 return os::accept(fd, him, (int *)len); |
0 | 3526 JVM_END |
3527 | |
3528 | |
3529 JVM_LEAF(jint, JVM_RecvFrom(jint fd, char *buf, int nBytes, int flags, struct sockaddr *from, int *fromlen)) | |
3530 JVMWrapper2("JVM_RecvFrom (0x%x)", fd); | |
3531 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3532 return os::recvfrom(fd, buf, nBytes, flags, from, fromlen); |
0 | 3533 JVM_END |
3534 | |
3535 | |
3536 JVM_LEAF(jint, JVM_GetSockName(jint fd, struct sockaddr *him, int *len)) | |
3537 JVMWrapper2("JVM_GetSockName (0x%x)", fd); | |
3538 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3539 return os::get_sock_name(fd, him, len); |
0 | 3540 JVM_END |
3541 | |
3542 | |
3543 JVM_LEAF(jint, JVM_SendTo(jint fd, char *buf, int len, int flags, struct sockaddr *to, int tolen)) | |
3544 JVMWrapper2("JVM_SendTo (0x%x)", fd); | |
3545 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3546 return os::sendto(fd, buf, len, flags, to, tolen); |
0 | 3547 JVM_END |
3548 | |
3549 | |
3550 JVM_LEAF(jint, JVM_SocketAvailable(jint fd, jint *pbytes)) | |
3551 JVMWrapper2("JVM_SocketAvailable (0x%x)", fd); | |
3552 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3553 return os::socket_available(fd, pbytes); |
0 | 3554 JVM_END |
3555 | |
3556 | |
3557 JVM_LEAF(jint, JVM_GetSockOpt(jint fd, int level, int optname, char *optval, int *optlen)) | |
3558 JVMWrapper2("JVM_GetSockOpt (0x%x)", fd); | |
3559 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3560 return os::get_sock_opt(fd, level, optname, optval, optlen); |
0 | 3561 JVM_END |
3562 | |
3563 | |
3564 JVM_LEAF(jint, JVM_SetSockOpt(jint fd, int level, int optname, const char *optval, int optlen)) | |
3565 JVMWrapper2("JVM_GetSockOpt (0x%x)", fd); | |
3566 //%note jvm_r6 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3567 return os::set_sock_opt(fd, level, optname, optval, optlen); |
0 | 3568 JVM_END |
3569 | |
3570 JVM_LEAF(int, JVM_GetHostName(char* name, int namelen)) | |
3571 JVMWrapper("JVM_GetHostName"); | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3572 return os::get_host_name(name, namelen); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3573 JVM_END |
0 | 3574 |
3575 // Library support /////////////////////////////////////////////////////////////////////////// | |
3576 | |
3577 JVM_ENTRY_NO_ENV(void*, JVM_LoadLibrary(const char* name)) | |
3578 //%note jvm_ct | |
3579 JVMWrapper2("JVM_LoadLibrary (%s)", name); | |
3580 char ebuf[1024]; | |
3581 void *load_result; | |
3582 { | |
3583 ThreadToNativeFromVM ttnfvm(thread); | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3584 load_result = os::dll_load(name, ebuf, sizeof ebuf); |
0 | 3585 } |
3586 if (load_result == NULL) { | |
3587 char msg[1024]; | |
3588 jio_snprintf(msg, sizeof msg, "%s: %s", name, ebuf); | |
3589 // Since 'ebuf' may contain a string encoded using | |
3590 // platform encoding scheme, we need to pass | |
3591 // Exceptions::unsafe_to_utf8 to the new_exception method | |
3592 // as the last argument. See bug 6367357. | |
3593 Handle h_exception = | |
3594 Exceptions::new_exception(thread, | |
3595 vmSymbols::java_lang_UnsatisfiedLinkError(), | |
3596 msg, Exceptions::unsafe_to_utf8); | |
3597 | |
3598 THROW_HANDLE_0(h_exception); | |
3599 } | |
3600 return load_result; | |
3601 JVM_END | |
3602 | |
3603 | |
3604 JVM_LEAF(void, JVM_UnloadLibrary(void* handle)) | |
3605 JVMWrapper("JVM_UnloadLibrary"); | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3606 os::dll_unload(handle); |
0 | 3607 JVM_END |
3608 | |
3609 | |
3610 JVM_LEAF(void*, JVM_FindLibraryEntry(void* handle, const char* name)) | |
3611 JVMWrapper2("JVM_FindLibraryEntry (%s)", name); | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
3612 return os::dll_lookup(handle, name); |
0 | 3613 JVM_END |
3614 | |
3615 // Floating point support //////////////////////////////////////////////////////////////////// | |
3616 | |
3617 JVM_LEAF(jboolean, JVM_IsNaN(jdouble a)) | |
3618 JVMWrapper("JVM_IsNaN"); | |
3619 return g_isnan(a); | |
3620 JVM_END | |
3621 | |
3622 | |
3623 | |
3624 // JNI version /////////////////////////////////////////////////////////////////////////////// | |
3625 | |
3626 JVM_LEAF(jboolean, JVM_IsSupportedJNIVersion(jint version)) | |
3627 JVMWrapper2("JVM_IsSupportedJNIVersion (%d)", version); | |
3628 return Threads::is_supported_jni_version_including_1_1(version); | |
3629 JVM_END | |
3630 | |
3631 | |
3632 // String support /////////////////////////////////////////////////////////////////////////// | |
3633 | |
3634 JVM_ENTRY(jstring, JVM_InternString(JNIEnv *env, jstring str)) | |
3635 JVMWrapper("JVM_InternString"); | |
3636 JvmtiVMObjectAllocEventCollector oam; | |
3637 if (str == NULL) return NULL; | |
3638 oop string = JNIHandles::resolve_non_null(str); | |
3639 oop result = StringTable::intern(string, CHECK_NULL); | |
3640 return (jstring) JNIHandles::make_local(env, result); | |
3641 JVM_END | |
3642 | |
3643 | |
3644 // Raw monitor support ////////////////////////////////////////////////////////////////////// | |
3645 | |
3646 // The lock routine below calls lock_without_safepoint_check in order to get a raw lock | |
3647 // without interfering with the safepoint mechanism. The routines are not JVM_LEAF because | |
3648 // they might be called by non-java threads. The JVM_LEAF installs a NoHandleMark check | |
3649 // that only works with java threads. | |
3650 | |
3651 | |
3652 JNIEXPORT void* JNICALL JVM_RawMonitorCreate(void) { | |
3653 VM_Exit::block_if_vm_exited(); | |
3654 JVMWrapper("JVM_RawMonitorCreate"); | |
3655 return new Mutex(Mutex::native, "JVM_RawMonitorCreate"); | |
3656 } | |
3657 | |
3658 | |
3659 JNIEXPORT void JNICALL JVM_RawMonitorDestroy(void *mon) { | |
3660 VM_Exit::block_if_vm_exited(); | |
3661 JVMWrapper("JVM_RawMonitorDestroy"); | |
3662 delete ((Mutex*) mon); | |
3663 } | |
3664 | |
3665 | |
3666 JNIEXPORT jint JNICALL JVM_RawMonitorEnter(void *mon) { | |
3667 VM_Exit::block_if_vm_exited(); | |
3668 JVMWrapper("JVM_RawMonitorEnter"); | |
3669 ((Mutex*) mon)->jvm_raw_lock(); | |
3670 return 0; | |
3671 } | |
3672 | |
3673 | |
3674 JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon) { | |
3675 VM_Exit::block_if_vm_exited(); | |
3676 JVMWrapper("JVM_RawMonitorExit"); | |
3677 ((Mutex*) mon)->jvm_raw_unlock(); | |
3678 } | |
3679 | |
3680 | |
3681 // Support for Serialization | |
3682 | |
3683 typedef jfloat (JNICALL *IntBitsToFloatFn )(JNIEnv* env, jclass cb, jint value); | |
3684 typedef jdouble (JNICALL *LongBitsToDoubleFn)(JNIEnv* env, jclass cb, jlong value); | |
3685 typedef jint (JNICALL *FloatToIntBitsFn )(JNIEnv* env, jclass cb, jfloat value); | |
3686 typedef jlong (JNICALL *DoubleToLongBitsFn)(JNIEnv* env, jclass cb, jdouble value); | |
3687 | |
3688 static IntBitsToFloatFn int_bits_to_float_fn = NULL; | |
3689 static LongBitsToDoubleFn long_bits_to_double_fn = NULL; | |
3690 static FloatToIntBitsFn float_to_int_bits_fn = NULL; | |
3691 static DoubleToLongBitsFn double_to_long_bits_fn = NULL; | |
3692 | |
3693 | |
3694 void initialize_converter_functions() { | |
3695 if (JDK_Version::is_gte_jdk14x_version()) { | |
3696 // These functions only exist for compatibility with 1.3.1 and earlier | |
3697 return; | |
3698 } | |
3699 | |
3700 // called from universe_post_init() | |
3701 assert( | |
3702 int_bits_to_float_fn == NULL && | |
3703 long_bits_to_double_fn == NULL && | |
3704 float_to_int_bits_fn == NULL && | |
3705 double_to_long_bits_fn == NULL , | |
3706 "initialization done twice" | |
3707 ); | |
3708 // initialize | |
3709 int_bits_to_float_fn = CAST_TO_FN_PTR(IntBitsToFloatFn , NativeLookup::base_library_lookup("java/lang/Float" , "intBitsToFloat" , "(I)F")); | |
3710 long_bits_to_double_fn = CAST_TO_FN_PTR(LongBitsToDoubleFn, NativeLookup::base_library_lookup("java/lang/Double", "longBitsToDouble", "(J)D")); | |
3711 float_to_int_bits_fn = CAST_TO_FN_PTR(FloatToIntBitsFn , NativeLookup::base_library_lookup("java/lang/Float" , "floatToIntBits" , "(F)I")); | |
3712 double_to_long_bits_fn = CAST_TO_FN_PTR(DoubleToLongBitsFn, NativeLookup::base_library_lookup("java/lang/Double", "doubleToLongBits", "(D)J")); | |
3713 // verify | |
3714 assert( | |
3715 int_bits_to_float_fn != NULL && | |
3716 long_bits_to_double_fn != NULL && | |
3717 float_to_int_bits_fn != NULL && | |
3718 double_to_long_bits_fn != NULL , | |
3719 "initialization failed" | |
3720 ); | |
3721 } | |
3722 | |
3723 | |
3724 // Serialization | |
3725 JVM_ENTRY(void, JVM_SetPrimitiveFieldValues(JNIEnv *env, jclass cb, jobject obj, | |
3726 jlongArray fieldIDs, jcharArray typecodes, jbyteArray data)) | |
3727 assert(!JDK_Version::is_gte_jdk14x_version(), "should only be used in 1.3.1 and earlier"); | |
3728 | |
3729 typeArrayOop tcodes = typeArrayOop(JNIHandles::resolve(typecodes)); | |
3730 typeArrayOop dbuf = typeArrayOop(JNIHandles::resolve(data)); | |
3731 typeArrayOop fids = typeArrayOop(JNIHandles::resolve(fieldIDs)); | |
3732 oop o = JNIHandles::resolve(obj); | |
3733 | |
3734 if (o == NULL || fids == NULL || dbuf == NULL || tcodes == NULL) { | |
3735 THROW(vmSymbols::java_lang_NullPointerException()); | |
3736 } | |
3737 | |
3738 jsize nfids = fids->length(); | |
3739 if (nfids == 0) return; | |
3740 | |
3741 if (tcodes->length() < nfids) { | |
3742 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); | |
3743 } | |
3744 | |
3745 jsize off = 0; | |
3746 /* loop through fields, setting values */ | |
3747 for (jsize i = 0; i < nfids; i++) { | |
3748 jfieldID fid = (jfieldID)(intptr_t) fids->long_at(i); | |
3749 int field_offset; | |
3750 if (fid != NULL) { | |
3751 // NULL is a legal value for fid, but retrieving the field offset | |
3752 // trigger assertion in that case | |
3753 field_offset = jfieldIDWorkaround::from_instance_jfieldID(o->klass(), fid); | |
3754 } | |
3755 | |
3756 switch (tcodes->char_at(i)) { | |
3757 case 'Z': | |
3758 if (fid != NULL) { | |
3759 jboolean val = (dbuf->byte_at(off) != 0) ? JNI_TRUE : JNI_FALSE; | |
3760 o->bool_field_put(field_offset, val); | |
3761 } | |
3762 off++; | |
3763 break; | |
3764 | |
3765 case 'B': | |
3766 if (fid != NULL) { | |
3767 o->byte_field_put(field_offset, dbuf->byte_at(off)); | |
3768 } | |
3769 off++; | |
3770 break; | |
3771 | |
3772 case 'C': | |
3773 if (fid != NULL) { | |
3774 jchar val = ((dbuf->byte_at(off + 0) & 0xFF) << 8) | |
3775 + ((dbuf->byte_at(off + 1) & 0xFF) << 0); | |
3776 o->char_field_put(field_offset, val); | |
3777 } | |
3778 off += 2; | |
3779 break; | |
3780 | |
3781 case 'S': | |
3782 if (fid != NULL) { | |
3783 jshort val = ((dbuf->byte_at(off + 0) & 0xFF) << 8) | |
3784 + ((dbuf->byte_at(off + 1) & 0xFF) << 0); | |
3785 o->short_field_put(field_offset, val); | |
3786 } | |
3787 off += 2; | |
3788 break; | |
3789 | |
3790 case 'I': | |
3791 if (fid != NULL) { | |
3792 jint ival = ((dbuf->byte_at(off + 0) & 0xFF) << 24) | |
3793 + ((dbuf->byte_at(off + 1) & 0xFF) << 16) | |
3794 + ((dbuf->byte_at(off + 2) & 0xFF) << 8) | |
3795 + ((dbuf->byte_at(off + 3) & 0xFF) << 0); | |
3796 o->int_field_put(field_offset, ival); | |
3797 } | |
3798 off += 4; | |
3799 break; | |
3800 | |
3801 case 'F': | |
3802 if (fid != NULL) { | |
3803 jint ival = ((dbuf->byte_at(off + 0) & 0xFF) << 24) | |
3804 + ((dbuf->byte_at(off + 1) & 0xFF) << 16) | |
3805 + ((dbuf->byte_at(off + 2) & 0xFF) << 8) | |
3806 + ((dbuf->byte_at(off + 3) & 0xFF) << 0); | |
3807 jfloat fval = (*int_bits_to_float_fn)(env, NULL, ival); | |
3808 o->float_field_put(field_offset, fval); | |
3809 } | |
3810 off += 4; | |
3811 break; | |
3812 | |
3813 case 'J': | |
3814 if (fid != NULL) { | |
3815 jlong lval = (((jlong) dbuf->byte_at(off + 0) & 0xFF) << 56) | |
3816 + (((jlong) dbuf->byte_at(off + 1) & 0xFF) << 48) | |
3817 + (((jlong) dbuf->byte_at(off + 2) & 0xFF) << 40) | |
3818 + (((jlong) dbuf->byte_at(off + 3) & 0xFF) << 32) | |
3819 + (((jlong) dbuf->byte_at(off + 4) & 0xFF) << 24) | |
3820 + (((jlong) dbuf->byte_at(off + 5) & 0xFF) << 16) | |
3821 + (((jlong) dbuf->byte_at(off + 6) & 0xFF) << 8) | |
3822 + (((jlong) dbuf->byte_at(off + 7) & 0xFF) << 0); | |
3823 o->long_field_put(field_offset, lval); | |
3824 } | |
3825 off += 8; | |
3826 break; | |
3827 | |
3828 case 'D': | |
3829 if (fid != NULL) { | |
3830 jlong lval = (((jlong) dbuf->byte_at(off + 0) & 0xFF) << 56) | |
3831 + (((jlong) dbuf->byte_at(off + 1) & 0xFF) << 48) | |
3832 + (((jlong) dbuf->byte_at(off + 2) & 0xFF) << 40) | |
3833 + (((jlong) dbuf->byte_at(off + 3) & 0xFF) << 32) | |
3834 + (((jlong) dbuf->byte_at(off + 4) & 0xFF) << 24) | |
3835 + (((jlong) dbuf->byte_at(off + 5) & 0xFF) << 16) | |
3836 + (((jlong) dbuf->byte_at(off + 6) & 0xFF) << 8) | |
3837 + (((jlong) dbuf->byte_at(off + 7) & 0xFF) << 0); | |
3838 jdouble dval = (*long_bits_to_double_fn)(env, NULL, lval); | |
3839 o->double_field_put(field_offset, dval); | |
3840 } | |
3841 off += 8; | |
3842 break; | |
3843 | |
3844 default: | |
3845 // Illegal typecode | |
3846 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "illegal typecode"); | |
3847 } | |
3848 } | |
3849 JVM_END | |
3850 | |
3851 | |
3852 JVM_ENTRY(void, JVM_GetPrimitiveFieldValues(JNIEnv *env, jclass cb, jobject obj, | |
3853 jlongArray fieldIDs, jcharArray typecodes, jbyteArray data)) | |
3854 assert(!JDK_Version::is_gte_jdk14x_version(), "should only be used in 1.3.1 and earlier"); | |
3855 | |
3856 typeArrayOop tcodes = typeArrayOop(JNIHandles::resolve(typecodes)); | |
3857 typeArrayOop dbuf = typeArrayOop(JNIHandles::resolve(data)); | |
3858 typeArrayOop fids = typeArrayOop(JNIHandles::resolve(fieldIDs)); | |
3859 oop o = JNIHandles::resolve(obj); | |
3860 | |
3861 if (o == NULL || fids == NULL || dbuf == NULL || tcodes == NULL) { | |
3862 THROW(vmSymbols::java_lang_NullPointerException()); | |
3863 } | |
3864 | |
3865 jsize nfids = fids->length(); | |
3866 if (nfids == 0) return; | |
3867 | |
3868 if (tcodes->length() < nfids) { | |
3869 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); | |
3870 } | |
3871 | |
3872 /* loop through fields, fetching values */ | |
3873 jsize off = 0; | |
3874 for (jsize i = 0; i < nfids; i++) { | |
3875 jfieldID fid = (jfieldID)(intptr_t) fids->long_at(i); | |
3876 if (fid == NULL) { | |
3877 THROW(vmSymbols::java_lang_NullPointerException()); | |
3878 } | |
3879 int field_offset = jfieldIDWorkaround::from_instance_jfieldID(o->klass(), fid); | |
3880 | |
3881 switch (tcodes->char_at(i)) { | |
3882 case 'Z': | |
3883 { | |
3884 jboolean val = o->bool_field(field_offset); | |
3885 dbuf->byte_at_put(off++, (val != 0) ? 1 : 0); | |
3886 } | |
3887 break; | |
3888 | |
3889 case 'B': | |
3890 dbuf->byte_at_put(off++, o->byte_field(field_offset)); | |
3891 break; | |
3892 | |
3893 case 'C': | |
3894 { | |
3895 jchar val = o->char_field(field_offset); | |
3896 dbuf->byte_at_put(off++, (val >> 8) & 0xFF); | |
3897 dbuf->byte_at_put(off++, (val >> 0) & 0xFF); | |
3898 } | |
3899 break; | |
3900 | |
3901 case 'S': | |
3902 { | |
3903 jshort val = o->short_field(field_offset); | |
3904 dbuf->byte_at_put(off++, (val >> 8) & 0xFF); | |
3905 dbuf->byte_at_put(off++, (val >> 0) & 0xFF); | |
3906 } | |
3907 break; | |
3908 | |
3909 case 'I': | |
3910 { | |
3911 jint val = o->int_field(field_offset); | |
3912 dbuf->byte_at_put(off++, (val >> 24) & 0xFF); | |
3913 dbuf->byte_at_put(off++, (val >> 16) & 0xFF); | |
3914 dbuf->byte_at_put(off++, (val >> 8) & 0xFF); | |
3915 dbuf->byte_at_put(off++, (val >> 0) & 0xFF); | |
3916 } | |
3917 break; | |
3918 | |
3919 case 'F': | |
3920 { | |
3921 jfloat fval = o->float_field(field_offset); | |
3922 jint ival = (*float_to_int_bits_fn)(env, NULL, fval); | |
3923 dbuf->byte_at_put(off++, (ival >> 24) & 0xFF); | |
3924 dbuf->byte_at_put(off++, (ival >> 16) & 0xFF); | |
3925 dbuf->byte_at_put(off++, (ival >> 8) & 0xFF); | |
3926 dbuf->byte_at_put(off++, (ival >> 0) & 0xFF); | |
3927 } | |
3928 break; | |
3929 | |
3930 case 'J': | |
3931 { | |
3932 jlong val = o->long_field(field_offset); | |
3933 dbuf->byte_at_put(off++, (val >> 56) & 0xFF); | |
3934 dbuf->byte_at_put(off++, (val >> 48) & 0xFF); | |
3935 dbuf->byte_at_put(off++, (val >> 40) & 0xFF); | |
3936 dbuf->byte_at_put(off++, (val >> 32) & 0xFF); | |
3937 dbuf->byte_at_put(off++, (val >> 24) & 0xFF); | |
3938 dbuf->byte_at_put(off++, (val >> 16) & 0xFF); | |
3939 dbuf->byte_at_put(off++, (val >> 8) & 0xFF); | |
3940 dbuf->byte_at_put(off++, (val >> 0) & 0xFF); | |
3941 } | |
3942 break; | |
3943 | |
3944 case 'D': | |
3945 { | |
3946 jdouble dval = o->double_field(field_offset); | |
3947 jlong lval = (*double_to_long_bits_fn)(env, NULL, dval); | |
3948 dbuf->byte_at_put(off++, (lval >> 56) & 0xFF); | |
3949 dbuf->byte_at_put(off++, (lval >> 48) & 0xFF); | |
3950 dbuf->byte_at_put(off++, (lval >> 40) & 0xFF); | |
3951 dbuf->byte_at_put(off++, (lval >> 32) & 0xFF); | |
3952 dbuf->byte_at_put(off++, (lval >> 24) & 0xFF); | |
3953 dbuf->byte_at_put(off++, (lval >> 16) & 0xFF); | |
3954 dbuf->byte_at_put(off++, (lval >> 8) & 0xFF); | |
3955 dbuf->byte_at_put(off++, (lval >> 0) & 0xFF); | |
3956 } | |
3957 break; | |
3958 | |
3959 default: | |
3960 // Illegal typecode | |
3961 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "illegal typecode"); | |
3962 } | |
3963 } | |
3964 JVM_END | |
3965 | |
3966 | |
3967 // Shared JNI/JVM entry points ////////////////////////////////////////////////////////////// | |
3968 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
3969 jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS) { |
0 | 3970 // Security Note: |
3971 // The Java level wrapper will perform the necessary security check allowing | |
3972 // us to pass the NULL as the initiating class loader. | |
3973 klassOop klass = SystemDictionary::resolve_or_fail(name, loader, protection_domain, throwError != 0, CHECK_NULL); | |
878
abe076e3636f
6864003: Modify JVM_FindClassFromBootLoader to return null if class not found
mchung
parents:
875
diff
changeset
|
3974 |
0 | 3975 KlassHandle klass_handle(THREAD, klass); |
3976 // Check if we should initialize the class | |
3977 if (init && klass_handle->oop_is_instance()) { | |
3978 klass_handle->initialize(CHECK_NULL); | |
3979 } | |
3980 return (jclass) JNIHandles::make_local(env, klass_handle->java_mirror()); | |
3981 } | |
3982 | |
3983 | |
3984 // Internal SQE debugging support /////////////////////////////////////////////////////////// | |
3985 | |
3986 #ifndef PRODUCT | |
3987 | |
3988 extern "C" { | |
3989 JNIEXPORT jboolean JNICALL JVM_AccessVMBooleanFlag(const char* name, jboolean* value, jboolean is_get); | |
3990 JNIEXPORT jboolean JNICALL JVM_AccessVMIntFlag(const char* name, jint* value, jboolean is_get); | |
3991 JNIEXPORT void JNICALL JVM_VMBreakPoint(JNIEnv *env, jobject obj); | |
3992 } | |
3993 | |
3994 JVM_LEAF(jboolean, JVM_AccessVMBooleanFlag(const char* name, jboolean* value, jboolean is_get)) | |
3995 JVMWrapper("JVM_AccessBoolVMFlag"); | |
3996 return is_get ? CommandLineFlags::boolAt((char*) name, (bool*) value) : CommandLineFlags::boolAtPut((char*) name, (bool*) value, INTERNAL); | |
3997 JVM_END | |
3998 | |
3999 JVM_LEAF(jboolean, JVM_AccessVMIntFlag(const char* name, jint* value, jboolean is_get)) | |
4000 JVMWrapper("JVM_AccessVMIntFlag"); | |
4001 intx v; | |
4002 jboolean result = is_get ? CommandLineFlags::intxAt((char*) name, &v) : CommandLineFlags::intxAtPut((char*) name, &v, INTERNAL); | |
4003 *value = (jint)v; | |
4004 return result; | |
4005 JVM_END | |
4006 | |
4007 | |
4008 JVM_ENTRY(void, JVM_VMBreakPoint(JNIEnv *env, jobject obj)) | |
4009 JVMWrapper("JVM_VMBreakPoint"); | |
4010 oop the_obj = JNIHandles::resolve(obj); | |
4011 BREAKPOINT; | |
4012 JVM_END | |
4013 | |
4014 | |
4015 #endif | |
4016 | |
4017 | |
4018 // Method /////////////////////////////////////////////////////////////////////////////////////////// | |
4019 | |
4020 JVM_ENTRY(jobject, JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0)) | |
4021 JVMWrapper("JVM_InvokeMethod"); | |
4022 Handle method_handle; | |
4023 if (thread->stack_available((address) &method_handle) >= JVMInvokeMethodSlack) { | |
4024 method_handle = Handle(THREAD, JNIHandles::resolve(method)); | |
4025 Handle receiver(THREAD, JNIHandles::resolve(obj)); | |
4026 objArrayHandle args(THREAD, objArrayOop(JNIHandles::resolve(args0))); | |
4027 oop result = Reflection::invoke_method(method_handle(), receiver, args, CHECK_NULL); | |
4028 jobject res = JNIHandles::make_local(env, result); | |
4029 if (JvmtiExport::should_post_vm_object_alloc()) { | |
4030 oop ret_type = java_lang_reflect_Method::return_type(method_handle()); | |
4031 assert(ret_type != NULL, "sanity check: ret_type oop must not be NULL!"); | |
4032 if (java_lang_Class::is_primitive(ret_type)) { | |
4033 // Only for primitive type vm allocates memory for java object. | |
4034 // See box() method. | |
4035 JvmtiExport::post_vm_object_alloc(JavaThread::current(), result); | |
4036 } | |
4037 } | |
4038 return res; | |
4039 } else { | |
4040 THROW_0(vmSymbols::java_lang_StackOverflowError()); | |
4041 } | |
4042 JVM_END | |
4043 | |
4044 | |
4045 JVM_ENTRY(jobject, JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args0)) | |
4046 JVMWrapper("JVM_NewInstanceFromConstructor"); | |
4047 oop constructor_mirror = JNIHandles::resolve(c); | |
4048 objArrayHandle args(THREAD, objArrayOop(JNIHandles::resolve(args0))); | |
4049 oop result = Reflection::invoke_constructor(constructor_mirror, args, CHECK_NULL); | |
4050 jobject res = JNIHandles::make_local(env, result); | |
4051 if (JvmtiExport::should_post_vm_object_alloc()) { | |
4052 JvmtiExport::post_vm_object_alloc(JavaThread::current(), result); | |
4053 } | |
4054 return res; | |
4055 JVM_END | |
4056 | |
4057 // Atomic /////////////////////////////////////////////////////////////////////////////////////////// | |
4058 | |
4059 JVM_LEAF(jboolean, JVM_SupportsCX8()) | |
4060 JVMWrapper("JVM_SupportsCX8"); | |
4061 return VM_Version::supports_cx8(); | |
4062 JVM_END | |
4063 | |
4064 | |
4065 JVM_ENTRY(jboolean, JVM_CX8Field(JNIEnv *env, jobject obj, jfieldID fid, jlong oldVal, jlong newVal)) | |
4066 JVMWrapper("JVM_CX8Field"); | |
4067 jlong res; | |
4068 oop o = JNIHandles::resolve(obj); | |
4069 intptr_t fldOffs = jfieldIDWorkaround::from_instance_jfieldID(o->klass(), fid); | |
4070 volatile jlong* addr = (volatile jlong*)((address)o + fldOffs); | |
4071 | |
4072 assert(VM_Version::supports_cx8(), "cx8 not supported"); | |
4073 res = Atomic::cmpxchg(newVal, addr, oldVal); | |
4074 | |
4075 return res == oldVal; | |
4076 JVM_END | |
4077 | |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4078 // DTrace /////////////////////////////////////////////////////////////////// |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4079 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4080 JVM_ENTRY(jint, JVM_DTraceGetVersion(JNIEnv* env)) |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4081 JVMWrapper("JVM_DTraceGetVersion"); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4082 return (jint)JVM_TRACING_DTRACE_VERSION; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4083 JVM_END |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4084 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4085 JVM_ENTRY(jlong,JVM_DTraceActivate( |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4086 JNIEnv* env, jint version, jstring module_name, jint providers_count, |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4087 JVM_DTraceProvider* providers)) |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4088 JVMWrapper("JVM_DTraceActivate"); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4089 return DTraceJSDT::activate( |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4090 version, module_name, providers_count, providers, CHECK_0); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4091 JVM_END |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4092 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4093 JVM_ENTRY(jboolean,JVM_DTraceIsProbeEnabled(JNIEnv* env, jmethodID method)) |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4094 JVMWrapper("JVM_DTraceIsProbeEnabled"); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4095 return DTraceJSDT::is_probe_enabled(method); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4096 JVM_END |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4097 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4098 JVM_ENTRY(void,JVM_DTraceDispose(JNIEnv* env, jlong handle)) |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4099 JVMWrapper("JVM_DTraceDispose"); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4100 DTraceJSDT::dispose(handle); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4101 JVM_END |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4102 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4103 JVM_ENTRY(jboolean,JVM_DTraceIsSupported(JNIEnv* env)) |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4104 JVMWrapper("JVM_DTraceIsSupported"); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4105 return DTraceJSDT::is_supported(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4106 JVM_END |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
4107 |
0 | 4108 // Returns an array of all live Thread objects (VM internal JavaThreads, |
4109 // jvmti agent threads, and JNI attaching threads are skipped) | |
4110 // See CR 6404306 regarding JNI attaching threads | |
4111 JVM_ENTRY(jobjectArray, JVM_GetAllThreads(JNIEnv *env, jclass dummy)) | |
4112 ResourceMark rm(THREAD); | |
4113 ThreadsListEnumerator tle(THREAD, false, false); | |
4114 JvmtiVMObjectAllocEventCollector oam; | |
4115 | |
4116 int num_threads = tle.num_threads(); | |
1142 | 4117 objArrayOop r = oopFactory::new_objArray(SystemDictionary::Thread_klass(), num_threads, CHECK_NULL); |
0 | 4118 objArrayHandle threads_ah(THREAD, r); |
4119 | |
4120 for (int i = 0; i < num_threads; i++) { | |
4121 Handle h = tle.get_threadObj(i); | |
4122 threads_ah->obj_at_put(i, h()); | |
4123 } | |
4124 | |
4125 return (jobjectArray) JNIHandles::make_local(env, threads_ah()); | |
4126 JVM_END | |
4127 | |
4128 | |
4129 // Support for java.lang.Thread.getStackTrace() and getAllStackTraces() methods | |
4130 // Return StackTraceElement[][], each element is the stack trace of a thread in | |
4131 // the corresponding entry in the given threads array | |
4132 JVM_ENTRY(jobjectArray, JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads)) | |
4133 JVMWrapper("JVM_DumpThreads"); | |
4134 JvmtiVMObjectAllocEventCollector oam; | |
4135 | |
4136 // Check if threads is null | |
4137 if (threads == NULL) { | |
4138 THROW_(vmSymbols::java_lang_NullPointerException(), 0); | |
4139 } | |
4140 | |
4141 objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(threads)); | |
4142 objArrayHandle ah(THREAD, a); | |
4143 int num_threads = ah->length(); | |
4144 // check if threads is non-empty array | |
4145 if (num_threads == 0) { | |
4146 THROW_(vmSymbols::java_lang_IllegalArgumentException(), 0); | |
4147 } | |
4148 | |
4149 // check if threads is not an array of objects of Thread class | |
4150 klassOop k = objArrayKlass::cast(ah->klass())->element_klass(); | |
1142 | 4151 if (k != SystemDictionary::Thread_klass()) { |
0 | 4152 THROW_(vmSymbols::java_lang_IllegalArgumentException(), 0); |
4153 } | |
4154 | |
4155 ResourceMark rm(THREAD); | |
4156 | |
4157 GrowableArray<instanceHandle>* thread_handle_array = new GrowableArray<instanceHandle>(num_threads); | |
4158 for (int i = 0; i < num_threads; i++) { | |
4159 oop thread_obj = ah->obj_at(i); | |
4160 instanceHandle h(THREAD, (instanceOop) thread_obj); | |
4161 thread_handle_array->append(h); | |
4162 } | |
4163 | |
4164 Handle stacktraces = ThreadService::dump_stack_traces(thread_handle_array, num_threads, CHECK_NULL); | |
4165 return (jobjectArray)JNIHandles::make_local(env, stacktraces()); | |
4166 | |
4167 JVM_END | |
4168 | |
4169 // JVM monitoring and management support | |
4170 JVM_ENTRY_NO_ENV(void*, JVM_GetManagement(jint version)) | |
4171 return Management::get_jmm_interface(version); | |
4172 JVM_END | |
4173 | |
4174 // com.sun.tools.attach.VirtualMachine agent properties support | |
4175 // | |
4176 // Initialize the agent properties with the properties maintained in the VM | |
4177 JVM_ENTRY(jobject, JVM_InitAgentProperties(JNIEnv *env, jobject properties)) | |
4178 JVMWrapper("JVM_InitAgentProperties"); | |
4179 ResourceMark rm; | |
4180 | |
4181 Handle props(THREAD, JNIHandles::resolve_non_null(properties)); | |
4182 | |
4183 PUTPROP(props, "sun.java.command", Arguments::java_command()); | |
4184 PUTPROP(props, "sun.jvm.flags", Arguments::jvm_flags()); | |
4185 PUTPROP(props, "sun.jvm.args", Arguments::jvm_args()); | |
4186 return properties; | |
4187 JVM_END | |
4188 | |
4189 JVM_ENTRY(jobjectArray, JVM_GetEnclosingMethodInfo(JNIEnv *env, jclass ofClass)) | |
4190 { | |
4191 JVMWrapper("JVM_GetEnclosingMethodInfo"); | |
4192 JvmtiVMObjectAllocEventCollector oam; | |
4193 | |
4194 if (ofClass == NULL) { | |
4195 return NULL; | |
4196 } | |
4197 Handle mirror(THREAD, JNIHandles::resolve_non_null(ofClass)); | |
4198 // Special handling for primitive objects | |
4199 if (java_lang_Class::is_primitive(mirror())) { | |
4200 return NULL; | |
4201 } | |
4202 klassOop k = java_lang_Class::as_klassOop(mirror()); | |
4203 if (!Klass::cast(k)->oop_is_instance()) { | |
4204 return NULL; | |
4205 } | |
4206 instanceKlassHandle ik_h(THREAD, k); | |
4207 int encl_method_class_idx = ik_h->enclosing_method_class_index(); | |
4208 if (encl_method_class_idx == 0) { | |
4209 return NULL; | |
4210 } | |
1142 | 4211 objArrayOop dest_o = oopFactory::new_objArray(SystemDictionary::Object_klass(), 3, CHECK_NULL); |
0 | 4212 objArrayHandle dest(THREAD, dest_o); |
4213 klassOop enc_k = ik_h->constants()->klass_at(encl_method_class_idx, CHECK_NULL); | |
4214 dest->obj_at_put(0, Klass::cast(enc_k)->java_mirror()); | |
4215 int encl_method_method_idx = ik_h->enclosing_method_method_index(); | |
4216 if (encl_method_method_idx != 0) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
4217 Symbol* sym = ik_h->constants()->symbol_at( |
0 | 4218 extract_low_short_from_int( |
4219 ik_h->constants()->name_and_type_at(encl_method_method_idx))); | |
4220 Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL); | |
4221 dest->obj_at_put(1, str()); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2162
diff
changeset
|
4222 sym = ik_h->constants()->symbol_at( |
0 | 4223 extract_high_short_from_int( |
4224 ik_h->constants()->name_and_type_at(encl_method_method_idx))); | |
4225 str = java_lang_String::create_from_symbol(sym, CHECK_NULL); | |
4226 dest->obj_at_put(2, str()); | |
4227 } | |
4228 return (jobjectArray) JNIHandles::make_local(dest()); | |
4229 } | |
4230 JVM_END | |
4231 | |
4232 JVM_ENTRY(jintArray, JVM_GetThreadStateValues(JNIEnv* env, | |
4233 jint javaThreadState)) | |
4234 { | |
4235 // If new thread states are added in future JDK and VM versions, | |
4236 // this should check if the JDK version is compatible with thread | |
4237 // states supported by the VM. Return NULL if not compatible. | |
4238 // | |
4239 // This function must map the VM java_lang_Thread::ThreadStatus | |
4240 // to the Java thread state that the JDK supports. | |
4241 // | |
4242 | |
4243 typeArrayHandle values_h; | |
4244 switch (javaThreadState) { | |
4245 case JAVA_THREAD_STATE_NEW : { | |
4246 typeArrayOop r = oopFactory::new_typeArray(T_INT, 1, CHECK_NULL); | |
4247 values_h = typeArrayHandle(THREAD, r); | |
4248 values_h->int_at_put(0, java_lang_Thread::NEW); | |
4249 break; | |
4250 } | |
4251 case JAVA_THREAD_STATE_RUNNABLE : { | |
4252 typeArrayOop r = oopFactory::new_typeArray(T_INT, 1, CHECK_NULL); | |
4253 values_h = typeArrayHandle(THREAD, r); | |
4254 values_h->int_at_put(0, java_lang_Thread::RUNNABLE); | |
4255 break; | |
4256 } | |
4257 case JAVA_THREAD_STATE_BLOCKED : { | |
4258 typeArrayOop r = oopFactory::new_typeArray(T_INT, 1, CHECK_NULL); | |
4259 values_h = typeArrayHandle(THREAD, r); | |
4260 values_h->int_at_put(0, java_lang_Thread::BLOCKED_ON_MONITOR_ENTER); | |
4261 break; | |
4262 } | |
4263 case JAVA_THREAD_STATE_WAITING : { | |
4264 typeArrayOop r = oopFactory::new_typeArray(T_INT, 2, CHECK_NULL); | |
4265 values_h = typeArrayHandle(THREAD, r); | |
4266 values_h->int_at_put(0, java_lang_Thread::IN_OBJECT_WAIT); | |
4267 values_h->int_at_put(1, java_lang_Thread::PARKED); | |
4268 break; | |
4269 } | |
4270 case JAVA_THREAD_STATE_TIMED_WAITING : { | |
4271 typeArrayOop r = oopFactory::new_typeArray(T_INT, 3, CHECK_NULL); | |
4272 values_h = typeArrayHandle(THREAD, r); | |
4273 values_h->int_at_put(0, java_lang_Thread::SLEEPING); | |
4274 values_h->int_at_put(1, java_lang_Thread::IN_OBJECT_WAIT_TIMED); | |
4275 values_h->int_at_put(2, java_lang_Thread::PARKED_TIMED); | |
4276 break; | |
4277 } | |
4278 case JAVA_THREAD_STATE_TERMINATED : { | |
4279 typeArrayOop r = oopFactory::new_typeArray(T_INT, 1, CHECK_NULL); | |
4280 values_h = typeArrayHandle(THREAD, r); | |
4281 values_h->int_at_put(0, java_lang_Thread::TERMINATED); | |
4282 break; | |
4283 } | |
4284 default: | |
4285 // Unknown state - probably incompatible JDK version | |
4286 return NULL; | |
4287 } | |
4288 | |
4289 return (jintArray) JNIHandles::make_local(env, values_h()); | |
4290 } | |
4291 JVM_END | |
4292 | |
4293 | |
4294 JVM_ENTRY(jobjectArray, JVM_GetThreadStateNames(JNIEnv* env, | |
4295 jint javaThreadState, | |
4296 jintArray values)) | |
4297 { | |
4298 // If new thread states are added in future JDK and VM versions, | |
4299 // this should check if the JDK version is compatible with thread | |
4300 // states supported by the VM. Return NULL if not compatible. | |
4301 // | |
4302 // This function must map the VM java_lang_Thread::ThreadStatus | |
4303 // to the Java thread state that the JDK supports. | |
4304 // | |
4305 | |
4306 ResourceMark rm; | |
4307 | |
4308 // Check if threads is null | |
4309 if (values == NULL) { | |
4310 THROW_(vmSymbols::java_lang_NullPointerException(), 0); | |
4311 } | |
4312 | |
4313 typeArrayOop v = typeArrayOop(JNIHandles::resolve_non_null(values)); | |
4314 typeArrayHandle values_h(THREAD, v); | |
4315 | |
4316 objArrayHandle names_h; | |
4317 switch (javaThreadState) { | |
4318 case JAVA_THREAD_STATE_NEW : { | |
4319 assert(values_h->length() == 1 && | |
4320 values_h->int_at(0) == java_lang_Thread::NEW, | |
4321 "Invalid threadStatus value"); | |
4322 | |
1142 | 4323 objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(), |
0 | 4324 1, /* only 1 substate */ |
4325 CHECK_NULL); | |
4326 names_h = objArrayHandle(THREAD, r); | |
4327 Handle name = java_lang_String::create_from_str("NEW", CHECK_NULL); | |
4328 names_h->obj_at_put(0, name()); | |
4329 break; | |
4330 } | |
4331 case JAVA_THREAD_STATE_RUNNABLE : { | |
4332 assert(values_h->length() == 1 && | |
4333 values_h->int_at(0) == java_lang_Thread::RUNNABLE, | |
4334 "Invalid threadStatus value"); | |
4335 | |
1142 | 4336 objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(), |
0 | 4337 1, /* only 1 substate */ |
4338 CHECK_NULL); | |
4339 names_h = objArrayHandle(THREAD, r); | |
4340 Handle name = java_lang_String::create_from_str("RUNNABLE", CHECK_NULL); | |
4341 names_h->obj_at_put(0, name()); | |
4342 break; | |
4343 } | |
4344 case JAVA_THREAD_STATE_BLOCKED : { | |
4345 assert(values_h->length() == 1 && | |
4346 values_h->int_at(0) == java_lang_Thread::BLOCKED_ON_MONITOR_ENTER, | |
4347 "Invalid threadStatus value"); | |
4348 | |
1142 | 4349 objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(), |
0 | 4350 1, /* only 1 substate */ |
4351 CHECK_NULL); | |
4352 names_h = objArrayHandle(THREAD, r); | |
4353 Handle name = java_lang_String::create_from_str("BLOCKED", CHECK_NULL); | |
4354 names_h->obj_at_put(0, name()); | |
4355 break; | |
4356 } | |
4357 case JAVA_THREAD_STATE_WAITING : { | |
4358 assert(values_h->length() == 2 && | |
4359 values_h->int_at(0) == java_lang_Thread::IN_OBJECT_WAIT && | |
4360 values_h->int_at(1) == java_lang_Thread::PARKED, | |
4361 "Invalid threadStatus value"); | |
1142 | 4362 objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(), |
0 | 4363 2, /* number of substates */ |
4364 CHECK_NULL); | |
4365 names_h = objArrayHandle(THREAD, r); | |
4366 Handle name0 = java_lang_String::create_from_str("WAITING.OBJECT_WAIT", | |
4367 CHECK_NULL); | |
4368 Handle name1 = java_lang_String::create_from_str("WAITING.PARKED", | |
4369 CHECK_NULL); | |
4370 names_h->obj_at_put(0, name0()); | |
4371 names_h->obj_at_put(1, name1()); | |
4372 break; | |
4373 } | |
4374 case JAVA_THREAD_STATE_TIMED_WAITING : { | |
4375 assert(values_h->length() == 3 && | |
4376 values_h->int_at(0) == java_lang_Thread::SLEEPING && | |
4377 values_h->int_at(1) == java_lang_Thread::IN_OBJECT_WAIT_TIMED && | |
4378 values_h->int_at(2) == java_lang_Thread::PARKED_TIMED, | |
4379 "Invalid threadStatus value"); | |
1142 | 4380 objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(), |
0 | 4381 3, /* number of substates */ |
4382 CHECK_NULL); | |
4383 names_h = objArrayHandle(THREAD, r); | |
4384 Handle name0 = java_lang_String::create_from_str("TIMED_WAITING.SLEEPING", | |
4385 CHECK_NULL); | |
4386 Handle name1 = java_lang_String::create_from_str("TIMED_WAITING.OBJECT_WAIT", | |
4387 CHECK_NULL); | |
4388 Handle name2 = java_lang_String::create_from_str("TIMED_WAITING.PARKED", | |
4389 CHECK_NULL); | |
4390 names_h->obj_at_put(0, name0()); | |
4391 names_h->obj_at_put(1, name1()); | |
4392 names_h->obj_at_put(2, name2()); | |
4393 break; | |
4394 } | |
4395 case JAVA_THREAD_STATE_TERMINATED : { | |
4396 assert(values_h->length() == 1 && | |
4397 values_h->int_at(0) == java_lang_Thread::TERMINATED, | |
4398 "Invalid threadStatus value"); | |
1142 | 4399 objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(), |
0 | 4400 1, /* only 1 substate */ |
4401 CHECK_NULL); | |
4402 names_h = objArrayHandle(THREAD, r); | |
4403 Handle name = java_lang_String::create_from_str("TERMINATED", CHECK_NULL); | |
4404 names_h->obj_at_put(0, name()); | |
4405 break; | |
4406 } | |
4407 default: | |
4408 // Unknown state - probably incompatible JDK version | |
4409 return NULL; | |
4410 } | |
4411 return (jobjectArray) JNIHandles::make_local(env, names_h()); | |
4412 } | |
4413 JVM_END | |
4414 | |
4415 JVM_ENTRY(void, JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size)) | |
4416 { | |
4417 memset(info, 0, sizeof(info_size)); | |
4418 | |
4419 info->jvm_version = Abstract_VM_Version::jvm_version(); | |
4420 info->update_version = 0; /* 0 in HotSpot Express VM */ | |
4421 info->special_update_version = 0; /* 0 in HotSpot Express VM */ | |
4422 | |
4423 // when we add a new capability in the jvm_version_info struct, we should also | |
4424 // consider to expose this new capability in the sun.rt.jvmCapabilities jvmstat | |
4425 // counter defined in runtimeService.cpp. | |
4426 info->is_attachable = AttachListener::is_attach_supported(); | |
4427 #ifdef KERNEL | |
4428 info->is_kernel_jvm = 1; // true; | |
4429 #else // KERNEL | |
4430 info->is_kernel_jvm = 0; // false; | |
4431 #endif // KERNEL | |
4432 } | |
4433 JVM_END |