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