Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/prims/jvm.cpp
32285 views
/*1* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved2* 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 "classfile/classLoader.hpp"26#include "classfile/classLoaderData.inline.hpp"27#include "classfile/classLoaderExt.hpp"28#include "classfile/javaAssertions.hpp"29#include "classfile/javaClasses.hpp"30#include "classfile/symbolTable.hpp"31#include "classfile/systemDictionary.hpp"32#if INCLUDE_CDS33#include "classfile/sharedClassUtil.hpp"34#include "classfile/systemDictionaryShared.hpp"35#endif36#include "classfile/vmSymbols.hpp"37#include "gc_interface/collectedHeap.inline.hpp"38#include "interpreter/bytecode.hpp"39#include "jfr/jfrEvents.hpp"40#include "memory/oopFactory.hpp"41#include "memory/referenceType.hpp"42#include "memory/universe.inline.hpp"43#include "oops/fieldStreams.hpp"44#include "oops/instanceKlass.hpp"45#include "oops/objArrayKlass.hpp"46#include "oops/method.hpp"47#include "prims/jvm.h"48#include "prims/jvm_misc.hpp"49#include "prims/jvmtiExport.hpp"50#include "prims/jvmtiThreadState.hpp"51#include "prims/nativeLookup.hpp"52#include "prims/privilegedStack.hpp"53#include "runtime/arguments.hpp"54#include "runtime/dtraceJSDT.hpp"55#include "runtime/handles.inline.hpp"56#include "runtime/init.hpp"57#include "runtime/interfaceSupport.hpp"58#include "runtime/java.hpp"59#include "runtime/javaCalls.hpp"60#include "runtime/jfieldIDWorkaround.hpp"61#include "runtime/orderAccess.inline.hpp"62#include "runtime/os.hpp"63#include "runtime/perfData.hpp"64#include "runtime/reflection.hpp"65#include "runtime/vframe.hpp"66#include "runtime/vm_operations.hpp"67#include "services/attachListener.hpp"68#include "services/management.hpp"69#include "services/threadService.hpp"70#include "utilities/copy.hpp"71#include "utilities/defaultStream.hpp"72#include "utilities/dtrace.hpp"73#include "utilities/events.hpp"74#include "utilities/histogram.hpp"75#include "utilities/macros.hpp"76#include "utilities/top.hpp"77#include "utilities/utf8.hpp"78#ifdef TARGET_OS_FAMILY_linux79# include "jvm_linux.h"80#endif81#ifdef TARGET_OS_FAMILY_solaris82# include "jvm_solaris.h"83#endif84#ifdef TARGET_OS_FAMILY_windows85# include "jvm_windows.h"86#endif87#ifdef TARGET_OS_FAMILY_aix88# include "jvm_aix.h"89#endif90#ifdef TARGET_OS_FAMILY_bsd91# include "jvm_bsd.h"92#endif9394#if INCLUDE_ALL_GCS95#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"96#include "gc_implementation/shenandoah/shenandoahBarrierSetClone.inline.hpp"97#endif // INCLUDE_ALL_GCS9899#include <errno.h>100101#ifndef USDT2102HS_DTRACE_PROBE_DECL1(hotspot, thread__sleep__begin, long long);103HS_DTRACE_PROBE_DECL1(hotspot, thread__sleep__end, int);104HS_DTRACE_PROBE_DECL0(hotspot, thread__yield);105#endif /* !USDT2 */106107/*108NOTE about use of any ctor or function call that can trigger a safepoint/GC:109such ctors and calls MUST NOT come between an oop declaration/init and its110usage because if objects are move this may cause various memory stomps, bus111errors and segfaults. Here is a cookbook for causing so called "naked oop112failures":113114JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields<etc> {115JVMWrapper("JVM_GetClassDeclaredFields");116117// 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 = JavaThread::current();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", CHECK);153Klass* access_controller_klass = SystemDictionary::resolve_or_fail(access_controller, false, CHECK);154TempNewSymbol privileged_action = SymbolTable::new_symbol("java/security/PrivilegedAction", CHECK);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(SystemDictionary::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() &&186(last_caller->name() == vmSymbols::loadClassInternal_name() ||187last_caller->name() == vmSymbols::loadClass_name())) {188found_it = true;189} else if (!vfst.at_end()) {190if (vfst.method()->is_native()) {191// JNI call192found_it = true;193}194}195if (found_it && !vfst.at_end()) {196// found the caller197caller = vfst.method()->method_holder();198line_number = vfst.method()->line_number_from_bci(vfst.bci());199if (line_number == -1) {200// show method name if it's a native method201trace = vfst.method()->name_and_sig_as_C_string();202}203Symbol* s = caller->source_file_name();204if (s != NULL) {205source_file = s->as_C_string();206}207}208}209if (caller != NULL) {210if (to_class != caller) {211const char * from = caller->external_name();212const char * to = to_class->external_name();213// print in a single call to reduce interleaving between threads214if (source_file != NULL) {215tty->print("RESOLVE %s %s %s:%d (%s)\n", from, to, source_file, line_number, trace);216} else {217tty->print("RESOLVE %s %s (%s)\n", from, to, trace);218}219}220}221}222223void trace_class_resolution(Klass* to_class) {224EXCEPTION_MARK;225trace_class_resolution_impl(to_class, THREAD);226if (HAS_PENDING_EXCEPTION) {227CLEAR_PENDING_EXCEPTION;228}229}230231// Wrapper to trace JVM functions232233#ifdef ASSERT234class JVMTraceWrapper : public StackObj {235public:236JVMTraceWrapper(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) {237if (TraceJVMCalls) {238va_list ap;239va_start(ap, format);240tty->print("JVM ");241tty->vprint_cr(format, ap);242va_end(ap);243}244}245};246247Histogram* JVMHistogram;248volatile jint JVMHistogram_lock = 0;249250class JVMHistogramElement : public HistogramElement {251public:252JVMHistogramElement(const char* name);253};254255JVMHistogramElement::JVMHistogramElement(const char* elementName) {256_name = elementName;257uintx count = 0;258259while (Atomic::cmpxchg(1, &JVMHistogram_lock, 0) != 0) {260while (OrderAccess::load_acquire(&JVMHistogram_lock) != 0) {261count +=1;262if ( (WarnOnStalledSpinLock > 0)263&& (count % WarnOnStalledSpinLock == 0)) {264warning("JVMHistogram_lock seems to be stalled");265}266}267}268269if(JVMHistogram == NULL)270JVMHistogram = new Histogram("JVM Call Counts",100);271272JVMHistogram->add_element(this);273Atomic::dec(&JVMHistogram_lock);274}275276#define JVMCountWrapper(arg) \277static JVMHistogramElement* e = new JVMHistogramElement(arg); \278if (e != NULL) e->increment_count(); // Due to bug in VC++, we need a NULL check here eventhough it should never happen!279280#define JVMWrapper(arg1) JVMCountWrapper(arg1); JVMTraceWrapper(arg1)281#define JVMWrapper2(arg1, arg2) JVMCountWrapper(arg1); JVMTraceWrapper(arg1, arg2)282#define JVMWrapper3(arg1, arg2, arg3) JVMCountWrapper(arg1); JVMTraceWrapper(arg1, arg2, arg3)283#define JVMWrapper4(arg1, arg2, arg3, arg4) JVMCountWrapper(arg1); JVMTraceWrapper(arg1, arg2, arg3, arg4)284#else285#define JVMWrapper(arg1)286#define JVMWrapper2(arg1, arg2)287#define JVMWrapper3(arg1, arg2, arg3)288#define JVMWrapper4(arg1, arg2, arg3, arg4)289#endif290291292// Interface version /////////////////////////////////////////////////////////////////////293294295JVM_LEAF(jint, JVM_GetInterfaceVersion())296return JVM_INTERFACE_VERSION;297JVM_END298299300// java.lang.System //////////////////////////////////////////////////////////////////////301302303JVM_LEAF(jlong, JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored))304JVMWrapper("JVM_CurrentTimeMillis");305return os::javaTimeMillis();306JVM_END307308JVM_LEAF(jlong, JVM_NanoTime(JNIEnv *env, jclass ignored))309JVMWrapper("JVM_NanoTime");310return os::javaTimeNanos();311JVM_END312313314JVM_ENTRY(void, JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos,315jobject dst, jint dst_pos, jint length))316JVMWrapper("JVM_ArrayCopy");317// Check if we have null pointers318if (src == NULL || dst == NULL) {319THROW(vmSymbols::java_lang_NullPointerException());320}321arrayOop s = arrayOop(JNIHandles::resolve_non_null(src));322arrayOop d = arrayOop(JNIHandles::resolve_non_null(dst));323assert(s->is_oop(), "JVM_ArrayCopy: src not an oop");324assert(d->is_oop(), "JVM_ArrayCopy: dst not an oop");325// Do copy326s->klass()->copy_array(s, src_pos, d, dst_pos, length, thread);327JVM_END328329330static void set_property(Handle props, const char* key, const char* value, TRAPS) {331JavaValue r(T_OBJECT);332// public synchronized Object put(Object key, Object value);333HandleMark hm(THREAD);334Handle key_str = java_lang_String::create_from_platform_dependent_str(key, CHECK);335Handle value_str = java_lang_String::create_from_platform_dependent_str((value != NULL ? value : ""), CHECK);336JavaCalls::call_virtual(&r,337props,338KlassHandle(THREAD, SystemDictionary::Properties_klass()),339vmSymbols::put_name(),340vmSymbols::object_object_object_signature(),341key_str,342value_str,343THREAD);344}345346347#define PUTPROP(props, name, value) set_property((props), (name), (value), CHECK_(properties));348349350JVM_ENTRY(jobject, JVM_InitProperties(JNIEnv *env, jobject properties))351JVMWrapper("JVM_InitProperties");352ResourceMark rm;353354Handle props(THREAD, JNIHandles::resolve_non_null(properties));355356// System property list includes both user set via -D option and357// jvm system specific properties.358for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) {359PUTPROP(props, p->key(), p->value());360}361362// Convert the -XX:MaxDirectMemorySize= command line flag363// to the sun.nio.MaxDirectMemorySize property.364// Do this after setting user properties to prevent people365// from setting the value with a -D option, as requested.366{367if (FLAG_IS_DEFAULT(MaxDirectMemorySize)) {368PUTPROP(props, "sun.nio.MaxDirectMemorySize", "-1");369} else {370char as_chars[256];371jio_snprintf(as_chars, sizeof(as_chars), UINTX_FORMAT, MaxDirectMemorySize);372PUTPROP(props, "sun.nio.MaxDirectMemorySize", as_chars);373}374}375376// JVM monitoring and management support377// Add the sun.management.compiler property for the compiler's name378{379#undef CSIZE380#if defined(_LP64) || defined(_WIN64)381#define CSIZE "64-Bit "382#else383#define CSIZE384#endif // 64bit385386#ifdef TIERED387const char* compiler_name = "HotSpot " CSIZE "Tiered Compilers";388#else389#if defined(COMPILER1)390const char* compiler_name = "HotSpot " CSIZE "Client Compiler";391#elif defined(COMPILER2)392const char* compiler_name = "HotSpot " CSIZE "Server Compiler";393#else394const char* compiler_name = "";395#endif // compilers396#endif // TIERED397398if (*compiler_name != '\0' &&399(Arguments::mode() != Arguments::_int)) {400PUTPROP(props, "sun.management.compiler", compiler_name);401}402}403404const char* enableSharedLookupCache = "false";405#if INCLUDE_CDS406if (ClassLoaderExt::is_lookup_cache_enabled()) {407enableSharedLookupCache = "true";408}409#endif410PUTPROP(props, "sun.cds.enableSharedLookupCache", enableSharedLookupCache);411412return properties;413JVM_END414415416/*417* Return the temporary directory that the VM uses for the attach418* and perf data files.419*420* It is important that this directory is well-known and the421* same for all VM instances. It cannot be affected by configuration422* variables such as java.io.tmpdir.423*/424JVM_ENTRY(jstring, JVM_GetTemporaryDirectory(JNIEnv *env))425JVMWrapper("JVM_GetTemporaryDirectory");426HandleMark hm(THREAD);427const char* temp_dir = os::get_temp_directory();428Handle h = java_lang_String::create_from_platform_dependent_str(temp_dir, CHECK_NULL);429return (jstring) JNIHandles::make_local(env, h());430JVM_END431432433// java.lang.Runtime /////////////////////////////////////////////////////////////////////////434435extern volatile jint vm_created;436437JVM_ENTRY_NO_ENV(void, JVM_Exit(jint code))438if (vm_created != 0 && (code == 0)) {439// The VM is about to exit. We call back into Java to check whether finalizers should be run440Universe::run_finalizers_on_exit();441}442before_exit(thread);443vm_exit(code);444JVM_END445446447JVM_ENTRY_NO_ENV(void, JVM_BeforeHalt())448JVMWrapper("JVM_BeforeHalt");449EventShutdown event;450if (event.should_commit()) {451event.set_reason("Shutdown requested from Java");452event.commit();453}454JVM_END455456457JVM_ENTRY_NO_ENV(void, JVM_Halt(jint code))458before_exit(thread);459vm_exit(code);460JVM_END461462463JVM_LEAF(void, JVM_OnExit(void (*func)(void)))464register_on_exit_function(func);465JVM_END466467468JVM_ENTRY_NO_ENV(void, JVM_GC(void))469JVMWrapper("JVM_GC");470if (!DisableExplicitGC) {471Universe::heap()->collect(GCCause::_java_lang_system_gc);472}473JVM_END474475476JVM_LEAF(jlong, JVM_MaxObjectInspectionAge(void))477JVMWrapper("JVM_MaxObjectInspectionAge");478return Universe::heap()->millis_since_last_gc();479JVM_END480481482JVM_LEAF(void, JVM_TraceInstructions(jboolean on))483if (PrintJVMWarnings) warning("JVM_TraceInstructions not supported");484JVM_END485486487JVM_LEAF(void, JVM_TraceMethodCalls(jboolean on))488if (PrintJVMWarnings) warning("JVM_TraceMethodCalls not supported");489JVM_END490491static inline jlong convert_size_t_to_jlong(size_t val) {492// In the 64-bit vm, a size_t can overflow a jlong (which is signed).493NOT_LP64 (return (jlong)val;)494LP64_ONLY(return (jlong)MIN2(val, (size_t)max_jlong);)495}496497JVM_ENTRY_NO_ENV(jlong, JVM_TotalMemory(void))498JVMWrapper("JVM_TotalMemory");499size_t n = Universe::heap()->capacity();500return convert_size_t_to_jlong(n);501JVM_END502503504JVM_ENTRY_NO_ENV(jlong, JVM_FreeMemory(void))505JVMWrapper("JVM_FreeMemory");506CollectedHeap* ch = Universe::heap();507size_t n;508{509MutexLocker x(Heap_lock);510n = ch->capacity() - ch->used();511}512return convert_size_t_to_jlong(n);513JVM_END514515516JVM_ENTRY_NO_ENV(jlong, JVM_MaxMemory(void))517JVMWrapper("JVM_MaxMemory");518size_t n = Universe::heap()->max_capacity();519return convert_size_t_to_jlong(n);520JVM_END521522523JVM_ENTRY_NO_ENV(jint, JVM_ActiveProcessorCount(void))524JVMWrapper("JVM_ActiveProcessorCount");525return os::active_processor_count();526JVM_END527528529JVM_ENTRY_NO_ENV(jboolean, JVM_IsUseContainerSupport(void))530JVMWrapper("JVM_IsUseContainerSupport");531#ifdef TARGET_OS_FAMILY_linux532if (UseContainerSupport) {533return JNI_TRUE;534}535#endif536return JNI_FALSE;537JVM_END538539540541// java.lang.Throwable //////////////////////////////////////////////////////542543544JVM_ENTRY(void, JVM_FillInStackTrace(JNIEnv *env, jobject receiver))545JVMWrapper("JVM_FillInStackTrace");546Handle exception(thread, JNIHandles::resolve_non_null(receiver));547java_lang_Throwable::fill_in_stack_trace(exception);548JVM_END549550551JVM_ENTRY(jint, JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable))552JVMWrapper("JVM_GetStackTraceDepth");553oop exception = JNIHandles::resolve(throwable);554return java_lang_Throwable::get_stack_trace_depth(exception, THREAD);555JVM_END556557558JVM_ENTRY(jobject, JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index))559JVMWrapper("JVM_GetStackTraceElement");560JvmtiVMObjectAllocEventCollector oam; // This ctor (throughout this module) may trigger a safepoint/GC561oop exception = JNIHandles::resolve(throwable);562oop element = java_lang_Throwable::get_stack_trace_element(exception, index, CHECK_NULL);563return JNIHandles::make_local(env, element);564JVM_END565566567// java.lang.Object ///////////////////////////////////////////////568569570JVM_ENTRY(jint, JVM_IHashCode(JNIEnv* env, jobject handle))571JVMWrapper("JVM_IHashCode");572// as implemented in the classic virtual machine; return 0 if object is NULL573return handle == NULL ? 0 : ObjectSynchronizer::FastHashCode (THREAD, JNIHandles::resolve_non_null(handle)) ;574JVM_END575576577JVM_ENTRY(void, JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms))578JVMWrapper("JVM_MonitorWait");579Handle obj(THREAD, JNIHandles::resolve_non_null(handle));580JavaThreadInObjectWaitState jtiows(thread, ms != 0);581if (JvmtiExport::should_post_monitor_wait()) {582JvmtiExport::post_monitor_wait((JavaThread *)THREAD, (oop)obj(), ms);583584// The current thread already owns the monitor and it has not yet585// been added to the wait queue so the current thread cannot be586// made the successor. This means that the JVMTI_EVENT_MONITOR_WAIT587// event handler cannot accidentally consume an unpark() meant for588// the ParkEvent associated with this ObjectMonitor.589}590ObjectSynchronizer::wait(obj, ms, CHECK);591JVM_END592593594JVM_ENTRY(void, JVM_MonitorNotify(JNIEnv* env, jobject handle))595JVMWrapper("JVM_MonitorNotify");596Handle obj(THREAD, JNIHandles::resolve_non_null(handle));597ObjectSynchronizer::notify(obj, CHECK);598JVM_END599600601JVM_ENTRY(void, JVM_MonitorNotifyAll(JNIEnv* env, jobject handle))602JVMWrapper("JVM_MonitorNotifyAll");603Handle obj(THREAD, JNIHandles::resolve_non_null(handle));604ObjectSynchronizer::notifyall(obj, CHECK);605JVM_END606607608static void fixup_cloned_reference(ReferenceType ref_type, oop src, oop clone) {609// If G1 is enabled then we need to register a non-null referent610// with the SATB barrier.611#if INCLUDE_ALL_GCS612if (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) {613oop referent = java_lang_ref_Reference::referent(clone);614if (referent != NULL) {615G1SATBCardTableModRefBS::enqueue(referent);616}617}618#endif // INCLUDE_ALL_GCS619if ((java_lang_ref_Reference::next(clone) != NULL) ||620(java_lang_ref_Reference::queue(clone) == java_lang_ref_ReferenceQueue::ENQUEUED_queue())) {621// If the source has been enqueued or is being enqueued, don't622// register the clone with a queue.623java_lang_ref_Reference::set_queue(clone, java_lang_ref_ReferenceQueue::NULL_queue());624}625// discovered and next are list links; the clone is not in those lists.626java_lang_ref_Reference::set_discovered(clone, NULL);627java_lang_ref_Reference::set_next(clone, NULL);628}629630JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))631JVMWrapper("JVM_Clone");632Handle obj(THREAD, JNIHandles::resolve_non_null(handle));633const KlassHandle klass (THREAD, obj->klass());634JvmtiVMObjectAllocEventCollector oam;635636#ifdef ASSERT637// Just checking that the cloneable flag is set correct638if (obj->is_array()) {639guarantee(klass->is_cloneable(), "all arrays are cloneable");640} else {641guarantee(obj->is_instance(), "should be instanceOop");642bool cloneable = klass->is_subtype_of(SystemDictionary::Cloneable_klass());643guarantee(cloneable == klass->is_cloneable(), "incorrect cloneable flag");644}645#endif646647// Check if class of obj supports the Cloneable interface.648// All arrays are considered to be cloneable (See JLS 20.1.5)649if (!klass->is_cloneable()) {650ResourceMark rm(THREAD);651THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name());652}653654// Make shallow object copy655ReferenceType ref_type = REF_NONE;656const int size = obj->size();657oop new_obj_oop = NULL;658if (obj->is_array()) {659const int length = ((arrayOop)obj())->length();660new_obj_oop = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL);661} else {662ref_type = InstanceKlass::cast(klass())->reference_type();663assert((ref_type == REF_NONE) ==664!klass->is_subclass_of(SystemDictionary::Reference_klass()),665"invariant");666new_obj_oop = CollectedHeap::obj_allocate(klass, size, CHECK_NULL);667}668669#if INCLUDE_ALL_GCS670if (UseShenandoahGC && ShenandoahCloneBarrier) {671ShenandoahBarrierSet::barrier_set()->clone_barrier_runtime(obj());672}673#endif674675// 4839641 (4840070): We must do an oop-atomic copy, because if another thread676// is modifying a reference field in the clonee, a non-oop-atomic copy might677// be suspended in the middle of copying the pointer and end up with parts678// of two different pointers in the field. Subsequent dereferences will crash.679// 4846409: an oop-copy of objects with long or double fields or arrays of same680// won't copy the longs/doubles atomically in 32-bit vm's, so we copy jlongs instead681// of oops. We know objects are aligned on a minimum of an jlong boundary.682// The same is true of StubRoutines::object_copy and the various oop_copy683// variants, and of the code generated by the inline_native_clone intrinsic.684assert(MinObjAlignmentInBytes >= BytesPerLong, "objects misaligned");685Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj_oop,686(size_t)align_object_size(size) / HeapWordsPerLong);687// Clear the header688new_obj_oop->init_mark();689690// Store check (mark entire object and let gc sort it out)691BarrierSet* bs = Universe::heap()->barrier_set();692assert(bs->has_write_region_opt(), "Barrier set does not have write_region");693bs->write_region(MemRegion((HeapWord*)new_obj_oop, size));694695// If cloning a Reference, set Reference fields to a safe state.696// Fixup must be completed before any safepoint.697if (ref_type != REF_NONE) {698fixup_cloned_reference(ref_type, obj(), new_obj_oop);699}700701Handle new_obj(THREAD, new_obj_oop);702// Special handling for MemberNames. Since they contain Method* metadata, they703// must be registered so that RedefineClasses can fix metadata contained in them.704if (java_lang_invoke_MemberName::is_instance(new_obj()) &&705java_lang_invoke_MemberName::is_method(new_obj())) {706Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(new_obj());707// MemberName may be unresolved, so doesn't need registration until resolved.708if (method != NULL) {709methodHandle m(THREAD, method);710// This can safepoint and redefine method, so need both new_obj and method711// in a handle, for two different reasons. new_obj can move, method can be712// deleted if nothing is using it on the stack.713m->method_holder()->add_member_name(new_obj(), false);714}715}716717// Caution: this involves a java upcall, so the clone should be718// "gc-robust" by this stage.719if (klass->has_finalizer()) {720assert(obj->is_instance(), "should be instanceOop");721new_obj_oop = InstanceKlass::register_finalizer(instanceOop(new_obj()), CHECK_NULL);722new_obj = Handle(THREAD, new_obj_oop);723}724725return JNIHandles::make_local(env, new_obj());726JVM_END727728// java.lang.Compiler ////////////////////////////////////////////////////729730// The initial cuts of the HotSpot VM will not support JITs, and all existing731// JITs would need extensive changes to work with HotSpot. The JIT-related JVM732// functions are all silently ignored unless JVM warnings are printed.733734JVM_LEAF(void, JVM_InitializeCompiler (JNIEnv *env, jclass compCls))735if (PrintJVMWarnings) warning("JVM_InitializeCompiler not supported");736JVM_END737738739JVM_LEAF(jboolean, JVM_IsSilentCompiler(JNIEnv *env, jclass compCls))740if (PrintJVMWarnings) warning("JVM_IsSilentCompiler not supported");741return JNI_FALSE;742JVM_END743744745JVM_LEAF(jboolean, JVM_CompileClass(JNIEnv *env, jclass compCls, jclass cls))746if (PrintJVMWarnings) warning("JVM_CompileClass not supported");747return JNI_FALSE;748JVM_END749750751JVM_LEAF(jboolean, JVM_CompileClasses(JNIEnv *env, jclass cls, jstring jname))752if (PrintJVMWarnings) warning("JVM_CompileClasses not supported");753return JNI_FALSE;754JVM_END755756757JVM_LEAF(jobject, JVM_CompilerCommand(JNIEnv *env, jclass compCls, jobject arg))758if (PrintJVMWarnings) warning("JVM_CompilerCommand not supported");759return NULL;760JVM_END761762763JVM_LEAF(void, JVM_EnableCompiler(JNIEnv *env, jclass compCls))764if (PrintJVMWarnings) warning("JVM_EnableCompiler not supported");765JVM_END766767768JVM_LEAF(void, JVM_DisableCompiler(JNIEnv *env, jclass compCls))769if (PrintJVMWarnings) warning("JVM_DisableCompiler not supported");770JVM_END771772773774// Error message support //////////////////////////////////////////////////////775776JVM_LEAF(jint, JVM_GetLastErrorString(char *buf, int len))777JVMWrapper("JVM_GetLastErrorString");778return (jint)os::lasterror(buf, len);779JVM_END780781782// java.io.File ///////////////////////////////////////////////////////////////783784JVM_LEAF(char*, JVM_NativePath(char* path))785JVMWrapper2("JVM_NativePath (%s)", path);786return os::native_path(path);787JVM_END788789790// java.nio.Bits ///////////////////////////////////////////////////////////////791792#define MAX_OBJECT_SIZE \793( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \794+ ((julong)max_jint * sizeof(double)) )795796static inline jlong field_offset_to_byte_offset(jlong field_offset) {797return field_offset;798}799800static inline void assert_field_offset_sane(oop p, jlong field_offset) {801#ifdef ASSERT802jlong byte_offset = field_offset_to_byte_offset(field_offset);803804if (p != NULL) {805assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset");806if (byte_offset == (jint)byte_offset) {807void* ptr_plus_disp = (address)p + byte_offset;808assert((void*)p->obj_field_addr<oop>((jint)byte_offset) == ptr_plus_disp,809"raw [ptr+disp] must be consistent with oop::field_base");810}811jlong p_size = HeapWordSize * (jlong)(p->size());812assert(byte_offset < p_size, err_msg("Unsafe access: offset " INT64_FORMAT813" > object's size " INT64_FORMAT,814(int64_t)byte_offset, (int64_t)p_size));815}816#endif817}818819static inline void* index_oop_from_field_offset_long(oop p, jlong field_offset) {820assert_field_offset_sane(p, field_offset);821jlong byte_offset = field_offset_to_byte_offset(field_offset);822823if (sizeof(char*) == sizeof(jint)) { // (this constant folds!)824return (address)p + (jint) byte_offset;825} else {826return (address)p + byte_offset;827}828}829830// This function is a leaf since if the source and destination are both in native memory831// the copy may potentially be very large, and we don't want to disable GC if we can avoid it.832// If either source or destination (or both) are on the heap, the function will enter VM using833// JVM_ENTRY_FROM_LEAF834JVM_LEAF(void, JVM_CopySwapMemory(JNIEnv *env, jobject srcObj, jlong srcOffset,835jobject dstObj, jlong dstOffset, jlong size,836jlong elemSize)) {837838size_t sz = (size_t)size;839size_t esz = (size_t)elemSize;840841if (srcObj == NULL && dstObj == NULL) {842// Both src & dst are in native memory843address src = (address)srcOffset;844address dst = (address)dstOffset;845846Copy::conjoint_swap(src, dst, sz, esz);847} else {848// At least one of src/dst are on heap, transition to VM to access raw pointers849850JVM_ENTRY_FROM_LEAF(env, void, JVM_CopySwapMemory) {851oop srcp = JNIHandles::resolve(srcObj);852oop dstp = JNIHandles::resolve(dstObj);853854address src = (address)index_oop_from_field_offset_long(srcp, srcOffset);855address dst = (address)index_oop_from_field_offset_long(dstp, dstOffset);856857Copy::conjoint_swap(src, dst, sz, esz);858} JVM_END859}860} JVM_END861862863// Misc. class handling ///////////////////////////////////////////////////////////864865866JVM_ENTRY(jclass, JVM_GetCallerClass(JNIEnv* env, int depth))867JVMWrapper("JVM_GetCallerClass");868869// Pre-JDK 8 and early builds of JDK 8 don't have a CallerSensitive annotation; or870// sun.reflect.Reflection.getCallerClass with a depth parameter is provided871// temporarily for existing code to use until a replacement API is defined.872if (SystemDictionary::reflect_CallerSensitive_klass() == NULL || depth != JVM_CALLER_DEPTH) {873Klass* k = thread->security_get_caller_class(depth);874return (k == NULL) ? NULL : (jclass) JNIHandles::make_local(env, k->java_mirror());875}876877// Getting the class of the caller frame.878//879// The call stack at this point looks something like this:880//881// [0] [ @CallerSensitive public sun.reflect.Reflection.getCallerClass ]882// [1] [ @CallerSensitive API.method ]883// [.] [ (skipped intermediate frames) ]884// [n] [ caller ]885vframeStream vfst(thread);886// Cf. LibraryCallKit::inline_native_Reflection_getCallerClass887for (int n = 0; !vfst.at_end(); vfst.security_next(), n++) {888Method* m = vfst.method();889assert(m != NULL, "sanity");890switch (n) {891case 0:892// This must only be called from Reflection.getCallerClass893if (m->intrinsic_id() != vmIntrinsics::_getCallerClass) {894THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetCallerClass must only be called from Reflection.getCallerClass");895}896// fall-through897case 1:898// Frame 0 and 1 must be caller sensitive.899if (!m->caller_sensitive()) {900THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), err_msg("CallerSensitive annotation expected at frame %d", n));901}902break;903default:904if (!m->is_ignored_by_security_stack_walk()) {905// We have reached the desired frame; return the holder class.906return (jclass) JNIHandles::make_local(env, m->method_holder()->java_mirror());907}908break;909}910}911return NULL;912JVM_END913914915JVM_ENTRY(jclass, JVM_FindPrimitiveClass(JNIEnv* env, const char* utf))916JVMWrapper("JVM_FindPrimitiveClass");917oop mirror = NULL;918BasicType t = name2type(utf);919if (t != T_ILLEGAL && t != T_OBJECT && t != T_ARRAY) {920mirror = Universe::java_mirror(t);921}922if (mirror == NULL) {923THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), (char*) utf);924} else {925return (jclass) JNIHandles::make_local(env, mirror);926}927JVM_END928929930JVM_ENTRY(void, JVM_ResolveClass(JNIEnv* env, jclass cls))931JVMWrapper("JVM_ResolveClass");932if (PrintJVMWarnings) warning("JVM_ResolveClass not implemented");933JVM_END934935936JVM_ENTRY(jboolean, JVM_KnownToNotExist(JNIEnv *env, jobject loader, const char *classname))937JVMWrapper("JVM_KnownToNotExist");938#if INCLUDE_CDS939return ClassLoaderExt::known_to_not_exist(env, loader, classname, THREAD);940#else941return false;942#endif943JVM_END944945946JVM_ENTRY(jobjectArray, JVM_GetResourceLookupCacheURLs(JNIEnv *env, jobject loader))947JVMWrapper("JVM_GetResourceLookupCacheURLs");948#if INCLUDE_CDS949return ClassLoaderExt::get_lookup_cache_urls(env, loader, THREAD);950#else951return NULL;952#endif953JVM_END954955956JVM_ENTRY(jintArray, JVM_GetResourceLookupCache(JNIEnv *env, jobject loader, const char *resource_name))957JVMWrapper("JVM_GetResourceLookupCache");958#if INCLUDE_CDS959return ClassLoaderExt::get_lookup_cache(env, loader, resource_name, THREAD);960#else961return NULL;962#endif963JVM_END964965966// Returns a class loaded by the bootstrap class loader; or null967// if not found. ClassNotFoundException is not thrown.968//969// Rationale behind JVM_FindClassFromBootLoader970// a> JVM_FindClassFromClassLoader was never exported in the export tables.971// b> because of (a) java.dll has a direct dependecy on the unexported972// private symbol "_JVM_FindClassFromClassLoader@20".973// c> the launcher cannot use the private symbol as it dynamically opens974// the entry point, so if something changes, the launcher will fail975// unexpectedly at runtime, it is safest for the launcher to dlopen a976// stable exported interface.977// d> re-exporting JVM_FindClassFromClassLoader as public, will cause its978// signature to change from _JVM_FindClassFromClassLoader@20 to979// JVM_FindClassFromClassLoader and will not be backward compatible980// with older JDKs.981// Thus a public/stable exported entry point is the right solution,982// public here means public in linker semantics, and is exported only983// to the JDK, and is not intended to be a public API.984985JVM_ENTRY(jclass, JVM_FindClassFromBootLoader(JNIEnv* env,986const char* name))987JVMWrapper2("JVM_FindClassFromBootLoader %s", name);988989// Java libraries should ensure that name is never null...990if (name == NULL || (int)strlen(name) > Symbol::max_length()) {991// It's impossible to create this class; the name cannot fit992// into the constant pool.993return NULL;994}995996TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL);997Klass* k = SystemDictionary::resolve_or_null(h_name, CHECK_NULL);998if (k == NULL) {999return NULL;1000}10011002if (TraceClassResolution) {1003trace_class_resolution(k);1004}1005return (jclass) JNIHandles::make_local(env, k->java_mirror());1006JVM_END10071008// Not used; JVM_FindClassFromCaller replaces this.1009JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name,1010jboolean init, jobject loader,1011jboolean throwError))1012JVMWrapper3("JVM_FindClassFromClassLoader %s throw %s", name,1013throwError ? "error" : "exception");1014// Java libraries should ensure that name is never null...1015if (name == NULL || (int)strlen(name) > Symbol::max_length()) {1016// It's impossible to create this class; the name cannot fit1017// into the constant pool.1018if (throwError) {1019THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);1020} else {1021THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name);1022}1023}1024TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL);1025Handle h_loader(THREAD, JNIHandles::resolve(loader));1026jclass result = find_class_from_class_loader(env, h_name, init, h_loader,1027Handle(), throwError, THREAD);10281029if (TraceClassResolution && result != NULL) {1030trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));1031}1032return result;1033JVM_END10341035// Find a class with this name in this loader, using the caller's protection domain.1036JVM_ENTRY(jclass, JVM_FindClassFromCaller(JNIEnv* env, const char* name,1037jboolean init, jobject loader,1038jclass caller))1039JVMWrapper2("JVM_FindClassFromCaller %s throws ClassNotFoundException", name);1040// Java libraries should ensure that name is never null...1041if (name == NULL || (int)strlen(name) > Symbol::max_length()) {1042// It's impossible to create this class; the name cannot fit1043// into the constant pool.1044THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name);1045}10461047TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL);10481049oop loader_oop = JNIHandles::resolve(loader);1050oop from_class = JNIHandles::resolve(caller);1051oop protection_domain = NULL;1052// If loader is null, shouldn't call ClassLoader.checkPackageAccess; otherwise get1053// NPE. Put it in another way, the bootstrap class loader has all permission and1054// thus no checkPackageAccess equivalence in the VM class loader.1055// The caller is also passed as NULL by the java code if there is no security1056// manager to avoid the performance cost of getting the calling class.1057if (from_class != NULL && loader_oop != NULL) {1058protection_domain = java_lang_Class::as_Klass(from_class)->protection_domain();1059}10601061Handle h_loader(THREAD, loader_oop);1062Handle h_prot(THREAD, protection_domain);1063jclass result = find_class_from_class_loader(env, h_name, init, h_loader,1064h_prot, false, THREAD);10651066if (TraceClassResolution && result != NULL) {1067trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));1068}1069return result;1070JVM_END10711072JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name,1073jboolean init, jclass from))1074JVMWrapper2("JVM_FindClassFromClass %s", name);1075if (name == NULL || (int)strlen(name) > Symbol::max_length()) {1076// It's impossible to create this class; the name cannot fit1077// into the constant pool.1078THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);1079}1080TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL);1081oop from_class_oop = JNIHandles::resolve(from);1082Klass* from_class = (from_class_oop == NULL)1083? (Klass*)NULL1084: java_lang_Class::as_Klass(from_class_oop);1085oop class_loader = NULL;1086oop protection_domain = NULL;1087if (from_class != NULL) {1088class_loader = from_class->class_loader();1089protection_domain = from_class->protection_domain();1090}1091Handle h_loader(THREAD, class_loader);1092Handle h_prot (THREAD, protection_domain);1093jclass result = find_class_from_class_loader(env, h_name, init, h_loader,1094h_prot, true, thread);10951096if (TraceClassResolution && result != NULL) {1097// this function is generally only used for class loading during verification.1098ResourceMark rm;1099oop from_mirror = JNIHandles::resolve_non_null(from);1100Klass* from_class = java_lang_Class::as_Klass(from_mirror);1101const char * from_name = from_class->external_name();11021103oop mirror = JNIHandles::resolve_non_null(result);1104Klass* to_class = java_lang_Class::as_Klass(mirror);1105const char * to = to_class->external_name();1106tty->print("RESOLVE %s %s (verification)\n", from_name, to);1107}11081109return result;1110JVM_END11111112static void is_lock_held_by_thread(Handle loader, PerfCounter* counter, TRAPS) {1113if (loader.is_null()) {1114return;1115}11161117// check whether the current caller thread holds the lock or not.1118// If not, increment the corresponding counter1119if (ObjectSynchronizer::query_lock_ownership((JavaThread*)THREAD, loader) !=1120ObjectSynchronizer::owner_self) {1121counter->inc();1122}1123}11241125// common code for JVM_DefineClass() and JVM_DefineClassWithSource()1126// and JVM_DefineClassWithSourceCond()1127static jclass jvm_define_class_common(JNIEnv *env, const char *name,1128jobject loader, const jbyte *buf,1129jsize len, jobject pd, const char *source,1130jboolean verify, TRAPS) {1131if (source == NULL) source = "__JVM_DefineClass__";11321133assert(THREAD->is_Java_thread(), "must be a JavaThread");1134JavaThread* jt = (JavaThread*) THREAD;11351136PerfClassTraceTime vmtimer(ClassLoader::perf_define_appclass_time(),1137ClassLoader::perf_define_appclass_selftime(),1138ClassLoader::perf_define_appclasses(),1139jt->get_thread_stat()->perf_recursion_counts_addr(),1140jt->get_thread_stat()->perf_timers_addr(),1141PerfClassTraceTime::DEFINE_CLASS);11421143if (UsePerfData) {1144ClassLoader::perf_app_classfile_bytes_read()->inc(len);1145}11461147// Since exceptions can be thrown, class initialization can take place1148// if name is NULL no check for class name in .class stream has to be made.1149TempNewSymbol class_name = NULL;1150if (name != NULL) {1151const int str_len = (int)strlen(name);1152if (str_len > Symbol::max_length()) {1153// It's impossible to create this class; the name cannot fit1154// into the constant pool.1155THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);1156}1157class_name = SymbolTable::new_symbol(name, str_len, CHECK_NULL);1158}11591160ResourceMark rm(THREAD);1161ClassFileStream st((u1*) buf, len, (char *)source);1162Handle class_loader (THREAD, JNIHandles::resolve(loader));1163if (UsePerfData) {1164is_lock_held_by_thread(class_loader,1165ClassLoader::sync_JVMDefineClassLockFreeCounter(),1166THREAD);1167}1168Handle protection_domain (THREAD, JNIHandles::resolve(pd));1169Klass* k = SystemDictionary::resolve_from_stream(class_name, class_loader,1170protection_domain, &st,1171verify != 0,1172CHECK_NULL);11731174if (TraceClassResolution && k != NULL) {1175trace_class_resolution(k);1176}11771178return (jclass) JNIHandles::make_local(env, k->java_mirror());1179}11801181JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd))1182JVMWrapper2("JVM_DefineClass %s", name);11831184return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, true, THREAD);1185JVM_END118611871188JVM_ENTRY(jclass, JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source))1189JVMWrapper2("JVM_DefineClassWithSource %s", name);11901191return jvm_define_class_common(env, name, loader, buf, len, pd, source, true, THREAD);1192JVM_END11931194JVM_ENTRY(jclass, JVM_DefineClassWithSourceCond(JNIEnv *env, const char *name,1195jobject loader, const jbyte *buf,1196jsize len, jobject pd,1197const char *source, jboolean verify))1198JVMWrapper2("JVM_DefineClassWithSourceCond %s", name);11991200return jvm_define_class_common(env, name, loader, buf, len, pd, source, verify, THREAD);1201JVM_END12021203JVM_ENTRY(jclass, JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name))1204JVMWrapper("JVM_FindLoadedClass");1205ResourceMark rm(THREAD);12061207Handle h_name (THREAD, JNIHandles::resolve_non_null(name));1208Handle string = java_lang_String::internalize_classname(h_name, CHECK_NULL);12091210const char* str = java_lang_String::as_utf8_string(string());1211// Sanity check, don't expect null1212if (str == NULL) return NULL;12131214const int str_len = (int)strlen(str);1215if (str_len > Symbol::max_length()) {1216// It's impossible to create this class; the name cannot fit1217// into the constant pool.1218return NULL;1219}1220TempNewSymbol klass_name = SymbolTable::new_symbol(str, str_len, CHECK_NULL);12211222// Security Note:1223// The Java level wrapper will perform the necessary security check allowing1224// us to pass the NULL as the initiating class loader.1225Handle h_loader(THREAD, JNIHandles::resolve(loader));1226if (UsePerfData) {1227is_lock_held_by_thread(h_loader,1228ClassLoader::sync_JVMFindLoadedClassLockFreeCounter(),1229THREAD);1230}12311232Klass* k = SystemDictionary::find_instance_or_array_klass(klass_name,1233h_loader,1234Handle(),1235CHECK_NULL);1236#if INCLUDE_CDS1237if (k == NULL) {1238// If the class is not already loaded, try to see if it's in the shared1239// archive for the current classloader (h_loader).1240instanceKlassHandle ik = SystemDictionaryShared::find_or_load_shared_class(1241klass_name, h_loader, CHECK_NULL);1242k = ik();1243}1244#endif1245return (k == NULL) ? NULL :1246(jclass) JNIHandles::make_local(env, k->java_mirror());1247JVM_END124812491250// Reflection support //////////////////////////////////////////////////////////////////////////////12511252JVM_ENTRY(jstring, JVM_GetClassName(JNIEnv *env, jclass cls))1253assert (cls != NULL, "illegal class");1254JVMWrapper("JVM_GetClassName");1255JvmtiVMObjectAllocEventCollector oam;1256ResourceMark rm(THREAD);1257const char* name;1258if (java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {1259name = type2name(java_lang_Class::primitive_type(JNIHandles::resolve(cls)));1260} else {1261// Consider caching interned string in Klass1262Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));1263assert(k->is_klass(), "just checking");1264name = k->external_name();1265}1266oop result = StringTable::intern((char*) name, CHECK_NULL);1267return (jstring) JNIHandles::make_local(env, result);1268JVM_END126912701271JVM_ENTRY(jobjectArray, JVM_GetClassInterfaces(JNIEnv *env, jclass cls))1272JVMWrapper("JVM_GetClassInterfaces");1273JvmtiVMObjectAllocEventCollector oam;1274oop mirror = JNIHandles::resolve_non_null(cls);12751276// Special handling for primitive objects1277if (java_lang_Class::is_primitive(mirror)) {1278// Primitive objects does not have any interfaces1279objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_NULL);1280return (jobjectArray) JNIHandles::make_local(env, r);1281}12821283KlassHandle klass(thread, java_lang_Class::as_Klass(mirror));1284// Figure size of result array1285int size;1286if (klass->oop_is_instance()) {1287size = InstanceKlass::cast(klass())->local_interfaces()->length();1288} else {1289assert(klass->oop_is_objArray() || klass->oop_is_typeArray(), "Illegal mirror klass");1290size = 2;1291}12921293// Allocate result array1294objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), size, CHECK_NULL);1295objArrayHandle result (THREAD, r);1296// Fill in result1297if (klass->oop_is_instance()) {1298// Regular instance klass, fill in all local interfaces1299for (int index = 0; index < size; index++) {1300Klass* k = InstanceKlass::cast(klass())->local_interfaces()->at(index);1301result->obj_at_put(index, k->java_mirror());1302}1303} else {1304// All arrays implement java.lang.Cloneable and java.io.Serializable1305result->obj_at_put(0, SystemDictionary::Cloneable_klass()->java_mirror());1306result->obj_at_put(1, SystemDictionary::Serializable_klass()->java_mirror());1307}1308return (jobjectArray) JNIHandles::make_local(env, result());1309JVM_END131013111312JVM_ENTRY(jobject, JVM_GetClassLoader(JNIEnv *env, jclass cls))1313JVMWrapper("JVM_GetClassLoader");1314if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {1315return NULL;1316}1317Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));1318oop loader = k->class_loader();1319return JNIHandles::make_local(env, loader);1320JVM_END132113221323JVM_QUICK_ENTRY(jboolean, JVM_IsInterface(JNIEnv *env, jclass cls))1324JVMWrapper("JVM_IsInterface");1325oop mirror = JNIHandles::resolve_non_null(cls);1326if (java_lang_Class::is_primitive(mirror)) {1327return JNI_FALSE;1328}1329Klass* k = java_lang_Class::as_Klass(mirror);1330jboolean result = k->is_interface();1331assert(!result || k->oop_is_instance(),1332"all interfaces are instance types");1333// The compiler intrinsic for isInterface tests the1334// Klass::_access_flags bits in the same way.1335return result;1336JVM_END133713381339JVM_ENTRY(jobjectArray, JVM_GetClassSigners(JNIEnv *env, jclass cls))1340JVMWrapper("JVM_GetClassSigners");1341JvmtiVMObjectAllocEventCollector oam;1342if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {1343// There are no signers for primitive types1344return NULL;1345}13461347objArrayOop signers = java_lang_Class::signers(JNIHandles::resolve_non_null(cls));13481349// If there are no signers set in the class, or if the class1350// is an array, return NULL.1351if (signers == NULL) return NULL;13521353// copy of the signers array1354Klass* element = ObjArrayKlass::cast(signers->klass())->element_klass();1355objArrayOop signers_copy = oopFactory::new_objArray(element, signers->length(), CHECK_NULL);1356for (int index = 0; index < signers->length(); index++) {1357signers_copy->obj_at_put(index, signers->obj_at(index));1358}13591360// return the copy1361return (jobjectArray) JNIHandles::make_local(env, signers_copy);1362JVM_END136313641365JVM_ENTRY(void, JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers))1366JVMWrapper("JVM_SetClassSigners");1367if (!java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {1368// This call is ignored for primitive types and arrays.1369// Signers are only set once, ClassLoader.java, and thus shouldn't1370// be called with an array. Only the bootstrap loader creates arrays.1371Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));1372if (k->oop_is_instance()) {1373java_lang_Class::set_signers(k->java_mirror(), objArrayOop(JNIHandles::resolve(signers)));1374}1375}1376JVM_END137713781379JVM_ENTRY(jobject, JVM_GetProtectionDomain(JNIEnv *env, jclass cls))1380JVMWrapper("JVM_GetProtectionDomain");1381if (JNIHandles::resolve(cls) == NULL) {1382THROW_(vmSymbols::java_lang_NullPointerException(), NULL);1383}13841385if (java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {1386// Primitive types does not have a protection domain.1387return NULL;1388}13891390oop pd = java_lang_Class::protection_domain(JNIHandles::resolve(cls));1391return (jobject) JNIHandles::make_local(env, pd);1392JVM_END139313941395static bool is_authorized(Handle context, instanceKlassHandle klass, TRAPS) {1396// If there is a security manager and protection domain, check the access1397// in the protection domain, otherwise it is authorized.1398if (java_lang_System::has_security_manager()) {13991400// For bootstrapping, if pd implies method isn't in the JDK, allow1401// this context to revert to older behavior.1402// In this case the isAuthorized field in AccessControlContext is also not1403// present.1404if (Universe::protection_domain_implies_method() == NULL) {1405return true;1406}14071408// Whitelist certain access control contexts1409if (java_security_AccessControlContext::is_authorized(context)) {1410return true;1411}14121413oop prot = klass->protection_domain();1414if (prot != NULL) {1415// Call pd.implies(new SecurityPermission("createAccessControlContext"))1416// in the new wrapper.1417methodHandle m(THREAD, Universe::protection_domain_implies_method());1418Handle h_prot(THREAD, prot);1419JavaValue result(T_BOOLEAN);1420JavaCallArguments args(h_prot);1421JavaCalls::call(&result, m, &args, CHECK_false);1422return (result.get_jboolean() != 0);1423}1424}1425return true;1426}14271428// Create an AccessControlContext with a protection domain with null codesource1429// and null permissions - which gives no permissions.1430oop create_dummy_access_control_context(TRAPS) {1431InstanceKlass* pd_klass = InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass());1432Handle obj = pd_klass->allocate_instance_handle(CHECK_NULL);1433// Call constructor ProtectionDomain(null, null);1434JavaValue result(T_VOID);1435JavaCalls::call_special(&result, obj, KlassHandle(THREAD, pd_klass),1436vmSymbols::object_initializer_name(),1437vmSymbols::codesource_permissioncollection_signature(),1438Handle(), Handle(), CHECK_NULL);14391440// new ProtectionDomain[] {pd};1441objArrayOop context = oopFactory::new_objArray(pd_klass, 1, CHECK_NULL);1442context->obj_at_put(0, obj());14431444// new AccessControlContext(new ProtectionDomain[] {pd})1445objArrayHandle h_context(THREAD, context);1446oop acc = java_security_AccessControlContext::create(h_context, false, Handle(), CHECK_NULL);1447return acc;1448}14491450JVM_ENTRY(jobject, JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject context, jboolean wrapException))1451JVMWrapper("JVM_DoPrivileged");14521453if (action == NULL) {1454THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), "Null action");1455}14561457// Compute the frame initiating the do privileged operation and setup the privileged stack1458vframeStream vfst(thread);1459vfst.security_get_caller_frame(1);14601461if (vfst.at_end()) {1462THROW_MSG_0(vmSymbols::java_lang_InternalError(), "no caller?");1463}14641465Method* method = vfst.method();1466instanceKlassHandle klass (THREAD, method->method_holder());14671468// Check that action object understands "Object run()"1469Handle h_context;1470if (context != NULL) {1471h_context = Handle(THREAD, JNIHandles::resolve(context));1472bool authorized = is_authorized(h_context, klass, CHECK_NULL);1473if (!authorized) {1474// Create an unprivileged access control object and call it's run function1475// instead.1476oop noprivs = create_dummy_access_control_context(CHECK_NULL);1477h_context = Handle(THREAD, noprivs);1478}1479}14801481// Check that action object understands "Object run()"1482Handle object (THREAD, JNIHandles::resolve(action));14831484// get run() method1485Method* m_oop = object->klass()->uncached_lookup_method(1486vmSymbols::run_method_name(),1487vmSymbols::void_object_signature(),1488Klass::find_overpass);1489methodHandle m (THREAD, m_oop);1490if (m.is_null() || !m->is_method() || !m()->is_public() || m()->is_static()) {1491THROW_MSG_0(vmSymbols::java_lang_InternalError(), "No run method");1492}14931494// Stack allocated list of privileged stack elements1495PrivilegedElement pi;1496if (!vfst.at_end()) {1497pi.initialize(&vfst, h_context(), thread->privileged_stack_top(), CHECK_NULL);1498thread->set_privileged_stack_top(&pi);1499}150015011502// invoke the Object run() in the action object. We cannot use call_interface here, since the static type1503// is not really known - it is either java.security.PrivilegedAction or java.security.PrivilegedExceptionAction1504Handle pending_exception;1505JavaValue result(T_OBJECT);1506JavaCallArguments args(object);1507JavaCalls::call(&result, m, &args, THREAD);15081509// done with action, remove ourselves from the list1510if (!vfst.at_end()) {1511assert(thread->privileged_stack_top() != NULL && thread->privileged_stack_top() == &pi, "wrong top element");1512thread->set_privileged_stack_top(thread->privileged_stack_top()->next());1513}15141515if (HAS_PENDING_EXCEPTION) {1516pending_exception = Handle(THREAD, PENDING_EXCEPTION);1517CLEAR_PENDING_EXCEPTION;1518// JVMTI has already reported the pending exception1519// JVMTI internal flag reset is needed in order to report PrivilegedActionException1520if (THREAD->is_Java_thread()) {1521JvmtiExport::clear_detected_exception((JavaThread*) THREAD);1522}1523if ( pending_exception->is_a(SystemDictionary::Exception_klass()) &&1524!pending_exception->is_a(SystemDictionary::RuntimeException_klass())) {1525// Throw a java.security.PrivilegedActionException(Exception e) exception1526JavaCallArguments args(pending_exception);1527THROW_ARG_0(vmSymbols::java_security_PrivilegedActionException(),1528vmSymbols::exception_void_signature(),1529&args);1530}1531}15321533if (pending_exception.not_null()) THROW_OOP_0(pending_exception());1534return JNIHandles::make_local(env, (oop) result.get_jobject());1535JVM_END153615371538// Returns the inherited_access_control_context field of the running thread.1539JVM_ENTRY(jobject, JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls))1540JVMWrapper("JVM_GetInheritedAccessControlContext");1541oop result = java_lang_Thread::inherited_access_control_context(thread->threadObj());1542return JNIHandles::make_local(env, result);1543JVM_END15441545class RegisterArrayForGC {1546private:1547JavaThread *_thread;1548public:1549RegisterArrayForGC(JavaThread *thread, GrowableArray<oop>* array) {1550_thread = thread;1551_thread->register_array_for_gc(array);1552}15531554~RegisterArrayForGC() {1555_thread->register_array_for_gc(NULL);1556}1557};155815591560JVM_ENTRY(jobject, JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls))1561JVMWrapper("JVM_GetStackAccessControlContext");1562if (!UsePrivilegedStack) return NULL;15631564ResourceMark rm(THREAD);1565GrowableArray<oop>* local_array = new GrowableArray<oop>(12);1566JvmtiVMObjectAllocEventCollector oam;15671568// count the protection domains on the execution stack. We collapse1569// duplicate consecutive protection domains into a single one, as1570// well as stopping when we hit a privileged frame.15711572// Use vframeStream to iterate through Java frames1573vframeStream vfst(thread);15741575oop previous_protection_domain = NULL;1576Handle privileged_context(thread, NULL);1577bool is_privileged = false;1578oop protection_domain = NULL;15791580for(; !vfst.at_end(); vfst.next()) {1581// get method of frame1582Method* method = vfst.method();1583intptr_t* frame_id = vfst.frame_id();15841585// check the privileged frames to see if we have a match1586if (thread->privileged_stack_top() && thread->privileged_stack_top()->frame_id() == frame_id) {1587// this frame is privileged1588is_privileged = true;1589privileged_context = Handle(thread, thread->privileged_stack_top()->privileged_context());1590protection_domain = thread->privileged_stack_top()->protection_domain();1591} else {1592protection_domain = method->method_holder()->protection_domain();1593}15941595if ((previous_protection_domain != protection_domain) && (protection_domain != NULL)) {1596local_array->push(protection_domain);1597previous_protection_domain = protection_domain;1598}15991600if (is_privileged) break;1601}160216031604// either all the domains on the stack were system domains, or1605// we had a privileged system domain1606if (local_array->is_empty()) {1607if (is_privileged && privileged_context.is_null()) return NULL;16081609oop result = java_security_AccessControlContext::create(objArrayHandle(), is_privileged, privileged_context, CHECK_NULL);1610return JNIHandles::make_local(env, result);1611}16121613// the resource area must be registered in case of a gc1614RegisterArrayForGC ragc(thread, local_array);1615objArrayOop context = oopFactory::new_objArray(SystemDictionary::ProtectionDomain_klass(),1616local_array->length(), CHECK_NULL);1617objArrayHandle h_context(thread, context);1618for (int index = 0; index < local_array->length(); index++) {1619h_context->obj_at_put(index, local_array->at(index));1620}16211622oop result = java_security_AccessControlContext::create(h_context, is_privileged, privileged_context, CHECK_NULL);16231624return JNIHandles::make_local(env, result);1625JVM_END162616271628JVM_QUICK_ENTRY(jboolean, JVM_IsArrayClass(JNIEnv *env, jclass cls))1629JVMWrapper("JVM_IsArrayClass");1630Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));1631return (k != NULL) && k->oop_is_array() ? true : false;1632JVM_END163316341635JVM_QUICK_ENTRY(jboolean, JVM_IsPrimitiveClass(JNIEnv *env, jclass cls))1636JVMWrapper("JVM_IsPrimitiveClass");1637oop mirror = JNIHandles::resolve_non_null(cls);1638return (jboolean) java_lang_Class::is_primitive(mirror);1639JVM_END164016411642JVM_ENTRY(jclass, JVM_GetComponentType(JNIEnv *env, jclass cls))1643JVMWrapper("JVM_GetComponentType");1644oop mirror = JNIHandles::resolve_non_null(cls);1645oop result = Reflection::array_component_type(mirror, CHECK_NULL);1646return (jclass) JNIHandles::make_local(env, result);1647JVM_END164816491650JVM_ENTRY(jint, JVM_GetClassModifiers(JNIEnv *env, jclass cls))1651JVMWrapper("JVM_GetClassModifiers");1652if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {1653// Primitive type1654return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC;1655}16561657Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));1658debug_only(int computed_modifiers = k->compute_modifier_flags(CHECK_0));1659assert(k->modifier_flags() == computed_modifiers, "modifiers cache is OK");1660return k->modifier_flags();1661JVM_END166216631664// Inner class reflection ///////////////////////////////////////////////////////////////////////////////16651666JVM_ENTRY(jobjectArray, JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass))1667JvmtiVMObjectAllocEventCollector oam;1668// ofClass is a reference to a java_lang_Class object. The mirror object1669// of an InstanceKlass16701671if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) ||1672! java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_instance()) {1673oop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_NULL);1674return (jobjectArray)JNIHandles::make_local(env, result);1675}16761677instanceKlassHandle k(thread, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)));1678InnerClassesIterator iter(k);16791680if (iter.length() == 0) {1681// Neither an inner nor outer class1682oop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_NULL);1683return (jobjectArray)JNIHandles::make_local(env, result);1684}16851686// find inner class info1687constantPoolHandle cp(thread, k->constants());1688int length = iter.length();16891690// Allocate temp. result array1691objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), length/4, CHECK_NULL);1692objArrayHandle result (THREAD, r);1693int members = 0;16941695for (; !iter.done(); iter.next()) {1696int ioff = iter.inner_class_info_index();1697int ooff = iter.outer_class_info_index();16981699if (ioff != 0 && ooff != 0) {1700// Check to see if the name matches the class we're looking for1701// before attempting to find the class.1702if (cp->klass_name_at_matches(k, ooff)) {1703Klass* outer_klass = cp->klass_at(ooff, CHECK_NULL);1704if (outer_klass == k()) {1705Klass* ik = cp->klass_at(ioff, CHECK_NULL);1706instanceKlassHandle inner_klass (THREAD, ik);17071708// Throws an exception if outer klass has not declared k as1709// an inner klass1710Reflection::check_for_inner_class(k, inner_klass, true, CHECK_NULL);17111712result->obj_at_put(members, inner_klass->java_mirror());1713members++;1714}1715}1716}1717}17181719if (members != length) {1720// Return array of right length1721objArrayOop res = oopFactory::new_objArray(SystemDictionary::Class_klass(), members, CHECK_NULL);1722for(int i = 0; i < members; i++) {1723res->obj_at_put(i, result->obj_at(i));1724}1725return (jobjectArray)JNIHandles::make_local(env, res);1726}17271728return (jobjectArray)JNIHandles::make_local(env, result());1729JVM_END173017311732JVM_ENTRY(jclass, JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass))1733{1734// ofClass is a reference to a java_lang_Class object.1735if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) ||1736! java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_instance()) {1737return NULL;1738}17391740bool inner_is_member = false;1741Klass* outer_klass1742= InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))1743)->compute_enclosing_class(&inner_is_member, CHECK_NULL);1744if (outer_klass == NULL) return NULL; // already a top-level class1745if (!inner_is_member) return NULL; // an anonymous class (inside a method)1746return (jclass) JNIHandles::make_local(env, outer_klass->java_mirror());1747}1748JVM_END17491750// should be in InstanceKlass.cpp, but is here for historical reasons1751Klass* InstanceKlass::compute_enclosing_class_impl(instanceKlassHandle k,1752bool* inner_is_member,1753TRAPS) {1754Thread* thread = THREAD;1755InnerClassesIterator iter(k);1756if (iter.length() == 0) {1757// No inner class info => no declaring class1758return NULL;1759}17601761constantPoolHandle i_cp(thread, k->constants());17621763bool found = false;1764Klass* ok;1765instanceKlassHandle outer_klass;1766*inner_is_member = false;17671768// Find inner_klass attribute1769for (; !iter.done() && !found; iter.next()) {1770int ioff = iter.inner_class_info_index();1771int ooff = iter.outer_class_info_index();1772int noff = iter.inner_name_index();1773if (ioff != 0) {1774// Check to see if the name matches the class we're looking for1775// before attempting to find the class.1776if (i_cp->klass_name_at_matches(k, ioff)) {1777Klass* inner_klass = i_cp->klass_at(ioff, CHECK_NULL);1778found = (k() == inner_klass);1779if (found && ooff != 0) {1780ok = i_cp->klass_at(ooff, CHECK_NULL);1781outer_klass = instanceKlassHandle(thread, ok);1782*inner_is_member = true;1783}1784}1785}1786}17871788if (found && outer_klass.is_null()) {1789// It may be anonymous; try for that.1790int encl_method_class_idx = k->enclosing_method_class_index();1791if (encl_method_class_idx != 0) {1792ok = i_cp->klass_at(encl_method_class_idx, CHECK_NULL);1793outer_klass = instanceKlassHandle(thread, ok);1794*inner_is_member = false;1795}1796}17971798// If no inner class attribute found for this class.1799if (outer_klass.is_null()) return NULL;18001801// Throws an exception if outer klass has not declared k as an inner klass1802// We need evidence that each klass knows about the other, or else1803// the system could allow a spoof of an inner class to gain access rights.1804Reflection::check_for_inner_class(outer_klass, k, *inner_is_member, CHECK_NULL);1805return outer_klass();1806}18071808JVM_ENTRY(jstring, JVM_GetClassSignature(JNIEnv *env, jclass cls))1809assert (cls != NULL, "illegal class");1810JVMWrapper("JVM_GetClassSignature");1811JvmtiVMObjectAllocEventCollector oam;1812ResourceMark rm(THREAD);1813// Return null for arrays and primatives1814if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {1815Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));1816if (k->oop_is_instance()) {1817Symbol* sym = InstanceKlass::cast(k)->generic_signature();1818if (sym == NULL) return NULL;1819Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL);1820return (jstring) JNIHandles::make_local(env, str());1821}1822}1823return NULL;1824JVM_END182518261827JVM_ENTRY(jbyteArray, JVM_GetClassAnnotations(JNIEnv *env, jclass cls))1828assert (cls != NULL, "illegal class");1829JVMWrapper("JVM_GetClassAnnotations");18301831// Return null for arrays and primitives1832if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {1833Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));1834if (k->oop_is_instance()) {1835typeArrayOop a = Annotations::make_java_array(InstanceKlass::cast(k)->class_annotations(), CHECK_NULL);1836return (jbyteArray) JNIHandles::make_local(env, a);1837}1838}1839return NULL;1840JVM_END184118421843static bool jvm_get_field_common(jobject field, fieldDescriptor& fd, TRAPS) {1844// some of this code was adapted from from jni_FromReflectedField18451846oop reflected = JNIHandles::resolve_non_null(field);1847oop mirror = java_lang_reflect_Field::clazz(reflected);1848Klass* k = java_lang_Class::as_Klass(mirror);1849int slot = java_lang_reflect_Field::slot(reflected);1850int modifiers = java_lang_reflect_Field::modifiers(reflected);18511852KlassHandle kh(THREAD, k);1853intptr_t offset = InstanceKlass::cast(kh())->field_offset(slot);18541855if (modifiers & JVM_ACC_STATIC) {1856// for static fields we only look in the current class1857if (!InstanceKlass::cast(kh())->find_local_field_from_offset(offset, true, &fd)) {1858assert(false, "cannot find static field");1859return false;1860}1861} else {1862// for instance fields we start with the current class and work1863// our way up through the superclass chain1864if (!InstanceKlass::cast(kh())->find_field_from_offset(offset, false, &fd)) {1865assert(false, "cannot find instance field");1866return false;1867}1868}1869return true;1870}18711872JVM_ENTRY(jbyteArray, JVM_GetFieldAnnotations(JNIEnv *env, jobject field))1873// field is a handle to a java.lang.reflect.Field object1874assert(field != NULL, "illegal field");1875JVMWrapper("JVM_GetFieldAnnotations");18761877fieldDescriptor fd;1878bool gotFd = jvm_get_field_common(field, fd, CHECK_NULL);1879if (!gotFd) {1880return NULL;1881}18821883return (jbyteArray) JNIHandles::make_local(env, Annotations::make_java_array(fd.annotations(), THREAD));1884JVM_END188518861887static Method* jvm_get_method_common(jobject method) {1888// some of this code was adapted from from jni_FromReflectedMethod18891890oop reflected = JNIHandles::resolve_non_null(method);1891oop mirror = NULL;1892int slot = 0;18931894if (reflected->klass() == SystemDictionary::reflect_Constructor_klass()) {1895mirror = java_lang_reflect_Constructor::clazz(reflected);1896slot = java_lang_reflect_Constructor::slot(reflected);1897} else {1898assert(reflected->klass() == SystemDictionary::reflect_Method_klass(),1899"wrong type");1900mirror = java_lang_reflect_Method::clazz(reflected);1901slot = java_lang_reflect_Method::slot(reflected);1902}1903Klass* k = java_lang_Class::as_Klass(mirror);19041905Method* m = InstanceKlass::cast(k)->method_with_idnum(slot);1906assert(m != NULL, "cannot find method");1907return m; // caller has to deal with NULL in product mode1908}190919101911JVM_ENTRY(jbyteArray, JVM_GetMethodAnnotations(JNIEnv *env, jobject method))1912JVMWrapper("JVM_GetMethodAnnotations");19131914// method is a handle to a java.lang.reflect.Method object1915Method* m = jvm_get_method_common(method);1916if (m == NULL) {1917return NULL;1918}19191920return (jbyteArray) JNIHandles::make_local(env,1921Annotations::make_java_array(m->annotations(), THREAD));1922JVM_END192319241925JVM_ENTRY(jbyteArray, JVM_GetMethodDefaultAnnotationValue(JNIEnv *env, jobject method))1926JVMWrapper("JVM_GetMethodDefaultAnnotationValue");19271928// method is a handle to a java.lang.reflect.Method object1929Method* m = jvm_get_method_common(method);1930if (m == NULL) {1931return NULL;1932}19331934return (jbyteArray) JNIHandles::make_local(env,1935Annotations::make_java_array(m->annotation_default(), THREAD));1936JVM_END193719381939JVM_ENTRY(jbyteArray, JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject method))1940JVMWrapper("JVM_GetMethodParameterAnnotations");19411942// method is a handle to a java.lang.reflect.Method object1943Method* m = jvm_get_method_common(method);1944if (m == NULL) {1945return NULL;1946}19471948return (jbyteArray) JNIHandles::make_local(env,1949Annotations::make_java_array(m->parameter_annotations(), THREAD));1950JVM_END19511952/* Type use annotations support (JDK 1.8) */19531954JVM_ENTRY(jbyteArray, JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls))1955assert (cls != NULL, "illegal class");1956JVMWrapper("JVM_GetClassTypeAnnotations");1957ResourceMark rm(THREAD);1958// Return null for arrays and primitives1959if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {1960Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));1961if (k->oop_is_instance()) {1962AnnotationArray* type_annotations = InstanceKlass::cast(k)->class_type_annotations();1963if (type_annotations != NULL) {1964typeArrayOop a = Annotations::make_java_array(type_annotations, CHECK_NULL);1965return (jbyteArray) JNIHandles::make_local(env, a);1966}1967}1968}1969return NULL;1970JVM_END19711972JVM_ENTRY(jbyteArray, JVM_GetMethodTypeAnnotations(JNIEnv *env, jobject method))1973assert (method != NULL, "illegal method");1974JVMWrapper("JVM_GetMethodTypeAnnotations");19751976// method is a handle to a java.lang.reflect.Method object1977Method* m = jvm_get_method_common(method);1978if (m == NULL) {1979return NULL;1980}19811982AnnotationArray* type_annotations = m->type_annotations();1983if (type_annotations != NULL) {1984typeArrayOop a = Annotations::make_java_array(type_annotations, CHECK_NULL);1985return (jbyteArray) JNIHandles::make_local(env, a);1986}19871988return NULL;1989JVM_END19901991JVM_ENTRY(jbyteArray, JVM_GetFieldTypeAnnotations(JNIEnv *env, jobject field))1992assert (field != NULL, "illegal field");1993JVMWrapper("JVM_GetFieldTypeAnnotations");19941995fieldDescriptor fd;1996bool gotFd = jvm_get_field_common(field, fd, CHECK_NULL);1997if (!gotFd) {1998return NULL;1999}20002001return (jbyteArray) JNIHandles::make_local(env, Annotations::make_java_array(fd.type_annotations(), THREAD));2002JVM_END20032004static void bounds_check(constantPoolHandle cp, jint index, TRAPS) {2005if (!cp->is_within_bounds(index)) {2006THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Constant pool index out of bounds");2007}2008}20092010JVM_ENTRY(jobjectArray, JVM_GetMethodParameters(JNIEnv *env, jobject method))2011{2012JVMWrapper("JVM_GetMethodParameters");2013// method is a handle to a java.lang.reflect.Method object2014Method* method_ptr = jvm_get_method_common(method);2015methodHandle mh (THREAD, method_ptr);2016Handle reflected_method (THREAD, JNIHandles::resolve_non_null(method));2017const int num_params = mh->method_parameters_length();20182019if (0 != num_params) {2020// make sure all the symbols are properly formatted2021for (int i = 0; i < num_params; i++) {2022MethodParametersElement* params = mh->method_parameters_start();2023int index = params[i].name_cp_index;2024bounds_check(mh->constants(), index, CHECK_NULL);20252026if (0 != index && !mh->constants()->tag_at(index).is_utf8()) {2027THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),2028"Wrong type at constant pool index");2029}20302031}20322033objArrayOop result_oop = oopFactory::new_objArray(SystemDictionary::reflect_Parameter_klass(), num_params, CHECK_NULL);2034objArrayHandle result (THREAD, result_oop);20352036for (int i = 0; i < num_params; i++) {2037MethodParametersElement* params = mh->method_parameters_start();2038// For a 0 index, give a NULL symbol2039Symbol* sym = 0 != params[i].name_cp_index ?2040mh->constants()->symbol_at(params[i].name_cp_index) : NULL;2041int flags = params[i].flags;2042oop param = Reflection::new_parameter(reflected_method, i, sym,2043flags, CHECK_NULL);2044result->obj_at_put(i, param);2045}2046return (jobjectArray)JNIHandles::make_local(env, result());2047} else {2048return (jobjectArray)NULL;2049}2050}2051JVM_END20522053// New (JDK 1.4) reflection implementation /////////////////////////////////////20542055JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly))2056{2057JVMWrapper("JVM_GetClassDeclaredFields");2058JvmtiVMObjectAllocEventCollector oam;20592060// Exclude primitive types and array types2061if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) ||2062java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) {2063// Return empty array2064oop res = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), 0, CHECK_NULL);2065return (jobjectArray) JNIHandles::make_local(env, res);2066}20672068instanceKlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)));2069constantPoolHandle cp(THREAD, k->constants());20702071// Ensure class is linked2072k->link_class(CHECK_NULL);20732074// 4496456 We need to filter out java.lang.Throwable.backtrace2075bool skip_backtrace = false;20762077// Allocate result2078int num_fields;20792080if (publicOnly) {2081num_fields = 0;2082for (JavaFieldStream fs(k()); !fs.done(); fs.next()) {2083if (fs.access_flags().is_public()) ++num_fields;2084}2085} else {2086num_fields = k->java_fields_count();20872088if (k() == SystemDictionary::Throwable_klass()) {2089num_fields--;2090skip_backtrace = true;2091}2092}20932094objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), num_fields, CHECK_NULL);2095objArrayHandle result (THREAD, r);20962097int out_idx = 0;2098fieldDescriptor fd;2099for (JavaFieldStream fs(k); !fs.done(); fs.next()) {2100if (skip_backtrace) {2101// 4496456 skip java.lang.Throwable.backtrace2102int offset = fs.offset();2103if (offset == java_lang_Throwable::get_backtrace_offset()) continue;2104}21052106if (!publicOnly || fs.access_flags().is_public()) {2107fd.reinitialize(k(), fs.index());2108oop field = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL);2109result->obj_at_put(out_idx, field);2110++out_idx;2111}2112}2113assert(out_idx == num_fields, "just checking");2114return (jobjectArray) JNIHandles::make_local(env, result());2115}2116JVM_END21172118static bool select_method(methodHandle method, bool want_constructor) {2119if (want_constructor) {2120return (method->is_initializer() && !method->is_static());2121} else {2122return (!method->is_initializer() && !method->is_overpass());2123}2124}21252126static jobjectArray get_class_declared_methods_helper(2127JNIEnv *env,2128jclass ofClass, jboolean publicOnly,2129bool want_constructor,2130Klass* klass, TRAPS) {21312132JvmtiVMObjectAllocEventCollector oam;21332134// Exclude primitive types and array types2135if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass))2136|| java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) {2137// Return empty array2138oop res = oopFactory::new_objArray(klass, 0, CHECK_NULL);2139return (jobjectArray) JNIHandles::make_local(env, res);2140}21412142instanceKlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)));21432144// Ensure class is linked2145k->link_class(CHECK_NULL);21462147Array<Method*>* methods = k->methods();2148int methods_length = methods->length();21492150// Save original method_idnum in case of redefinition, which can change2151// the idnum of obsolete methods. The new method will have the same idnum2152// but if we refresh the methods array, the counts will be wrong.2153ResourceMark rm(THREAD);2154GrowableArray<int>* idnums = new GrowableArray<int>(methods_length);2155int num_methods = 0;21562157for (int i = 0; i < methods_length; i++) {2158methodHandle method(THREAD, methods->at(i));2159if (select_method(method, want_constructor)) {2160if (!publicOnly || method->is_public()) {2161idnums->push(method->method_idnum());2162++num_methods;2163}2164}2165}21662167// Allocate result2168objArrayOop r = oopFactory::new_objArray(klass, num_methods, CHECK_NULL);2169objArrayHandle result (THREAD, r);21702171// Now just put the methods that we selected above, but go by their idnum2172// in case of redefinition. The methods can be redefined at any safepoint,2173// so above when allocating the oop array and below when creating reflect2174// objects.2175for (int i = 0; i < num_methods; i++) {2176methodHandle method(THREAD, k->method_with_idnum(idnums->at(i)));2177if (method.is_null()) {2178// Method may have been deleted and seems this API can handle null2179// Otherwise should probably put a method that throws NSME2180result->obj_at_put(i, NULL);2181} else {2182oop m;2183if (want_constructor) {2184m = Reflection::new_constructor(method, CHECK_NULL);2185} else {2186m = Reflection::new_method(method, UseNewReflection, false, CHECK_NULL);2187}2188result->obj_at_put(i, m);2189}2190}21912192return (jobjectArray) JNIHandles::make_local(env, result());2193}21942195JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly))2196{2197JVMWrapper("JVM_GetClassDeclaredMethods");2198return get_class_declared_methods_helper(env, ofClass, publicOnly,2199/*want_constructor*/ false,2200SystemDictionary::reflect_Method_klass(), THREAD);2201}2202JVM_END22032204JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly))2205{2206JVMWrapper("JVM_GetClassDeclaredConstructors");2207return get_class_declared_methods_helper(env, ofClass, publicOnly,2208/*want_constructor*/ true,2209SystemDictionary::reflect_Constructor_klass(), THREAD);2210}2211JVM_END22122213JVM_ENTRY(jint, JVM_GetClassAccessFlags(JNIEnv *env, jclass cls))2214{2215JVMWrapper("JVM_GetClassAccessFlags");2216if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {2217// Primitive type2218return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC;2219}22202221Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2222return k->access_flags().as_int() & JVM_ACC_WRITTEN_FLAGS;2223}2224JVM_END222522262227// Constant pool access //////////////////////////////////////////////////////////22282229JVM_ENTRY(jobject, JVM_GetClassConstantPool(JNIEnv *env, jclass cls))2230{2231JVMWrapper("JVM_GetClassConstantPool");2232JvmtiVMObjectAllocEventCollector oam;22332234// Return null for primitives and arrays2235if (!java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {2236Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2237if (k->oop_is_instance()) {2238instanceKlassHandle k_h(THREAD, k);2239Handle jcp = sun_reflect_ConstantPool::create(CHECK_NULL);2240sun_reflect_ConstantPool::set_cp(jcp(), k_h->constants());2241return JNIHandles::make_local(jcp());2242}2243}2244return NULL;2245}2246JVM_END224722482249JVM_ENTRY(jint, JVM_ConstantPoolGetSize(JNIEnv *env, jobject obj, jobject unused))2250{2251JVMWrapper("JVM_ConstantPoolGetSize");2252constantPoolHandle cp = constantPoolHandle(THREAD, sun_reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2253return cp->length();2254}2255JVM_END225622572258JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject obj, jobject unused, jint index))2259{2260JVMWrapper("JVM_ConstantPoolGetClassAt");2261constantPoolHandle cp = constantPoolHandle(THREAD, sun_reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2262bounds_check(cp, index, CHECK_NULL);2263constantTag tag = cp->tag_at(index);2264if (!tag.is_klass() && !tag.is_unresolved_klass()) {2265THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2266}2267Klass* k = cp->klass_at(index, CHECK_NULL);2268return (jclass) JNIHandles::make_local(k->java_mirror());2269}2270JVM_END22712272JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject obj, jobject unused, jint index))2273{2274JVMWrapper("JVM_ConstantPoolGetClassAtIfLoaded");2275constantPoolHandle cp = constantPoolHandle(THREAD, sun_reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2276bounds_check(cp, index, CHECK_NULL);2277constantTag tag = cp->tag_at(index);2278if (!tag.is_klass() && !tag.is_unresolved_klass()) {2279THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2280}2281Klass* k = ConstantPool::klass_at_if_loaded(cp, index);2282if (k == NULL) return NULL;2283return (jclass) JNIHandles::make_local(k->java_mirror());2284}2285JVM_END22862287static jobject get_method_at_helper(constantPoolHandle cp, jint index, bool force_resolution, TRAPS) {2288constantTag tag = cp->tag_at(index);2289if (!tag.is_method() && !tag.is_interface_method()) {2290THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2291}2292int klass_ref = cp->uncached_klass_ref_index_at(index);2293Klass* k_o;2294if (force_resolution) {2295k_o = cp->klass_at(klass_ref, CHECK_NULL);2296} else {2297k_o = ConstantPool::klass_at_if_loaded(cp, klass_ref);2298if (k_o == NULL) return NULL;2299}2300instanceKlassHandle k(THREAD, k_o);2301Symbol* name = cp->uncached_name_ref_at(index);2302Symbol* sig = cp->uncached_signature_ref_at(index);2303methodHandle m (THREAD, k->find_method(name, sig));2304if (m.is_null()) {2305THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "Unable to look up method in target class");2306}2307oop method;2308if (!m->is_initializer() || m->is_static()) {2309method = Reflection::new_method(m, true, true, CHECK_NULL);2310} else {2311method = Reflection::new_constructor(m, CHECK_NULL);2312}2313return JNIHandles::make_local(method);2314}23152316JVM_ENTRY(jobject, JVM_ConstantPoolGetMethodAt(JNIEnv *env, jobject obj, jobject unused, jint index))2317{2318JVMWrapper("JVM_ConstantPoolGetMethodAt");2319JvmtiVMObjectAllocEventCollector oam;2320constantPoolHandle cp = constantPoolHandle(THREAD, sun_reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2321bounds_check(cp, index, CHECK_NULL);2322jobject res = get_method_at_helper(cp, index, true, CHECK_NULL);2323return res;2324}2325JVM_END23262327JVM_ENTRY(jobject, JVM_ConstantPoolGetMethodAtIfLoaded(JNIEnv *env, jobject obj, jobject unused, jint index))2328{2329JVMWrapper("JVM_ConstantPoolGetMethodAtIfLoaded");2330JvmtiVMObjectAllocEventCollector oam;2331constantPoolHandle cp = constantPoolHandle(THREAD, sun_reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2332bounds_check(cp, index, CHECK_NULL);2333jobject res = get_method_at_helper(cp, index, false, CHECK_NULL);2334return res;2335}2336JVM_END23372338static jobject get_field_at_helper(constantPoolHandle cp, jint index, bool force_resolution, TRAPS) {2339constantTag tag = cp->tag_at(index);2340if (!tag.is_field()) {2341THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2342}2343int klass_ref = cp->uncached_klass_ref_index_at(index);2344Klass* k_o;2345if (force_resolution) {2346k_o = cp->klass_at(klass_ref, CHECK_NULL);2347} else {2348k_o = ConstantPool::klass_at_if_loaded(cp, klass_ref);2349if (k_o == NULL) return NULL;2350}2351instanceKlassHandle k(THREAD, k_o);2352Symbol* name = cp->uncached_name_ref_at(index);2353Symbol* sig = cp->uncached_signature_ref_at(index);2354fieldDescriptor fd;2355Klass* target_klass = k->find_field(name, sig, &fd);2356if (target_klass == NULL) {2357THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "Unable to look up field in target class");2358}2359oop field = Reflection::new_field(&fd, true, CHECK_NULL);2360return JNIHandles::make_local(field);2361}23622363JVM_ENTRY(jobject, JVM_ConstantPoolGetFieldAt(JNIEnv *env, jobject obj, jobject unusedl, jint index))2364{2365JVMWrapper("JVM_ConstantPoolGetFieldAt");2366JvmtiVMObjectAllocEventCollector oam;2367constantPoolHandle cp = constantPoolHandle(THREAD, sun_reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2368bounds_check(cp, index, CHECK_NULL);2369jobject res = get_field_at_helper(cp, index, true, CHECK_NULL);2370return res;2371}2372JVM_END23732374JVM_ENTRY(jobject, JVM_ConstantPoolGetFieldAtIfLoaded(JNIEnv *env, jobject obj, jobject unused, jint index))2375{2376JVMWrapper("JVM_ConstantPoolGetFieldAtIfLoaded");2377JvmtiVMObjectAllocEventCollector oam;2378constantPoolHandle cp = constantPoolHandle(THREAD, sun_reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2379bounds_check(cp, index, CHECK_NULL);2380jobject res = get_field_at_helper(cp, index, false, CHECK_NULL);2381return res;2382}2383JVM_END23842385JVM_ENTRY(jobjectArray, JVM_ConstantPoolGetMemberRefInfoAt(JNIEnv *env, jobject obj, jobject unused, jint index))2386{2387JVMWrapper("JVM_ConstantPoolGetMemberRefInfoAt");2388JvmtiVMObjectAllocEventCollector oam;2389constantPoolHandle cp = constantPoolHandle(THREAD, sun_reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2390bounds_check(cp, index, CHECK_NULL);2391constantTag tag = cp->tag_at(index);2392if (!tag.is_field_or_method()) {2393THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2394}2395int klass_ref = cp->uncached_klass_ref_index_at(index);2396Symbol* klass_name = cp->klass_name_at(klass_ref);2397Symbol* member_name = cp->uncached_name_ref_at(index);2398Symbol* member_sig = cp->uncached_signature_ref_at(index);2399objArrayOop dest_o = oopFactory::new_objArray(SystemDictionary::String_klass(), 3, CHECK_NULL);2400objArrayHandle dest(THREAD, dest_o);2401Handle str = java_lang_String::create_from_symbol(klass_name, CHECK_NULL);2402dest->obj_at_put(0, str());2403str = java_lang_String::create_from_symbol(member_name, CHECK_NULL);2404dest->obj_at_put(1, str());2405str = java_lang_String::create_from_symbol(member_sig, CHECK_NULL);2406dest->obj_at_put(2, str());2407return (jobjectArray) JNIHandles::make_local(dest());2408}2409JVM_END24102411JVM_ENTRY(jint, JVM_ConstantPoolGetIntAt(JNIEnv *env, jobject obj, jobject unused, jint index))2412{2413JVMWrapper("JVM_ConstantPoolGetIntAt");2414constantPoolHandle cp = constantPoolHandle(THREAD, sun_reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2415bounds_check(cp, index, CHECK_0);2416constantTag tag = cp->tag_at(index);2417if (!tag.is_int()) {2418THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2419}2420return cp->int_at(index);2421}2422JVM_END24232424JVM_ENTRY(jlong, JVM_ConstantPoolGetLongAt(JNIEnv *env, jobject obj, jobject unused, jint index))2425{2426JVMWrapper("JVM_ConstantPoolGetLongAt");2427constantPoolHandle cp = constantPoolHandle(THREAD, sun_reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2428bounds_check(cp, index, CHECK_(0L));2429constantTag tag = cp->tag_at(index);2430if (!tag.is_long()) {2431THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2432}2433return cp->long_at(index);2434}2435JVM_END24362437JVM_ENTRY(jfloat, JVM_ConstantPoolGetFloatAt(JNIEnv *env, jobject obj, jobject unused, jint index))2438{2439JVMWrapper("JVM_ConstantPoolGetFloatAt");2440constantPoolHandle cp = constantPoolHandle(THREAD, sun_reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2441bounds_check(cp, index, CHECK_(0.0f));2442constantTag tag = cp->tag_at(index);2443if (!tag.is_float()) {2444THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2445}2446return cp->float_at(index);2447}2448JVM_END24492450JVM_ENTRY(jdouble, JVM_ConstantPoolGetDoubleAt(JNIEnv *env, jobject obj, jobject unused, jint index))2451{2452JVMWrapper("JVM_ConstantPoolGetDoubleAt");2453constantPoolHandle cp = constantPoolHandle(THREAD, sun_reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2454bounds_check(cp, index, CHECK_(0.0));2455constantTag tag = cp->tag_at(index);2456if (!tag.is_double()) {2457THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2458}2459return cp->double_at(index);2460}2461JVM_END24622463JVM_ENTRY(jstring, JVM_ConstantPoolGetStringAt(JNIEnv *env, jobject obj, jobject unused, jint index))2464{2465JVMWrapper("JVM_ConstantPoolGetStringAt");2466constantPoolHandle cp = constantPoolHandle(THREAD, sun_reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2467bounds_check(cp, index, CHECK_NULL);2468constantTag tag = cp->tag_at(index);2469if (!tag.is_string()) {2470THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2471}2472oop str = cp->string_at(index, CHECK_NULL);2473return (jstring) JNIHandles::make_local(str);2474}2475JVM_END24762477JVM_ENTRY(jstring, JVM_ConstantPoolGetUTF8At(JNIEnv *env, jobject obj, jobject unused, jint index))2478{2479JVMWrapper("JVM_ConstantPoolGetUTF8At");2480JvmtiVMObjectAllocEventCollector oam;2481constantPoolHandle cp = constantPoolHandle(THREAD, sun_reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));2482bounds_check(cp, index, CHECK_NULL);2483constantTag tag = cp->tag_at(index);2484if (!tag.is_symbol()) {2485THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");2486}2487Symbol* sym = cp->symbol_at(index);2488Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL);2489return (jstring) JNIHandles::make_local(str());2490}2491JVM_END249224932494// Assertion support. //////////////////////////////////////////////////////////24952496JVM_ENTRY(jboolean, JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls))2497JVMWrapper("JVM_DesiredAssertionStatus");2498assert(cls != NULL, "bad class");24992500oop r = JNIHandles::resolve(cls);2501assert(! java_lang_Class::is_primitive(r), "primitive classes not allowed");2502if (java_lang_Class::is_primitive(r)) return false;25032504Klass* k = java_lang_Class::as_Klass(r);2505assert(k->oop_is_instance(), "must be an instance klass");2506if (! k->oop_is_instance()) return false;25072508ResourceMark rm(THREAD);2509const char* name = k->name()->as_C_string();2510bool system_class = k->class_loader() == NULL;2511return JavaAssertions::enabled(name, system_class);25122513JVM_END251425152516// Return a new AssertionStatusDirectives object with the fields filled in with2517// command-line assertion arguments (i.e., -ea, -da).2518JVM_ENTRY(jobject, JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused))2519JVMWrapper("JVM_AssertionStatusDirectives");2520JvmtiVMObjectAllocEventCollector oam;2521oop asd = JavaAssertions::createAssertionStatusDirectives(CHECK_NULL);2522return JNIHandles::make_local(env, asd);2523JVM_END25242525// Verification ////////////////////////////////////////////////////////////////////////////////25262527// Reflection for the verifier /////////////////////////////////////////////////////////////////25282529// RedefineClasses support: bug 6214132 caused verification to fail.2530// All functions from this section should call the jvmtiThreadSate function:2531// Klass* class_to_verify_considering_redefinition(Klass* klass).2532// The function returns a Klass* of the _scratch_class if the verifier2533// was invoked in the middle of the class redefinition.2534// Otherwise it returns its argument value which is the _the_class Klass*.2535// Please, refer to the description in the jvmtiThreadSate.hpp.25362537JVM_ENTRY(const char*, JVM_GetClassNameUTF(JNIEnv *env, jclass cls))2538JVMWrapper("JVM_GetClassNameUTF");2539Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2540k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2541return k->name()->as_utf8();2542JVM_END254325442545JVM_QUICK_ENTRY(void, JVM_GetClassCPTypes(JNIEnv *env, jclass cls, unsigned char *types))2546JVMWrapper("JVM_GetClassCPTypes");2547Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2548k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2549// types will have length zero if this is not an InstanceKlass2550// (length is determined by call to JVM_GetClassCPEntriesCount)2551if (k->oop_is_instance()) {2552ConstantPool* cp = InstanceKlass::cast(k)->constants();2553for (int index = cp->length() - 1; index >= 0; index--) {2554constantTag tag = cp->tag_at(index);2555types[index] = (tag.is_unresolved_klass()) ? JVM_CONSTANT_Class : tag.value();2556}2557}2558JVM_END255925602561JVM_QUICK_ENTRY(jint, JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cls))2562JVMWrapper("JVM_GetClassCPEntriesCount");2563Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2564k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2565if (!k->oop_is_instance())2566return 0;2567return InstanceKlass::cast(k)->constants()->length();2568JVM_END256925702571JVM_QUICK_ENTRY(jint, JVM_GetClassFieldsCount(JNIEnv *env, jclass cls))2572JVMWrapper("JVM_GetClassFieldsCount");2573Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2574k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2575if (!k->oop_is_instance())2576return 0;2577return InstanceKlass::cast(k)->java_fields_count();2578JVM_END257925802581JVM_QUICK_ENTRY(jint, JVM_GetClassMethodsCount(JNIEnv *env, jclass cls))2582JVMWrapper("JVM_GetClassMethodsCount");2583Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2584k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2585if (!k->oop_is_instance())2586return 0;2587return InstanceKlass::cast(k)->methods()->length();2588JVM_END258925902591// The following methods, used for the verifier, are never called with2592// array klasses, so a direct cast to InstanceKlass is safe.2593// Typically, these methods are called in a loop with bounds determined2594// by the results of JVM_GetClass{Fields,Methods}Count, which return2595// zero for arrays.2596JVM_QUICK_ENTRY(void, JVM_GetMethodIxExceptionIndexes(JNIEnv *env, jclass cls, jint method_index, unsigned short *exceptions))2597JVMWrapper("JVM_GetMethodIxExceptionIndexes");2598Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2599k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2600Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2601int length = method->checked_exceptions_length();2602if (length > 0) {2603CheckedExceptionElement* table= method->checked_exceptions_start();2604for (int i = 0; i < length; i++) {2605exceptions[i] = table[i].class_cp_index;2606}2607}2608JVM_END260926102611JVM_QUICK_ENTRY(jint, JVM_GetMethodIxExceptionsCount(JNIEnv *env, jclass cls, jint method_index))2612JVMWrapper("JVM_GetMethodIxExceptionsCount");2613Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2614k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2615Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2616return method->checked_exceptions_length();2617JVM_END261826192620JVM_QUICK_ENTRY(void, JVM_GetMethodIxByteCode(JNIEnv *env, jclass cls, jint method_index, unsigned char *code))2621JVMWrapper("JVM_GetMethodIxByteCode");2622Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2623k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2624Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2625memcpy(code, method->code_base(), method->code_size());2626JVM_END262726282629JVM_QUICK_ENTRY(jint, JVM_GetMethodIxByteCodeLength(JNIEnv *env, jclass cls, jint method_index))2630JVMWrapper("JVM_GetMethodIxByteCodeLength");2631Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2632k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2633Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2634return method->code_size();2635JVM_END263626372638JVM_QUICK_ENTRY(void, JVM_GetMethodIxExceptionTableEntry(JNIEnv *env, jclass cls, jint method_index, jint entry_index, JVM_ExceptionTableEntryType *entry))2639JVMWrapper("JVM_GetMethodIxExceptionTableEntry");2640Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2641k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2642Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2643ExceptionTable extable(method);2644entry->start_pc = extable.start_pc(entry_index);2645entry->end_pc = extable.end_pc(entry_index);2646entry->handler_pc = extable.handler_pc(entry_index);2647entry->catchType = extable.catch_type_index(entry_index);2648JVM_END264926502651JVM_QUICK_ENTRY(jint, JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cls, int method_index))2652JVMWrapper("JVM_GetMethodIxExceptionTableLength");2653Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2654k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2655Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2656return method->exception_table_length();2657JVM_END265826592660JVM_QUICK_ENTRY(jint, JVM_GetMethodIxModifiers(JNIEnv *env, jclass cls, int method_index))2661JVMWrapper("JVM_GetMethodIxModifiers");2662Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2663k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2664Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2665return method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS;2666JVM_END266726682669JVM_QUICK_ENTRY(jint, JVM_GetFieldIxModifiers(JNIEnv *env, jclass cls, int field_index))2670JVMWrapper("JVM_GetFieldIxModifiers");2671Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2672k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2673return InstanceKlass::cast(k)->field_access_flags(field_index) & JVM_RECOGNIZED_FIELD_MODIFIERS;2674JVM_END267526762677JVM_QUICK_ENTRY(jint, JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cls, int method_index))2678JVMWrapper("JVM_GetMethodIxLocalsCount");2679Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2680k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2681Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2682return method->max_locals();2683JVM_END268426852686JVM_QUICK_ENTRY(jint, JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cls, int method_index))2687JVMWrapper("JVM_GetMethodIxArgsSize");2688Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2689k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2690Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2691return method->size_of_parameters();2692JVM_END269326942695JVM_QUICK_ENTRY(jint, JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cls, int method_index))2696JVMWrapper("JVM_GetMethodIxMaxStack");2697Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2698k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2699Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2700return method->verifier_max_stack();2701JVM_END270227032704JVM_QUICK_ENTRY(jboolean, JVM_IsConstructorIx(JNIEnv *env, jclass cls, int method_index))2705JVMWrapper("JVM_IsConstructorIx");2706ResourceMark rm(THREAD);2707Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2708k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2709Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2710return method->name() == vmSymbols::object_initializer_name();2711JVM_END271227132714JVM_QUICK_ENTRY(jboolean, JVM_IsVMGeneratedMethodIx(JNIEnv *env, jclass cls, int method_index))2715JVMWrapper("JVM_IsVMGeneratedMethodIx");2716ResourceMark rm(THREAD);2717Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2718k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2719Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2720return method->is_overpass();2721JVM_END27222723JVM_ENTRY(const char*, JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cls, jint method_index))2724JVMWrapper("JVM_GetMethodIxIxUTF");2725Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2726k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2727Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2728return method->name()->as_utf8();2729JVM_END273027312732JVM_ENTRY(const char*, JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cls, jint method_index))2733JVMWrapper("JVM_GetMethodIxSignatureUTF");2734Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2735k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2736Method* method = InstanceKlass::cast(k)->methods()->at(method_index);2737return method->signature()->as_utf8();2738JVM_END27392740/**2741* All of these JVM_GetCP-xxx methods are used by the old verifier to2742* read entries in the constant pool. Since the old verifier always2743* works on a copy of the code, it will not see any rewriting that2744* may possibly occur in the middle of verification. So it is important2745* that nothing it calls tries to use the cpCache instead of the raw2746* constant pool, so we must use cp->uncached_x methods when appropriate.2747*/2748JVM_ENTRY(const char*, JVM_GetCPFieldNameUTF(JNIEnv *env, jclass cls, jint cp_index))2749JVMWrapper("JVM_GetCPFieldNameUTF");2750Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2751k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2752ConstantPool* cp = InstanceKlass::cast(k)->constants();2753switch (cp->tag_at(cp_index).value()) {2754case JVM_CONSTANT_Fieldref:2755return cp->uncached_name_ref_at(cp_index)->as_utf8();2756default:2757fatal("JVM_GetCPFieldNameUTF: illegal constant");2758}2759ShouldNotReachHere();2760return NULL;2761JVM_END276227632764JVM_ENTRY(const char*, JVM_GetCPMethodNameUTF(JNIEnv *env, jclass cls, jint cp_index))2765JVMWrapper("JVM_GetCPMethodNameUTF");2766Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2767k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2768ConstantPool* cp = InstanceKlass::cast(k)->constants();2769switch (cp->tag_at(cp_index).value()) {2770case JVM_CONSTANT_InterfaceMethodref:2771case JVM_CONSTANT_Methodref:2772return cp->uncached_name_ref_at(cp_index)->as_utf8();2773default:2774fatal("JVM_GetCPMethodNameUTF: illegal constant");2775}2776ShouldNotReachHere();2777return NULL;2778JVM_END277927802781JVM_ENTRY(const char*, JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cls, jint cp_index))2782JVMWrapper("JVM_GetCPMethodSignatureUTF");2783Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2784k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2785ConstantPool* cp = InstanceKlass::cast(k)->constants();2786switch (cp->tag_at(cp_index).value()) {2787case JVM_CONSTANT_InterfaceMethodref:2788case JVM_CONSTANT_Methodref:2789return cp->uncached_signature_ref_at(cp_index)->as_utf8();2790default:2791fatal("JVM_GetCPMethodSignatureUTF: illegal constant");2792}2793ShouldNotReachHere();2794return NULL;2795JVM_END279627972798JVM_ENTRY(const char*, JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cls, jint cp_index))2799JVMWrapper("JVM_GetCPFieldSignatureUTF");2800Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2801k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2802ConstantPool* cp = InstanceKlass::cast(k)->constants();2803switch (cp->tag_at(cp_index).value()) {2804case JVM_CONSTANT_Fieldref:2805return cp->uncached_signature_ref_at(cp_index)->as_utf8();2806default:2807fatal("JVM_GetCPFieldSignatureUTF: illegal constant");2808}2809ShouldNotReachHere();2810return NULL;2811JVM_END281228132814JVM_ENTRY(const char*, JVM_GetCPClassNameUTF(JNIEnv *env, jclass cls, jint cp_index))2815JVMWrapper("JVM_GetCPClassNameUTF");2816Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2817k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2818ConstantPool* cp = InstanceKlass::cast(k)->constants();2819Symbol* classname = cp->klass_name_at(cp_index);2820return classname->as_utf8();2821JVM_END282228232824JVM_ENTRY(const char*, JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cls, jint cp_index))2825JVMWrapper("JVM_GetCPFieldClassNameUTF");2826Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2827k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2828ConstantPool* cp = InstanceKlass::cast(k)->constants();2829switch (cp->tag_at(cp_index).value()) {2830case JVM_CONSTANT_Fieldref: {2831int class_index = cp->uncached_klass_ref_index_at(cp_index);2832Symbol* classname = cp->klass_name_at(class_index);2833return classname->as_utf8();2834}2835default:2836fatal("JVM_GetCPFieldClassNameUTF: illegal constant");2837}2838ShouldNotReachHere();2839return NULL;2840JVM_END284128422843JVM_ENTRY(const char*, JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cls, jint cp_index))2844JVMWrapper("JVM_GetCPMethodClassNameUTF");2845Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2846k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2847ConstantPool* cp = InstanceKlass::cast(k)->constants();2848switch (cp->tag_at(cp_index).value()) {2849case JVM_CONSTANT_Methodref:2850case JVM_CONSTANT_InterfaceMethodref: {2851int class_index = cp->uncached_klass_ref_index_at(cp_index);2852Symbol* classname = cp->klass_name_at(class_index);2853return classname->as_utf8();2854}2855default:2856fatal("JVM_GetCPMethodClassNameUTF: illegal constant");2857}2858ShouldNotReachHere();2859return NULL;2860JVM_END286128622863JVM_ENTRY(jint, JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls))2864JVMWrapper("JVM_GetCPFieldModifiers");2865Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2866Klass* k_called = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(called_cls));2867k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2868k_called = JvmtiThreadState::class_to_verify_considering_redefinition(k_called, thread);2869ConstantPool* cp = InstanceKlass::cast(k)->constants();2870ConstantPool* cp_called = InstanceKlass::cast(k_called)->constants();2871switch (cp->tag_at(cp_index).value()) {2872case JVM_CONSTANT_Fieldref: {2873Symbol* name = cp->uncached_name_ref_at(cp_index);2874Symbol* signature = cp->uncached_signature_ref_at(cp_index);2875for (JavaFieldStream fs(k_called); !fs.done(); fs.next()) {2876if (fs.name() == name && fs.signature() == signature) {2877return fs.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS;2878}2879}2880return -1;2881}2882default:2883fatal("JVM_GetCPFieldModifiers: illegal constant");2884}2885ShouldNotReachHere();2886return 0;2887JVM_END288828892890JVM_QUICK_ENTRY(jint, JVM_GetCPMethodModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls))2891JVMWrapper("JVM_GetCPMethodModifiers");2892Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));2893Klass* k_called = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(called_cls));2894k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);2895k_called = JvmtiThreadState::class_to_verify_considering_redefinition(k_called, thread);2896ConstantPool* cp = InstanceKlass::cast(k)->constants();2897switch (cp->tag_at(cp_index).value()) {2898case JVM_CONSTANT_Methodref:2899case JVM_CONSTANT_InterfaceMethodref: {2900Symbol* name = cp->uncached_name_ref_at(cp_index);2901Symbol* signature = cp->uncached_signature_ref_at(cp_index);2902Array<Method*>* methods = InstanceKlass::cast(k_called)->methods();2903int methods_count = methods->length();2904for (int i = 0; i < methods_count; i++) {2905Method* method = methods->at(i);2906if (method->name() == name && method->signature() == signature) {2907return method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS;2908}2909}2910return -1;2911}2912default:2913fatal("JVM_GetCPMethodModifiers: illegal constant");2914}2915ShouldNotReachHere();2916return 0;2917JVM_END291829192920// Misc //////////////////////////////////////////////////////////////////////////////////////////////29212922JVM_LEAF(void, JVM_ReleaseUTF(const char *utf))2923// So long as UTF8::convert_to_utf8 returns resource strings, we don't have to do anything2924JVM_END292529262927JVM_ENTRY(jboolean, JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2))2928JVMWrapper("JVM_IsSameClassPackage");2929oop class1_mirror = JNIHandles::resolve_non_null(class1);2930oop class2_mirror = JNIHandles::resolve_non_null(class2);2931Klass* klass1 = java_lang_Class::as_Klass(class1_mirror);2932Klass* klass2 = java_lang_Class::as_Klass(class2_mirror);2933return (jboolean) Reflection::is_same_class_package(klass1, klass2);2934JVM_END293529362937// IO functions ////////////////////////////////////////////////////////////////////////////////////////29382939JVM_LEAF(jint, JVM_Open(const char *fname, jint flags, jint mode))2940JVMWrapper2("JVM_Open (%s)", fname);29412942//%note jvm_r62943int result = os::open(fname, flags, mode);2944if (result >= 0) {2945return result;2946} else {2947switch(errno) {2948case EEXIST:2949return JVM_EEXIST;2950default:2951return -1;2952}2953}2954JVM_END295529562957JVM_LEAF(jint, JVM_Close(jint fd))2958JVMWrapper2("JVM_Close (0x%x)", fd);2959//%note jvm_r62960return os::close(fd);2961JVM_END296229632964JVM_LEAF(jint, JVM_Read(jint fd, char *buf, jint nbytes))2965JVMWrapper2("JVM_Read (0x%x)", fd);29662967//%note jvm_r62968return (jint)os::restartable_read(fd, buf, nbytes);2969JVM_END297029712972JVM_LEAF(jint, JVM_Write(jint fd, char *buf, jint nbytes))2973JVMWrapper2("JVM_Write (0x%x)", fd);29742975//%note jvm_r62976return (jint)os::write(fd, buf, nbytes);2977JVM_END297829792980JVM_LEAF(jint, JVM_Available(jint fd, jlong *pbytes))2981JVMWrapper2("JVM_Available (0x%x)", fd);2982//%note jvm_r62983return os::available(fd, pbytes);2984JVM_END298529862987JVM_LEAF(jlong, JVM_Lseek(jint fd, jlong offset, jint whence))2988JVMWrapper4("JVM_Lseek (0x%x, " INT64_FORMAT ", %d)", fd, (int64_t) offset, whence);2989//%note jvm_r62990return os::lseek(fd, offset, whence);2991JVM_END299229932994JVM_LEAF(jint, JVM_SetLength(jint fd, jlong length))2995JVMWrapper3("JVM_SetLength (0x%x, " INT64_FORMAT ")", fd, (int64_t) length);2996return os::ftruncate(fd, length);2997JVM_END299829993000JVM_LEAF(jint, JVM_Sync(jint fd))3001JVMWrapper2("JVM_Sync (0x%x)", fd);3002//%note jvm_r63003return os::fsync(fd);3004JVM_END300530063007// Printing support //////////////////////////////////////////////////3008extern "C" {30093010ATTRIBUTE_PRINTF(3, 0)3011int jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args) {3012// Reject count values that are negative signed values converted to3013// unsigned; see bug 4399518, 44172143014if ((intptr_t)count <= 0) return -1;30153016int result = os::vsnprintf(str, count, fmt, args);3017if (result > 0 && (size_t)result >= count) {3018result = -1;3019}30203021return result;3022}30233024ATTRIBUTE_PRINTF(3, 0)3025int jio_snprintf(char *str, size_t count, const char *fmt, ...) {3026va_list args;3027int len;3028va_start(args, fmt);3029len = jio_vsnprintf(str, count, fmt, args);3030va_end(args);3031return len;3032}30333034ATTRIBUTE_PRINTF(2,3)3035int jio_fprintf(FILE* f, const char *fmt, ...) {3036int len;3037va_list args;3038va_start(args, fmt);3039len = jio_vfprintf(f, fmt, args);3040va_end(args);3041return len;3042}30433044ATTRIBUTE_PRINTF(2, 0)3045int jio_vfprintf(FILE* f, const char *fmt, va_list args) {3046if (Arguments::vfprintf_hook() != NULL) {3047return Arguments::vfprintf_hook()(f, fmt, args);3048} else {3049return vfprintf(f, fmt, args);3050}3051}30523053ATTRIBUTE_PRINTF(1, 2)3054JNIEXPORT int jio_printf(const char *fmt, ...) {3055int len;3056va_list args;3057va_start(args, fmt);3058len = jio_vfprintf(defaultStream::output_stream(), fmt, args);3059va_end(args);3060return len;3061}306230633064// HotSpot specific jio method3065void jio_print(const char* s) {3066// Try to make this function as atomic as possible.3067if (Arguments::vfprintf_hook() != NULL) {3068jio_fprintf(defaultStream::output_stream(), "%s", s);3069} else {3070// Make an unused local variable to avoid warning from gcc 4.x compiler.3071size_t count = ::write(defaultStream::output_fd(), s, (int)strlen(s));3072}3073}30743075} // Extern C30763077// java.lang.Thread //////////////////////////////////////////////////////////////////////////////30783079// In most of the JVM Thread support functions we need to be sure to lock the Threads_lock3080// to prevent the target thread from exiting after we have a pointer to the C++ Thread or3081// OSThread objects. The exception to this rule is when the target object is the thread3082// doing the operation, in which case we know that the thread won't exit until the3083// operation is done (all exits being voluntary). There are a few cases where it is3084// rather silly to do operations on yourself, like resuming yourself or asking whether3085// you are alive. While these can still happen, they are not subject to deadlocks if3086// the lock is held while the operation occurs (this is not the case for suspend, for3087// instance), and are very unlikely. Because IsAlive needs to be fast and its3088// implementation is local to this file, we always lock Threads_lock for that one.30893090static void thread_entry(JavaThread* thread, TRAPS) {3091HandleMark hm(THREAD);3092Handle obj(THREAD, thread->threadObj());3093JavaValue result(T_VOID);3094JavaCalls::call_virtual(&result,3095obj,3096KlassHandle(THREAD, SystemDictionary::Thread_klass()),3097vmSymbols::run_method_name(),3098vmSymbols::void_method_signature(),3099THREAD);3100}310131023103JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))3104JVMWrapper("JVM_StartThread");3105JavaThread *native_thread = NULL;31063107// We cannot hold the Threads_lock when we throw an exception,3108// due to rank ordering issues. Example: we might need to grab the3109// Heap_lock while we construct the exception.3110bool throw_illegal_thread_state = false;31113112// We must release the Threads_lock before we can post a jvmti event3113// in Thread::start.3114{3115// Ensure that the C++ Thread and OSThread structures aren't freed before3116// we operate.3117MutexLocker mu(Threads_lock);31183119// Since JDK 5 the java.lang.Thread threadStatus is used to prevent3120// re-starting an already started thread, so we should usually find3121// that the JavaThread is null. However for a JNI attached thread3122// there is a small window between the Thread object being created3123// (with its JavaThread set) and the update to its threadStatus, so we3124// have to check for this3125if (java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) {3126throw_illegal_thread_state = true;3127} else {3128// We could also check the stillborn flag to see if this thread was already stopped, but3129// for historical reasons we let the thread detect that itself when it starts running31303131jlong size =3132java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread));3133// Allocate the C++ Thread structure and create the native thread. The3134// stack size retrieved from java is signed, but the constructor takes3135// size_t (an unsigned type), so avoid passing negative values which would3136// result in really large stacks.3137size_t sz = size > 0 ? (size_t) size : 0;3138native_thread = new JavaThread(&thread_entry, sz);31393140// At this point it may be possible that no osthread was created for the3141// JavaThread due to lack of memory. Check for this situation and throw3142// an exception if necessary. Eventually we may want to change this so3143// that we only grab the lock if the thread was created successfully -3144// then we can also do this check and throw the exception in the3145// JavaThread constructor.3146if (native_thread->osthread() != NULL) {3147// Note: the current thread is not being used within "prepare".3148native_thread->prepare(jthread);3149}3150}3151}31523153if (throw_illegal_thread_state) {3154THROW(vmSymbols::java_lang_IllegalThreadStateException());3155}31563157assert(native_thread != NULL, "Starting null thread?");31583159if (native_thread->osthread() == NULL) {3160// No one should hold a reference to the 'native_thread'.3161delete native_thread;3162if (JvmtiExport::should_post_resource_exhausted()) {3163JvmtiExport::post_resource_exhausted(3164JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_THREADS,3165"unable to create new native thread");3166}3167THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(),3168"unable to create new native thread");3169}31703171Thread::start(native_thread);31723173JVM_END31743175// JVM_Stop is implemented using a VM_Operation, so threads are forced to safepoints3176// before the quasi-asynchronous exception is delivered. This is a little obtrusive,3177// but is thought to be reliable and simple. In the case, where the receiver is the3178// same thread as the sender, no safepoint is needed.3179JVM_ENTRY(void, JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable))3180JVMWrapper("JVM_StopThread");31813182oop java_throwable = JNIHandles::resolve(throwable);3183if (java_throwable == NULL) {3184THROW(vmSymbols::java_lang_NullPointerException());3185}3186oop java_thread = JNIHandles::resolve_non_null(jthread);3187JavaThread* receiver = java_lang_Thread::thread(java_thread);3188Events::log_exception(JavaThread::current(),3189"JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]",3190p2i(receiver), p2i((address)java_thread), p2i(throwable));3191// First check if thread is alive3192if (receiver != NULL) {3193// Check if exception is getting thrown at self (use oop equality, since the3194// target object might exit)3195if (java_thread == thread->threadObj()) {3196THROW_OOP(java_throwable);3197} else {3198// Enques a VM_Operation to stop all threads and then deliver the exception...3199Thread::send_async_exception(java_thread, JNIHandles::resolve(throwable));3200}3201}3202else {3203// Either:3204// - target thread has not been started before being stopped, or3205// - target thread already terminated3206// We could read the threadStatus to determine which case it is3207// but that is overkill as it doesn't matter. We must set the3208// stillborn flag for the first case, and if the thread has already3209// exited setting this flag has no affect3210java_lang_Thread::set_stillborn(java_thread);3211}3212JVM_END321332143215JVM_ENTRY(jboolean, JVM_IsThreadAlive(JNIEnv* env, jobject jthread))3216JVMWrapper("JVM_IsThreadAlive");32173218oop thread_oop = JNIHandles::resolve_non_null(jthread);3219return java_lang_Thread::is_alive(thread_oop);3220JVM_END322132223223JVM_ENTRY(void, JVM_SuspendThread(JNIEnv* env, jobject jthread))3224JVMWrapper("JVM_SuspendThread");3225oop java_thread = JNIHandles::resolve_non_null(jthread);3226JavaThread* receiver = java_lang_Thread::thread(java_thread);32273228if (receiver != NULL) {3229// thread has run and has not exited (still on threads list)32303231{3232MutexLockerEx ml(receiver->SR_lock(), Mutex::_no_safepoint_check_flag);3233if (receiver->is_external_suspend()) {3234// Don't allow nested external suspend requests. We can't return3235// an error from this interface so just ignore the problem.3236return;3237}3238if (receiver->is_exiting()) { // thread is in the process of exiting3239return;3240}3241receiver->set_external_suspend();3242}32433244// java_suspend() will catch threads in the process of exiting3245// and will ignore them.3246receiver->java_suspend();32473248// It would be nice to have the following assertion in all the3249// time, but it is possible for a racing resume request to have3250// resumed this thread right after we suspended it. Temporarily3251// enable this assertion if you are chasing a different kind of3252// bug.3253//3254// assert(java_lang_Thread::thread(receiver->threadObj()) == NULL ||3255// receiver->is_being_ext_suspended(), "thread is not suspended");3256}3257JVM_END325832593260JVM_ENTRY(void, JVM_ResumeThread(JNIEnv* env, jobject jthread))3261JVMWrapper("JVM_ResumeThread");3262// Ensure that the C++ Thread and OSThread structures aren't freed before we operate.3263// We need to *always* get the threads lock here, since this operation cannot be allowed during3264// a safepoint. The safepoint code relies on suspending a thread to examine its state. If other3265// threads randomly resumes threads, then a thread might not be suspended when the safepoint code3266// looks at it.3267MutexLocker ml(Threads_lock);3268JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));3269if (thr != NULL) {3270// the thread has run and is not in the process of exiting3271thr->java_resume();3272}3273JVM_END327432753276JVM_ENTRY(void, JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio))3277JVMWrapper("JVM_SetThreadPriority");3278// Ensure that the C++ Thread and OSThread structures aren't freed before we operate3279MutexLocker ml(Threads_lock);3280oop java_thread = JNIHandles::resolve_non_null(jthread);3281java_lang_Thread::set_priority(java_thread, (ThreadPriority)prio);3282JavaThread* thr = java_lang_Thread::thread(java_thread);3283if (thr != NULL) { // Thread not yet started; priority pushed down when it is3284Thread::set_priority(thr, (ThreadPriority)prio);3285}3286JVM_END328732883289JVM_ENTRY(void, JVM_Yield(JNIEnv *env, jclass threadClass))3290JVMWrapper("JVM_Yield");3291if (os::dont_yield()) return;3292#ifndef USDT23293HS_DTRACE_PROBE0(hotspot, thread__yield);3294#else /* USDT2 */3295HOTSPOT_THREAD_YIELD();3296#endif /* USDT2 */3297// When ConvertYieldToSleep is off (default), this matches the classic VM use of yield.3298// Critical for similar threading behaviour3299if (ConvertYieldToSleep) {3300os::sleep(thread, MinSleepInterval, false);3301} else {3302os::yield();3303}3304JVM_END33053306static void post_thread_sleep_event(EventThreadSleep* event, jlong millis) {3307assert(event != NULL, "invariant");3308assert(event->should_commit(), "invariant");3309event->set_time(millis);3310event->commit();3311}33123313JVM_ENTRY(void, JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis))3314JVMWrapper("JVM_Sleep");33153316if (millis < 0) {3317THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative");3318}33193320if (Thread::is_interrupted (THREAD, true) && !HAS_PENDING_EXCEPTION) {3321THROW_MSG(vmSymbols::java_lang_InterruptedException(), "sleep interrupted");3322}33233324// Save current thread state and restore it at the end of this block.3325// And set new thread state to SLEEPING.3326JavaThreadSleepState jtss(thread);33273328#ifndef USDT23329HS_DTRACE_PROBE1(hotspot, thread__sleep__begin, millis);3330#else /* USDT2 */3331HOTSPOT_THREAD_SLEEP_BEGIN(3332millis);3333#endif /* USDT2 */33343335EventThreadSleep event;33363337if (millis == 0) {3338// When ConvertSleepToYield is on, this matches the classic VM implementation of3339// JVM_Sleep. Critical for similar threading behaviour (Win32)3340// It appears that in certain GUI contexts, it may be beneficial to do a short sleep3341// for SOLARIS3342if (ConvertSleepToYield) {3343os::yield();3344} else {3345ThreadState old_state = thread->osthread()->get_state();3346thread->osthread()->set_state(SLEEPING);3347os::sleep(thread, MinSleepInterval, false);3348thread->osthread()->set_state(old_state);3349}3350} else {3351ThreadState old_state = thread->osthread()->get_state();3352thread->osthread()->set_state(SLEEPING);3353if (os::sleep(thread, millis, true) == OS_INTRPT) {3354// An asynchronous exception (e.g., ThreadDeathException) could have been thrown on3355// us while we were sleeping. We do not overwrite those.3356if (!HAS_PENDING_EXCEPTION) {3357if (event.should_commit()) {3358post_thread_sleep_event(&event, millis);3359}3360#ifndef USDT23361HS_DTRACE_PROBE1(hotspot, thread__sleep__end,1);3362#else /* USDT2 */3363HOTSPOT_THREAD_SLEEP_END(33641);3365#endif /* USDT2 */3366// TODO-FIXME: THROW_MSG returns which means we will not call set_state()3367// to properly restore the thread state. That's likely wrong.3368THROW_MSG(vmSymbols::java_lang_InterruptedException(), "sleep interrupted");3369}3370}3371thread->osthread()->set_state(old_state);3372}3373if (event.should_commit()) {3374post_thread_sleep_event(&event, millis);3375}3376#ifndef USDT23377HS_DTRACE_PROBE1(hotspot, thread__sleep__end,0);3378#else /* USDT2 */3379HOTSPOT_THREAD_SLEEP_END(33800);3381#endif /* USDT2 */3382JVM_END33833384JVM_ENTRY(jobject, JVM_CurrentThread(JNIEnv* env, jclass threadClass))3385JVMWrapper("JVM_CurrentThread");3386oop jthread = thread->threadObj();3387assert (thread != NULL, "no current thread!");3388return JNIHandles::make_local(env, jthread);3389JVM_END339033913392JVM_ENTRY(jint, JVM_CountStackFrames(JNIEnv* env, jobject jthread))3393JVMWrapper("JVM_CountStackFrames");33943395// Ensure that the C++ Thread and OSThread structures aren't freed before we operate3396oop java_thread = JNIHandles::resolve_non_null(jthread);3397bool throw_illegal_thread_state = false;3398int count = 0;33993400{3401MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);3402// We need to re-resolve the java_thread, since a GC might have happened during the3403// acquire of the lock3404JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));34053406if (thr == NULL) {3407// do nothing3408} else if(! thr->is_external_suspend() || ! thr->frame_anchor()->walkable()) {3409// Check whether this java thread has been suspended already. If not, throws3410// IllegalThreadStateException. We defer to throw that exception until3411// Threads_lock is released since loading exception class has to leave VM.3412// The correct way to test a thread is actually suspended is3413// wait_for_ext_suspend_completion(), but we can't call that while holding3414// the Threads_lock. The above tests are sufficient for our purposes3415// provided the walkability of the stack is stable - which it isn't3416// 100% but close enough for most practical purposes.3417throw_illegal_thread_state = true;3418} else {3419// Count all java activation, i.e., number of vframes3420for(vframeStream vfst(thr); !vfst.at_end(); vfst.next()) {3421// Native frames are not counted3422if (!vfst.method()->is_native()) count++;3423}3424}3425}34263427if (throw_illegal_thread_state) {3428THROW_MSG_0(vmSymbols::java_lang_IllegalThreadStateException(),3429"this thread is not suspended");3430}3431return count;3432JVM_END34333434// Consider: A better way to implement JVM_Interrupt() is to acquire3435// Threads_lock to resolve the jthread into a Thread pointer, fetch3436// Thread->platformevent, Thread->native_thr, Thread->parker, etc.,3437// drop Threads_lock, and the perform the unpark() and thr_kill() operations3438// outside the critical section. Threads_lock is hot so we want to minimize3439// the hold-time. A cleaner interface would be to decompose interrupt into3440// two steps. The 1st phase, performed under Threads_lock, would return3441// a closure that'd be invoked after Threads_lock was dropped.3442// This tactic is safe as PlatformEvent and Parkers are type-stable (TSM) and3443// admit spurious wakeups.34443445JVM_ENTRY(void, JVM_Interrupt(JNIEnv* env, jobject jthread))3446JVMWrapper("JVM_Interrupt");34473448// Ensure that the C++ Thread and OSThread structures aren't freed before we operate3449oop java_thread = JNIHandles::resolve_non_null(jthread);3450MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);3451// We need to re-resolve the java_thread, since a GC might have happened during the3452// acquire of the lock3453JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));3454if (thr != NULL) {3455Thread::interrupt(thr);3456}3457JVM_END345834593460JVM_QUICK_ENTRY(jboolean, JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrupted))3461JVMWrapper("JVM_IsInterrupted");34623463// Ensure that the C++ Thread and OSThread structures aren't freed before we operate3464oop java_thread = JNIHandles::resolve_non_null(jthread);3465MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);3466// We need to re-resolve the java_thread, since a GC might have happened during the3467// acquire of the lock3468JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));3469if (thr == NULL) {3470return JNI_FALSE;3471} else {3472return (jboolean) Thread::is_interrupted(thr, clear_interrupted != 0);3473}3474JVM_END347534763477// Return true iff the current thread has locked the object passed in34783479JVM_ENTRY(jboolean, JVM_HoldsLock(JNIEnv* env, jclass threadClass, jobject obj))3480JVMWrapper("JVM_HoldsLock");3481assert(THREAD->is_Java_thread(), "sanity check");3482if (obj == NULL) {3483THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE);3484}3485Handle h_obj(THREAD, JNIHandles::resolve(obj));3486return ObjectSynchronizer::current_thread_holds_lock((JavaThread*)THREAD, h_obj);3487JVM_END348834893490JVM_ENTRY(void, JVM_DumpAllStacks(JNIEnv* env, jclass))3491JVMWrapper("JVM_DumpAllStacks");3492VM_PrintThreads op;3493VMThread::execute(&op);3494if (JvmtiExport::should_post_data_dump()) {3495JvmtiExport::post_data_dump();3496}3497JVM_END34983499JVM_ENTRY(void, JVM_SetNativeThreadName(JNIEnv* env, jobject jthread, jstring name))3500JVMWrapper("JVM_SetNativeThreadName");3501ResourceMark rm(THREAD);3502oop java_thread = JNIHandles::resolve_non_null(jthread);3503JavaThread* thr = java_lang_Thread::thread(java_thread);3504// Thread naming only supported for the current thread, doesn't work for3505// target threads.3506if (Thread::current() == thr && !thr->has_attached_via_jni()) {3507// we don't set the name of an attached thread to avoid stepping3508// on other programs3509const char *thread_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));3510os::set_native_thread_name(thread_name);3511}3512JVM_END35133514// java.lang.SecurityManager ///////////////////////////////////////////////////////////////////////35153516static bool is_trusted_frame(JavaThread* jthread, vframeStream* vfst) {3517assert(jthread->is_Java_thread(), "must be a Java thread");3518if (jthread->privileged_stack_top() == NULL) return false;3519if (jthread->privileged_stack_top()->frame_id() == vfst->frame_id()) {3520oop loader = jthread->privileged_stack_top()->class_loader();3521if (loader == NULL) return true;3522bool trusted = java_lang_ClassLoader::is_trusted_loader(loader);3523if (trusted) return true;3524}3525return false;3526}35273528JVM_ENTRY(jclass, JVM_CurrentLoadedClass(JNIEnv *env))3529JVMWrapper("JVM_CurrentLoadedClass");3530ResourceMark rm(THREAD);35313532for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {3533// if a method in a class in a trusted loader is in a doPrivileged, return NULL3534bool trusted = is_trusted_frame(thread, &vfst);3535if (trusted) return NULL;35363537Method* m = vfst.method();3538if (!m->is_native()) {3539InstanceKlass* holder = m->method_holder();3540oop loader = holder->class_loader();3541if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) {3542return (jclass) JNIHandles::make_local(env, holder->java_mirror());3543}3544}3545}3546return NULL;3547JVM_END354835493550JVM_ENTRY(jobject, JVM_CurrentClassLoader(JNIEnv *env))3551JVMWrapper("JVM_CurrentClassLoader");3552ResourceMark rm(THREAD);35533554for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {35553556// if a method in a class in a trusted loader is in a doPrivileged, return NULL3557bool trusted = is_trusted_frame(thread, &vfst);3558if (trusted) return NULL;35593560Method* m = vfst.method();3561if (!m->is_native()) {3562InstanceKlass* holder = m->method_holder();3563assert(holder->is_klass(), "just checking");3564oop loader = holder->class_loader();3565if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) {3566return JNIHandles::make_local(env, loader);3567}3568}3569}3570return NULL;3571JVM_END357235733574JVM_ENTRY(jobjectArray, JVM_GetClassContext(JNIEnv *env))3575JVMWrapper("JVM_GetClassContext");3576ResourceMark rm(THREAD);3577JvmtiVMObjectAllocEventCollector oam;3578vframeStream vfst(thread);35793580if (SystemDictionary::reflect_CallerSensitive_klass() != NULL) {3581// This must only be called from SecurityManager.getClassContext3582Method* m = vfst.method();3583if (!(m->method_holder() == SystemDictionary::SecurityManager_klass() &&3584m->name() == vmSymbols::getClassContext_name() &&3585m->signature() == vmSymbols::void_class_array_signature())) {3586THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetClassContext must only be called from SecurityManager.getClassContext");3587}3588}35893590// Collect method holders3591GrowableArray<KlassHandle>* klass_array = new GrowableArray<KlassHandle>();3592for (; !vfst.at_end(); vfst.security_next()) {3593Method* m = vfst.method();3594// Native frames are not returned3595if (!m->is_ignored_by_security_stack_walk() && !m->is_native()) {3596Klass* holder = m->method_holder();3597assert(holder->is_klass(), "just checking");3598klass_array->append(holder);3599}3600}36013602// Create result array of type [Ljava/lang/Class;3603objArrayOop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), klass_array->length(), CHECK_NULL);3604// Fill in mirrors corresponding to method holders3605for (int i = 0; i < klass_array->length(); i++) {3606result->obj_at_put(i, klass_array->at(i)->java_mirror());3607}36083609return (jobjectArray) JNIHandles::make_local(env, result);3610JVM_END361136123613JVM_ENTRY(jint, JVM_ClassDepth(JNIEnv *env, jstring name))3614JVMWrapper("JVM_ClassDepth");3615ResourceMark rm(THREAD);3616Handle h_name (THREAD, JNIHandles::resolve_non_null(name));3617Handle class_name_str = java_lang_String::internalize_classname(h_name, CHECK_0);36183619const char* str = java_lang_String::as_utf8_string(class_name_str());3620TempNewSymbol class_name_sym = SymbolTable::probe(str, (int)strlen(str));3621if (class_name_sym == NULL) {3622return -1;3623}36243625int depth = 0;36263627for(vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {3628if (!vfst.method()->is_native()) {3629InstanceKlass* holder = vfst.method()->method_holder();3630assert(holder->is_klass(), "just checking");3631if (holder->name() == class_name_sym) {3632return depth;3633}3634depth++;3635}3636}3637return -1;3638JVM_END363936403641JVM_ENTRY(jint, JVM_ClassLoaderDepth(JNIEnv *env))3642JVMWrapper("JVM_ClassLoaderDepth");3643ResourceMark rm(THREAD);3644int depth = 0;3645for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {3646// if a method in a class in a trusted loader is in a doPrivileged, return -13647bool trusted = is_trusted_frame(thread, &vfst);3648if (trusted) return -1;36493650Method* m = vfst.method();3651if (!m->is_native()) {3652InstanceKlass* holder = m->method_holder();3653assert(holder->is_klass(), "just checking");3654oop loader = holder->class_loader();3655if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) {3656return depth;3657}3658depth++;3659}3660}3661return -1;3662JVM_END366336643665// java.lang.Package ////////////////////////////////////////////////////////////////366636673668JVM_ENTRY(jstring, JVM_GetSystemPackage(JNIEnv *env, jstring name))3669JVMWrapper("JVM_GetSystemPackage");3670ResourceMark rm(THREAD);3671JvmtiVMObjectAllocEventCollector oam;3672char* str = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));3673oop result = ClassLoader::get_system_package(str, CHECK_NULL);3674return (jstring) JNIHandles::make_local(result);3675JVM_END367636773678JVM_ENTRY(jobjectArray, JVM_GetSystemPackages(JNIEnv *env))3679JVMWrapper("JVM_GetSystemPackages");3680JvmtiVMObjectAllocEventCollector oam;3681objArrayOop result = ClassLoader::get_system_packages(CHECK_NULL);3682return (jobjectArray) JNIHandles::make_local(result);3683JVM_END368436853686// ObjectInputStream ///////////////////////////////////////////////////////////////36873688bool force_verify_field_access(Klass* current_class, Klass* field_class, AccessFlags access, bool classloader_only) {3689if (current_class == NULL) {3690return true;3691}3692if ((current_class == field_class) || access.is_public()) {3693return true;3694}36953696if (access.is_protected()) {3697// See if current_class is a subclass of field_class3698if (current_class->is_subclass_of(field_class)) {3699return true;3700}3701}37023703return (!access.is_private() && InstanceKlass::cast(current_class)->is_same_class_package(field_class));3704}370537063707// JVM_AllocateNewObject and JVM_AllocateNewArray are unused as of 1.43708JVM_ENTRY(jobject, JVM_AllocateNewObject(JNIEnv *env, jobject receiver, jclass currClass, jclass initClass))3709JVMWrapper("JVM_AllocateNewObject");3710JvmtiVMObjectAllocEventCollector oam;3711// Receiver is not used3712oop curr_mirror = JNIHandles::resolve_non_null(currClass);3713oop init_mirror = JNIHandles::resolve_non_null(initClass);37143715// Cannot instantiate primitive types3716if (java_lang_Class::is_primitive(curr_mirror) || java_lang_Class::is_primitive(init_mirror)) {3717ResourceMark rm(THREAD);3718THROW_0(vmSymbols::java_lang_InvalidClassException());3719}37203721// Arrays not allowed here, must use JVM_AllocateNewArray3722if (java_lang_Class::as_Klass(curr_mirror)->oop_is_array() ||3723java_lang_Class::as_Klass(init_mirror)->oop_is_array()) {3724ResourceMark rm(THREAD);3725THROW_0(vmSymbols::java_lang_InvalidClassException());3726}37273728instanceKlassHandle curr_klass (THREAD, java_lang_Class::as_Klass(curr_mirror));3729instanceKlassHandle init_klass (THREAD, java_lang_Class::as_Klass(init_mirror));37303731assert(curr_klass->is_subclass_of(init_klass()), "just checking");37323733// Interfaces, abstract classes, and java.lang.Class classes cannot be instantiated directly.3734curr_klass->check_valid_for_instantiation(false, CHECK_NULL);37353736// Make sure klass is initialized, since we are about to instantiate one of them.3737curr_klass->initialize(CHECK_NULL);37383739methodHandle m (THREAD,3740init_klass->find_method(vmSymbols::object_initializer_name(),3741vmSymbols::void_method_signature()));3742if (m.is_null()) {3743ResourceMark rm(THREAD);3744THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(),3745Method::name_and_sig_as_C_string(init_klass(),3746vmSymbols::object_initializer_name(),3747vmSymbols::void_method_signature()));3748}37493750if (curr_klass == init_klass && !m->is_public()) {3751// Calling the constructor for class 'curr_klass'.3752// Only allow calls to a public no-arg constructor.3753// This path corresponds to creating an Externalizable object.3754THROW_0(vmSymbols::java_lang_IllegalAccessException());3755}37563757if (!force_verify_field_access(curr_klass(), init_klass(), m->access_flags(), false)) {3758// subclass 'curr_klass' does not have access to no-arg constructor of 'initcb'3759THROW_0(vmSymbols::java_lang_IllegalAccessException());3760}37613762Handle obj = curr_klass->allocate_instance_handle(CHECK_NULL);3763// Call constructor m. This might call a constructor higher up in the hierachy3764JavaCalls::call_default_constructor(thread, m, obj, CHECK_NULL);37653766return JNIHandles::make_local(obj());3767JVM_END376837693770JVM_ENTRY(jobject, JVM_AllocateNewArray(JNIEnv *env, jobject obj, jclass currClass, jint length))3771JVMWrapper("JVM_AllocateNewArray");3772JvmtiVMObjectAllocEventCollector oam;3773oop mirror = JNIHandles::resolve_non_null(currClass);37743775if (java_lang_Class::is_primitive(mirror)) {3776THROW_0(vmSymbols::java_lang_InvalidClassException());3777}3778Klass* k = java_lang_Class::as_Klass(mirror);3779oop result;37803781if (k->oop_is_typeArray()) {3782// typeArray3783result = TypeArrayKlass::cast(k)->allocate(length, CHECK_NULL);3784} else if (k->oop_is_objArray()) {3785// objArray3786ObjArrayKlass* oak = ObjArrayKlass::cast(k);3787oak->initialize(CHECK_NULL); // make sure class is initialized (matches Classic VM behavior)3788result = oak->allocate(length, CHECK_NULL);3789} else {3790THROW_0(vmSymbols::java_lang_InvalidClassException());3791}3792return JNIHandles::make_local(env, result);3793JVM_END379437953796// Returns first non-privileged class loader on the stack (excluding reflection3797// generated frames) or null if only classes loaded by the boot class loader3798// and extension class loader are found on the stack.37993800JVM_ENTRY(jobject, JVM_LatestUserDefinedLoader(JNIEnv *env))3801for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {3802// UseNewReflection3803vfst.skip_reflection_related_frames(); // Only needed for 1.4 reflection3804oop loader = vfst.method()->method_holder()->class_loader();3805if (loader != NULL && !SystemDictionary::is_ext_class_loader(loader)) {3806return JNIHandles::make_local(env, loader);3807}3808}3809return NULL;3810JVM_END381138123813// Load a class relative to the most recent class on the stack with a non-null3814// classloader.3815// This function has been deprecated and should not be considered part of the3816// specified JVM interface.38173818JVM_ENTRY(jclass, JVM_LoadClass0(JNIEnv *env, jobject receiver,3819jclass currClass, jstring currClassName))3820JVMWrapper("JVM_LoadClass0");3821// Receiver is not used3822ResourceMark rm(THREAD);38233824// Class name argument is not guaranteed to be in internal format3825Handle classname (THREAD, JNIHandles::resolve_non_null(currClassName));3826Handle string = java_lang_String::internalize_classname(classname, CHECK_NULL);38273828const char* str = java_lang_String::as_utf8_string(string());38293830if (str == NULL || (int)strlen(str) > Symbol::max_length()) {3831// It's impossible to create this class; the name cannot fit3832// into the constant pool.3833THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), str);3834}38353836TempNewSymbol name = SymbolTable::new_symbol(str, CHECK_NULL);3837Handle curr_klass (THREAD, JNIHandles::resolve(currClass));3838// Find the most recent class on the stack with a non-null classloader3839oop loader = NULL;3840oop protection_domain = NULL;3841if (curr_klass.is_null()) {3842for (vframeStream vfst(thread);3843!vfst.at_end() && loader == NULL;3844vfst.next()) {3845if (!vfst.method()->is_native()) {3846InstanceKlass* holder = vfst.method()->method_holder();3847loader = holder->class_loader();3848protection_domain = holder->protection_domain();3849}3850}3851} else {3852Klass* curr_klass_oop = java_lang_Class::as_Klass(curr_klass());3853loader = InstanceKlass::cast(curr_klass_oop)->class_loader();3854protection_domain = InstanceKlass::cast(curr_klass_oop)->protection_domain();3855}3856Handle h_loader(THREAD, loader);3857Handle h_prot (THREAD, protection_domain);3858jclass result = find_class_from_class_loader(env, name, true, h_loader, h_prot,3859false, thread);3860if (TraceClassResolution && result != NULL) {3861trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));3862}3863return result;3864JVM_END386538663867// Array ///////////////////////////////////////////////////////////////////////////////////////////386838693870// resolve array handle and check arguments3871static inline arrayOop check_array(JNIEnv *env, jobject arr, bool type_array_only, TRAPS) {3872if (arr == NULL) {3873THROW_0(vmSymbols::java_lang_NullPointerException());3874}3875oop a = JNIHandles::resolve_non_null(arr);3876if (!a->is_array() || (type_array_only && !a->is_typeArray())) {3877THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Argument is not an array");3878}3879return arrayOop(a);3880}388138823883JVM_ENTRY(jint, JVM_GetArrayLength(JNIEnv *env, jobject arr))3884JVMWrapper("JVM_GetArrayLength");3885arrayOop a = check_array(env, arr, false, CHECK_0);3886return a->length();3887JVM_END388838893890JVM_ENTRY(jobject, JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index))3891JVMWrapper("JVM_Array_Get");3892JvmtiVMObjectAllocEventCollector oam;3893arrayOop a = check_array(env, arr, false, CHECK_NULL);3894jvalue value;3895BasicType type = Reflection::array_get(&value, a, index, CHECK_NULL);3896oop box = Reflection::box(&value, type, CHECK_NULL);3897return JNIHandles::make_local(env, box);3898JVM_END389939003901JVM_ENTRY(jvalue, JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint wCode))3902JVMWrapper("JVM_GetPrimitiveArrayElement");3903jvalue value;3904value.i = 0; // to initialize value before getting used in CHECK3905arrayOop a = check_array(env, arr, true, CHECK_(value));3906assert(a->is_typeArray(), "just checking");3907BasicType type = Reflection::array_get(&value, a, index, CHECK_(value));3908BasicType wide_type = (BasicType) wCode;3909if (type != wide_type) {3910Reflection::widen(&value, type, wide_type, CHECK_(value));3911}3912return value;3913JVM_END391439153916JVM_ENTRY(void, JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val))3917JVMWrapper("JVM_SetArrayElement");3918arrayOop a = check_array(env, arr, false, CHECK);3919oop box = JNIHandles::resolve(val);3920jvalue value;3921value.i = 0; // to initialize value before getting used in CHECK3922BasicType value_type;3923if (a->is_objArray()) {3924// Make sure we do no unbox e.g. java/lang/Integer instances when storing into an object array3925value_type = Reflection::unbox_for_regular_object(box, &value);3926} else {3927value_type = Reflection::unbox_for_primitive(box, &value, CHECK);3928}3929Reflection::array_set(&value, a, index, value_type, CHECK);3930JVM_END393139323933JVM_ENTRY(void, JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v, unsigned char vCode))3934JVMWrapper("JVM_SetPrimitiveArrayElement");3935arrayOop a = check_array(env, arr, true, CHECK);3936assert(a->is_typeArray(), "just checking");3937BasicType value_type = (BasicType) vCode;3938Reflection::array_set(&v, a, index, value_type, CHECK);3939JVM_END394039413942JVM_ENTRY(jobject, JVM_NewArray(JNIEnv *env, jclass eltClass, jint length))3943JVMWrapper("JVM_NewArray");3944JvmtiVMObjectAllocEventCollector oam;3945oop element_mirror = JNIHandles::resolve(eltClass);3946oop result = Reflection::reflect_new_array(element_mirror, length, CHECK_NULL);3947return JNIHandles::make_local(env, result);3948JVM_END394939503951JVM_ENTRY(jobject, JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim))3952JVMWrapper("JVM_NewMultiArray");3953JvmtiVMObjectAllocEventCollector oam;3954arrayOop dim_array = check_array(env, dim, true, CHECK_NULL);3955oop element_mirror = JNIHandles::resolve(eltClass);3956assert(dim_array->is_typeArray(), "just checking");3957oop result = Reflection::reflect_new_multi_array(element_mirror, typeArrayOop(dim_array), CHECK_NULL);3958return JNIHandles::make_local(env, result);3959JVM_END396039613962// Networking library support ////////////////////////////////////////////////////////////////////39633964JVM_LEAF(jint, JVM_InitializeSocketLibrary())3965JVMWrapper("JVM_InitializeSocketLibrary");3966return 0;3967JVM_END396839693970JVM_LEAF(jint, JVM_Socket(jint domain, jint type, jint protocol))3971JVMWrapper("JVM_Socket");3972return os::socket(domain, type, protocol);3973JVM_END397439753976JVM_LEAF(jint, JVM_SocketClose(jint fd))3977JVMWrapper2("JVM_SocketClose (0x%x)", fd);3978//%note jvm_r63979return os::socket_close(fd);3980JVM_END398139823983JVM_LEAF(jint, JVM_SocketShutdown(jint fd, jint howto))3984JVMWrapper2("JVM_SocketShutdown (0x%x)", fd);3985//%note jvm_r63986return os::socket_shutdown(fd, howto);3987JVM_END398839893990JVM_LEAF(jint, JVM_Recv(jint fd, char *buf, jint nBytes, jint flags))3991JVMWrapper2("JVM_Recv (0x%x)", fd);3992//%note jvm_r63993return os::recv(fd, buf, (size_t)nBytes, (uint)flags);3994JVM_END399539963997JVM_LEAF(jint, JVM_Send(jint fd, char *buf, jint nBytes, jint flags))3998JVMWrapper2("JVM_Send (0x%x)", fd);3999//%note jvm_r64000return os::send(fd, buf, (size_t)nBytes, (uint)flags);4001JVM_END400240034004JVM_LEAF(jint, JVM_Timeout(int fd, long timeout))4005JVMWrapper2("JVM_Timeout (0x%x)", fd);4006//%note jvm_r64007return os::timeout(fd, timeout);4008JVM_END400940104011JVM_LEAF(jint, JVM_Listen(jint fd, jint count))4012JVMWrapper2("JVM_Listen (0x%x)", fd);4013//%note jvm_r64014return os::listen(fd, count);4015JVM_END401640174018JVM_LEAF(jint, JVM_Connect(jint fd, struct sockaddr *him, jint len))4019JVMWrapper2("JVM_Connect (0x%x)", fd);4020//%note jvm_r64021return os::connect(fd, him, (socklen_t)len);4022JVM_END402340244025JVM_LEAF(jint, JVM_Bind(jint fd, struct sockaddr *him, jint len))4026JVMWrapper2("JVM_Bind (0x%x)", fd);4027//%note jvm_r64028return os::bind(fd, him, (socklen_t)len);4029JVM_END403040314032JVM_LEAF(jint, JVM_Accept(jint fd, struct sockaddr *him, jint *len))4033JVMWrapper2("JVM_Accept (0x%x)", fd);4034//%note jvm_r64035socklen_t socklen = (socklen_t)(*len);4036jint result = os::accept(fd, him, &socklen);4037*len = (jint)socklen;4038return result;4039JVM_END404040414042JVM_LEAF(jint, JVM_RecvFrom(jint fd, char *buf, int nBytes, int flags, struct sockaddr *from, int *fromlen))4043JVMWrapper2("JVM_RecvFrom (0x%x)", fd);4044//%note jvm_r64045socklen_t socklen = (socklen_t)(*fromlen);4046jint result = os::recvfrom(fd, buf, (size_t)nBytes, (uint)flags, from, &socklen);4047*fromlen = (int)socklen;4048return result;4049JVM_END405040514052JVM_LEAF(jint, JVM_GetSockName(jint fd, struct sockaddr *him, int *len))4053JVMWrapper2("JVM_GetSockName (0x%x)", fd);4054//%note jvm_r64055socklen_t socklen = (socklen_t)(*len);4056jint result = os::get_sock_name(fd, him, &socklen);4057*len = (int)socklen;4058return result;4059JVM_END406040614062JVM_LEAF(jint, JVM_SendTo(jint fd, char *buf, int len, int flags, struct sockaddr *to, int tolen))4063JVMWrapper2("JVM_SendTo (0x%x)", fd);4064//%note jvm_r64065return os::sendto(fd, buf, (size_t)len, (uint)flags, to, (socklen_t)tolen);4066JVM_END406740684069JVM_LEAF(jint, JVM_SocketAvailable(jint fd, jint *pbytes))4070JVMWrapper2("JVM_SocketAvailable (0x%x)", fd);4071//%note jvm_r64072return os::socket_available(fd, pbytes);4073JVM_END407440754076JVM_LEAF(jint, JVM_GetSockOpt(jint fd, int level, int optname, char *optval, int *optlen))4077JVMWrapper2("JVM_GetSockOpt (0x%x)", fd);4078//%note jvm_r64079socklen_t socklen = (socklen_t)(*optlen);4080jint result = os::get_sock_opt(fd, level, optname, optval, &socklen);4081*optlen = (int)socklen;4082return result;4083JVM_END408440854086JVM_LEAF(jint, JVM_SetSockOpt(jint fd, int level, int optname, const char *optval, int optlen))4087JVMWrapper2("JVM_GetSockOpt (0x%x)", fd);4088//%note jvm_r64089return os::set_sock_opt(fd, level, optname, optval, (socklen_t)optlen);4090JVM_END409140924093JVM_LEAF(int, JVM_GetHostName(char* name, int namelen))4094JVMWrapper("JVM_GetHostName");4095return os::get_host_name(name, namelen);4096JVM_END409740984099// Library support ///////////////////////////////////////////////////////////////////////////41004101JVM_ENTRY_NO_ENV(void*, JVM_LoadLibrary(const char* name))4102//%note jvm_ct4103JVMWrapper2("JVM_LoadLibrary (%s)", name);4104char ebuf[1024];4105void *load_result;4106{4107ThreadToNativeFromVM ttnfvm(thread);4108load_result = os::dll_load(name, ebuf, sizeof ebuf);4109}4110if (load_result == NULL) {4111char msg[1024];4112jio_snprintf(msg, sizeof msg, "%s: %s", name, ebuf);4113// Since 'ebuf' may contain a string encoded using4114// platform encoding scheme, we need to pass4115// Exceptions::unsafe_to_utf8 to the new_exception method4116// as the last argument. See bug 6367357.4117Handle h_exception =4118Exceptions::new_exception(thread,4119vmSymbols::java_lang_UnsatisfiedLinkError(),4120msg, Exceptions::unsafe_to_utf8);41214122THROW_HANDLE_0(h_exception);4123}4124return load_result;4125JVM_END412641274128JVM_LEAF(void, JVM_UnloadLibrary(void* handle))4129JVMWrapper("JVM_UnloadLibrary");4130os::dll_unload(handle);4131JVM_END413241334134JVM_LEAF(void*, JVM_FindLibraryEntry(void* handle, const char* name))4135JVMWrapper2("JVM_FindLibraryEntry (%s)", name);4136return os::dll_lookup(handle, name);4137JVM_END413841394140// Floating point support ////////////////////////////////////////////////////////////////////41414142JVM_LEAF(jboolean, JVM_IsNaN(jdouble a))4143JVMWrapper("JVM_IsNaN");4144return g_isnan(a);4145JVM_END414641474148// JNI version ///////////////////////////////////////////////////////////////////////////////41494150JVM_LEAF(jboolean, JVM_IsSupportedJNIVersion(jint version))4151JVMWrapper2("JVM_IsSupportedJNIVersion (%d)", version);4152return Threads::is_supported_jni_version_including_1_1(version);4153JVM_END415441554156// String support ///////////////////////////////////////////////////////////////////////////41574158JVM_ENTRY(jstring, JVM_InternString(JNIEnv *env, jstring str))4159JVMWrapper("JVM_InternString");4160JvmtiVMObjectAllocEventCollector oam;4161if (str == NULL) return NULL;4162oop string = JNIHandles::resolve_non_null(str);4163oop result = StringTable::intern(string, CHECK_NULL);4164return (jstring) JNIHandles::make_local(env, result);4165JVM_END416641674168// Raw monitor support //////////////////////////////////////////////////////////////////////41694170// The lock routine below calls lock_without_safepoint_check in order to get a raw lock4171// without interfering with the safepoint mechanism. The routines are not JVM_LEAF because4172// they might be called by non-java threads. The JVM_LEAF installs a NoHandleMark check4173// that only works with java threads.417441754176JNIEXPORT void* JNICALL JVM_RawMonitorCreate(void) {4177VM_Exit::block_if_vm_exited();4178JVMWrapper("JVM_RawMonitorCreate");4179return new Mutex(Mutex::native, "JVM_RawMonitorCreate");4180}418141824183JNIEXPORT void JNICALL JVM_RawMonitorDestroy(void *mon) {4184VM_Exit::block_if_vm_exited();4185JVMWrapper("JVM_RawMonitorDestroy");4186delete ((Mutex*) mon);4187}418841894190JNIEXPORT jint JNICALL JVM_RawMonitorEnter(void *mon) {4191VM_Exit::block_if_vm_exited();4192JVMWrapper("JVM_RawMonitorEnter");4193((Mutex*) mon)->jvm_raw_lock();4194return 0;4195}419641974198JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon) {4199VM_Exit::block_if_vm_exited();4200JVMWrapper("JVM_RawMonitorExit");4201((Mutex*) mon)->jvm_raw_unlock();4202}420342044205// Support for Serialization42064207typedef jfloat (JNICALL *IntBitsToFloatFn )(JNIEnv* env, jclass cb, jint value);4208typedef jdouble (JNICALL *LongBitsToDoubleFn)(JNIEnv* env, jclass cb, jlong value);4209typedef jint (JNICALL *FloatToIntBitsFn )(JNIEnv* env, jclass cb, jfloat value);4210typedef jlong (JNICALL *DoubleToLongBitsFn)(JNIEnv* env, jclass cb, jdouble value);42114212static IntBitsToFloatFn int_bits_to_float_fn = NULL;4213static LongBitsToDoubleFn long_bits_to_double_fn = NULL;4214static FloatToIntBitsFn float_to_int_bits_fn = NULL;4215static DoubleToLongBitsFn double_to_long_bits_fn = NULL;421642174218void initialize_converter_functions() {4219if (JDK_Version::is_gte_jdk14x_version()) {4220// These functions only exist for compatibility with 1.3.1 and earlier4221return;4222}42234224// called from universe_post_init()4225assert(4226int_bits_to_float_fn == NULL &&4227long_bits_to_double_fn == NULL &&4228float_to_int_bits_fn == NULL &&4229double_to_long_bits_fn == NULL ,4230"initialization done twice"4231);4232// initialize4233int_bits_to_float_fn = CAST_TO_FN_PTR(IntBitsToFloatFn , NativeLookup::base_library_lookup("java/lang/Float" , "intBitsToFloat" , "(I)F"));4234long_bits_to_double_fn = CAST_TO_FN_PTR(LongBitsToDoubleFn, NativeLookup::base_library_lookup("java/lang/Double", "longBitsToDouble", "(J)D"));4235float_to_int_bits_fn = CAST_TO_FN_PTR(FloatToIntBitsFn , NativeLookup::base_library_lookup("java/lang/Float" , "floatToIntBits" , "(F)I"));4236double_to_long_bits_fn = CAST_TO_FN_PTR(DoubleToLongBitsFn, NativeLookup::base_library_lookup("java/lang/Double", "doubleToLongBits", "(D)J"));4237// verify4238assert(4239int_bits_to_float_fn != NULL &&4240long_bits_to_double_fn != NULL &&4241float_to_int_bits_fn != NULL &&4242double_to_long_bits_fn != NULL ,4243"initialization failed"4244);4245}4246424742484249// Shared JNI/JVM entry points //////////////////////////////////////////////////////////////42504251jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init,4252Handle loader, Handle protection_domain,4253jboolean throwError, TRAPS) {4254// Security Note:4255// The Java level wrapper will perform the necessary security check allowing4256// us to pass the NULL as the initiating class loader. The VM is responsible for4257// the checkPackageAccess relative to the initiating class loader via the4258// protection_domain. The protection_domain is passed as NULL by the java code4259// if there is no security manager in 3-arg Class.forName().4260Klass* klass = SystemDictionary::resolve_or_fail(name, loader, protection_domain, throwError != 0, CHECK_NULL);42614262KlassHandle klass_handle(THREAD, klass);4263// Check if we should initialize the class4264if (init && klass_handle->oop_is_instance()) {4265klass_handle->initialize(CHECK_NULL);4266}4267return (jclass) JNIHandles::make_local(env, klass_handle->java_mirror());4268}426942704271// Internal SQE debugging support ///////////////////////////////////////////////////////////42724273#ifndef PRODUCT42744275extern "C" {4276JNIEXPORT jboolean JNICALL JVM_AccessVMBooleanFlag(const char* name, jboolean* value, jboolean is_get);4277JNIEXPORT jboolean JNICALL JVM_AccessVMIntFlag(const char* name, jint* value, jboolean is_get);4278JNIEXPORT void JNICALL JVM_VMBreakPoint(JNIEnv *env, jobject obj);4279}42804281JVM_LEAF(jboolean, JVM_AccessVMBooleanFlag(const char* name, jboolean* value, jboolean is_get))4282JVMWrapper("JVM_AccessBoolVMFlag");4283return is_get ? CommandLineFlags::boolAt((char*) name, (bool*) value) : CommandLineFlags::boolAtPut((char*) name, (bool*) value, Flag::INTERNAL);4284JVM_END42854286JVM_LEAF(jboolean, JVM_AccessVMIntFlag(const char* name, jint* value, jboolean is_get))4287JVMWrapper("JVM_AccessVMIntFlag");4288intx v;4289jboolean result = is_get ? CommandLineFlags::intxAt((char*) name, &v) : CommandLineFlags::intxAtPut((char*) name, &v, Flag::INTERNAL);4290*value = (jint)v;4291return result;4292JVM_END429342944295JVM_ENTRY(void, JVM_VMBreakPoint(JNIEnv *env, jobject obj))4296JVMWrapper("JVM_VMBreakPoint");4297oop the_obj = JNIHandles::resolve(obj);4298BREAKPOINT;4299JVM_END430043014302#endif430343044305// Method ///////////////////////////////////////////////////////////////////////////////////////////43064307JVM_ENTRY(jobject, JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0))4308JVMWrapper("JVM_InvokeMethod");4309Handle method_handle;4310if (thread->stack_available((address) &method_handle) >= JVMInvokeMethodSlack) {4311method_handle = Handle(THREAD, JNIHandles::resolve(method));4312Handle receiver(THREAD, JNIHandles::resolve(obj));4313objArrayHandle args(THREAD, objArrayOop(JNIHandles::resolve(args0)));4314oop result = Reflection::invoke_method(method_handle(), receiver, args, CHECK_NULL);4315jobject res = JNIHandles::make_local(env, result);4316if (JvmtiExport::should_post_vm_object_alloc()) {4317oop ret_type = java_lang_reflect_Method::return_type(method_handle());4318assert(ret_type != NULL, "sanity check: ret_type oop must not be NULL!");4319if (java_lang_Class::is_primitive(ret_type)) {4320// Only for primitive type vm allocates memory for java object.4321// See box() method.4322JvmtiExport::post_vm_object_alloc(JavaThread::current(), result);4323}4324}4325return res;4326} else {4327THROW_0(vmSymbols::java_lang_StackOverflowError());4328}4329JVM_END433043314332JVM_ENTRY(jobject, JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args0))4333JVMWrapper("JVM_NewInstanceFromConstructor");4334oop constructor_mirror = JNIHandles::resolve(c);4335objArrayHandle args(THREAD, objArrayOop(JNIHandles::resolve(args0)));4336oop result = Reflection::invoke_constructor(constructor_mirror, args, CHECK_NULL);4337jobject res = JNIHandles::make_local(env, result);4338if (JvmtiExport::should_post_vm_object_alloc()) {4339JvmtiExport::post_vm_object_alloc(JavaThread::current(), result);4340}4341return res;4342JVM_END43434344// Atomic ///////////////////////////////////////////////////////////////////////////////////////////43454346JVM_LEAF(jboolean, JVM_SupportsCX8())4347JVMWrapper("JVM_SupportsCX8");4348return VM_Version::supports_cx8();4349JVM_END435043514352JVM_ENTRY(jboolean, JVM_CX8Field(JNIEnv *env, jobject obj, jfieldID fid, jlong oldVal, jlong newVal))4353JVMWrapper("JVM_CX8Field");4354jlong res;4355oop o = JNIHandles::resolve(obj);4356intptr_t fldOffs = jfieldIDWorkaround::from_instance_jfieldID(o->klass(), fid);4357volatile jlong* addr = (volatile jlong*)((address)o + fldOffs);43584359assert(VM_Version::supports_cx8(), "cx8 not supported");4360res = Atomic::cmpxchg(newVal, addr, oldVal);43614362return res == oldVal;4363JVM_END43644365// DTrace ///////////////////////////////////////////////////////////////////43664367JVM_ENTRY(jint, JVM_DTraceGetVersion(JNIEnv* env))4368JVMWrapper("JVM_DTraceGetVersion");4369return (jint)JVM_TRACING_DTRACE_VERSION;4370JVM_END43714372JVM_ENTRY(jlong,JVM_DTraceActivate(4373JNIEnv* env, jint version, jstring module_name, jint providers_count,4374JVM_DTraceProvider* providers))4375JVMWrapper("JVM_DTraceActivate");4376return DTraceJSDT::activate(4377version, module_name, providers_count, providers, THREAD);4378JVM_END43794380JVM_ENTRY(jboolean,JVM_DTraceIsProbeEnabled(JNIEnv* env, jmethodID method))4381JVMWrapper("JVM_DTraceIsProbeEnabled");4382return DTraceJSDT::is_probe_enabled(method);4383JVM_END43844385JVM_ENTRY(void,JVM_DTraceDispose(JNIEnv* env, jlong handle))4386JVMWrapper("JVM_DTraceDispose");4387DTraceJSDT::dispose(handle);4388JVM_END43894390JVM_ENTRY(jboolean,JVM_DTraceIsSupported(JNIEnv* env))4391JVMWrapper("JVM_DTraceIsSupported");4392return DTraceJSDT::is_supported();4393JVM_END43944395// Returns an array of all live Thread objects (VM internal JavaThreads,4396// jvmti agent threads, and JNI attaching threads are skipped)4397// See CR 6404306 regarding JNI attaching threads4398JVM_ENTRY(jobjectArray, JVM_GetAllThreads(JNIEnv *env, jclass dummy))4399ResourceMark rm(THREAD);4400ThreadsListEnumerator tle(THREAD, false, false);4401JvmtiVMObjectAllocEventCollector oam;44024403int num_threads = tle.num_threads();4404objArrayOop r = oopFactory::new_objArray(SystemDictionary::Thread_klass(), num_threads, CHECK_NULL);4405objArrayHandle threads_ah(THREAD, r);44064407for (int i = 0; i < num_threads; i++) {4408Handle h = tle.get_threadObj(i);4409threads_ah->obj_at_put(i, h());4410}44114412return (jobjectArray) JNIHandles::make_local(env, threads_ah());4413JVM_END441444154416// Support for java.lang.Thread.getStackTrace() and getAllStackTraces() methods4417// Return StackTraceElement[][], each element is the stack trace of a thread in4418// the corresponding entry in the given threads array4419JVM_ENTRY(jobjectArray, JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads))4420JVMWrapper("JVM_DumpThreads");4421JvmtiVMObjectAllocEventCollector oam;44224423// Check if threads is null4424if (threads == NULL) {4425THROW_(vmSymbols::java_lang_NullPointerException(), 0);4426}44274428objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(threads));4429objArrayHandle ah(THREAD, a);4430int num_threads = ah->length();4431// check if threads is non-empty array4432if (num_threads == 0) {4433THROW_(vmSymbols::java_lang_IllegalArgumentException(), 0);4434}44354436// check if threads is not an array of objects of Thread class4437Klass* k = ObjArrayKlass::cast(ah->klass())->element_klass();4438if (k != SystemDictionary::Thread_klass()) {4439THROW_(vmSymbols::java_lang_IllegalArgumentException(), 0);4440}44414442ResourceMark rm(THREAD);44434444GrowableArray<instanceHandle>* thread_handle_array = new GrowableArray<instanceHandle>(num_threads);4445for (int i = 0; i < num_threads; i++) {4446oop thread_obj = ah->obj_at(i);4447instanceHandle h(THREAD, (instanceOop) thread_obj);4448thread_handle_array->append(h);4449}44504451Handle stacktraces = ThreadService::dump_stack_traces(thread_handle_array, num_threads, CHECK_NULL);4452return (jobjectArray)JNIHandles::make_local(env, stacktraces());44534454JVM_END44554456// JVM monitoring and management support4457JVM_ENTRY_NO_ENV(void*, JVM_GetManagement(jint version))4458return Management::get_jmm_interface(version);4459JVM_END44604461// com.sun.tools.attach.VirtualMachine agent properties support4462//4463// Initialize the agent properties with the properties maintained in the VM4464JVM_ENTRY(jobject, JVM_InitAgentProperties(JNIEnv *env, jobject properties))4465JVMWrapper("JVM_InitAgentProperties");4466ResourceMark rm;44674468Handle props(THREAD, JNIHandles::resolve_non_null(properties));44694470PUTPROP(props, "sun.java.command", Arguments::java_command());4471PUTPROP(props, "sun.jvm.flags", Arguments::jvm_flags());4472PUTPROP(props, "sun.jvm.args", Arguments::jvm_args());4473return properties;4474JVM_END44754476JVM_ENTRY(jobjectArray, JVM_GetEnclosingMethodInfo(JNIEnv *env, jclass ofClass))4477{4478JVMWrapper("JVM_GetEnclosingMethodInfo");4479JvmtiVMObjectAllocEventCollector oam;44804481if (ofClass == NULL) {4482return NULL;4483}4484Handle mirror(THREAD, JNIHandles::resolve_non_null(ofClass));4485// Special handling for primitive objects4486if (java_lang_Class::is_primitive(mirror())) {4487return NULL;4488}4489Klass* k = java_lang_Class::as_Klass(mirror());4490if (!k->oop_is_instance()) {4491return NULL;4492}4493instanceKlassHandle ik_h(THREAD, k);4494int encl_method_class_idx = ik_h->enclosing_method_class_index();4495if (encl_method_class_idx == 0) {4496return NULL;4497}4498objArrayOop dest_o = oopFactory::new_objArray(SystemDictionary::Object_klass(), 3, CHECK_NULL);4499objArrayHandle dest(THREAD, dest_o);4500Klass* enc_k = ik_h->constants()->klass_at(encl_method_class_idx, CHECK_NULL);4501dest->obj_at_put(0, enc_k->java_mirror());4502int encl_method_method_idx = ik_h->enclosing_method_method_index();4503if (encl_method_method_idx != 0) {4504Symbol* sym = ik_h->constants()->symbol_at(4505extract_low_short_from_int(4506ik_h->constants()->name_and_type_at(encl_method_method_idx)));4507Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL);4508dest->obj_at_put(1, str());4509sym = ik_h->constants()->symbol_at(4510extract_high_short_from_int(4511ik_h->constants()->name_and_type_at(encl_method_method_idx)));4512str = java_lang_String::create_from_symbol(sym, CHECK_NULL);4513dest->obj_at_put(2, str());4514}4515return (jobjectArray) JNIHandles::make_local(dest());4516}4517JVM_END45184519JVM_ENTRY(jintArray, JVM_GetThreadStateValues(JNIEnv* env,4520jint javaThreadState))4521{4522// If new thread states are added in future JDK and VM versions,4523// this should check if the JDK version is compatible with thread4524// states supported by the VM. Return NULL if not compatible.4525//4526// This function must map the VM java_lang_Thread::ThreadStatus4527// to the Java thread state that the JDK supports.4528//45294530typeArrayHandle values_h;4531switch (javaThreadState) {4532case JAVA_THREAD_STATE_NEW : {4533typeArrayOop r = oopFactory::new_typeArray(T_INT, 1, CHECK_NULL);4534values_h = typeArrayHandle(THREAD, r);4535values_h->int_at_put(0, java_lang_Thread::NEW);4536break;4537}4538case JAVA_THREAD_STATE_RUNNABLE : {4539typeArrayOop r = oopFactory::new_typeArray(T_INT, 1, CHECK_NULL);4540values_h = typeArrayHandle(THREAD, r);4541values_h->int_at_put(0, java_lang_Thread::RUNNABLE);4542break;4543}4544case JAVA_THREAD_STATE_BLOCKED : {4545typeArrayOop r = oopFactory::new_typeArray(T_INT, 1, CHECK_NULL);4546values_h = typeArrayHandle(THREAD, r);4547values_h->int_at_put(0, java_lang_Thread::BLOCKED_ON_MONITOR_ENTER);4548break;4549}4550case JAVA_THREAD_STATE_WAITING : {4551typeArrayOop r = oopFactory::new_typeArray(T_INT, 2, CHECK_NULL);4552values_h = typeArrayHandle(THREAD, r);4553values_h->int_at_put(0, java_lang_Thread::IN_OBJECT_WAIT);4554values_h->int_at_put(1, java_lang_Thread::PARKED);4555break;4556}4557case JAVA_THREAD_STATE_TIMED_WAITING : {4558typeArrayOop r = oopFactory::new_typeArray(T_INT, 3, CHECK_NULL);4559values_h = typeArrayHandle(THREAD, r);4560values_h->int_at_put(0, java_lang_Thread::SLEEPING);4561values_h->int_at_put(1, java_lang_Thread::IN_OBJECT_WAIT_TIMED);4562values_h->int_at_put(2, java_lang_Thread::PARKED_TIMED);4563break;4564}4565case JAVA_THREAD_STATE_TERMINATED : {4566typeArrayOop r = oopFactory::new_typeArray(T_INT, 1, CHECK_NULL);4567values_h = typeArrayHandle(THREAD, r);4568values_h->int_at_put(0, java_lang_Thread::TERMINATED);4569break;4570}4571default:4572// Unknown state - probably incompatible JDK version4573return NULL;4574}45754576return (jintArray) JNIHandles::make_local(env, values_h());4577}4578JVM_END457945804581JVM_ENTRY(jobjectArray, JVM_GetThreadStateNames(JNIEnv* env,4582jint javaThreadState,4583jintArray values))4584{4585// If new thread states are added in future JDK and VM versions,4586// this should check if the JDK version is compatible with thread4587// states supported by the VM. Return NULL if not compatible.4588//4589// This function must map the VM java_lang_Thread::ThreadStatus4590// to the Java thread state that the JDK supports.4591//45924593ResourceMark rm;45944595// Check if threads is null4596if (values == NULL) {4597THROW_(vmSymbols::java_lang_NullPointerException(), 0);4598}45994600typeArrayOop v = typeArrayOop(JNIHandles::resolve_non_null(values));4601typeArrayHandle values_h(THREAD, v);46024603objArrayHandle names_h;4604switch (javaThreadState) {4605case JAVA_THREAD_STATE_NEW : {4606assert(values_h->length() == 1 &&4607values_h->int_at(0) == java_lang_Thread::NEW,4608"Invalid threadStatus value");46094610objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),46111, /* only 1 substate */4612CHECK_NULL);4613names_h = objArrayHandle(THREAD, r);4614Handle name = java_lang_String::create_from_str("NEW", CHECK_NULL);4615names_h->obj_at_put(0, name());4616break;4617}4618case JAVA_THREAD_STATE_RUNNABLE : {4619assert(values_h->length() == 1 &&4620values_h->int_at(0) == java_lang_Thread::RUNNABLE,4621"Invalid threadStatus value");46224623objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),46241, /* only 1 substate */4625CHECK_NULL);4626names_h = objArrayHandle(THREAD, r);4627Handle name = java_lang_String::create_from_str("RUNNABLE", CHECK_NULL);4628names_h->obj_at_put(0, name());4629break;4630}4631case JAVA_THREAD_STATE_BLOCKED : {4632assert(values_h->length() == 1 &&4633values_h->int_at(0) == java_lang_Thread::BLOCKED_ON_MONITOR_ENTER,4634"Invalid threadStatus value");46354636objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),46371, /* only 1 substate */4638CHECK_NULL);4639names_h = objArrayHandle(THREAD, r);4640Handle name = java_lang_String::create_from_str("BLOCKED", CHECK_NULL);4641names_h->obj_at_put(0, name());4642break;4643}4644case JAVA_THREAD_STATE_WAITING : {4645assert(values_h->length() == 2 &&4646values_h->int_at(0) == java_lang_Thread::IN_OBJECT_WAIT &&4647values_h->int_at(1) == java_lang_Thread::PARKED,4648"Invalid threadStatus value");4649objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),46502, /* number of substates */4651CHECK_NULL);4652names_h = objArrayHandle(THREAD, r);4653Handle name0 = java_lang_String::create_from_str("WAITING.OBJECT_WAIT",4654CHECK_NULL);4655Handle name1 = java_lang_String::create_from_str("WAITING.PARKED",4656CHECK_NULL);4657names_h->obj_at_put(0, name0());4658names_h->obj_at_put(1, name1());4659break;4660}4661case JAVA_THREAD_STATE_TIMED_WAITING : {4662assert(values_h->length() == 3 &&4663values_h->int_at(0) == java_lang_Thread::SLEEPING &&4664values_h->int_at(1) == java_lang_Thread::IN_OBJECT_WAIT_TIMED &&4665values_h->int_at(2) == java_lang_Thread::PARKED_TIMED,4666"Invalid threadStatus value");4667objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),46683, /* number of substates */4669CHECK_NULL);4670names_h = objArrayHandle(THREAD, r);4671Handle name0 = java_lang_String::create_from_str("TIMED_WAITING.SLEEPING",4672CHECK_NULL);4673Handle name1 = java_lang_String::create_from_str("TIMED_WAITING.OBJECT_WAIT",4674CHECK_NULL);4675Handle name2 = java_lang_String::create_from_str("TIMED_WAITING.PARKED",4676CHECK_NULL);4677names_h->obj_at_put(0, name0());4678names_h->obj_at_put(1, name1());4679names_h->obj_at_put(2, name2());4680break;4681}4682case JAVA_THREAD_STATE_TERMINATED : {4683assert(values_h->length() == 1 &&4684values_h->int_at(0) == java_lang_Thread::TERMINATED,4685"Invalid threadStatus value");4686objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),46871, /* only 1 substate */4688CHECK_NULL);4689names_h = objArrayHandle(THREAD, r);4690Handle name = java_lang_String::create_from_str("TERMINATED", CHECK_NULL);4691names_h->obj_at_put(0, name());4692break;4693}4694default:4695// Unknown state - probably incompatible JDK version4696return NULL;4697}4698return (jobjectArray) JNIHandles::make_local(env, names_h());4699}4700JVM_END47014702JVM_ENTRY(void, JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size))4703{4704memset(info, 0, info_size);47054706info->jvm_version = Abstract_VM_Version::jvm_version();4707info->update_version = 0; /* 0 in HotSpot Express VM */4708info->special_update_version = 0; /* 0 in HotSpot Express VM */47094710// when we add a new capability in the jvm_version_info struct, we should also4711// consider to expose this new capability in the sun.rt.jvmCapabilities jvmstat4712// counter defined in runtimeService.cpp.4713info->is_attachable = AttachListener::is_attach_supported();4714}4715JVM_END471647174718