Path: blob/master/src/hotspot/share/prims/jvm.cpp
41145 views
/*1* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "jvm.h"26#include "cds/classListParser.hpp"27#include "cds/classListWriter.hpp"28#include "cds/dynamicArchive.hpp"29#include "cds/heapShared.hpp"30#include "cds/lambdaFormInvokers.hpp"31#include "classfile/classFileStream.hpp"32#include "classfile/classLoader.hpp"33#include "classfile/classLoaderData.hpp"34#include "classfile/classLoaderData.inline.hpp"35#include "classfile/classLoadInfo.hpp"36#include "classfile/javaAssertions.hpp"37#include "classfile/javaClasses.inline.hpp"38#include "classfile/moduleEntry.hpp"39#include "classfile/modules.hpp"40#include "classfile/packageEntry.hpp"41#include "classfile/stringTable.hpp"42#include "classfile/symbolTable.hpp"43#include "classfile/systemDictionary.hpp"44#include "classfile/vmClasses.hpp"45#include "classfile/vmSymbols.hpp"46#include "gc/shared/collectedHeap.inline.hpp"47#include "interpreter/bytecode.hpp"48#include "interpreter/bytecodeUtils.hpp"49#include "jfr/jfrEvents.hpp"50#include "logging/log.hpp"51#include "memory/oopFactory.hpp"52#include "memory/referenceType.hpp"53#include "memory/resourceArea.hpp"54#include "memory/universe.hpp"55#include "oops/access.inline.hpp"56#include "oops/constantPool.hpp"57#include "oops/fieldStreams.inline.hpp"58#include "oops/instanceKlass.hpp"59#include "oops/klass.inline.hpp"60#include "oops/method.hpp"61#include "oops/recordComponent.hpp"62#include "oops/objArrayKlass.hpp"63#include "oops/objArrayOop.inline.hpp"64#include "oops/oop.inline.hpp"65#include "prims/jvm_misc.hpp"66#include "prims/jvmtiExport.hpp"67#include "prims/jvmtiThreadState.hpp"68#include "prims/stackwalk.hpp"69#include "runtime/arguments.hpp"70#include "runtime/atomic.hpp"71#include "runtime/globals_extension.hpp"72#include "runtime/handles.inline.hpp"73#include "runtime/init.hpp"74#include "runtime/interfaceSupport.inline.hpp"75#include "runtime/deoptimization.hpp"76#include "runtime/handshake.hpp"77#include "runtime/java.hpp"78#include "runtime/javaCalls.hpp"79#include "runtime/jfieldIDWorkaround.hpp"80#include "runtime/jniHandles.inline.hpp"81#include "runtime/os.inline.hpp"82#include "runtime/osThread.hpp"83#include "runtime/perfData.hpp"84#include "runtime/reflection.hpp"85#include "runtime/synchronizer.hpp"86#include "runtime/thread.inline.hpp"87#include "runtime/threadSMR.hpp"88#include "runtime/vframe.inline.hpp"89#include "runtime/vmOperations.hpp"90#include "runtime/vm_version.hpp"91#include "services/attachListener.hpp"92#include "services/management.hpp"93#include "services/threadService.hpp"94#include "utilities/copy.hpp"95#include "utilities/defaultStream.hpp"96#include "utilities/dtrace.hpp"97#include "utilities/events.hpp"98#include "utilities/macros.hpp"99#include "utilities/utf8.hpp"100#if INCLUDE_CDS101#include "classfile/systemDictionaryShared.hpp"102#endif103#if INCLUDE_JFR104#include "jfr/jfr.hpp"105#endif106107#include <errno.h>108109/*110NOTE about use of any ctor or function call that can trigger a safepoint/GC:111such ctors and calls MUST NOT come between an oop declaration/init and its112usage because if objects are move this may cause various memory stomps, bus113errors and segfaults. Here is a cookbook for causing so called "naked oop114failures":115116JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields<etc> {117// Object address to be held directly in mirror & not visible to GC118oop mirror = JNIHandles::resolve_non_null(ofClass);119120// If this ctor can hit a safepoint, moving objects around, then121ComplexConstructor foo;122123// Boom! mirror may point to JUNK instead of the intended object124(some dereference of mirror)125126// Here's another call that may block for GC, making mirror stale127MutexLocker ml(some_lock);128129// And here's an initializer that can result in a stale oop130// all in one step.131oop o = call_that_can_throw_exception(TRAPS);132133134The solution is to keep the oop declaration BELOW the ctor or function135call that might cause a GC, do another resolve to reassign the oop, or136consider use of a Handle instead of an oop so there is immunity from object137motion. But note that the "QUICK" entries below do not have a handlemark138and thus can only support use of handles passed in.139*/140141static void trace_class_resolution_impl(Klass* to_class, TRAPS) {142ResourceMark rm;143int line_number = -1;144const char * source_file = NULL;145const char * trace = "explicit";146InstanceKlass* caller = NULL;147JavaThread* jthread = THREAD;148if (jthread->has_last_Java_frame()) {149vframeStream vfst(jthread);150151// scan up the stack skipping ClassLoader, AccessController and PrivilegedAction frames152TempNewSymbol access_controller = SymbolTable::new_symbol("java/security/AccessController");153Klass* access_controller_klass = SystemDictionary::resolve_or_fail(access_controller, false, CHECK);154TempNewSymbol privileged_action = SymbolTable::new_symbol("java/security/PrivilegedAction");155Klass* privileged_action_klass = SystemDictionary::resolve_or_fail(privileged_action, false, CHECK);156157Method* last_caller = NULL;158159while (!vfst.at_end()) {160Method* m = vfst.method();161if (!vfst.method()->method_holder()->is_subclass_of(vmClasses::ClassLoader_klass())&&162!vfst.method()->method_holder()->is_subclass_of(access_controller_klass) &&163!vfst.method()->method_holder()->is_subclass_of(privileged_action_klass)) {164break;165}166last_caller = m;167vfst.next();168}169// if this is called from Class.forName0 and that is called from Class.forName,170// then print the caller of Class.forName. If this is Class.loadClass, then print171// that caller, otherwise keep quiet since this should be picked up elsewhere.172bool found_it = false;173if (!vfst.at_end() &&174vfst.method()->method_holder()->name() == vmSymbols::java_lang_Class() &&175vfst.method()->name() == vmSymbols::forName0_name()) {176vfst.next();177if (!vfst.at_end() &&178vfst.method()->method_holder()->name() == vmSymbols::java_lang_Class() &&179vfst.method()->name() == vmSymbols::forName_name()) {180vfst.next();181found_it = true;182}183} else if (last_caller != NULL &&184last_caller->method_holder()->name() ==185vmSymbols::java_lang_ClassLoader() &&186last_caller->name() == vmSymbols::loadClass_name()) {187found_it = true;188} else if (!vfst.at_end()) {189if (vfst.method()->is_native()) {190// JNI call191found_it = true;192}193}194if (found_it && !vfst.at_end()) {195// found the caller196caller = vfst.method()->method_holder();197line_number = vfst.method()->line_number_from_bci(vfst.bci());198if (line_number == -1) {199// show method name if it's a native method200trace = vfst.method()->name_and_sig_as_C_string();201}202Symbol* s = caller->source_file_name();203if (s != NULL) {204source_file = s->as_C_string();205}206}207}208if (caller != NULL) {209if (to_class != caller) {210const char * from = caller->external_name();211const char * to = to_class->external_name();212// print in a single call to reduce interleaving between threads213if (source_file != NULL) {214log_debug(class, resolve)("%s %s %s:%d (%s)", from, to, source_file, line_number, trace);215} else {216log_debug(class, resolve)("%s %s (%s)", from, to, trace);217}218}219}220}221222void trace_class_resolution(Klass* to_class) {223EXCEPTION_MARK;224trace_class_resolution_impl(to_class, THREAD);225if (HAS_PENDING_EXCEPTION) {226CLEAR_PENDING_EXCEPTION;227}228}229230// java.lang.System //////////////////////////////////////////////////////////////////////231232233JVM_LEAF(jlong, JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored))234return os::javaTimeMillis();235JVM_END236237JVM_LEAF(jlong, JVM_NanoTime(JNIEnv *env, jclass ignored))238return os::javaTimeNanos();239JVM_END240241// The function below is actually exposed by jdk.internal.misc.VM and not242// java.lang.System, but we choose to keep it here so that it stays next243// to JVM_CurrentTimeMillis and JVM_NanoTime244245const jlong MAX_DIFF_SECS = CONST64(0x0100000000); // 2^32246const jlong MIN_DIFF_SECS = -MAX_DIFF_SECS; // -2^32247248JVM_LEAF(jlong, JVM_GetNanoTimeAdjustment(JNIEnv *env, jclass ignored, jlong offset_secs))249jlong seconds;250jlong nanos;251252os::javaTimeSystemUTC(seconds, nanos);253254// We're going to verify that the result can fit in a long.255// For that we need the difference in seconds between 'seconds'256// and 'offset_secs' to be such that:257// |seconds - offset_secs| < (2^63/10^9)258// We're going to approximate 10^9 ~< 2^30 (1000^3 ~< 1024^3)259// which makes |seconds - offset_secs| < 2^33260// and we will prefer +/- 2^32 as the maximum acceptable diff261// as 2^32 has a more natural feel than 2^33...262//263// So if |seconds - offset_secs| >= 2^32 - we return a special264// sentinel value (-1) which the caller should take as an265// exception value indicating that the offset given to us is266// too far from range of the current time - leading to too big267// a nano adjustment. The caller is expected to recover by268// computing a more accurate offset and calling this method269// again. (For the record 2^32 secs is ~136 years, so that270// should rarely happen)271//272jlong diff = seconds - offset_secs;273if (diff >= MAX_DIFF_SECS || diff <= MIN_DIFF_SECS) {274return -1; // sentinel value: the offset is too far off the target275}276277// return the adjustment. If you compute a time by adding278// this number of nanoseconds along with the number of seconds279// in the offset you should get the current UTC time.280return (diff * (jlong)1000000000) + nanos;281JVM_END282283JVM_ENTRY(void, JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos,284jobject dst, jint dst_pos, jint length))285// Check if we have null pointers286if (src == NULL || dst == NULL) {287THROW(vmSymbols::java_lang_NullPointerException());288}289arrayOop s = arrayOop(JNIHandles::resolve_non_null(src));290arrayOop d = arrayOop(JNIHandles::resolve_non_null(dst));291assert(oopDesc::is_oop(s), "JVM_ArrayCopy: src not an oop");292assert(oopDesc::is_oop(d), "JVM_ArrayCopy: dst not an oop");293// Do copy294s->klass()->copy_array(s, src_pos, d, dst_pos, length, thread);295JVM_END296297298static void set_property(Handle props, const char* key, const char* value, TRAPS) {299JavaValue r(T_OBJECT);300// public synchronized Object put(Object key, Object value);301HandleMark hm(THREAD);302Handle key_str = java_lang_String::create_from_platform_dependent_str(key, CHECK);303Handle value_str = java_lang_String::create_from_platform_dependent_str((value != NULL ? value : ""), CHECK);304JavaCalls::call_virtual(&r,305props,306vmClasses::Properties_klass(),307vmSymbols::put_name(),308vmSymbols::object_object_object_signature(),309key_str,310value_str,311THREAD);312}313314315#define PUTPROP(props, name, value) set_property((props), (name), (value), CHECK_(properties));316317/*318* Return all of the system properties in a Java String array with alternating319* names and values from the jvm SystemProperty.320* Which includes some internal and all commandline -D defined properties.321*/322JVM_ENTRY(jobjectArray, JVM_GetProperties(JNIEnv *env))323ResourceMark rm(THREAD);324HandleMark hm(THREAD);325int ndx = 0;326int fixedCount = 2;327328SystemProperty* p = Arguments::system_properties();329int count = Arguments::PropertyList_count(p);330331// Allocate result String array332InstanceKlass* ik = vmClasses::String_klass();333objArrayOop r = oopFactory::new_objArray(ik, (count + fixedCount) * 2, CHECK_NULL);334objArrayHandle result_h(THREAD, r);335336while (p != NULL) {337const char * key = p->key();338if (strcmp(key, "sun.nio.MaxDirectMemorySize") != 0) {339const char * value = p->value();340Handle key_str = java_lang_String::create_from_platform_dependent_str(key, CHECK_NULL);341Handle value_str = java_lang_String::create_from_platform_dependent_str((value != NULL ? value : ""), CHECK_NULL);342result_h->obj_at_put(ndx * 2, key_str());343result_h->obj_at_put(ndx * 2 + 1, value_str());344ndx++;345}346p = p->next();347}348349// Convert the -XX:MaxDirectMemorySize= command line flag350// to the sun.nio.MaxDirectMemorySize property.351// Do this after setting user properties to prevent people352// from setting the value with a -D option, as requested.353// Leave empty if not supplied354if (!FLAG_IS_DEFAULT(MaxDirectMemorySize)) {355char as_chars[256];356jio_snprintf(as_chars, sizeof(as_chars), JULONG_FORMAT, MaxDirectMemorySize);357Handle key_str = java_lang_String::create_from_platform_dependent_str("sun.nio.MaxDirectMemorySize", CHECK_NULL);358Handle value_str = java_lang_String::create_from_platform_dependent_str(as_chars, CHECK_NULL);359result_h->obj_at_put(ndx * 2, key_str());360result_h->obj_at_put(ndx * 2 + 1, value_str());361ndx++;362}363364// JVM monitoring and management support365// Add the sun.management.compiler property for the compiler's name366{367#undef CSIZE368#if defined(_LP64) || defined(_WIN64)369#define CSIZE "64-Bit "370#else371#define CSIZE372#endif // 64bit373374#if COMPILER1_AND_COMPILER2375const char* compiler_name = "HotSpot " CSIZE "Tiered Compilers";376#else377#if defined(COMPILER1)378const char* compiler_name = "HotSpot " CSIZE "Client Compiler";379#elif defined(COMPILER2)380const char* compiler_name = "HotSpot " CSIZE "Server Compiler";381#elif INCLUDE_JVMCI382#error "INCLUDE_JVMCI should imply COMPILER1_OR_COMPILER2"383#else384const char* compiler_name = "";385#endif // compilers386#endif // COMPILER1_AND_COMPILER2387388if (*compiler_name != '\0' &&389(Arguments::mode() != Arguments::_int)) {390Handle key_str = java_lang_String::create_from_platform_dependent_str("sun.management.compiler", CHECK_NULL);391Handle value_str = java_lang_String::create_from_platform_dependent_str(compiler_name, CHECK_NULL);392result_h->obj_at_put(ndx * 2, key_str());393result_h->obj_at_put(ndx * 2 + 1, value_str());394ndx++;395}396}397398return (jobjectArray) JNIHandles::make_local(THREAD, result_h());399JVM_END400401402/*403* Return the temporary directory that the VM uses for the attach404* and perf data files.405*406* It is important that this directory is well-known and the407* same for all VM instances. It cannot be affected by configuration408* variables such as java.io.tmpdir.409*/410JVM_ENTRY(jstring, JVM_GetTemporaryDirectory(JNIEnv *env))411HandleMark hm(THREAD);412const char* temp_dir = os::get_temp_directory();413Handle h = java_lang_String::create_from_platform_dependent_str(temp_dir, CHECK_NULL);414return (jstring) JNIHandles::make_local(THREAD, h());415JVM_END416417418// java.lang.Runtime /////////////////////////////////////////////////////////////////////////419420extern volatile jint vm_created;421422JVM_ENTRY_NO_ENV(void, JVM_BeforeHalt())423#if INCLUDE_CDS424// Link all classes for dynamic CDS dumping before vm exit.425if (DynamicDumpSharedSpaces) {426DynamicArchive::prepare_for_dynamic_dumping_at_exit();427}428#endif429EventShutdown event;430if (event.should_commit()) {431event.set_reason("Shutdown requested from Java");432event.commit();433}434JVM_END435436437JVM_ENTRY_NO_ENV(void, JVM_Halt(jint code))438before_exit(thread);439vm_exit(code);440JVM_END441442443JVM_ENTRY_NO_ENV(void, JVM_GC(void))444if (!DisableExplicitGC) {445Universe::heap()->collect(GCCause::_java_lang_system_gc);446}447JVM_END448449450JVM_LEAF(jlong, JVM_MaxObjectInspectionAge(void))451return Universe::heap()->millis_since_last_whole_heap_examined();452JVM_END453454455static inline jlong convert_size_t_to_jlong(size_t val) {456// In the 64-bit vm, a size_t can overflow a jlong (which is signed).457NOT_LP64 (return (jlong)val;)458LP64_ONLY(return (jlong)MIN2(val, (size_t)max_jlong);)459}460461JVM_ENTRY_NO_ENV(jlong, JVM_TotalMemory(void))462size_t n = Universe::heap()->capacity();463return convert_size_t_to_jlong(n);464JVM_END465466467JVM_ENTRY_NO_ENV(jlong, JVM_FreeMemory(void))468size_t n = Universe::heap()->unused();469return convert_size_t_to_jlong(n);470JVM_END471472473JVM_ENTRY_NO_ENV(jlong, JVM_MaxMemory(void))474size_t n = Universe::heap()->max_capacity();475return convert_size_t_to_jlong(n);476JVM_END477478479JVM_ENTRY_NO_ENV(jint, JVM_ActiveProcessorCount(void))480return os::active_processor_count();481JVM_END482483JVM_ENTRY_NO_ENV(jboolean, JVM_IsUseContainerSupport(void))484#ifdef LINUX485if (UseContainerSupport) {486return JNI_TRUE;487}488#endif489return JNI_FALSE;490JVM_END491492// java.lang.Throwable //////////////////////////////////////////////////////493494JVM_ENTRY(void, JVM_FillInStackTrace(JNIEnv *env, jobject receiver))495Handle exception(thread, JNIHandles::resolve_non_null(receiver));496java_lang_Throwable::fill_in_stack_trace(exception);497JVM_END498499// java.lang.NullPointerException ///////////////////////////////////////////500501JVM_ENTRY(jstring, JVM_GetExtendedNPEMessage(JNIEnv *env, jthrowable throwable))502if (!ShowCodeDetailsInExceptionMessages) return NULL;503504oop exc = JNIHandles::resolve_non_null(throwable);505506Method* method;507int bci;508if (!java_lang_Throwable::get_top_method_and_bci(exc, &method, &bci)) {509return NULL;510}511if (method->is_native()) {512return NULL;513}514515stringStream ss;516bool ok = BytecodeUtils::get_NPE_message_at(&ss, method, bci);517if (ok) {518oop result = java_lang_String::create_oop_from_str(ss.base(), CHECK_NULL);519return (jstring) JNIHandles::make_local(THREAD, result);520} else {521return NULL;522}523JVM_END524525// java.lang.StackTraceElement //////////////////////////////////////////////526527528JVM_ENTRY(void, JVM_InitStackTraceElementArray(JNIEnv *env, jobjectArray elements, jobject throwable))529Handle exception(THREAD, JNIHandles::resolve(throwable));530objArrayOop st = objArrayOop(JNIHandles::resolve(elements));531objArrayHandle stack_trace(THREAD, st);532// Fill in the allocated stack trace533java_lang_Throwable::get_stack_trace_elements(exception, stack_trace, CHECK);534JVM_END535536537JVM_ENTRY(void, JVM_InitStackTraceElement(JNIEnv* env, jobject element, jobject stackFrameInfo))538Handle stack_frame_info(THREAD, JNIHandles::resolve_non_null(stackFrameInfo));539Handle stack_trace_element(THREAD, JNIHandles::resolve_non_null(element));540java_lang_StackFrameInfo::to_stack_trace_element(stack_frame_info, stack_trace_element, THREAD);541JVM_END542543544// java.lang.StackWalker //////////////////////////////////////////////////////545546547JVM_ENTRY(jobject, JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mode,548jint skip_frames, jint frame_count, jint start_index,549jobjectArray frames))550if (!thread->has_last_Java_frame()) {551THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: no stack trace", NULL);552}553554Handle stackStream_h(THREAD, JNIHandles::resolve_non_null(stackStream));555556// frames array is a Class<?>[] array when only getting caller reference,557// and a StackFrameInfo[] array (or derivative) otherwise. It should never558// be null.559objArrayOop fa = objArrayOop(JNIHandles::resolve_non_null(frames));560objArrayHandle frames_array_h(THREAD, fa);561562int limit = start_index + frame_count;563if (frames_array_h->length() < limit) {564THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "not enough space in buffers", NULL);565}566567oop result = StackWalk::walk(stackStream_h, mode, skip_frames, frame_count,568start_index, frames_array_h, CHECK_NULL);569return JNIHandles::make_local(THREAD, result);570JVM_END571572573JVM_ENTRY(jint, JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode, jlong anchor,574jint frame_count, jint start_index,575jobjectArray frames))576// frames array is a Class<?>[] array when only getting caller reference,577// and a StackFrameInfo[] array (or derivative) otherwise. It should never578// be null.579objArrayOop fa = objArrayOop(JNIHandles::resolve_non_null(frames));580objArrayHandle frames_array_h(THREAD, fa);581582int limit = start_index+frame_count;583if (frames_array_h->length() < limit) {584THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "not enough space in buffers");585}586587Handle stackStream_h(THREAD, JNIHandles::resolve_non_null(stackStream));588return StackWalk::fetchNextBatch(stackStream_h, mode, anchor, frame_count,589start_index, frames_array_h, THREAD);590JVM_END591592// java.lang.Object ///////////////////////////////////////////////593594595JVM_ENTRY(jint, JVM_IHashCode(JNIEnv* env, jobject handle))596// as implemented in the classic virtual machine; return 0 if object is NULL597return handle == NULL ? 0 : ObjectSynchronizer::FastHashCode (THREAD, JNIHandles::resolve_non_null(handle)) ;598JVM_END599600601JVM_ENTRY(void, JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms))602Handle obj(THREAD, JNIHandles::resolve_non_null(handle));603JavaThreadInObjectWaitState jtiows(thread, ms != 0);604if (JvmtiExport::should_post_monitor_wait()) {605JvmtiExport::post_monitor_wait(thread, obj(), ms);606607// The current thread already owns the monitor and it has not yet608// been added to the wait queue so the current thread cannot be609// made the successor. This means that the JVMTI_EVENT_MONITOR_WAIT610// event handler cannot accidentally consume an unpark() meant for611// the ParkEvent associated with this ObjectMonitor.612}613ObjectSynchronizer::wait(obj, ms, CHECK);614JVM_END615616617JVM_ENTRY(void, JVM_MonitorNotify(JNIEnv* env, jobject handle))618Handle obj(THREAD, JNIHandles::resolve_non_null(handle));619ObjectSynchronizer::notify(obj, CHECK);620JVM_END621622623JVM_ENTRY(void, JVM_MonitorNotifyAll(JNIEnv* env, jobject handle))624Handle obj(THREAD, JNIHandles::resolve_non_null(handle));625ObjectSynchronizer::notifyall(obj, CHECK);626JVM_END627628629JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))630Handle obj(THREAD, JNIHandles::resolve_non_null(handle));631Klass* klass = obj->klass();632JvmtiVMObjectAllocEventCollector oam;633634#ifdef ASSERT635// Just checking that the cloneable flag is set correct636if (obj->is_array()) {637guarantee(klass->is_cloneable(), "all arrays are cloneable");638} else {639guarantee(obj->is_instance(), "should be instanceOop");640bool cloneable = klass->is_subtype_of(vmClasses::Cloneable_klass());641guarantee(cloneable == klass->is_cloneable(), "incorrect cloneable flag");642}643#endif644645// Check if class of obj supports the Cloneable interface.646// All arrays are considered to be cloneable (See JLS 20.1.5).647// All j.l.r.Reference classes are considered non-cloneable.648if (!klass->is_cloneable() ||649(klass->is_instance_klass() &&650InstanceKlass::cast(klass)->reference_type() != REF_NONE)) {651ResourceMark rm(THREAD);652THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name());653}654655// Make shallow object copy656const int size = obj->size();657oop new_obj_oop = NULL;658if (obj->is_array()) {659const int length = ((arrayOop)obj())->length();660new_obj_oop = Universe::heap()->array_allocate(klass, size, length,661/* do_zero */ true, CHECK_NULL);662} else {663new_obj_oop = Universe::heap()->obj_allocate(klass, size, CHECK_NULL);664}665666HeapAccess<>::clone(obj(), new_obj_oop, size);667668Handle new_obj(THREAD, new_obj_oop);669// Caution: this involves a java upcall, so the clone should be670// "gc-robust" by this stage.671if (klass->has_finalizer()) {672assert(obj->is_instance(), "should be instanceOop");673new_obj_oop = InstanceKlass::register_finalizer(instanceOop(new_obj()), CHECK_NULL);674new_obj = Handle(THREAD, new_obj_oop);675}676677return JNIHandles::make_local(THREAD, new_obj());678JVM_END679680// java.io.File ///////////////////////////////////////////////////////////////681682JVM_LEAF(char*, JVM_NativePath(char* path))683return os::native_path(path);684JVM_END685686687// Misc. class handling ///////////////////////////////////////////////////////////688689690JVM_ENTRY(jclass, JVM_GetCallerClass(JNIEnv* env))691// Getting the class of the caller frame.692//693// The call stack at this point looks something like this:694//695// [0] [ @CallerSensitive public sun.reflect.Reflection.getCallerClass ]696// [1] [ @CallerSensitive API.method ]697// [.] [ (skipped intermediate frames) ]698// [n] [ caller ]699vframeStream vfst(thread);700// Cf. LibraryCallKit::inline_native_Reflection_getCallerClass701for (int n = 0; !vfst.at_end(); vfst.security_next(), n++) {702Method* m = vfst.method();703assert(m != NULL, "sanity");704switch (n) {705case 0:706// This must only be called from Reflection.getCallerClass707if (m->intrinsic_id() != vmIntrinsics::_getCallerClass) {708THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetCallerClass must only be called from Reflection.getCallerClass");709}710// fall-through711case 1:712// Frame 0 and 1 must be caller sensitive.713if (!m->caller_sensitive()) {714THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), err_msg("CallerSensitive annotation expected at frame %d", n));715}716break;717default:718if (!m->is_ignored_by_security_stack_walk()) {719// We have reached the desired frame; return the holder class.720return (jclass) JNIHandles::make_local(THREAD, m->method_holder()->java_mirror());721}722break;723}724}725return NULL;726JVM_END727728729JVM_ENTRY(jclass, JVM_FindPrimitiveClass(JNIEnv* env, const char* utf))730oop mirror = NULL;731BasicType t = name2type(utf);732if (t != T_ILLEGAL && !is_reference_type(t)) {733mirror = Universe::java_mirror(t);734}735if (mirror == NULL) {736THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), (char*) utf);737} else {738return (jclass) JNIHandles::make_local(THREAD, mirror);739}740JVM_END741742743// Returns a class loaded by the bootstrap class loader; or null744// if not found. ClassNotFoundException is not thrown.745// FindClassFromBootLoader is exported to the launcher for windows.746JVM_ENTRY(jclass, JVM_FindClassFromBootLoader(JNIEnv* env,747const char* name))748// Java libraries should ensure that name is never null or illegal.749if (name == NULL || (int)strlen(name) > Symbol::max_length()) {750// It's impossible to create this class; the name cannot fit751// into the constant pool.752return NULL;753}754assert(UTF8::is_legal_utf8((const unsigned char*)name, (int)strlen(name), false), "illegal UTF name");755756TempNewSymbol h_name = SymbolTable::new_symbol(name);757Klass* k = SystemDictionary::resolve_or_null(h_name, CHECK_NULL);758if (k == NULL) {759return NULL;760}761762if (log_is_enabled(Debug, class, resolve)) {763trace_class_resolution(k);764}765return (jclass) JNIHandles::make_local(THREAD, k->java_mirror());766JVM_END767768// Find a class with this name in this loader, using the caller's protection domain.769JVM_ENTRY(jclass, JVM_FindClassFromCaller(JNIEnv* env, const char* name,770jboolean init, jobject loader,771jclass caller))772TempNewSymbol h_name =773SystemDictionary::class_name_symbol(name, vmSymbols::java_lang_ClassNotFoundException(),774CHECK_NULL);775776oop loader_oop = JNIHandles::resolve(loader);777oop from_class = JNIHandles::resolve(caller);778oop protection_domain = NULL;779// If loader is null, shouldn't call ClassLoader.checkPackageAccess; otherwise get780// NPE. Put it in another way, the bootstrap class loader has all permission and781// thus no checkPackageAccess equivalence in the VM class loader.782// The caller is also passed as NULL by the java code if there is no security783// manager to avoid the performance cost of getting the calling class.784if (from_class != NULL && loader_oop != NULL) {785protection_domain = java_lang_Class::as_Klass(from_class)->protection_domain();786}787788Handle h_loader(THREAD, loader_oop);789Handle h_prot(THREAD, protection_domain);790jclass result = find_class_from_class_loader(env, h_name, init, h_loader,791h_prot, false, THREAD);792793if (log_is_enabled(Debug, class, resolve) && result != NULL) {794trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));795}796return result;797JVM_END798799// Currently only called from the old verifier.800JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name,801jboolean init, jclass from))802TempNewSymbol h_name =803SystemDictionary::class_name_symbol(name, vmSymbols::java_lang_ClassNotFoundException(),804CHECK_NULL);805oop from_class_oop = JNIHandles::resolve(from);806Klass* from_class = (from_class_oop == NULL)807? (Klass*)NULL808: java_lang_Class::as_Klass(from_class_oop);809oop class_loader = NULL;810oop protection_domain = NULL;811if (from_class != NULL) {812class_loader = from_class->class_loader();813protection_domain = from_class->protection_domain();814}815Handle h_loader(THREAD, class_loader);816Handle h_prot (THREAD, protection_domain);817jclass result = find_class_from_class_loader(env, h_name, init, h_loader,818h_prot, true, thread);819820if (log_is_enabled(Debug, class, resolve) && result != NULL) {821// this function is generally only used for class loading during verification.822ResourceMark rm;823oop from_mirror = JNIHandles::resolve_non_null(from);824Klass* from_class = java_lang_Class::as_Klass(from_mirror);825const char * from_name = from_class->external_name();826827oop mirror = JNIHandles::resolve_non_null(result);828Klass* to_class = java_lang_Class::as_Klass(mirror);829const char * to = to_class->external_name();830log_debug(class, resolve)("%s %s (verification)", from_name, to);831}832833return result;834JVM_END835836// common code for JVM_DefineClass() and JVM_DefineClassWithSource()837static jclass jvm_define_class_common(const char *name,838jobject loader, const jbyte *buf,839jsize len, jobject pd, const char *source,840TRAPS) {841if (source == NULL) source = "__JVM_DefineClass__";842843JavaThread* jt = THREAD;844845PerfClassTraceTime vmtimer(ClassLoader::perf_define_appclass_time(),846ClassLoader::perf_define_appclass_selftime(),847ClassLoader::perf_define_appclasses(),848jt->get_thread_stat()->perf_recursion_counts_addr(),849jt->get_thread_stat()->perf_timers_addr(),850PerfClassTraceTime::DEFINE_CLASS);851852if (UsePerfData) {853ClassLoader::perf_app_classfile_bytes_read()->inc(len);854}855856// Class resolution will get the class name from the .class stream if the name is null.857TempNewSymbol class_name = name == NULL ? NULL :858SystemDictionary::class_name_symbol(name, vmSymbols::java_lang_NoClassDefFoundError(),859CHECK_NULL);860861ResourceMark rm(THREAD);862ClassFileStream st((u1*)buf, len, source, ClassFileStream::verify);863Handle class_loader (THREAD, JNIHandles::resolve(loader));864Handle protection_domain (THREAD, JNIHandles::resolve(pd));865ClassLoadInfo cl_info(protection_domain);866Klass* k = SystemDictionary::resolve_from_stream(&st, class_name,867class_loader,868cl_info,869CHECK_NULL);870871if (log_is_enabled(Debug, class, resolve)) {872trace_class_resolution(k);873}874875return (jclass) JNIHandles::make_local(THREAD, k->java_mirror());876}877878enum {879NESTMATE = java_lang_invoke_MemberName::MN_NESTMATE_CLASS,880HIDDEN_CLASS = java_lang_invoke_MemberName::MN_HIDDEN_CLASS,881STRONG_LOADER_LINK = java_lang_invoke_MemberName::MN_STRONG_LOADER_LINK,882ACCESS_VM_ANNOTATIONS = java_lang_invoke_MemberName::MN_ACCESS_VM_ANNOTATIONS883};884885/*886* Define a class with the specified flags that indicates if it's a nestmate,887* hidden, or strongly referenced from class loader.888*/889static jclass jvm_lookup_define_class(jclass lookup, const char *name,890const jbyte *buf, jsize len, jobject pd,891jboolean init, int flags, jobject classData, TRAPS) {892ResourceMark rm(THREAD);893894Klass* lookup_k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(lookup));895// Lookup class must be a non-null instance896if (lookup_k == NULL) {897THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Lookup class is null");898}899assert(lookup_k->is_instance_klass(), "Lookup class must be an instance klass");900901Handle class_loader (THREAD, lookup_k->class_loader());902903bool is_nestmate = (flags & NESTMATE) == NESTMATE;904bool is_hidden = (flags & HIDDEN_CLASS) == HIDDEN_CLASS;905bool is_strong = (flags & STRONG_LOADER_LINK) == STRONG_LOADER_LINK;906bool vm_annotations = (flags & ACCESS_VM_ANNOTATIONS) == ACCESS_VM_ANNOTATIONS;907908InstanceKlass* host_class = NULL;909if (is_nestmate) {910host_class = InstanceKlass::cast(lookup_k)->nest_host(CHECK_NULL);911}912913log_info(class, nestmates)("LookupDefineClass: %s - %s%s, %s, %s, %s",914name,915is_nestmate ? "with dynamic nest-host " : "non-nestmate",916is_nestmate ? host_class->external_name() : "",917is_hidden ? "hidden" : "not hidden",918is_strong ? "strong" : "weak",919vm_annotations ? "with vm annotations" : "without vm annotation");920921if (!is_hidden) {922// classData is only applicable for hidden classes923if (classData != NULL) {924THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "classData is only applicable for hidden classes");925}926if (is_nestmate) {927THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "dynamic nestmate is only applicable for hidden classes");928}929if (!is_strong) {930THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "an ordinary class must be strongly referenced by its defining loader");931}932if (vm_annotations) {933THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "vm annotations only allowed for hidden classes");934}935if (flags != STRONG_LOADER_LINK) {936THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),937err_msg("invalid flag 0x%x", flags));938}939}940941// Class resolution will get the class name from the .class stream if the name is null.942TempNewSymbol class_name = name == NULL ? NULL :943SystemDictionary::class_name_symbol(name, vmSymbols::java_lang_NoClassDefFoundError(),944CHECK_NULL);945946Handle protection_domain (THREAD, JNIHandles::resolve(pd));947const char* source = is_nestmate ? host_class->external_name() : "__JVM_LookupDefineClass__";948ClassFileStream st((u1*)buf, len, source, ClassFileStream::verify);949950InstanceKlass* ik = NULL;951if (!is_hidden) {952ClassLoadInfo cl_info(protection_domain);953ik = SystemDictionary::resolve_from_stream(&st, class_name,954class_loader,955cl_info,956CHECK_NULL);957958if (log_is_enabled(Debug, class, resolve)) {959trace_class_resolution(ik);960}961} else { // hidden962Handle classData_h(THREAD, JNIHandles::resolve(classData));963ClassLoadInfo cl_info(protection_domain,964host_class,965classData_h,966is_hidden,967is_strong,968vm_annotations);969ik = SystemDictionary::resolve_from_stream(&st, class_name,970class_loader,971cl_info,972CHECK_NULL);973974// The hidden class loader data has been artificially been kept alive to975// this point. The mirror and any instances of this class have to keep976// it alive afterwards.977ik->class_loader_data()->dec_keep_alive();978979if (is_nestmate && log_is_enabled(Debug, class, nestmates)) {980ModuleEntry* module = ik->module();981const char * module_name = module->is_named() ? module->name()->as_C_string() : UNNAMED_MODULE;982log_debug(class, nestmates)("Dynamic nestmate: %s/%s, nest_host %s, %s",983module_name,984ik->external_name(),985host_class->external_name(),986ik->is_hidden() ? "is hidden" : "is not hidden");987}988}989assert(Reflection::is_same_class_package(lookup_k, ik),990"lookup class and defined class are in different packages");991992if (init) {993ik->initialize(CHECK_NULL);994} else {995ik->link_class(CHECK_NULL);996}997998return (jclass) JNIHandles::make_local(THREAD, ik->java_mirror());999}10001001JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd))1002return jvm_define_class_common(name, loader, buf, len, pd, NULL, THREAD);1003JVM_END10041005/*1006* Define a class with the specified lookup class.1007* lookup: Lookup class1008* name: the name of the class1009* buf: class bytes1010* len: length of class bytes1011* pd: protection domain1012* init: initialize the class1013* flags: properties of the class1014* classData: private static pre-initialized field1015*/1016JVM_ENTRY(jclass, JVM_LookupDefineClass(JNIEnv *env, jclass lookup, const char *name, const jbyte *buf,1017jsize len, jobject pd, jboolean initialize, int flags, jobject classData))10181019if (lookup == NULL) {1020THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Lookup class is null");1021}10221023assert(buf != NULL, "buf must not be NULL");10241025return jvm_lookup_define_class(lookup, name, buf, len, pd, initialize, flags, classData, THREAD);1026JVM_END10271028JVM_ENTRY(jclass, JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source))10291030return jvm_define_class_common(name, loader, buf, len, pd, source, THREAD);1031JVM_END10321033JVM_ENTRY(jclass, JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name))1034ResourceMark rm(THREAD);10351036Handle h_name (THREAD, JNIHandles::resolve_non_null(name));1037char* str = java_lang_String::as_utf8_string(h_name());10381039// Sanity check, don't expect null1040if (str == NULL) return NULL;10411042// Internalize the string, converting '.' to '/' in string.1043char* p = (char*)str;1044while (*p != '\0') {1045if (*p == '.') {1046*p = '/';1047}1048p++;1049}10501051const int str_len = (int)(p - str);1052if (str_len > Symbol::max_length()) {1053// It's impossible to create this class; the name cannot fit1054// into the constant pool.1055return NULL;1056}1057TempNewSymbol klass_name = SymbolTable::new_symbol(str, str_len);10581059// Security Note:1060// The Java level wrapper will perform the necessary security check allowing1061// us to pass the NULL as the initiating class loader.1062Handle h_loader(THREAD, JNIHandles::resolve(loader));1063Klass* k = SystemDictionary::find_instance_or_array_klass(klass_name,1064h_loader,1065Handle());1066#if INCLUDE_CDS1067if (k == NULL) {1068// If the class is not already loaded, try to see if it's in the shared1069// archive for the current classloader (h_loader).1070k = SystemDictionaryShared::find_or_load_shared_class(klass_name, h_loader, CHECK_NULL);1071}1072#endif1073return (k == NULL) ? NULL :1074(jclass) JNIHandles::make_local(THREAD, k->java_mirror());1075JVM_END10761077// Module support //////////////////////////////////////////////////////////////////////////////10781079JVM_ENTRY(void, JVM_DefineModule(JNIEnv *env, jobject module, jboolean is_open, jstring version,1080jstring location, jobjectArray packages))1081Handle h_module (THREAD, JNIHandles::resolve(module));1082Modules::define_module(h_module, is_open, version, location, packages, CHECK);1083JVM_END10841085JVM_ENTRY(void, JVM_SetBootLoaderUnnamedModule(JNIEnv *env, jobject module))1086Handle h_module (THREAD, JNIHandles::resolve(module));1087Modules::set_bootloader_unnamed_module(h_module, CHECK);1088JVM_END10891090JVM_ENTRY(void, JVM_AddModuleExports(JNIEnv *env, jobject from_module, jstring package, jobject to_module))1091Handle h_from_module (THREAD, JNIHandles::resolve(from_module));1092Handle h_to_module (THREAD, JNIHandles::resolve(to_module));1093Modules::add_module_exports_qualified(h_from_module, package, h_to_module, CHECK);1094JVM_END10951096JVM_ENTRY(void, JVM_AddModuleExportsToAllUnnamed(JNIEnv *env, jobject from_module, jstring package))1097Handle h_from_module (THREAD, JNIHandles::resolve(from_module));1098Modules::add_module_exports_to_all_unnamed(h_from_module, package, CHECK);1099JVM_END11001101JVM_ENTRY(void, JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, jstring package))1102Handle h_from_module (THREAD, JNIHandles::resolve(from_module));1103Modules::add_module_exports(h_from_module, package, Handle(), CHECK);1104JVM_END11051106JVM_ENTRY (void, JVM_AddReadsModule(JNIEnv *env, jobject from_module, jobject source_module))1107Handle h_from_module (THREAD, JNIHandles::resolve(from_module));1108Handle h_source_module (THREAD, JNIHandles::resolve(source_module));1109Modules::add_reads_module(h_from_module, h_source_module, CHECK);1110JVM_END11111112JVM_ENTRY(void, JVM_DefineArchivedModules(JNIEnv *env, jobject platform_loader, jobject system_loader))1113Handle h_platform_loader (THREAD, JNIHandles::resolve(platform_loader));1114Handle h_system_loader (THREAD, JNIHandles::resolve(system_loader));1115Modules::define_archived_modules(h_platform_loader, h_system_loader, CHECK);1116JVM_END11171118// Reflection support //////////////////////////////////////////////////////////////////////////////11191120JVM_ENTRY(jstring, JVM_InitClassName(JNIEnv *env, jclass cls))1121assert (cls != NULL, "illegal class");1122JvmtiVMObjectAllocEventCollector oam;1123ResourceMark rm(THREAD);1124HandleMark hm(THREAD);1125Handle java_class(THREAD, JNIHandles::resolve(cls));1126oop result = java_lang_Class::name(java_class, CHECK_NULL);1127return (jstring) JNIHandles::make_local(THREAD, result);1128JVM_END112911301131JVM_ENTRY(jobjectArray, JVM_GetClassInterfaces(JNIEnv *env, jclass cls))1132JvmtiVMObjectAllocEventCollector oam;1133oop mirror = JNIHandles::resolve_non_null(cls);11341135// Special handling for primitive objects1136if (java_lang_Class::is_primitive(mirror)) {1137// Primitive objects does not have any interfaces1138objArrayOop r = oopFactory::new_objArray(vmClasses::Class_klass(), 0, CHECK_NULL);1139return (jobjectArray) JNIHandles::make_local(THREAD, r);1140}11411142Klass* klass = java_lang_Class::as_Klass(mirror);1143// Figure size of result array1144int size;1145if (klass->is_instance_klass()) {1146size = InstanceKlass::cast(klass)->local_interfaces()->length();1147} else {1148assert(klass->is_objArray_klass() || klass->is_typeArray_klass(), "Illegal mirror klass");1149size = 2;1150}11511152// Allocate result array1153objArrayOop r = oopFactory::new_objArray(vmClasses::Class_klass(), size, CHECK_NULL);1154objArrayHandle result (THREAD, r);1155// Fill in result1156if (klass->is_instance_klass()) {1157// Regular instance klass, fill in all local interfaces1158for (int index = 0; index < size; index++) {1159Klass* k = InstanceKlass::cast(klass)->local_interfaces()->at(index);1160result->obj_at_put(index, k->java_mirror());1161}1162} else {1163// All arrays implement java.lang.Cloneable and java.io.Serializable1164result->obj_at_put(0, vmClasses::Cloneable_klass()->java_mirror());1165result->obj_at_put(1, vmClasses::Serializable_klass()->java_mirror());1166}1167return (jobjectArray) JNIHandles::make_local(THREAD, result());1168JVM_END116911701171JVM_ENTRY(jboolean, JVM_IsInterface(JNIEnv *env, jclass cls))1172oop mirror = JNIHandles::resolve_non_null(cls);1173if (java_lang_Class::is_primitive(mirror)) {1174return JNI_FALSE;1175}1176Klass* k = java_lang_Class::as_Klass(mirror);1177jboolean result = k->is_interface();1178assert(!result || k->is_instance_klass(),1179"all interfaces are instance types");1180// The compiler intrinsic for isInterface tests the1181// Klass::_access_flags bits in the same way.1182return result;1183JVM_END11841185JVM_ENTRY(jboolean, JVM_IsHiddenClass(JNIEnv *env, jclass cls))1186oop mirror = JNIHandles::resolve_non_null(cls);1187if (java_lang_Class::is_primitive(mirror)) {1188return JNI_FALSE;1189}1190Klass* k = java_lang_Class::as_Klass(mirror);1191return k->is_hidden();1192JVM_END11931194JVM_ENTRY(jobjectArray, JVM_GetClassSigners(JNIEnv *env, jclass cls))1195JvmtiVMObjectAllocEventCollector oam;1196oop mirror = JNIHandles::resolve_non_null(cls);1197if (java_lang_Class::is_primitive(mirror)) {1198// There are no signers for primitive types1199return NULL;1200}12011202objArrayHandle signers(THREAD, java_lang_Class::signers(mirror));12031204// If there are no signers set in the class, or if the class1205// is an array, return NULL.1206if (signers == NULL) return NULL;12071208// copy of the signers array1209Klass* element = ObjArrayKlass::cast(signers->klass())->element_klass();1210objArrayOop signers_copy = oopFactory::new_objArray(element, signers->length(), CHECK_NULL);1211for (int index = 0; index < signers->length(); index++) {1212signers_copy->obj_at_put(index, signers->obj_at(index));1213}12141215// return the copy1216return (jobjectArray) JNIHandles::make_local(THREAD, signers_copy);1217JVM_END121812191220JVM_ENTRY(void, JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers))1221oop mirror = JNIHandles::resolve_non_null(cls);1222if (!java_lang_Class::is_primitive(mirror)) {1223// This call is ignored for primitive types and arrays.1224// Signers are only set once, ClassLoader.java, and thus shouldn't1225// be called with an array. Only the bootstrap loader creates arrays.1226Klass* k = java_lang_Class::as_Klass(mirror);1227if (k->is_instance_klass()) {1228java_lang_Class::set_signers(k->java_mirror(), objArrayOop(JNIHandles::resolve(signers)));1229}1230}1231JVM_END123212331234JVM_ENTRY(jobject, JVM_GetProtectionDomain(JNIEnv *env, jclass cls))1235oop mirror = JNIHandles::resolve_non_null(cls);1236if (mirror == NULL) {1237THROW_(vmSymbols::java_lang_NullPointerException(), NULL);1238}12391240if (java_lang_Class::is_primitive(mirror)) {1241// Primitive types does not have a protection domain.1242return NULL;1243}12441245oop pd = java_lang_Class::protection_domain(mirror);1246return (jobject) JNIHandles::make_local(THREAD, pd);1247JVM_END124812491250// Returns the inherited_access_control_context field of the running thread.1251JVM_ENTRY(jobject, JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls))1252oop result = java_lang_Thread::inherited_access_control_context(thread->threadObj());1253return JNIHandles::make_local(THREAD, result);1254JVM_END12551256JVM_ENTRY(jobject, JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls))1257if (!UsePrivilegedStack) return NULL;12581259ResourceMark rm(THREAD);1260GrowableArray<Handle>* local_array = new GrowableArray<Handle>(12);1261JvmtiVMObjectAllocEventCollector oam;12621263// count the protection domains on the execution stack. We collapse1264// duplicate consecutive protection domains into a single one, as1265// well as stopping when we hit a privileged frame.12661267oop previous_protection_domain = NULL;1268Handle privileged_context(thread, NULL);1269bool is_privileged = false;1270oop protection_domain = NULL;12711272// Iterate through Java frames1273vframeStream vfst(thread);1274for(; !vfst.at_end(); vfst.next()) {1275// get method of frame1276Method* method = vfst.method();12771278// stop at the first privileged frame1279if (method->method_holder() == vmClasses::AccessController_klass() &&1280method->name() == vmSymbols::executePrivileged_name())1281{1282// this frame is privileged1283is_privileged = true;12841285javaVFrame *priv = vfst.asJavaVFrame(); // executePrivileged12861287StackValueCollection* locals = priv->locals();1288StackValue* ctx_sv = locals->at(1); // AccessControlContext context1289StackValue* clr_sv = locals->at(2); // Class<?> caller1290assert(!ctx_sv->obj_is_scalar_replaced(), "found scalar-replaced object");1291assert(!clr_sv->obj_is_scalar_replaced(), "found scalar-replaced object");1292privileged_context = ctx_sv->get_obj();1293Handle caller = clr_sv->get_obj();12941295Klass *caller_klass = java_lang_Class::as_Klass(caller());1296protection_domain = caller_klass->protection_domain();1297} else {1298protection_domain = method->method_holder()->protection_domain();1299}13001301if ((previous_protection_domain != protection_domain) && (protection_domain != NULL)) {1302local_array->push(Handle(thread, protection_domain));1303previous_protection_domain = protection_domain;1304}13051306if (is_privileged) break;1307}130813091310// either all the domains on the stack were system domains, or1311// we had a privileged system domain1312if (local_array->is_empty()) {1313if (is_privileged && privileged_context.is_null()) return NULL;13141315oop result = java_security_AccessControlContext::create(objArrayHandle(), is_privileged, privileged_context, CHECK_NULL);1316return JNIHandles::make_local(THREAD, result);1317}13181319objArrayOop context = oopFactory::new_objArray(vmClasses::ProtectionDomain_klass(),1320local_array->length(), CHECK_NULL);1321objArrayHandle h_context(thread, context);1322for (int index = 0; index < local_array->length(); index++) {1323h_context->obj_at_put(index, local_array->at(index)());1324}13251326oop result = java_security_AccessControlContext::create(h_context, is_privileged, privileged_context, CHECK_NULL);13271328return JNIHandles::make_local(THREAD, result);1329JVM_END133013311332JVM_ENTRY(jboolean, JVM_IsArrayClass(JNIEnv *env, jclass cls))1333Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));1334return (k != NULL) && k->is_array_klass() ? true : false;1335JVM_END133613371338JVM_ENTRY(jboolean, JVM_IsPrimitiveClass(JNIEnv *env, jclass cls))1339oop mirror = JNIHandles::resolve_non_null(cls);1340return (jboolean) java_lang_Class::is_primitive(mirror);1341JVM_END134213431344JVM_ENTRY(jint, JVM_GetClassModifiers(JNIEnv *env, jclass cls))1345oop mirror = JNIHandles::resolve_non_null(cls);1346if (java_lang_Class::is_primitive(mirror)) {1347// Primitive type1348return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC;1349}13501351Klass* k = java_lang_Class::as_Klass(mirror);1352debug_only(int computed_modifiers = k->compute_modifier_flags());1353assert(k->modifier_flags() == computed_modifiers, "modifiers cache is OK");1354return k->modifier_flags();1355JVM_END135613571358// Inner class reflection ///////////////////////////////////////////////////////////////////////////////13591360JVM_ENTRY(jobjectArray, JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass))1361JvmtiVMObjectAllocEventCollector oam;1362// ofClass is a reference to a java_lang_Class object. The mirror object1363// of an InstanceKlass1364oop ofMirror = JNIHandles::resolve_non_null(ofClass);1365if (java_lang_Class::is_primitive(ofMirror) ||1366! java_lang_Class::as_Klass(ofMirror)->is_instance_klass()) {1367oop result = oopFactory::new_objArray(vmClasses::Class_klass(), 0, CHECK_NULL);1368return (jobjectArray)JNIHandles::make_local(THREAD, result);1369}13701371InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(ofMirror));1372InnerClassesIterator iter(k);13731374if (iter.length() == 0) {1375// Neither an inner nor outer class1376oop result = oopFactory::new_objArray(vmClasses::Class_klass(), 0, CHECK_NULL);1377return (jobjectArray)JNIHandles::make_local(THREAD, result);1378}13791380// find inner class info1381constantPoolHandle cp(thread, k->constants());1382int length = iter.length();13831384// Allocate temp. result array1385objArrayOop r = oopFactory::new_objArray(vmClasses::Class_klass(), length/4, CHECK_NULL);1386objArrayHandle result (THREAD, r);1387int members = 0;13881389for (; !iter.done(); iter.next()) {1390int ioff = iter.inner_class_info_index();1391int ooff = iter.outer_class_info_index();13921393if (ioff != 0 && ooff != 0) {1394// Check to see if the name matches the class we're looking for1395// before attempting to find the class.1396if (cp->klass_name_at_matches(k, ooff)) {1397Klass* outer_klass = cp->klass_at(ooff, CHECK_NULL);1398if (outer_klass == k) {1399Klass* ik = cp->klass_at(ioff, CHECK_NULL);1400InstanceKlass* inner_klass = InstanceKlass::cast(ik);14011402// Throws an exception if outer klass has not declared k as1403// an inner klass1404Reflection::check_for_inner_class(k, inner_klass, true, CHECK_NULL);14051406result->obj_at_put(members, inner_klass->java_mirror());1407members++;1408}1409}1410}1411}14121413if (members != length) {1414// Return array of right length1415objArrayOop res = oopFactory::new_objArray(vmClasses::Class_klass(), members, CHECK_NULL);1416for(int i = 0; i < members; i++) {1417res->obj_at_put(i, result->obj_at(i));1418}1419return (jobjectArray)JNIHandles::make_local(THREAD, res);1420}14211422return (jobjectArray)JNIHandles::make_local(THREAD, result());1423JVM_END142414251426JVM_ENTRY(jclass, JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass))1427{1428// ofClass is a reference to a java_lang_Class object.1429oop ofMirror = JNIHandles::resolve_non_null(ofClass);1430if (java_lang_Class::is_primitive(ofMirror)) {1431return NULL;1432}1433Klass* klass = java_lang_Class::as_Klass(ofMirror);1434if (!klass->is_instance_klass()) {1435return NULL;1436}14371438bool inner_is_member = false;1439Klass* outer_klass1440= InstanceKlass::cast(klass)->compute_enclosing_class(&inner_is_member, CHECK_NULL);1441if (outer_klass == NULL) return NULL; // already a top-level class1442if (!inner_is_member) return NULL; // a hidden class (inside a method)1443return (jclass) JNIHandles::make_local(THREAD, outer_klass->java_mirror());1444}1445JVM_END14461447JVM_ENTRY(jstring, JVM_GetSimpleBinaryName(JNIEnv *env, jclass cls))1448{1449oop mirror = JNIHandles::resolve_non_null(cls);1450if (java_lang_Class::is_primitive(mirror)) {1451return NULL;1452}1453Klass* klass = java_lang_Class::as_Klass(mirror);1454if (!klass->is_instance_klass()) {1455return NULL;1456}1457InstanceKlass* k = InstanceKlass::cast(klass);1458int ooff = 0, noff = 0;1459if (k->find_inner_classes_attr(&ooff, &noff, THREAD)) {1460if (noff != 0) {1461constantPoolHandle i_cp(thread, k->constants());1462Symbol* name = i_cp->symbol_at(noff);1463Handle str = java_lang_String::create_from_symbol(name, CHECK_NULL);1464return (jstring) JNIHandles::make_local(THREAD, str());1465}1466}1467return NULL;1468}1469JVM_END14701471JVM_ENTRY(jstring, JVM_GetClassSignature(JNIEnv *env, jclass cls))1472assert (cls != NULL, "illegal class");1473JvmtiVMObjectAllocEventCollector oam;1474ResourceMark rm(THREAD);1475oop mirror = JNIHandles::resolve_non_null(cls);1476// Return null for arrays and primatives1477if (!java_lang_Class::is_primitive(mirror)) {1478Klass* k = java_lang_Class::as_Klass(mirror);1479if (k->is_instance_klass()) {1480Symbol* sym = InstanceKlass::cast(k)->generic_signature();1481if (sym == NULL) return NULL;1482Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL);1483return (jstring) JNIHandles::make_local(THREAD, str());1484}1485}1486return NULL;1487JVM_END148814891490JVM_ENTRY(jbyteArray, JVM_GetClassAnnotations(JNIEnv *env, jclass cls))1491assert (cls != NULL, "illegal class");1492oop mirror = JNIHandles::resolve_non_null(cls);1493// Return null for arrays and primitives1494if (!java_lang_Class::is_primitive(mirror)) {1495Klass* k = java_lang_Class::as_Klass(mirror);1496if (k->is_instance_klass()) {1497typeArrayOop a = Annotations::make_java_array(InstanceKlass::cast(k)->class_annotations(), CHECK_NULL);1498return (jbyteArray) JNIHandles::make_local(THREAD, a);1499}1500}1501return NULL;1502JVM_END150315041505static bool jvm_get_field_common(jobject field, fieldDescriptor& fd) {1506// some of this code was adapted from from jni_FromReflectedField15071508oop reflected = JNIHandles::resolve_non_null(field);1509oop mirror = java_lang_reflect_Field::clazz(reflected);1510Klass* k = java_lang_Class::as_Klass(mirror);1511int slot = java_lang_reflect_Field::slot(reflected);1512int modifiers = java_lang_reflect_Field::modifiers(reflected);15131514InstanceKlass* ik = InstanceKlass::cast(k);1515intptr_t offset = ik->field_offset(slot);15161517if (modifiers & JVM_ACC_STATIC) {1518// for static fields we only look in the current class1519if (!ik->find_local_field_from_offset(offset, true, &fd)) {1520assert(false, "cannot find static field");1521return false;1522}1523} else {1524// for instance fields we start with the current class and work1525// our way up through the superclass chain1526if (!ik->find_field_from_offset(offset, false, &fd)) {1527assert(false, "cannot find instance field");1528return false;1529}1530}1531return true;1532}15331534static Method* jvm_get_method_common(jobject method) {1535// some of this code was adapted from from jni_FromReflectedMethod15361537oop reflected = JNIHandles::resolve_non_null(method);1538oop mirror = NULL;1539int slot = 0;15401541if (reflected->klass() == vmClasses::reflect_Constructor_klass()) {1542mirror = java_lang_reflect_Constructor::clazz(reflected);1543slot = java_lang_reflect_Constructor::slot(reflected);1544} else {1545assert(reflected->klass() == vmClasses::reflect_Method_klass(),1546"wrong type");1547mirror = java_lang_reflect_Method::clazz(reflected);1548slot = java_lang_reflect_Method::slot(reflected);1549}1550Klass* k = java_lang_Class::as_Klass(mirror);15511552Method* m = InstanceKlass::cast(k)->method_with_idnum(slot);1553assert(m != NULL, "cannot find method");1554return m; // caller has to deal with NULL in product mode1555}15561557/* Type use annotations support (JDK 1.8) */15581559JVM_ENTRY(jbyteArray, JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls))1560assert (cls != NULL, "illegal class");1561ResourceMark rm(THREAD);1562// Return null for arrays and primitives1563if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {1564Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));1565if (k->is_instance_klass()) {1566AnnotationArray* type_annotations = InstanceKlass::cast(k)->class_type_annotations();1567if (type_annotations != NULL) {1568typeArrayOop a = Annotations::make_java_array(type_annotations, CHECK_NULL);1569return (jbyteArray) JNIHandles::make_local(THREAD, a);1570}1571}1572}1573return NULL;1574JVM_END15751576JVM_ENTRY(jbyteArray, JVM_GetMethodTypeAnnotations(JNIEnv *env, jobject method))1577assert (method != NULL, "illegal method");1578// method is a handle to a java.lang.reflect.Method object1579Method* m = jvm_get_method_common(method);1580if (m == NULL) {1581return NULL;1582}15831584AnnotationArray* type_annotations = m->type_annotations();1585if (type_annotations != NULL) {1586typeArrayOop a = Annotations::make_java_array(type_annotations, CHECK_NULL);1587return (jbyteArray) JNIHandles::make_local(THREAD, a);1588}15891590return NULL;1591JVM_END15921593JVM_ENTRY(jbyteArray, JVM_GetFieldTypeAnnotations(JNIEnv *env, jobject field))1594assert (field != NULL, "illegal field");1595fieldDescriptor fd;1596bool gotFd = jvm_get_field_common(field, fd);1597if (!gotFd) {1598return NULL;1599}16001601return (jbyteArray) JNIHandles::make_local(THREAD, Annotations::make_java_array(fd.type_annotations(), THREAD));1602JVM_END16031604static void bounds_check(const constantPoolHandle& cp, jint index, TRAPS) {1605if (!cp->is_within_bounds(index)) {1606THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Constant pool index out of bounds");1607}1608}16091610JVM_ENTRY(jobjectArray, JVM_GetMethodParameters(JNIEnv *env, jobject method))1611{1612// method is a handle to a java.lang.reflect.Method object1613Method* method_ptr = jvm_get_method_common(method);1614methodHandle mh (THREAD, method_ptr);1615Handle reflected_method (THREAD, JNIHandles::resolve_non_null(method));1616const int num_params = mh->method_parameters_length();16171618if (num_params < 0) {1619// A -1 return value from method_parameters_length means there is no1620// parameter data. Return null to indicate this to the reflection1621// API.1622assert(num_params == -1, "num_params should be -1 if it is less than zero");1623return (jobjectArray)NULL;1624} else {1625// Otherwise, we return something up to reflection, even if it is1626// a zero-length array. Why? Because in some cases this can1627// trigger a MalformedParametersException.16281629// make sure all the symbols are properly formatted1630for (int i = 0; i < num_params; i++) {1631MethodParametersElement* params = mh->method_parameters_start();1632int index = params[i].name_cp_index;1633constantPoolHandle cp(THREAD, mh->constants());1634bounds_check(cp, index, CHECK_NULL);16351636if (0 != index && !mh->constants()->tag_at(index).is_utf8()) {1637THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),1638"Wrong type at constant pool index");1639}16401641}16421643objArrayOop result_oop = oopFactory::new_objArray(vmClasses::reflect_Parameter_klass(), num_params, CHECK_NULL);1644objArrayHandle result (THREAD, result_oop);16451646for (int i = 0; i < num_params; i++) {1647MethodParametersElement* params = mh->method_parameters_start();1648// For a 0 index, give a NULL symbol1649Symbol* sym = 0 != params[i].name_cp_index ?1650mh->constants()->symbol_at(params[i].name_cp_index) : NULL;1651int flags = params[i].flags;1652oop param = Reflection::new_parameter(reflected_method, i, sym,1653flags, CHECK_NULL);1654result->obj_at_put(i, param);1655}1656return (jobjectArray)JNIHandles::make_local(THREAD, result());1657}1658}1659JVM_END16601661// New (JDK 1.4) reflection implementation /////////////////////////////////////16621663JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly))1664{1665JvmtiVMObjectAllocEventCollector oam;16661667oop ofMirror = JNIHandles::resolve_non_null(ofClass);1668// Exclude primitive types and array types1669if (java_lang_Class::is_primitive(ofMirror) ||1670java_lang_Class::as_Klass(ofMirror)->is_array_klass()) {1671// Return empty array1672oop res = oopFactory::new_objArray(vmClasses::reflect_Field_klass(), 0, CHECK_NULL);1673return (jobjectArray) JNIHandles::make_local(THREAD, res);1674}16751676InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(ofMirror));1677constantPoolHandle cp(THREAD, k->constants());16781679// Ensure class is linked1680k->link_class(CHECK_NULL);16811682// Allocate result1683int num_fields;16841685if (publicOnly) {1686num_fields = 0;1687for (JavaFieldStream fs(k); !fs.done(); fs.next()) {1688if (fs.access_flags().is_public()) ++num_fields;1689}1690} else {1691num_fields = k->java_fields_count();1692}16931694objArrayOop r = oopFactory::new_objArray(vmClasses::reflect_Field_klass(), num_fields, CHECK_NULL);1695objArrayHandle result (THREAD, r);16961697int out_idx = 0;1698fieldDescriptor fd;1699for (JavaFieldStream fs(k); !fs.done(); fs.next()) {1700if (!publicOnly || fs.access_flags().is_public()) {1701fd.reinitialize(k, fs.index());1702oop field = Reflection::new_field(&fd, CHECK_NULL);1703result->obj_at_put(out_idx, field);1704++out_idx;1705}1706}1707assert(out_idx == num_fields, "just checking");1708return (jobjectArray) JNIHandles::make_local(THREAD, result());1709}1710JVM_END17111712// A class is a record if and only if it is final and a direct subclass of1713// java.lang.Record and has a Record attribute; otherwise, it is not a record.1714JVM_ENTRY(jboolean, JVM_IsRecord(JNIEnv *env, jclass cls))1715{1716Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));1717if (k != NULL && k->is_instance_klass()) {1718InstanceKlass* ik = InstanceKlass::cast(k);1719return ik->is_record();1720} else {1721return false;1722}1723}1724JVM_END17251726// Returns an array containing the components of the Record attribute,1727// or NULL if the attribute is not present.1728//1729// Note that this function returns the components of the Record attribute1730// even if the class is not a record.1731JVM_ENTRY(jobjectArray, JVM_GetRecordComponents(JNIEnv* env, jclass ofClass))1732{1733Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass));1734assert(c->is_instance_klass(), "must be");1735InstanceKlass* ik = InstanceKlass::cast(c);17361737Array<RecordComponent*>* components = ik->record_components();1738if (components != NULL) {1739JvmtiVMObjectAllocEventCollector oam;1740constantPoolHandle cp(THREAD, ik->constants());1741int length = components->length();1742assert(length >= 0, "unexpected record_components length");1743objArrayOop record_components =1744oopFactory::new_objArray(vmClasses::RecordComponent_klass(), length, CHECK_NULL);1745objArrayHandle components_h (THREAD, record_components);17461747for (int x = 0; x < length; x++) {1748RecordComponent* component = components->at(x);1749assert(component != NULL, "unexpected NULL record component");1750oop component_oop = java_lang_reflect_RecordComponent::create(ik, component, CHECK_NULL);1751components_h->obj_at_put(x, component_oop);1752}1753return (jobjectArray)JNIHandles::make_local(THREAD, components_h());1754}17551756return NULL;1757}1758JVM_END17591760static bool select_method(const methodHandle& method, bool want_constructor) {1761if (want_constructor) {1762return (method->is_initializer() && !method->is_static());1763} else {1764return (!method->is_initializer() && !method->is_overpass());1765}1766}17671768static jobjectArray get_class_declared_methods_helper(1769JNIEnv *env,1770jclass ofClass, jboolean publicOnly,1771bool want_constructor,1772Klass* klass, TRAPS) {17731774JvmtiVMObjectAllocEventCollector oam;17751776oop ofMirror = JNIHandles::resolve_non_null(ofClass);1777// Exclude primitive types and array types1778if (java_lang_Class::is_primitive(ofMirror)1779|| java_lang_Class::as_Klass(ofMirror)->is_array_klass()) {1780// Return empty array1781oop res = oopFactory::new_objArray(klass, 0, CHECK_NULL);1782return (jobjectArray) JNIHandles::make_local(THREAD, res);1783}17841785InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(ofMirror));17861787// Ensure class is linked1788k->link_class(CHECK_NULL);17891790Array<Method*>* methods = k->methods();1791int methods_length = methods->length();17921793// Save original method_idnum in case of redefinition, which can change1794// the idnum of obsolete methods. The new method will have the same idnum1795// but if we refresh the methods array, the counts will be wrong.1796ResourceMark rm(THREAD);1797GrowableArray<int>* idnums = new GrowableArray<int>(methods_length);1798int num_methods = 0;17991800for (int i = 0; i < methods_length; i++) {1801methodHandle method(THREAD, methods->at(i));1802if (select_method(method, want_constructor)) {1803if (!publicOnly || method->is_public()) {1804idnums->push(method->method_idnum());1805++num_methods;1806}1807}1808}18091810// Allocate result1811objArrayOop r = oopFactory::new_objArray(klass, num_methods, CHECK_NULL);1812objArrayHandle result (THREAD, r);18131814// Now just put the methods that we selected above, but go by their idnum1815// in case of redefinition. The methods can be redefined at any safepoint,1816// so above when allocating the oop array and below when creating reflect1817// objects.1818for (int i = 0; i < num_methods; i++) {1819methodHandle method(THREAD, k->method_with_idnum(idnums->at(i)));1820if (method.is_null()) {1821// Method may have been deleted and seems this API can handle null1822// Otherwise should probably put a method that throws NSME1823result->obj_at_put(i, NULL);1824} else {1825oop m;1826if (want_constructor) {1827m = Reflection::new_constructor(method, CHECK_NULL);1828} else {1829m = Reflection::new_method(method, false, CHECK_NULL);1830}1831result->obj_at_put(i, m);1832}1833}18341835return (jobjectArray) JNIHandles::make_local(THREAD, result());1836}18371838JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly))1839{1840return get_class_declared_methods_helper(env, ofClass, publicOnly,1841/*want_constructor*/ false,1842vmClasses::reflect_Method_klass(), THREAD);1843}1844JVM_END18451846JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly))1847{1848return get_class_declared_methods_helper(env, ofClass, publicOnly,1849/*want_constructor*/ true,1850vmClasses::reflect_Constructor_klass(), THREAD);1851}1852JVM_END18531854JVM_ENTRY(jint, JVM_GetClassAccessFlags(JNIEnv *env, jclass cls))1855{1856oop mirror = JNIHandles::resolve_non_null(cls);1857if (java_lang_Class::is_primitive(mirror)) {1858// Primitive type1859return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC;1860}18611862Klass* k = java_lang_Class::as_Klass(mirror);1863return k->access_flags().as_int() & JVM_ACC_WRITTEN_FLAGS;1864}1865JVM_END18661867JVM_ENTRY(jboolean, JVM_AreNestMates(JNIEnv *env, jclass current, jclass member))1868{1869Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));1870assert(c->is_instance_klass(), "must be");1871InstanceKlass* ck = InstanceKlass::cast(c);1872Klass* m = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(member));1873assert(m->is_instance_klass(), "must be");1874InstanceKlass* mk = InstanceKlass::cast(m);1875return ck->has_nestmate_access_to(mk, THREAD);1876}1877JVM_END18781879JVM_ENTRY(jclass, JVM_GetNestHost(JNIEnv* env, jclass current))1880{1881// current is not a primitive or array class1882Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));1883assert(c->is_instance_klass(), "must be");1884InstanceKlass* ck = InstanceKlass::cast(c);1885InstanceKlass* host = ck->nest_host(THREAD);1886return (jclass) (host == NULL ? NULL :1887JNIHandles::make_local(THREAD, host->java_mirror()));1888}1889JVM_END18901891JVM_ENTRY(jobjectArray, JVM_GetNestMembers(JNIEnv* env, jclass current))1892{1893// current is not a primitive or array class1894ResourceMark rm(THREAD);1895Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));1896assert(c->is_instance_klass(), "must be");1897InstanceKlass* ck = InstanceKlass::cast(c);1898InstanceKlass* host = ck->nest_host(THREAD);18991900log_trace(class, nestmates)("Calling GetNestMembers for type %s with nest-host %s",1901ck->external_name(), host->external_name());1902{1903JvmtiVMObjectAllocEventCollector oam;1904Array<u2>* members = host->nest_members();1905int length = members == NULL ? 0 : members->length();19061907log_trace(class, nestmates)(" - host has %d listed nest members", length);19081909// nest host is first in the array so make it one bigger1910objArrayOop r = oopFactory::new_objArray(vmClasses::Class_klass(),1911length + 1, CHECK_NULL);1912objArrayHandle result(THREAD, r);1913result->obj_at_put(0, host->java_mirror());1914if (length != 0) {1915int count = 0;1916for (int i = 0; i < length; i++) {1917int cp_index = members->at(i);1918Klass* k = host->constants()->klass_at(cp_index, THREAD);1919if (HAS_PENDING_EXCEPTION) {1920if (PENDING_EXCEPTION->is_a(vmClasses::VirtualMachineError_klass())) {1921return NULL; // propagate VMEs1922}1923if (log_is_enabled(Trace, class, nestmates)) {1924stringStream ss;1925char* target_member_class = host->constants()->klass_name_at(cp_index)->as_C_string();1926ss.print(" - resolution of nest member %s failed: ", target_member_class);1927java_lang_Throwable::print(PENDING_EXCEPTION, &ss);1928log_trace(class, nestmates)("%s", ss.as_string());1929}1930CLEAR_PENDING_EXCEPTION;1931continue;1932}1933if (k->is_instance_klass()) {1934InstanceKlass* ik = InstanceKlass::cast(k);1935InstanceKlass* nest_host_k = ik->nest_host(CHECK_NULL);1936if (nest_host_k == host) {1937result->obj_at_put(count+1, k->java_mirror());1938count++;1939log_trace(class, nestmates)(" - [%d] = %s", count, ik->external_name());1940} else {1941log_trace(class, nestmates)(" - skipping member %s with different host %s",1942ik->external_name(), nest_host_k->external_name());1943}1944} else {1945log_trace(class, nestmates)(" - skipping member %s that is not an instance class",1946k->external_name());1947}1948}1949if (count < length) {1950// we had invalid entries so we need to compact the array1951log_trace(class, nestmates)(" - compacting array from length %d to %d",1952length + 1, count + 1);19531954objArrayOop r2 = oopFactory::new_objArray(vmClasses::Class_klass(),1955count + 1, CHECK_NULL);1956objArrayHandle result2(THREAD, r2);1957for (int i = 0; i < count + 1; i++) {1958result2->obj_at_put(i, result->obj_at(i));1959}1960return (jobjectArray)JNIHandles::make_local(THREAD, result2());1961}1962}1963else {1964assert(host == ck || ck->is_hidden(), "must be singleton nest or dynamic nestmate");1965}1966return (jobjectArray)JNIHandles::make_local(THREAD, result());1967}1968}1969JVM_END19701971JVM_ENTRY(jobjectArray, JVM_GetPermittedSubclasses(JNIEnv* env, jclass current))1972{1973oop mirror = JNIHandles::resolve_non_null(current);1974assert(!java_lang_Class::is_primitive(mirror), "should not be");1975Klass* c = java_lang_Class::as_Klass(mirror);1976assert(c->is_instance_klass(), "must be");1977InstanceKlass* ik = InstanceKlass::cast(c);1978ResourceMark rm(THREAD);1979log_trace(class, sealed)("Calling GetPermittedSubclasses for %s type %s",1980ik->is_sealed() ? "sealed" : "non-sealed", ik->external_name());1981if (ik->is_sealed()) {1982JvmtiVMObjectAllocEventCollector oam;1983Array<u2>* subclasses = ik->permitted_subclasses();1984int length = subclasses->length();19851986log_trace(class, sealed)(" - sealed class has %d permitted subclasses", length);19871988objArrayOop r = oopFactory::new_objArray(vmClasses::Class_klass(),1989length, CHECK_NULL);1990objArrayHandle result(THREAD, r);1991int count = 0;1992for (int i = 0; i < length; i++) {1993int cp_index = subclasses->at(i);1994Klass* k = ik->constants()->klass_at(cp_index, THREAD);1995if (HAS_PENDING_EXCEPTION) {1996if (PENDING_EXCEPTION->is_a(vmClasses::VirtualMachineError_klass())) {1997return NULL; // propagate VMEs1998}1999if (log_is_enabled(Trace, class, sealed)) {2000stringStream ss;2001char* permitted_subclass = ik->constants()->klass_name_at(cp_index)->as_C_string();2002ss.print(" - resolution of permitted subclass %s failed: ", permitted_subclass);2003java_lang_Throwable::print(PENDING_EXCEPTION, &ss);2004log_trace(class, sealed)("%s", ss.as_string());2005}20062007CLEAR_PENDING_EXCEPTION;2008continue;2009}2010if (k->is_instance_klass()) {2011result->obj_at_put(count++, k->java_mirror());2012log_trace(class, sealed)(" - [%d] = %s", count, k->external_name());2013}2014}2015if (count < length) {2016// we had invalid entries so we need to compact the array2017objArrayOop r2 = oopFactory::new_objArray(vmClasses::Class_klass(),2018count, CHECK_NULL);2019objArrayHandle result2(THREAD, r2);2020for (int i = 0; i < count; i++) {2021result2->obj_at_put(i, result->obj_at(i));2022}2023return (jobjectArray)JNIHandles::make_local(THREAD, result2());2024}2025return (jobjectArray)JNIHandles::make_local(THREAD, result());2026} else {2027return NULL;2028}2029}2030JVM_END20312032// Constant pool access //////////////////////////////////////////////////////////20332034JVM_ENTRY(jobject, JVM_GetClassConstantPool(JNIEnv *env, jclass cls))2035{2036JvmtiVMObjectAllocEventCollector oam;2037oop mirror = JNIHandles::resolve_non_null(cls);2038// Return null for primitives and arrays2039if (!java_lang_Class::is_primitive(mirror)) {2040Klass* k = java_lang_Class::as_Klass(mirror);2041if (k->is_instance_klass()) {2042InstanceKlass* k_h = InstanceKlass::cast(k);2043Handle jcp = reflect_ConstantPool::create(CHECK_NULL);2044reflect_ConstantPool::set_cp(jcp(), k_h->constants());2045return JNIHandles::make_local(THREAD, jcp());2046}2047}2048return NULL;2049}2050JVM_END205120522053JVM_ENTRY(jint, JVM_ConstantPoolGetSize(JNIEnv *env, jobject obj, jobject unused))2054{2055constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2056return cp->length();2057}2058JVM_END205920602061JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject obj, jobject unused, jint index))2062{2063constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2064bounds_check(cp, index, CHECK_NULL);2065constantTag tag = cp->tag_at(index);2066if (!tag.is_klass() && !tag.is_unresolved_klass()) {2067THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2068}2069Klass* k = cp->klass_at(index, CHECK_NULL);2070return (jclass) JNIHandles::make_local(THREAD, k->java_mirror());2071}2072JVM_END20732074JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject obj, jobject unused, jint index))2075{2076constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2077bounds_check(cp, index, CHECK_NULL);2078constantTag tag = cp->tag_at(index);2079if (!tag.is_klass() && !tag.is_unresolved_klass()) {2080THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2081}2082Klass* k = ConstantPool::klass_at_if_loaded(cp, index);2083if (k == NULL) return NULL;2084return (jclass) JNIHandles::make_local(THREAD, k->java_mirror());2085}2086JVM_END20872088static jobject get_method_at_helper(const constantPoolHandle& cp, jint index, bool force_resolution, TRAPS) {2089constantTag tag = cp->tag_at(index);2090if (!tag.is_method() && !tag.is_interface_method()) {2091THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2092}2093int klass_ref = cp->uncached_klass_ref_index_at(index);2094Klass* k_o;2095if (force_resolution) {2096k_o = cp->klass_at(klass_ref, CHECK_NULL);2097} else {2098k_o = ConstantPool::klass_at_if_loaded(cp, klass_ref);2099if (k_o == NULL) return NULL;2100}2101InstanceKlass* k = InstanceKlass::cast(k_o);2102Symbol* name = cp->uncached_name_ref_at(index);2103Symbol* sig = cp->uncached_signature_ref_at(index);2104methodHandle m (THREAD, k->find_method(name, sig));2105if (m.is_null()) {2106THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "Unable to look up method in target class");2107}2108oop method;2109if (!m->is_initializer() || m->is_static()) {2110method = Reflection::new_method(m, true, CHECK_NULL);2111} else {2112method = Reflection::new_constructor(m, CHECK_NULL);2113}2114return JNIHandles::make_local(THREAD, method);2115}21162117JVM_ENTRY(jobject, JVM_ConstantPoolGetMethodAt(JNIEnv *env, jobject obj, jobject unused, jint index))2118{2119JvmtiVMObjectAllocEventCollector oam;2120constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2121bounds_check(cp, index, CHECK_NULL);2122jobject res = get_method_at_helper(cp, index, true, CHECK_NULL);2123return res;2124}2125JVM_END21262127JVM_ENTRY(jobject, JVM_ConstantPoolGetMethodAtIfLoaded(JNIEnv *env, jobject obj, jobject unused, jint index))2128{2129JvmtiVMObjectAllocEventCollector oam;2130constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2131bounds_check(cp, index, CHECK_NULL);2132jobject res = get_method_at_helper(cp, index, false, CHECK_NULL);2133return res;2134}2135JVM_END21362137static jobject get_field_at_helper(constantPoolHandle cp, jint index, bool force_resolution, TRAPS) {2138constantTag tag = cp->tag_at(index);2139if (!tag.is_field()) {2140THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2141}2142int klass_ref = cp->uncached_klass_ref_index_at(index);2143Klass* k_o;2144if (force_resolution) {2145k_o = cp->klass_at(klass_ref, CHECK_NULL);2146} else {2147k_o = ConstantPool::klass_at_if_loaded(cp, klass_ref);2148if (k_o == NULL) return NULL;2149}2150InstanceKlass* k = InstanceKlass::cast(k_o);2151Symbol* name = cp->uncached_name_ref_at(index);2152Symbol* sig = cp->uncached_signature_ref_at(index);2153fieldDescriptor fd;2154Klass* target_klass = k->find_field(name, sig, &fd);2155if (target_klass == NULL) {2156THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "Unable to look up field in target class");2157}2158oop field = Reflection::new_field(&fd, CHECK_NULL);2159return JNIHandles::make_local(THREAD, field);2160}21612162JVM_ENTRY(jobject, JVM_ConstantPoolGetFieldAt(JNIEnv *env, jobject obj, jobject unusedl, jint index))2163{2164JvmtiVMObjectAllocEventCollector oam;2165constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2166bounds_check(cp, index, CHECK_NULL);2167jobject res = get_field_at_helper(cp, index, true, CHECK_NULL);2168return res;2169}2170JVM_END21712172JVM_ENTRY(jobject, JVM_ConstantPoolGetFieldAtIfLoaded(JNIEnv *env, jobject obj, jobject unused, jint index))2173{2174JvmtiVMObjectAllocEventCollector oam;2175constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2176bounds_check(cp, index, CHECK_NULL);2177jobject res = get_field_at_helper(cp, index, false, CHECK_NULL);2178return res;2179}2180JVM_END21812182JVM_ENTRY(jobjectArray, JVM_ConstantPoolGetMemberRefInfoAt(JNIEnv *env, jobject obj, jobject unused, jint index))2183{2184JvmtiVMObjectAllocEventCollector oam;2185constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2186bounds_check(cp, index, CHECK_NULL);2187constantTag tag = cp->tag_at(index);2188if (!tag.is_field_or_method()) {2189THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2190}2191int klass_ref = cp->uncached_klass_ref_index_at(index);2192Symbol* klass_name = cp->klass_name_at(klass_ref);2193Symbol* member_name = cp->uncached_name_ref_at(index);2194Symbol* member_sig = cp->uncached_signature_ref_at(index);2195objArrayOop dest_o = oopFactory::new_objArray(vmClasses::String_klass(), 3, CHECK_NULL);2196objArrayHandle dest(THREAD, dest_o);2197Handle str = java_lang_String::create_from_symbol(klass_name, CHECK_NULL);2198dest->obj_at_put(0, str());2199str = java_lang_String::create_from_symbol(member_name, CHECK_NULL);2200dest->obj_at_put(1, str());2201str = java_lang_String::create_from_symbol(member_sig, CHECK_NULL);2202dest->obj_at_put(2, str());2203return (jobjectArray) JNIHandles::make_local(THREAD, dest());2204}2205JVM_END22062207JVM_ENTRY(jint, JVM_ConstantPoolGetClassRefIndexAt(JNIEnv *env, jobject obj, jobject unused, jint index))2208{2209JvmtiVMObjectAllocEventCollector oam;2210constantPoolHandle cp(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2211bounds_check(cp, index, CHECK_0);2212constantTag tag = cp->tag_at(index);2213if (!tag.is_field_or_method()) {2214THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2215}2216return (jint) cp->uncached_klass_ref_index_at(index);2217}2218JVM_END22192220JVM_ENTRY(jint, JVM_ConstantPoolGetNameAndTypeRefIndexAt(JNIEnv *env, jobject obj, jobject unused, jint index))2221{2222JvmtiVMObjectAllocEventCollector oam;2223constantPoolHandle cp(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2224bounds_check(cp, index, CHECK_0);2225constantTag tag = cp->tag_at(index);2226if (!tag.is_invoke_dynamic() && !tag.is_field_or_method()) {2227THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2228}2229return (jint) cp->uncached_name_and_type_ref_index_at(index);2230}2231JVM_END22322233JVM_ENTRY(jobjectArray, JVM_ConstantPoolGetNameAndTypeRefInfoAt(JNIEnv *env, jobject obj, jobject unused, jint index))2234{2235JvmtiVMObjectAllocEventCollector oam;2236constantPoolHandle cp(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2237bounds_check(cp, index, CHECK_NULL);2238constantTag tag = cp->tag_at(index);2239if (!tag.is_name_and_type()) {2240THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2241}2242Symbol* member_name = cp->symbol_at(cp->name_ref_index_at(index));2243Symbol* member_sig = cp->symbol_at(cp->signature_ref_index_at(index));2244objArrayOop dest_o = oopFactory::new_objArray(vmClasses::String_klass(), 2, CHECK_NULL);2245objArrayHandle dest(THREAD, dest_o);2246Handle str = java_lang_String::create_from_symbol(member_name, CHECK_NULL);2247dest->obj_at_put(0, str());2248str = java_lang_String::create_from_symbol(member_sig, CHECK_NULL);2249dest->obj_at_put(1, str());2250return (jobjectArray) JNIHandles::make_local(THREAD, dest());2251}2252JVM_END22532254JVM_ENTRY(jint, JVM_ConstantPoolGetIntAt(JNIEnv *env, jobject obj, jobject unused, jint index))2255{2256constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2257bounds_check(cp, index, CHECK_0);2258constantTag tag = cp->tag_at(index);2259if (!tag.is_int()) {2260THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2261}2262return cp->int_at(index);2263}2264JVM_END22652266JVM_ENTRY(jlong, JVM_ConstantPoolGetLongAt(JNIEnv *env, jobject obj, jobject unused, jint index))2267{2268constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2269bounds_check(cp, index, CHECK_(0L));2270constantTag tag = cp->tag_at(index);2271if (!tag.is_long()) {2272THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2273}2274return cp->long_at(index);2275}2276JVM_END22772278JVM_ENTRY(jfloat, JVM_ConstantPoolGetFloatAt(JNIEnv *env, jobject obj, jobject unused, jint index))2279{2280constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2281bounds_check(cp, index, CHECK_(0.0f));2282constantTag tag = cp->tag_at(index);2283if (!tag.is_float()) {2284THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2285}2286return cp->float_at(index);2287}2288JVM_END22892290JVM_ENTRY(jdouble, JVM_ConstantPoolGetDoubleAt(JNIEnv *env, jobject obj, jobject unused, jint index))2291{2292constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2293bounds_check(cp, index, CHECK_(0.0));2294constantTag tag = cp->tag_at(index);2295if (!tag.is_double()) {2296THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2297}2298return cp->double_at(index);2299}2300JVM_END23012302JVM_ENTRY(jstring, JVM_ConstantPoolGetStringAt(JNIEnv *env, jobject obj, jobject unused, jint index))2303{2304constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2305bounds_check(cp, index, CHECK_NULL);2306constantTag tag = cp->tag_at(index);2307if (!tag.is_string()) {2308THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2309}2310oop str = cp->string_at(index, CHECK_NULL);2311return (jstring) JNIHandles::make_local(THREAD, str);2312}2313JVM_END23142315JVM_ENTRY(jstring, JVM_ConstantPoolGetUTF8At(JNIEnv *env, jobject obj, jobject unused, jint index))2316{2317JvmtiVMObjectAllocEventCollector oam;2318constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2319bounds_check(cp, index, CHECK_NULL);2320constantTag tag = cp->tag_at(index);2321if (!tag.is_symbol()) {2322THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2323}2324Symbol* sym = cp->symbol_at(index);2325Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL);2326return (jstring) JNIHandles::make_local(THREAD, str());2327}2328JVM_END23292330JVM_ENTRY(jbyte, JVM_ConstantPoolGetTagAt(JNIEnv *env, jobject obj, jobject unused, jint index))2331{2332constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2333bounds_check(cp, index, CHECK_0);2334constantTag tag = cp->tag_at(index);2335jbyte result = tag.value();2336// If returned tag values are not from the JVM spec, e.g. tags from 100 to 105,2337// they are changed to the corresponding tags from the JVM spec, so that java code in2338// sun.reflect.ConstantPool will return only tags from the JVM spec, not internal ones.2339if (tag.is_klass_or_reference()) {2340result = JVM_CONSTANT_Class;2341} else if (tag.is_string_index()) {2342result = JVM_CONSTANT_String;2343} else if (tag.is_method_type_in_error()) {2344result = JVM_CONSTANT_MethodType;2345} else if (tag.is_method_handle_in_error()) {2346result = JVM_CONSTANT_MethodHandle;2347} else if (tag.is_dynamic_constant_in_error()) {2348result = JVM_CONSTANT_Dynamic;2349}2350return result;2351}2352JVM_END23532354// Assertion support. //////////////////////////////////////////////////////////23552356JVM_ENTRY(jboolean, JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls))2357assert(cls != NULL, "bad class");23582359oop r = JNIHandles::resolve(cls);2360assert(! java_lang_Class::is_primitive(r), "primitive classes not allowed");2361if (java_lang_Class::is_primitive(r)) return false;23622363Klass* k = java_lang_Class::as_Klass(r);2364assert(k->is_instance_klass(), "must be an instance klass");2365if (!k->is_instance_klass()) return false;23662367ResourceMark rm(THREAD);2368const char* name = k->name()->as_C_string();2369bool system_class = k->class_loader() == NULL;2370return JavaAssertions::enabled(name, system_class);23712372JVM_END237323742375// Return a new AssertionStatusDirectives object with the fields filled in with2376// command-line assertion arguments (i.e., -ea, -da).2377JVM_ENTRY(jobject, JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused))2378JvmtiVMObjectAllocEventCollector oam;2379oop asd = JavaAssertions::createAssertionStatusDirectives(CHECK_NULL);2380return JNIHandles::make_local(THREAD, asd);2381JVM_END23822383// Verification ////////////////////////////////////////////////////////////////////////////////23842385// Reflection for the verifier /////////////////////////////////////////////////////////////////23862387// RedefineClasses support: bug 6214132 caused verification to fail.2388// All functions from this section should call the jvmtiThreadSate function:2389// Klass* class_to_verify_considering_redefinition(Klass* klass).2390// The function returns a Klass* of the _scratch_class if the verifier2391// was invoked in the middle of the class redefinition.2392// Otherwise it returns its argument value which is the _the_class Klass*.2393// Please, refer to the description in the jvmtiThreadSate.hpp.23942395JVM_ENTRY(const char*, JVM_GetClassNameUTF(JNIEnv *env, jclass cls))2396Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2397k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2398return k->name()->as_utf8();2399JVM_END240024012402JVM_ENTRY(void, JVM_GetClassCPTypes(JNIEnv *env, jclass cls, unsigned char *types))2403Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2404k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2405// types will have length zero if this is not an InstanceKlass2406// (length is determined by call to JVM_GetClassCPEntriesCount)2407if (k->is_instance_klass()) {2408ConstantPool* cp = InstanceKlass::cast(k)->constants();2409for (int index = cp->length() - 1; index >= 0; index--) {2410constantTag tag = cp->tag_at(index);2411types[index] = (tag.is_unresolved_klass()) ? (unsigned char) JVM_CONSTANT_Class : tag.value();2412}2413}2414JVM_END241524162417JVM_ENTRY(jint, JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cls))2418Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2419k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2420return (!k->is_instance_klass()) ? 0 : InstanceKlass::cast(k)->constants()->length();2421JVM_END242224232424JVM_ENTRY(jint, JVM_GetClassFieldsCount(JNIEnv *env, jclass cls))2425Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2426k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2427return (!k->is_instance_klass()) ? 0 : InstanceKlass::cast(k)->java_fields_count();2428JVM_END242924302431JVM_ENTRY(jint, JVM_GetClassMethodsCount(JNIEnv *env, jclass cls))2432Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2433k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2434return (!k->is_instance_klass()) ? 0 : InstanceKlass::cast(k)->methods()->length();2435JVM_END243624372438// The following methods, used for the verifier, are never called with2439// array klasses, so a direct cast to InstanceKlass is safe.2440// Typically, these methods are called in a loop with bounds determined2441// by the results of JVM_GetClass{Fields,Methods}Count, which return2442// zero for arrays.2443JVM_ENTRY(void, JVM_GetMethodIxExceptionIndexes(JNIEnv *env, jclass cls, jint method_index, unsigned short *exceptions))2444Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2445k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2446Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2447int length = method->checked_exceptions_length();2448if (length > 0) {2449CheckedExceptionElement* table= method->checked_exceptions_start();2450for (int i = 0; i < length; i++) {2451exceptions[i] = table[i].class_cp_index;2452}2453}2454JVM_END245524562457JVM_ENTRY(jint, JVM_GetMethodIxExceptionsCount(JNIEnv *env, jclass cls, jint method_index))2458Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2459k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2460Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2461return method->checked_exceptions_length();2462JVM_END246324642465JVM_ENTRY(void, JVM_GetMethodIxByteCode(JNIEnv *env, jclass cls, jint method_index, unsigned char *code))2466Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2467k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2468Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2469memcpy(code, method->code_base(), method->code_size());2470JVM_END247124722473JVM_ENTRY(jint, JVM_GetMethodIxByteCodeLength(JNIEnv *env, jclass cls, jint method_index))2474Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2475k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2476Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2477return method->code_size();2478JVM_END247924802481JVM_ENTRY(void, JVM_GetMethodIxExceptionTableEntry(JNIEnv *env, jclass cls, jint method_index, jint entry_index, JVM_ExceptionTableEntryType *entry))2482Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2483k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2484Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2485ExceptionTable extable(method);2486entry->start_pc = extable.start_pc(entry_index);2487entry->end_pc = extable.end_pc(entry_index);2488entry->handler_pc = extable.handler_pc(entry_index);2489entry->catchType = extable.catch_type_index(entry_index);2490JVM_END249124922493JVM_ENTRY(jint, JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cls, int method_index))2494Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2495k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2496Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2497return method->exception_table_length();2498JVM_END249925002501JVM_ENTRY(jint, JVM_GetMethodIxModifiers(JNIEnv *env, jclass cls, int method_index))2502Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2503k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2504Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2505return method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS;2506JVM_END250725082509JVM_ENTRY(jint, JVM_GetFieldIxModifiers(JNIEnv *env, jclass cls, int field_index))2510Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2511k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2512return InstanceKlass::cast(k)->field_access_flags(field_index) & JVM_RECOGNIZED_FIELD_MODIFIERS;2513JVM_END251425152516JVM_ENTRY(jint, JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cls, int method_index))2517Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2518k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2519Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2520return method->max_locals();2521JVM_END252225232524JVM_ENTRY(jint, JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cls, int method_index))2525Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2526k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2527Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2528return method->size_of_parameters();2529JVM_END253025312532JVM_ENTRY(jint, JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cls, int method_index))2533Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2534k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2535Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2536return method->verifier_max_stack();2537JVM_END253825392540JVM_ENTRY(jboolean, JVM_IsConstructorIx(JNIEnv *env, jclass cls, int method_index))2541ResourceMark rm(THREAD);2542Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2543k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2544Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2545return method->name() == vmSymbols::object_initializer_name();2546JVM_END254725482549JVM_ENTRY(jboolean, JVM_IsVMGeneratedMethodIx(JNIEnv *env, jclass cls, int method_index))2550ResourceMark rm(THREAD);2551Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2552k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2553Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2554return method->is_overpass();2555JVM_END25562557JVM_ENTRY(const char*, JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cls, jint method_index))2558Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2559k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2560Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2561return method->name()->as_utf8();2562JVM_END256325642565JVM_ENTRY(const char*, JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cls, jint method_index))2566Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2567k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2568Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2569return method->signature()->as_utf8();2570JVM_END25712572/**2573* All of these JVM_GetCP-xxx methods are used by the old verifier to2574* read entries in the constant pool. Since the old verifier always2575* works on a copy of the code, it will not see any rewriting that2576* may possibly occur in the middle of verification. So it is important2577* that nothing it calls tries to use the cpCache instead of the raw2578* constant pool, so we must use cp->uncached_x methods when appropriate.2579*/2580JVM_ENTRY(const char*, JVM_GetCPFieldNameUTF(JNIEnv *env, jclass cls, jint cp_index))2581Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2582k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2583ConstantPool* cp = InstanceKlass::cast(k)->constants();2584switch (cp->tag_at(cp_index).value()) {2585case JVM_CONSTANT_Fieldref:2586return cp->uncached_name_ref_at(cp_index)->as_utf8();2587default:2588fatal("JVM_GetCPFieldNameUTF: illegal constant");2589}2590ShouldNotReachHere();2591return NULL;2592JVM_END259325942595JVM_ENTRY(const char*, JVM_GetCPMethodNameUTF(JNIEnv *env, jclass cls, jint cp_index))2596Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2597k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2598ConstantPool* cp = InstanceKlass::cast(k)->constants();2599switch (cp->tag_at(cp_index).value()) {2600case JVM_CONSTANT_InterfaceMethodref:2601case JVM_CONSTANT_Methodref:2602return cp->uncached_name_ref_at(cp_index)->as_utf8();2603default:2604fatal("JVM_GetCPMethodNameUTF: illegal constant");2605}2606ShouldNotReachHere();2607return NULL;2608JVM_END260926102611JVM_ENTRY(const char*, JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cls, jint cp_index))2612Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2613k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2614ConstantPool* cp = InstanceKlass::cast(k)->constants();2615switch (cp->tag_at(cp_index).value()) {2616case JVM_CONSTANT_InterfaceMethodref:2617case JVM_CONSTANT_Methodref:2618return cp->uncached_signature_ref_at(cp_index)->as_utf8();2619default:2620fatal("JVM_GetCPMethodSignatureUTF: illegal constant");2621}2622ShouldNotReachHere();2623return NULL;2624JVM_END262526262627JVM_ENTRY(const char*, JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cls, jint cp_index))2628Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2629k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2630ConstantPool* cp = InstanceKlass::cast(k)->constants();2631switch (cp->tag_at(cp_index).value()) {2632case JVM_CONSTANT_Fieldref:2633return cp->uncached_signature_ref_at(cp_index)->as_utf8();2634default:2635fatal("JVM_GetCPFieldSignatureUTF: illegal constant");2636}2637ShouldNotReachHere();2638return NULL;2639JVM_END264026412642JVM_ENTRY(const char*, JVM_GetCPClassNameUTF(JNIEnv *env, jclass cls, jint cp_index))2643Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2644k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2645ConstantPool* cp = InstanceKlass::cast(k)->constants();2646Symbol* classname = cp->klass_name_at(cp_index);2647return classname->as_utf8();2648JVM_END264926502651JVM_ENTRY(const char*, JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cls, jint cp_index))2652Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2653k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2654ConstantPool* cp = InstanceKlass::cast(k)->constants();2655switch (cp->tag_at(cp_index).value()) {2656case JVM_CONSTANT_Fieldref: {2657int class_index = cp->uncached_klass_ref_index_at(cp_index);2658Symbol* classname = cp->klass_name_at(class_index);2659return classname->as_utf8();2660}2661default:2662fatal("JVM_GetCPFieldClassNameUTF: illegal constant");2663}2664ShouldNotReachHere();2665return NULL;2666JVM_END266726682669JVM_ENTRY(const char*, JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cls, jint cp_index))2670Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2671k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2672ConstantPool* cp = InstanceKlass::cast(k)->constants();2673switch (cp->tag_at(cp_index).value()) {2674case JVM_CONSTANT_Methodref:2675case JVM_CONSTANT_InterfaceMethodref: {2676int class_index = cp->uncached_klass_ref_index_at(cp_index);2677Symbol* classname = cp->klass_name_at(class_index);2678return classname->as_utf8();2679}2680default:2681fatal("JVM_GetCPMethodClassNameUTF: illegal constant");2682}2683ShouldNotReachHere();2684return NULL;2685JVM_END268626872688JVM_ENTRY(jint, JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls))2689Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2690Klass* k_called = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(called_cls));2691k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2692k_called = JvmtiThreadState::class_to_verify_considering_redefinition(k_called, thread);2693ConstantPool* cp = InstanceKlass::cast(k)->constants();2694ConstantPool* cp_called = InstanceKlass::cast(k_called)->constants();2695switch (cp->tag_at(cp_index).value()) {2696case JVM_CONSTANT_Fieldref: {2697Symbol* name = cp->uncached_name_ref_at(cp_index);2698Symbol* signature = cp->uncached_signature_ref_at(cp_index);2699InstanceKlass* ik = InstanceKlass::cast(k_called);2700for (JavaFieldStream fs(ik); !fs.done(); fs.next()) {2701if (fs.name() == name && fs.signature() == signature) {2702return fs.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS;2703}2704}2705return -1;2706}2707default:2708fatal("JVM_GetCPFieldModifiers: illegal constant");2709}2710ShouldNotReachHere();2711return 0;2712JVM_END271327142715JVM_ENTRY(jint, JVM_GetCPMethodModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls))2716Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2717Klass* k_called = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(called_cls));2718k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2719k_called = JvmtiThreadState::class_to_verify_considering_redefinition(k_called, thread);2720ConstantPool* cp = InstanceKlass::cast(k)->constants();2721switch (cp->tag_at(cp_index).value()) {2722case JVM_CONSTANT_Methodref:2723case JVM_CONSTANT_InterfaceMethodref: {2724Symbol* name = cp->uncached_name_ref_at(cp_index);2725Symbol* signature = cp->uncached_signature_ref_at(cp_index);2726Array<Method*>* methods = InstanceKlass::cast(k_called)->methods();2727int methods_count = methods->length();2728for (int i = 0; i < methods_count; i++) {2729Method* method = methods->at(i);2730if (method->name() == name && method->signature() == signature) {2731return method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS;2732}2733}2734return -1;2735}2736default:2737fatal("JVM_GetCPMethodModifiers: illegal constant");2738}2739ShouldNotReachHere();2740return 0;2741JVM_END274227432744// Misc //////////////////////////////////////////////////////////////////////////////////////////////27452746JVM_LEAF(void, JVM_ReleaseUTF(const char *utf))2747// So long as UTF8::convert_to_utf8 returns resource strings, we don't have to do anything2748JVM_END274927502751JVM_ENTRY(jboolean, JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2))2752oop class1_mirror = JNIHandles::resolve_non_null(class1);2753oop class2_mirror = JNIHandles::resolve_non_null(class2);2754Klass* klass1 = java_lang_Class::as_Klass(class1_mirror);2755Klass* klass2 = java_lang_Class::as_Klass(class2_mirror);2756return (jboolean) Reflection::is_same_class_package(klass1, klass2);2757JVM_END27582759// Printing support //////////////////////////////////////////////////2760extern "C" {27612762ATTRIBUTE_PRINTF(3, 0)2763int jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args) {2764// Reject count values that are negative signed values converted to2765// unsigned; see bug 4399518, 44172142766if ((intptr_t)count <= 0) return -1;27672768int result = os::vsnprintf(str, count, fmt, args);2769if (result > 0 && (size_t)result >= count) {2770result = -1;2771}27722773return result;2774}27752776ATTRIBUTE_PRINTF(3, 4)2777int jio_snprintf(char *str, size_t count, const char *fmt, ...) {2778va_list args;2779int len;2780va_start(args, fmt);2781len = jio_vsnprintf(str, count, fmt, args);2782va_end(args);2783return len;2784}27852786ATTRIBUTE_PRINTF(2, 3)2787int jio_fprintf(FILE* f, const char *fmt, ...) {2788int len;2789va_list args;2790va_start(args, fmt);2791len = jio_vfprintf(f, fmt, args);2792va_end(args);2793return len;2794}27952796ATTRIBUTE_PRINTF(2, 0)2797int jio_vfprintf(FILE* f, const char *fmt, va_list args) {2798if (Arguments::vfprintf_hook() != NULL) {2799return Arguments::vfprintf_hook()(f, fmt, args);2800} else {2801return vfprintf(f, fmt, args);2802}2803}28042805ATTRIBUTE_PRINTF(1, 2)2806JNIEXPORT int jio_printf(const char *fmt, ...) {2807int len;2808va_list args;2809va_start(args, fmt);2810len = jio_vfprintf(defaultStream::output_stream(), fmt, args);2811va_end(args);2812return len;2813}28142815// HotSpot specific jio method2816void jio_print(const char* s, size_t len) {2817// Try to make this function as atomic as possible.2818if (Arguments::vfprintf_hook() != NULL) {2819jio_fprintf(defaultStream::output_stream(), "%.*s", (int)len, s);2820} else {2821// Make an unused local variable to avoid warning from gcc compiler.2822size_t count = ::write(defaultStream::output_fd(), s, (int)len);2823}2824}28252826} // Extern C28272828// java.lang.Thread //////////////////////////////////////////////////////////////////////////////28292830// In most of the JVM thread support functions we need to access the2831// thread through a ThreadsListHandle to prevent it from exiting and2832// being reclaimed while we try to operate on it. The exceptions to this2833// rule are when operating on the current thread, or if the monitor of2834// the target java.lang.Thread is locked at the Java level - in both2835// cases the target cannot exit.28362837static void thread_entry(JavaThread* thread, TRAPS) {2838HandleMark hm(THREAD);2839Handle obj(THREAD, thread->threadObj());2840JavaValue result(T_VOID);2841JavaCalls::call_virtual(&result,2842obj,2843vmClasses::Thread_klass(),2844vmSymbols::run_method_name(),2845vmSymbols::void_method_signature(),2846THREAD);2847}284828492850JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))2851JavaThread *native_thread = NULL;28522853// We cannot hold the Threads_lock when we throw an exception,2854// due to rank ordering issues. Example: we might need to grab the2855// Heap_lock while we construct the exception.2856bool throw_illegal_thread_state = false;28572858// We must release the Threads_lock before we can post a jvmti event2859// in Thread::start.2860{2861// Ensure that the C++ Thread and OSThread structures aren't freed before2862// we operate.2863MutexLocker mu(Threads_lock);28642865// Since JDK 5 the java.lang.Thread threadStatus is used to prevent2866// re-starting an already started thread, so we should usually find2867// that the JavaThread is null. However for a JNI attached thread2868// there is a small window between the Thread object being created2869// (with its JavaThread set) and the update to its threadStatus, so we2870// have to check for this2871if (java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) {2872throw_illegal_thread_state = true;2873} else {2874// We could also check the stillborn flag to see if this thread was already stopped, but2875// for historical reasons we let the thread detect that itself when it starts running28762877jlong size =2878java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread));2879// Allocate the C++ Thread structure and create the native thread. The2880// stack size retrieved from java is 64-bit signed, but the constructor takes2881// size_t (an unsigned type), which may be 32 or 64-bit depending on the platform.2882// - Avoid truncating on 32-bit platforms if size is greater than UINT_MAX.2883// - Avoid passing negative values which would result in really large stacks.2884NOT_LP64(if (size > SIZE_MAX) size = SIZE_MAX;)2885size_t sz = size > 0 ? (size_t) size : 0;2886native_thread = new JavaThread(&thread_entry, sz);28872888// At this point it may be possible that no osthread was created for the2889// JavaThread due to lack of memory. Check for this situation and throw2890// an exception if necessary. Eventually we may want to change this so2891// that we only grab the lock if the thread was created successfully -2892// then we can also do this check and throw the exception in the2893// JavaThread constructor.2894if (native_thread->osthread() != NULL) {2895// Note: the current thread is not being used within "prepare".2896native_thread->prepare(jthread);2897}2898}2899}29002901if (throw_illegal_thread_state) {2902THROW(vmSymbols::java_lang_IllegalThreadStateException());2903}29042905assert(native_thread != NULL, "Starting null thread?");29062907if (native_thread->osthread() == NULL) {2908// No one should hold a reference to the 'native_thread'.2909native_thread->smr_delete();2910if (JvmtiExport::should_post_resource_exhausted()) {2911JvmtiExport::post_resource_exhausted(2912JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_THREADS,2913os::native_thread_creation_failed_msg());2914}2915THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(),2916os::native_thread_creation_failed_msg());2917}29182919#if INCLUDE_JFR2920if (Jfr::is_recording() && EventThreadStart::is_enabled() &&2921EventThreadStart::is_stacktrace_enabled()) {2922JfrThreadLocal* tl = native_thread->jfr_thread_local();2923// skip Thread.start() and Thread.start0()2924tl->set_cached_stack_trace_id(JfrStackTraceRepository::record(thread, 2));2925}2926#endif29272928Thread::start(native_thread);29292930JVM_END293129322933// JVM_Stop is implemented using a VM_Operation, so threads are forced to safepoints2934// before the quasi-asynchronous exception is delivered. This is a little obtrusive,2935// but is thought to be reliable and simple. In the case, where the receiver is the2936// same thread as the sender, no VM_Operation is needed.2937JVM_ENTRY(void, JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable))2938ThreadsListHandle tlh(thread);2939oop java_throwable = JNIHandles::resolve(throwable);2940if (java_throwable == NULL) {2941THROW(vmSymbols::java_lang_NullPointerException());2942}2943oop java_thread = NULL;2944JavaThread* receiver = NULL;2945bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, &java_thread);2946Events::log_exception(thread,2947"JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]",2948p2i(receiver), p2i(java_thread), p2i(throwable));29492950if (is_alive) {2951// jthread refers to a live JavaThread.2952if (thread == receiver) {2953// Exception is getting thrown at self so no VM_Operation needed.2954THROW_OOP(java_throwable);2955} else {2956// Use a VM_Operation to throw the exception.2957JavaThread::send_async_exception(java_thread, java_throwable);2958}2959} else {2960// Either:2961// - target thread has not been started before being stopped, or2962// - target thread already terminated2963// We could read the threadStatus to determine which case it is2964// but that is overkill as it doesn't matter. We must set the2965// stillborn flag for the first case, and if the thread has already2966// exited setting this flag has no effect.2967java_lang_Thread::set_stillborn(java_thread);2968}2969JVM_END297029712972JVM_ENTRY(jboolean, JVM_IsThreadAlive(JNIEnv* env, jobject jthread))2973oop thread_oop = JNIHandles::resolve_non_null(jthread);2974return java_lang_Thread::is_alive(thread_oop);2975JVM_END297629772978JVM_ENTRY(void, JVM_SuspendThread(JNIEnv* env, jobject jthread))2979ThreadsListHandle tlh(thread);2980JavaThread* receiver = NULL;2981bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);2982if (is_alive) {2983// jthread refers to a live JavaThread, but java_suspend() will2984// detect a thread that has started to exit and will ignore it.2985receiver->java_suspend();2986}2987JVM_END298829892990JVM_ENTRY(void, JVM_ResumeThread(JNIEnv* env, jobject jthread))2991ThreadsListHandle tlh(thread);2992JavaThread* receiver = NULL;2993bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);2994if (is_alive) {2995// jthread refers to a live JavaThread.2996receiver->java_resume();2997}2998JVM_END299930003001JVM_ENTRY(void, JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio))3002ThreadsListHandle tlh(thread);3003oop java_thread = NULL;3004JavaThread* receiver = NULL;3005bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, &java_thread);3006java_lang_Thread::set_priority(java_thread, (ThreadPriority)prio);30073008if (is_alive) {3009// jthread refers to a live JavaThread.3010Thread::set_priority(receiver, (ThreadPriority)prio);3011}3012// Implied else: If the JavaThread hasn't started yet, then the3013// priority set in the java.lang.Thread object above will be pushed3014// down when it does start.3015JVM_END301630173018JVM_ENTRY(void, JVM_Yield(JNIEnv *env, jclass threadClass))3019if (os::dont_yield()) return;3020HOTSPOT_THREAD_YIELD();3021os::naked_yield();3022JVM_END30233024static void post_thread_sleep_event(EventThreadSleep* event, jlong millis) {3025assert(event != NULL, "invariant");3026assert(event->should_commit(), "invariant");3027event->set_time(millis);3028event->commit();3029}30303031JVM_ENTRY(void, JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis))3032if (millis < 0) {3033THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative");3034}30353036if (thread->is_interrupted(true) && !HAS_PENDING_EXCEPTION) {3037THROW_MSG(vmSymbols::java_lang_InterruptedException(), "sleep interrupted");3038}30393040// Save current thread state and restore it at the end of this block.3041// And set new thread state to SLEEPING.3042JavaThreadSleepState jtss(thread);30433044HOTSPOT_THREAD_SLEEP_BEGIN(millis);3045EventThreadSleep event;30463047if (millis == 0) {3048os::naked_yield();3049} else {3050ThreadState old_state = thread->osthread()->get_state();3051thread->osthread()->set_state(SLEEPING);3052if (!thread->sleep(millis)) { // interrupted3053// An asynchronous exception (e.g., ThreadDeathException) could have been thrown on3054// us while we were sleeping. We do not overwrite those.3055if (!HAS_PENDING_EXCEPTION) {3056if (event.should_commit()) {3057post_thread_sleep_event(&event, millis);3058}3059HOTSPOT_THREAD_SLEEP_END(1);30603061// TODO-FIXME: THROW_MSG returns which means we will not call set_state()3062// to properly restore the thread state. That's likely wrong.3063THROW_MSG(vmSymbols::java_lang_InterruptedException(), "sleep interrupted");3064}3065}3066thread->osthread()->set_state(old_state);3067}3068if (event.should_commit()) {3069post_thread_sleep_event(&event, millis);3070}3071HOTSPOT_THREAD_SLEEP_END(0);3072JVM_END30733074JVM_ENTRY(jobject, JVM_CurrentThread(JNIEnv* env, jclass threadClass))3075oop jthread = thread->threadObj();3076assert(jthread != NULL, "no current thread!");3077return JNIHandles::make_local(THREAD, jthread);3078JVM_END30793080JVM_ENTRY(void, JVM_Interrupt(JNIEnv* env, jobject jthread))3081ThreadsListHandle tlh(thread);3082JavaThread* receiver = NULL;3083bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);3084if (is_alive) {3085// jthread refers to a live JavaThread.3086receiver->interrupt();3087}3088JVM_END308930903091// Return true iff the current thread has locked the object passed in30923093JVM_ENTRY(jboolean, JVM_HoldsLock(JNIEnv* env, jclass threadClass, jobject obj))3094if (obj == NULL) {3095THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE);3096}3097Handle h_obj(THREAD, JNIHandles::resolve(obj));3098return ObjectSynchronizer::current_thread_holds_lock(thread, h_obj);3099JVM_END310031013102JVM_ENTRY(void, JVM_DumpAllStacks(JNIEnv* env, jclass))3103VM_PrintThreads op;3104VMThread::execute(&op);3105if (JvmtiExport::should_post_data_dump()) {3106JvmtiExport::post_data_dump();3107}3108JVM_END31093110JVM_ENTRY(void, JVM_SetNativeThreadName(JNIEnv* env, jobject jthread, jstring name))3111// We don't use a ThreadsListHandle here because the current thread3112// must be alive.3113oop java_thread = JNIHandles::resolve_non_null(jthread);3114JavaThread* thr = java_lang_Thread::thread(java_thread);3115if (thread == thr && !thr->has_attached_via_jni()) {3116// Thread naming is only supported for the current thread and3117// we don't set the name of an attached thread to avoid stepping3118// on other programs.3119ResourceMark rm(thread);3120const char *thread_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));3121os::set_native_thread_name(thread_name);3122}3123JVM_END31243125// java.lang.SecurityManager ///////////////////////////////////////////////////////////////////////31263127JVM_ENTRY(jobjectArray, JVM_GetClassContext(JNIEnv *env))3128ResourceMark rm(THREAD);3129JvmtiVMObjectAllocEventCollector oam;3130vframeStream vfst(thread);31313132if (vmClasses::reflect_CallerSensitive_klass() != NULL) {3133// This must only be called from SecurityManager.getClassContext3134Method* m = vfst.method();3135if (!(m->method_holder() == vmClasses::SecurityManager_klass() &&3136m->name() == vmSymbols::getClassContext_name() &&3137m->signature() == vmSymbols::void_class_array_signature())) {3138THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetClassContext must only be called from SecurityManager.getClassContext");3139}3140}31413142// Collect method holders3143GrowableArray<Klass*>* klass_array = new GrowableArray<Klass*>();3144for (; !vfst.at_end(); vfst.security_next()) {3145Method* m = vfst.method();3146// Native frames are not returned3147if (!m->is_ignored_by_security_stack_walk() && !m->is_native()) {3148Klass* holder = m->method_holder();3149assert(holder->is_klass(), "just checking");3150klass_array->append(holder);3151}3152}31533154// Create result array of type [Ljava/lang/Class;3155objArrayOop result = oopFactory::new_objArray(vmClasses::Class_klass(), klass_array->length(), CHECK_NULL);3156// Fill in mirrors corresponding to method holders3157for (int i = 0; i < klass_array->length(); i++) {3158result->obj_at_put(i, klass_array->at(i)->java_mirror());3159}31603161return (jobjectArray) JNIHandles::make_local(THREAD, result);3162JVM_END316331643165// java.lang.Package ////////////////////////////////////////////////////////////////316631673168JVM_ENTRY(jstring, JVM_GetSystemPackage(JNIEnv *env, jstring name))3169ResourceMark rm(THREAD);3170JvmtiVMObjectAllocEventCollector oam;3171char* str = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));3172oop result = ClassLoader::get_system_package(str, CHECK_NULL);3173return (jstring) JNIHandles::make_local(THREAD, result);3174JVM_END317531763177JVM_ENTRY(jobjectArray, JVM_GetSystemPackages(JNIEnv *env))3178JvmtiVMObjectAllocEventCollector oam;3179objArrayOop result = ClassLoader::get_system_packages(CHECK_NULL);3180return (jobjectArray) JNIHandles::make_local(THREAD, result);3181JVM_END318231833184// java.lang.ref.Reference ///////////////////////////////////////////////////////////////318531863187JVM_ENTRY(jobject, JVM_GetAndClearReferencePendingList(JNIEnv* env))3188MonitorLocker ml(Heap_lock);3189oop ref = Universe::reference_pending_list();3190if (ref != NULL) {3191Universe::clear_reference_pending_list();3192}3193return JNIHandles::make_local(THREAD, ref);3194JVM_END31953196JVM_ENTRY(jboolean, JVM_HasReferencePendingList(JNIEnv* env))3197MonitorLocker ml(Heap_lock);3198return Universe::has_reference_pending_list();3199JVM_END32003201JVM_ENTRY(void, JVM_WaitForReferencePendingList(JNIEnv* env))3202MonitorLocker ml(Heap_lock);3203while (!Universe::has_reference_pending_list()) {3204ml.wait();3205}3206JVM_END32073208JVM_ENTRY(jboolean, JVM_ReferenceRefersTo(JNIEnv* env, jobject ref, jobject o))3209oop ref_oop = JNIHandles::resolve_non_null(ref);3210oop referent = java_lang_ref_Reference::weak_referent_no_keepalive(ref_oop);3211return referent == JNIHandles::resolve(o);3212JVM_END32133214JVM_ENTRY(void, JVM_ReferenceClear(JNIEnv* env, jobject ref))3215oop ref_oop = JNIHandles::resolve_non_null(ref);3216// FinalReference has it's own implementation of clear().3217assert(!java_lang_ref_Reference::is_final(ref_oop), "precondition");3218if (java_lang_ref_Reference::unknown_referent_no_keepalive(ref_oop) == NULL) {3219// If the referent has already been cleared then done.3220// However, if the referent is dead but has not yet been cleared by3221// concurrent reference processing, it should NOT be cleared here.3222// Instead, clearing should be left to the GC. Clearing it here could3223// detectably lose an expected notification, which is impossible with3224// STW reference processing. The clearing in enqueue() doesn't have3225// this problem, since the enqueue covers the notification, but it's not3226// worth the effort to handle that case specially.3227return;3228}3229java_lang_ref_Reference::clear_referent(ref_oop);3230JVM_END323132323233// java.lang.ref.PhantomReference //////////////////////////////////////////////////323432353236JVM_ENTRY(jboolean, JVM_PhantomReferenceRefersTo(JNIEnv* env, jobject ref, jobject o))3237oop ref_oop = JNIHandles::resolve_non_null(ref);3238oop referent = java_lang_ref_Reference::phantom_referent_no_keepalive(ref_oop);3239return referent == JNIHandles::resolve(o);3240JVM_END324132423243// ObjectInputStream ///////////////////////////////////////////////////////////////32443245// Return the first user-defined class loader up the execution stack, or null3246// if only code from the bootstrap or platform class loader is on the stack.32473248JVM_ENTRY(jobject, JVM_LatestUserDefinedLoader(JNIEnv *env))3249for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {3250InstanceKlass* ik = vfst.method()->method_holder();3251oop loader = ik->class_loader();3252if (loader != NULL && !SystemDictionary::is_platform_class_loader(loader)) {3253// Skip reflection related frames3254if (!ik->is_subclass_of(vmClasses::reflect_MethodAccessorImpl_klass()) &&3255!ik->is_subclass_of(vmClasses::reflect_ConstructorAccessorImpl_klass())) {3256return JNIHandles::make_local(THREAD, loader);3257}3258}3259}3260return NULL;3261JVM_END326232633264// Array ///////////////////////////////////////////////////////////////////////////////////////////326532663267// resolve array handle and check arguments3268static inline arrayOop check_array(JNIEnv *env, jobject arr, bool type_array_only, TRAPS) {3269if (arr == NULL) {3270THROW_0(vmSymbols::java_lang_NullPointerException());3271}3272oop a = JNIHandles::resolve_non_null(arr);3273if (!a->is_array()) {3274THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Argument is not an array");3275} else if (type_array_only && !a->is_typeArray()) {3276THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Argument is not an array of primitive type");3277}3278return arrayOop(a);3279}328032813282JVM_ENTRY(jint, JVM_GetArrayLength(JNIEnv *env, jobject arr))3283arrayOop a = check_array(env, arr, false, CHECK_0);3284return a->length();3285JVM_END328632873288JVM_ENTRY(jobject, JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index))3289JvmtiVMObjectAllocEventCollector oam;3290arrayOop a = check_array(env, arr, false, CHECK_NULL);3291jvalue value;3292BasicType type = Reflection::array_get(&value, a, index, CHECK_NULL);3293oop box = Reflection::box(&value, type, CHECK_NULL);3294return JNIHandles::make_local(THREAD, box);3295JVM_END329632973298JVM_ENTRY(jvalue, JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint wCode))3299jvalue value;3300value.i = 0; // to initialize value before getting used in CHECK3301arrayOop a = check_array(env, arr, true, CHECK_(value));3302assert(a->is_typeArray(), "just checking");3303BasicType type = Reflection::array_get(&value, a, index, CHECK_(value));3304BasicType wide_type = (BasicType) wCode;3305if (type != wide_type) {3306Reflection::widen(&value, type, wide_type, CHECK_(value));3307}3308return value;3309JVM_END331033113312JVM_ENTRY(void, JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val))3313arrayOop a = check_array(env, arr, false, CHECK);3314oop box = JNIHandles::resolve(val);3315jvalue value;3316value.i = 0; // to initialize value before getting used in CHECK3317BasicType value_type;3318if (a->is_objArray()) {3319// Make sure we do no unbox e.g. java/lang/Integer instances when storing into an object array3320value_type = Reflection::unbox_for_regular_object(box, &value);3321} else {3322value_type = Reflection::unbox_for_primitive(box, &value, CHECK);3323}3324Reflection::array_set(&value, a, index, value_type, CHECK);3325JVM_END332633273328JVM_ENTRY(void, JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v, unsigned char vCode))3329arrayOop a = check_array(env, arr, true, CHECK);3330assert(a->is_typeArray(), "just checking");3331BasicType value_type = (BasicType) vCode;3332Reflection::array_set(&v, a, index, value_type, CHECK);3333JVM_END333433353336JVM_ENTRY(jobject, JVM_NewArray(JNIEnv *env, jclass eltClass, jint length))3337JvmtiVMObjectAllocEventCollector oam;3338oop element_mirror = JNIHandles::resolve(eltClass);3339oop result = Reflection::reflect_new_array(element_mirror, length, CHECK_NULL);3340return JNIHandles::make_local(THREAD, result);3341JVM_END334233433344JVM_ENTRY(jobject, JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim))3345JvmtiVMObjectAllocEventCollector oam;3346arrayOop dim_array = check_array(env, dim, true, CHECK_NULL);3347oop element_mirror = JNIHandles::resolve(eltClass);3348assert(dim_array->is_typeArray(), "just checking");3349oop result = Reflection::reflect_new_multi_array(element_mirror, typeArrayOop(dim_array), CHECK_NULL);3350return JNIHandles::make_local(THREAD, result);3351JVM_END335233533354// Library support ///////////////////////////////////////////////////////////////////////////33553356JVM_ENTRY_NO_ENV(void*, JVM_LoadLibrary(const char* name))3357//%note jvm_ct3358char ebuf[1024];3359void *load_result;3360{3361ThreadToNativeFromVM ttnfvm(thread);3362load_result = os::dll_load(name, ebuf, sizeof ebuf);3363}3364if (load_result == NULL) {3365char msg[1024];3366jio_snprintf(msg, sizeof msg, "%s: %s", name, ebuf);3367// Since 'ebuf' may contain a string encoded using3368// platform encoding scheme, we need to pass3369// Exceptions::unsafe_to_utf8 to the new_exception method3370// as the last argument. See bug 6367357.3371Handle h_exception =3372Exceptions::new_exception(thread,3373vmSymbols::java_lang_UnsatisfiedLinkError(),3374msg, Exceptions::unsafe_to_utf8);33753376THROW_HANDLE_0(h_exception);3377}3378log_info(library)("Loaded library %s, handle " INTPTR_FORMAT, name, p2i(load_result));3379return load_result;3380JVM_END338133823383JVM_LEAF(void, JVM_UnloadLibrary(void* handle))3384os::dll_unload(handle);3385log_info(library)("Unloaded library with handle " INTPTR_FORMAT, p2i(handle));3386JVM_END338733883389JVM_LEAF(void*, JVM_FindLibraryEntry(void* handle, const char* name))3390void* find_result = os::dll_lookup(handle, name);3391log_info(library)("%s %s in library with handle " INTPTR_FORMAT,3392find_result != NULL ? "Found" : "Failed to find",3393name, p2i(handle));3394return find_result;3395JVM_END339633973398// JNI version ///////////////////////////////////////////////////////////////////////////////33993400JVM_LEAF(jboolean, JVM_IsSupportedJNIVersion(jint version))3401return Threads::is_supported_jni_version_including_1_1(version);3402JVM_END340334043405// String support ///////////////////////////////////////////////////////////////////////////34063407JVM_ENTRY(jstring, JVM_InternString(JNIEnv *env, jstring str))3408JvmtiVMObjectAllocEventCollector oam;3409if (str == NULL) return NULL;3410oop string = JNIHandles::resolve_non_null(str);3411oop result = StringTable::intern(string, CHECK_NULL);3412return (jstring) JNIHandles::make_local(THREAD, result);3413JVM_END341434153416// VM Raw monitor support //////////////////////////////////////////////////////////////////////34173418// VM Raw monitors (not to be confused with JvmtiRawMonitors) are a simple mutual exclusion3419// lock (not actually monitors: no wait/notify) that is exported by the VM for use by JDK3420// library code. They may be used by JavaThreads and non-JavaThreads and do not participate3421// in the safepoint protocol, thread suspension, thread interruption, or anything of that3422// nature. JavaThreads will be "in native" when using this API from JDK code.342334243425JNIEXPORT void* JNICALL JVM_RawMonitorCreate(void) {3426VM_Exit::block_if_vm_exited();3427return new os::PlatformMutex();3428}342934303431JNIEXPORT void JNICALL JVM_RawMonitorDestroy(void *mon) {3432VM_Exit::block_if_vm_exited();3433delete ((os::PlatformMutex*) mon);3434}343534363437JNIEXPORT jint JNICALL JVM_RawMonitorEnter(void *mon) {3438VM_Exit::block_if_vm_exited();3439((os::PlatformMutex*) mon)->lock();3440return 0;3441}344234433444JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon) {3445VM_Exit::block_if_vm_exited();3446((os::PlatformMutex*) mon)->unlock();3447}344834493450// Shared JNI/JVM entry points //////////////////////////////////////////////////////////////34513452jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init,3453Handle loader, Handle protection_domain,3454jboolean throwError, TRAPS) {3455// Security Note:3456// The Java level wrapper will perform the necessary security check allowing3457// us to pass the NULL as the initiating class loader. The VM is responsible for3458// the checkPackageAccess relative to the initiating class loader via the3459// protection_domain. The protection_domain is passed as NULL by the java code3460// if there is no security manager in 3-arg Class.forName().3461Klass* klass = SystemDictionary::resolve_or_fail(name, loader, protection_domain, throwError != 0, CHECK_NULL);34623463// Check if we should initialize the class3464if (init && klass->is_instance_klass()) {3465klass->initialize(CHECK_NULL);3466}3467return (jclass) JNIHandles::make_local(THREAD, klass->java_mirror());3468}346934703471// Method ///////////////////////////////////////////////////////////////////////////////////////////34723473JVM_ENTRY(jobject, JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0))3474Handle method_handle;3475if (thread->stack_overflow_state()->stack_available((address) &method_handle) >= JVMInvokeMethodSlack) {3476method_handle = Handle(THREAD, JNIHandles::resolve(method));3477Handle receiver(THREAD, JNIHandles::resolve(obj));3478objArrayHandle args(THREAD, objArrayOop(JNIHandles::resolve(args0)));3479oop result = Reflection::invoke_method(method_handle(), receiver, args, CHECK_NULL);3480jobject res = JNIHandles::make_local(THREAD, result);3481if (JvmtiExport::should_post_vm_object_alloc()) {3482oop ret_type = java_lang_reflect_Method::return_type(method_handle());3483assert(ret_type != NULL, "sanity check: ret_type oop must not be NULL!");3484if (java_lang_Class::is_primitive(ret_type)) {3485// Only for primitive type vm allocates memory for java object.3486// See box() method.3487JvmtiExport::post_vm_object_alloc(thread, result);3488}3489}3490return res;3491} else {3492THROW_0(vmSymbols::java_lang_StackOverflowError());3493}3494JVM_END349534963497JVM_ENTRY(jobject, JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args0))3498oop constructor_mirror = JNIHandles::resolve(c);3499objArrayHandle args(THREAD, objArrayOop(JNIHandles::resolve(args0)));3500oop result = Reflection::invoke_constructor(constructor_mirror, args, CHECK_NULL);3501jobject res = JNIHandles::make_local(THREAD, result);3502if (JvmtiExport::should_post_vm_object_alloc()) {3503JvmtiExport::post_vm_object_alloc(thread, result);3504}3505return res;3506JVM_END35073508// Atomic ///////////////////////////////////////////////////////////////////////////////////////////35093510JVM_LEAF(jboolean, JVM_SupportsCX8())3511return VM_Version::supports_cx8();3512JVM_END35133514JVM_ENTRY(void, JVM_InitializeFromArchive(JNIEnv* env, jclass cls))3515Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));3516assert(k->is_klass(), "just checking");3517HeapShared::initialize_from_archived_subgraph(k, THREAD);3518JVM_END35193520JVM_ENTRY(void, JVM_RegisterLambdaProxyClassForArchiving(JNIEnv* env,3521jclass caller,3522jstring invokedName,3523jobject invokedType,3524jobject methodType,3525jobject implMethodMember,3526jobject instantiatedMethodType,3527jclass lambdaProxyClass))3528#if INCLUDE_CDS3529if (!Arguments::is_dumping_archive()) {3530return;3531}35323533Klass* caller_k = java_lang_Class::as_Klass(JNIHandles::resolve(caller));3534InstanceKlass* caller_ik = InstanceKlass::cast(caller_k);3535if (caller_ik->is_hidden()) {3536// Hidden classes not of type lambda proxy classes are currently not being archived.3537// If the caller_ik is of one of the above types, the corresponding lambda proxy class won't be3538// registered for archiving.3539return;3540}3541Klass* lambda_k = java_lang_Class::as_Klass(JNIHandles::resolve(lambdaProxyClass));3542InstanceKlass* lambda_ik = InstanceKlass::cast(lambda_k);3543assert(lambda_ik->is_hidden(), "must be a hidden class");3544assert(!lambda_ik->is_non_strong_hidden(), "expected a strong hidden class");35453546Symbol* invoked_name = NULL;3547if (invokedName != NULL) {3548invoked_name = java_lang_String::as_symbol(JNIHandles::resolve_non_null(invokedName));3549}3550Handle invoked_type_oop(THREAD, JNIHandles::resolve_non_null(invokedType));3551Symbol* invoked_type = java_lang_invoke_MethodType::as_signature(invoked_type_oop(), true);35523553Handle method_type_oop(THREAD, JNIHandles::resolve_non_null(methodType));3554Symbol* method_type = java_lang_invoke_MethodType::as_signature(method_type_oop(), true);35553556Handle impl_method_member_oop(THREAD, JNIHandles::resolve_non_null(implMethodMember));3557assert(java_lang_invoke_MemberName::is_method(impl_method_member_oop()), "must be");3558Method* m = java_lang_invoke_MemberName::vmtarget(impl_method_member_oop());35593560Handle instantiated_method_type_oop(THREAD, JNIHandles::resolve_non_null(instantiatedMethodType));3561Symbol* instantiated_method_type = java_lang_invoke_MethodType::as_signature(instantiated_method_type_oop(), true);35623563SystemDictionaryShared::add_lambda_proxy_class(caller_ik, lambda_ik, invoked_name, invoked_type,3564method_type, m, instantiated_method_type, THREAD);3565#endif // INCLUDE_CDS3566JVM_END35673568JVM_ENTRY(jclass, JVM_LookupLambdaProxyClassFromArchive(JNIEnv* env,3569jclass caller,3570jstring invokedName,3571jobject invokedType,3572jobject methodType,3573jobject implMethodMember,3574jobject instantiatedMethodType))3575#if INCLUDE_CDS35763577if (invokedName == NULL || invokedType == NULL || methodType == NULL ||3578implMethodMember == NULL || instantiatedMethodType == NULL) {3579THROW_(vmSymbols::java_lang_NullPointerException(), NULL);3580}35813582Klass* caller_k = java_lang_Class::as_Klass(JNIHandles::resolve(caller));3583InstanceKlass* caller_ik = InstanceKlass::cast(caller_k);3584if (!caller_ik->is_shared()) {3585// there won't be a shared lambda class if the caller_ik is not in the shared archive.3586return NULL;3587}35883589Symbol* invoked_name = java_lang_String::as_symbol(JNIHandles::resolve_non_null(invokedName));3590Handle invoked_type_oop(THREAD, JNIHandles::resolve_non_null(invokedType));3591Symbol* invoked_type = java_lang_invoke_MethodType::as_signature(invoked_type_oop(), true);35923593Handle method_type_oop(THREAD, JNIHandles::resolve_non_null(methodType));3594Symbol* method_type = java_lang_invoke_MethodType::as_signature(method_type_oop(), true);35953596Handle impl_method_member_oop(THREAD, JNIHandles::resolve_non_null(implMethodMember));3597assert(java_lang_invoke_MemberName::is_method(impl_method_member_oop()), "must be");3598Method* m = java_lang_invoke_MemberName::vmtarget(impl_method_member_oop());35993600Handle instantiated_method_type_oop(THREAD, JNIHandles::resolve_non_null(instantiatedMethodType));3601Symbol* instantiated_method_type = java_lang_invoke_MethodType::as_signature(instantiated_method_type_oop(), true);36023603InstanceKlass* lambda_ik = SystemDictionaryShared::get_shared_lambda_proxy_class(caller_ik, invoked_name, invoked_type,3604method_type, m, instantiated_method_type);3605jclass jcls = NULL;3606if (lambda_ik != NULL) {3607InstanceKlass* loaded_lambda = SystemDictionaryShared::prepare_shared_lambda_proxy_class(lambda_ik, caller_ik, THREAD);3608jcls = loaded_lambda == NULL ? NULL : (jclass) JNIHandles::make_local(THREAD, loaded_lambda->java_mirror());3609}3610return jcls;3611#else3612return NULL;3613#endif // INCLUDE_CDS3614JVM_END36153616JVM_ENTRY(jboolean, JVM_IsCDSDumpingEnabled(JNIEnv* env))3617return Arguments::is_dumping_archive();3618JVM_END36193620JVM_ENTRY(jboolean, JVM_IsSharingEnabled(JNIEnv* env))3621return UseSharedSpaces;3622JVM_END36233624JVM_ENTRY_NO_ENV(jlong, JVM_GetRandomSeedForDumping())3625if (DumpSharedSpaces) {3626const char* release = Abstract_VM_Version::vm_release();3627const char* dbg_level = Abstract_VM_Version::jdk_debug_level();3628const char* version = VM_Version::internal_vm_info_string();3629jlong seed = (jlong)(java_lang_String::hash_code((const jbyte*)release, (int)strlen(release)) ^3630java_lang_String::hash_code((const jbyte*)dbg_level, (int)strlen(dbg_level)) ^3631java_lang_String::hash_code((const jbyte*)version, (int)strlen(version)));3632seed += (jlong)Abstract_VM_Version::vm_major_version();3633seed += (jlong)Abstract_VM_Version::vm_minor_version();3634seed += (jlong)Abstract_VM_Version::vm_security_version();3635seed += (jlong)Abstract_VM_Version::vm_patch_version();3636if (seed == 0) { // don't let this ever be zero.3637seed = 0x87654321;3638}3639log_debug(cds)("JVM_GetRandomSeedForDumping() = " JLONG_FORMAT, seed);3640return seed;3641} else {3642return 0;3643}3644JVM_END36453646JVM_ENTRY(jboolean, JVM_IsDumpingClassList(JNIEnv *env))3647#if INCLUDE_CDS3648return ClassListWriter::is_enabled() || DynamicDumpSharedSpaces;3649#else3650return false;3651#endif // INCLUDE_CDS3652JVM_END36533654JVM_ENTRY(void, JVM_LogLambdaFormInvoker(JNIEnv *env, jstring line))3655#if INCLUDE_CDS3656assert(ClassListWriter::is_enabled() || DynamicDumpSharedSpaces, "Should be set and open or do dynamic dump");3657if (line != NULL) {3658ResourceMark rm(THREAD);3659Handle h_line (THREAD, JNIHandles::resolve_non_null(line));3660char* c_line = java_lang_String::as_utf8_string(h_line());3661if (DynamicDumpSharedSpaces) {3662// Note: LambdaFormInvokers::append_filtered and LambdaFormInvokers::append take same format which is not3663// same as below the print format. The line does not include LAMBDA_FORM_TAG.3664LambdaFormInvokers::append_filtered(os::strdup((const char*)c_line, mtInternal));3665}3666if (ClassListWriter::is_enabled()) {3667ClassListWriter w;3668w.stream()->print_cr("%s %s", LAMBDA_FORM_TAG, c_line);3669}3670}3671#endif // INCLUDE_CDS3672JVM_END36733674JVM_ENTRY(void, JVM_DumpClassListToFile(JNIEnv *env, jstring listFileName))3675#if INCLUDE_CDS3676ResourceMark rm(THREAD);3677Handle file_handle(THREAD, JNIHandles::resolve_non_null(listFileName));3678char* file_name = java_lang_String::as_utf8_string(file_handle());3679MetaspaceShared::dump_loaded_classes(file_name, THREAD);3680#endif // INCLUDE_CDS3681JVM_END36823683JVM_ENTRY(void, JVM_DumpDynamicArchive(JNIEnv *env, jstring archiveName))3684#if INCLUDE_CDS3685ResourceMark rm(THREAD);3686Handle file_handle(THREAD, JNIHandles::resolve_non_null(archiveName));3687char* archive_name = java_lang_String::as_utf8_string(file_handle());3688DynamicArchive::dump(archive_name, CHECK);3689#endif // INCLUDE_CDS3690JVM_END36913692// Returns an array of all live Thread objects (VM internal JavaThreads,3693// jvmti agent threads, and JNI attaching threads are skipped)3694// See CR 6404306 regarding JNI attaching threads3695JVM_ENTRY(jobjectArray, JVM_GetAllThreads(JNIEnv *env, jclass dummy))3696ResourceMark rm(THREAD);3697ThreadsListEnumerator tle(THREAD, false, false);3698JvmtiVMObjectAllocEventCollector oam;36993700int num_threads = tle.num_threads();3701objArrayOop r = oopFactory::new_objArray(vmClasses::Thread_klass(), num_threads, CHECK_NULL);3702objArrayHandle threads_ah(THREAD, r);37033704for (int i = 0; i < num_threads; i++) {3705Handle h = tle.get_threadObj(i);3706threads_ah->obj_at_put(i, h());3707}37083709return (jobjectArray) JNIHandles::make_local(THREAD, threads_ah());3710JVM_END371137123713// Support for java.lang.Thread.getStackTrace() and getAllStackTraces() methods3714// Return StackTraceElement[][], each element is the stack trace of a thread in3715// the corresponding entry in the given threads array3716JVM_ENTRY(jobjectArray, JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads))3717JvmtiVMObjectAllocEventCollector oam;37183719// Check if threads is null3720if (threads == NULL) {3721THROW_(vmSymbols::java_lang_NullPointerException(), 0);3722}37233724objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(threads));3725objArrayHandle ah(THREAD, a);3726int num_threads = ah->length();3727// check if threads is non-empty array3728if (num_threads == 0) {3729THROW_(vmSymbols::java_lang_IllegalArgumentException(), 0);3730}37313732// check if threads is not an array of objects of Thread class3733Klass* k = ObjArrayKlass::cast(ah->klass())->element_klass();3734if (k != vmClasses::Thread_klass()) {3735THROW_(vmSymbols::java_lang_IllegalArgumentException(), 0);3736}37373738ResourceMark rm(THREAD);37393740GrowableArray<instanceHandle>* thread_handle_array = new GrowableArray<instanceHandle>(num_threads);3741for (int i = 0; i < num_threads; i++) {3742oop thread_obj = ah->obj_at(i);3743instanceHandle h(THREAD, (instanceOop) thread_obj);3744thread_handle_array->append(h);3745}37463747// The JavaThread references in thread_handle_array are validated3748// in VM_ThreadDump::doit().3749Handle stacktraces = ThreadService::dump_stack_traces(thread_handle_array, num_threads, CHECK_NULL);3750return (jobjectArray)JNIHandles::make_local(THREAD, stacktraces());37513752JVM_END37533754// JVM monitoring and management support3755JVM_ENTRY_NO_ENV(void*, JVM_GetManagement(jint version))3756return Management::get_jmm_interface(version);3757JVM_END37583759// com.sun.tools.attach.VirtualMachine agent properties support3760//3761// Initialize the agent properties with the properties maintained in the VM3762JVM_ENTRY(jobject, JVM_InitAgentProperties(JNIEnv *env, jobject properties))3763ResourceMark rm;37643765Handle props(THREAD, JNIHandles::resolve_non_null(properties));37663767PUTPROP(props, "sun.java.command", Arguments::java_command());3768PUTPROP(props, "sun.jvm.flags", Arguments::jvm_flags());3769PUTPROP(props, "sun.jvm.args", Arguments::jvm_args());3770return properties;3771JVM_END37723773JVM_ENTRY(jobjectArray, JVM_GetEnclosingMethodInfo(JNIEnv *env, jclass ofClass))3774{3775JvmtiVMObjectAllocEventCollector oam;37763777if (ofClass == NULL) {3778return NULL;3779}3780Handle mirror(THREAD, JNIHandles::resolve_non_null(ofClass));3781// Special handling for primitive objects3782if (java_lang_Class::is_primitive(mirror())) {3783return NULL;3784}3785Klass* k = java_lang_Class::as_Klass(mirror());3786if (!k->is_instance_klass()) {3787return NULL;3788}3789InstanceKlass* ik = InstanceKlass::cast(k);3790int encl_method_class_idx = ik->enclosing_method_class_index();3791if (encl_method_class_idx == 0) {3792return NULL;3793}3794objArrayOop dest_o = oopFactory::new_objArray(vmClasses::Object_klass(), 3, CHECK_NULL);3795objArrayHandle dest(THREAD, dest_o);3796Klass* enc_k = ik->constants()->klass_at(encl_method_class_idx, CHECK_NULL);3797dest->obj_at_put(0, enc_k->java_mirror());3798int encl_method_method_idx = ik->enclosing_method_method_index();3799if (encl_method_method_idx != 0) {3800Symbol* sym = ik->constants()->symbol_at(3801extract_low_short_from_int(3802ik->constants()->name_and_type_at(encl_method_method_idx)));3803Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL);3804dest->obj_at_put(1, str());3805sym = ik->constants()->symbol_at(3806extract_high_short_from_int(3807ik->constants()->name_and_type_at(encl_method_method_idx)));3808str = java_lang_String::create_from_symbol(sym, CHECK_NULL);3809dest->obj_at_put(2, str());3810}3811return (jobjectArray) JNIHandles::make_local(THREAD, dest());3812}3813JVM_END38143815// Returns an array of java.lang.String objects containing the input arguments to the VM.3816JVM_ENTRY(jobjectArray, JVM_GetVmArguments(JNIEnv *env))3817ResourceMark rm(THREAD);38183819if (Arguments::num_jvm_args() == 0 && Arguments::num_jvm_flags() == 0) {3820return NULL;3821}38223823char** vm_flags = Arguments::jvm_flags_array();3824char** vm_args = Arguments::jvm_args_array();3825int num_flags = Arguments::num_jvm_flags();3826int num_args = Arguments::num_jvm_args();38273828InstanceKlass* ik = vmClasses::String_klass();3829objArrayOop r = oopFactory::new_objArray(ik, num_args + num_flags, CHECK_NULL);3830objArrayHandle result_h(THREAD, r);38313832int index = 0;3833for (int j = 0; j < num_flags; j++, index++) {3834Handle h = java_lang_String::create_from_platform_dependent_str(vm_flags[j], CHECK_NULL);3835result_h->obj_at_put(index, h());3836}3837for (int i = 0; i < num_args; i++, index++) {3838Handle h = java_lang_String::create_from_platform_dependent_str(vm_args[i], CHECK_NULL);3839result_h->obj_at_put(index, h());3840}3841return (jobjectArray) JNIHandles::make_local(THREAD, result_h());3842JVM_END38433844JVM_ENTRY_NO_ENV(jint, JVM_FindSignal(const char *name))3845return os::get_signal_number(name);3846JVM_END384738483849