# HG changeset patch # User dcubed # Date 1260822389 25200 # Node ID dcb15a6f342de12f335600391af5f5f8328bca48 # Parent 547f81740344bc7188c919f8e25f6178324e830e# Parent 98cd9901c1614fce1837d1fa74946f3f2ea3f3fe Merge diff -r 547f81740344 -r dcb15a6f342d src/share/vm/prims/jvmtiEnv.cpp --- a/src/share/vm/prims/jvmtiEnv.cpp Fri Dec 11 11:09:49 2009 -0800 +++ b/src/share/vm/prims/jvmtiEnv.cpp Mon Dec 14 13:26:29 2009 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,15 +32,15 @@ // FIXLATER: hook into JvmtiTrace #define TraceJVMTICalls false -JvmtiEnv::JvmtiEnv() : JvmtiEnvBase() { +JvmtiEnv::JvmtiEnv(jint version) : JvmtiEnvBase(version) { } JvmtiEnv::~JvmtiEnv() { } JvmtiEnv* -JvmtiEnv::create_a_jvmti() { - return new JvmtiEnv(); +JvmtiEnv::create_a_jvmti(jint version) { + return new JvmtiEnv(version); } // VM operation class to copy jni function table at safepoint. @@ -411,8 +411,15 @@ if (phase == JVMTI_PHASE_ONLOAD) { Arguments::append_sysclasspath(segment); return JVMTI_ERROR_NONE; - } else { - assert(phase == JVMTI_PHASE_LIVE, "sanity check"); + } else if (use_version_1_0_semantics()) { + // This JvmtiEnv requested version 1.0 semantics and this function + // is only allowed in the ONLOAD phase in version 1.0 so we need to + // return an error here. + return JVMTI_ERROR_WRONG_PHASE; + } else if (phase == JVMTI_PHASE_LIVE) { + // The phase is checked by the wrapper that called this function, + // but this thread could be racing with the thread that is + // terminating the VM so we check one more time. // create the zip entry ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment); @@ -433,6 +440,8 @@ } ClassLoader::add_to_list(zip_entry); return JVMTI_ERROR_NONE; + } else { + return JVMTI_ERROR_WRONG_PHASE; } } /* end AddToBootstrapClassLoaderSearch */ @@ -451,11 +460,12 @@ } } return JVMTI_ERROR_NONE; - } else { + } else if (phase == JVMTI_PHASE_LIVE) { + // The phase is checked by the wrapper that called this function, + // but this thread could be racing with the thread that is + // terminating the VM so we check one more time. HandleMark hm; - assert(phase == JVMTI_PHASE_LIVE, "sanity check"); - // create the zip entry (which will open the zip file and hence // check that the segment is indeed a zip file). ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment); @@ -504,6 +514,8 @@ } return JVMTI_ERROR_NONE; + } else { + return JVMTI_ERROR_WRONG_PHASE; } } /* end AddToSystemClassLoaderSearch */ @@ -2863,6 +2875,14 @@ // is_obsolete_ptr - pre-checked for NULL jvmtiError JvmtiEnv::IsMethodObsolete(methodOop method_oop, jboolean* is_obsolete_ptr) { + if (use_version_1_0_semantics() && + get_capabilities()->can_redefine_classes == 0) { + // This JvmtiEnv requested version 1.0 semantics and this function + // requires the can_redefine_classes capability in version 1.0 so + // we need to return an error here. + return JVMTI_ERROR_MUST_POSSESS_CAPABILITY; + } + if (method_oop == NULL || method_oop->is_obsolete()) { *is_obsolete_ptr = true; } else { diff -r 547f81740344 -r dcb15a6f342d src/share/vm/prims/jvmtiEnvBase.cpp --- a/src/share/vm/prims/jvmtiEnvBase.cpp Fri Dec 11 11:09:49 2009 -0800 +++ b/src/share/vm/prims/jvmtiEnvBase.cpp Mon Dec 14 13:26:29 2009 -0700 @@ -123,7 +123,26 @@ } -JvmtiEnvBase::JvmtiEnvBase() : _env_event_enable() { +bool +JvmtiEnvBase::use_version_1_0_semantics() { + int major, minor, micro; + + JvmtiExport::decode_version_values(_version, &major, &minor, µ); + return major == 1 && minor == 0; // micro version doesn't matter here +} + + +bool +JvmtiEnvBase::use_version_1_1_semantics() { + int major, minor, micro; + + JvmtiExport::decode_version_values(_version, &major, &minor, µ); + return major == 1 && minor == 1; // micro version doesn't matter here +} + + +JvmtiEnvBase::JvmtiEnvBase(jint version) : _env_event_enable() { + _version = version; _env_local_storage = NULL; _tag_map = NULL; _native_method_prefix_count = 0; diff -r 547f81740344 -r dcb15a6f342d src/share/vm/prims/jvmtiEnvBase.hpp --- a/src/share/vm/prims/jvmtiEnvBase.hpp Fri Dec 11 11:09:49 2009 -0800 +++ b/src/share/vm/prims/jvmtiEnvBase.hpp Mon Dec 14 13:26:29 2009 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,6 +76,7 @@ jvmtiEnv _jvmti_external; jint _magic; + jint _version; // version value passed to JNI GetEnv() JvmtiEnvBase* _next; bool _is_retransformable; const void *_env_local_storage; // per env agent allocated data. @@ -91,7 +92,7 @@ int _native_method_prefix_count; protected: - JvmtiEnvBase(); + JvmtiEnvBase(jint version); ~JvmtiEnvBase(); void dispose(); void env_dispose(); @@ -122,6 +123,9 @@ bool is_valid(); + bool use_version_1_0_semantics(); // agent asked for version 1.0 + bool use_version_1_1_semantics(); // agent asked for version 1.1 + bool is_retransformable() { return _is_retransformable; } static ByteSize jvmti_external_offset() { diff -r 547f81740344 -r dcb15a6f342d src/share/vm/prims/jvmtiExport.cpp --- a/src/share/vm/prims/jvmtiExport.cpp Fri Dec 11 11:09:49 2009 -0800 +++ b/src/share/vm/prims/jvmtiExport.cpp Mon Dec 14 13:26:29 2009 -0700 @@ -319,7 +319,27 @@ jint JvmtiExport::get_jvmti_interface(JavaVM *jvm, void **penv, jint version) { - /* To Do: add version checks */ + // The JVMTI_VERSION_INTERFACE_JVMTI part of the version number + // has already been validated in JNI GetEnv(). + int major, minor, micro; + + // micro version doesn't matter here (yet?) + decode_version_values(version, &major, &minor, µ); + switch (major) { + case 1: + switch (minor) { + case 0: // version 1.0. is recognized + case 1: // version 1.1. is recognized + break; + + default: + return JNI_EVERSION; // unsupported minor version number + } + break; + + default: + return JNI_EVERSION; // unsupported major version number + } if (JvmtiEnv::get_phase() == JVMTI_PHASE_LIVE) { JavaThread* current_thread = (JavaThread*) ThreadLocalStorage::thread(); @@ -328,13 +348,13 @@ __ENTRY(jvmtiEnv*, JvmtiExport::get_jvmti_interface, current_thread) debug_only(VMNativeEntryWrapper __vew;) - JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti(); + JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti(version); *penv = jvmti_env->jvmti_external(); // actual type is jvmtiEnv* -- not to be confused with JvmtiEnv* return JNI_OK; } else if (JvmtiEnv::get_phase() == JVMTI_PHASE_ONLOAD) { // not live, no thread to transition - JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti(); + JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti(version); *penv = jvmti_env->jvmti_external(); // actual type is jvmtiEnv* -- not to be confused with JvmtiEnv* return JNI_OK; @@ -345,6 +365,15 @@ } } + +void +JvmtiExport::decode_version_values(jint version, int * major, int * minor, + int * micro) { + *major = (version & JVMTI_VERSION_MASK_MAJOR) >> JVMTI_VERSION_SHIFT_MAJOR; + *minor = (version & JVMTI_VERSION_MASK_MINOR) >> JVMTI_VERSION_SHIFT_MINOR; + *micro = (version & JVMTI_VERSION_MASK_MICRO) >> JVMTI_VERSION_SHIFT_MICRO; +} + void JvmtiExport::enter_primordial_phase() { JvmtiEnvBase::set_phase(JVMTI_PHASE_PRIMORDIAL); } diff -r 547f81740344 -r dcb15a6f342d src/share/vm/prims/jvmtiExport.hpp --- a/src/share/vm/prims/jvmtiExport.hpp Fri Dec 11 11:09:49 2009 -0800 +++ b/src/share/vm/prims/jvmtiExport.hpp Mon Dec 14 13:26:29 2009 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -236,6 +236,8 @@ static bool is_jvmti_version(jint version) { return (version & JVMTI_VERSION_MASK) == JVMTI_VERSION_VALUE; } static bool is_jvmdi_version(jint version) { return (version & JVMTI_VERSION_MASK) == JVMDI_VERSION_VALUE; } static jint get_jvmti_interface(JavaVM *jvm, void **penv, jint version); + static void decode_version_values(jint version, int * major, int * minor, + int * micro); // single stepping management methods static void at_single_stepping_point(JavaThread *thread, methodOop method, address location) KERNEL_RETURN; diff -r 547f81740344 -r dcb15a6f342d src/share/vm/prims/jvmtiHpp.xsl --- a/src/share/vm/prims/jvmtiHpp.xsl Fri Dec 11 11:09:49 2009 -0800 +++ b/src/share/vm/prims/jvmtiHpp.xsl Mon Dec 14 13:26:29 2009 -0700 @@ -1,6 +1,6 @@