src/share/vm/prims/jvm.cpp

Wed, 27 Apr 2016 01:25:04 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:25:04 +0800
changeset 0
f90c822e73f8
child 6876
710a3c8b516e
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/
changeset: 6782:28b50d07f6f8
tag: jdk8u25-b17

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

mercurial