annotate src/share/vm/prims/jvm.cpp @ 4570:ae4adc1492d1

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