# HG changeset patch # User acorn # Date 1252083182 14400 # Node ID ad6585fd4087c27d44ab489363c56b775d4a0ab9 # Parent 6918603297f7aa69b8d74fe38126fd2c99adaacc 6830542: Performance: JVM_DefineClass already verified. Reviewed-by: kamg, phh diff -r 6918603297f7 -r ad6585fd4087 make/linux/makefiles/mapfile-vers-debug --- a/make/linux/makefiles/mapfile-vers-debug Tue Sep 01 23:34:08 2009 -0700 +++ b/make/linux/makefiles/mapfile-vers-debug Fri Sep 04 12:53:02 2009 -0400 @@ -74,6 +74,7 @@ JVM_CurrentTimeMillis; JVM_DefineClass; JVM_DefineClassWithSource; + JVM_DefineClassWithSourceCond; JVM_DesiredAssertionStatus; JVM_DisableCompiler; JVM_DoPrivileged; diff -r 6918603297f7 -r ad6585fd4087 make/linux/makefiles/mapfile-vers-product --- a/make/linux/makefiles/mapfile-vers-product Tue Sep 01 23:34:08 2009 -0700 +++ b/make/linux/makefiles/mapfile-vers-product Fri Sep 04 12:53:02 2009 -0400 @@ -74,6 +74,7 @@ JVM_CurrentTimeMillis; JVM_DefineClass; JVM_DefineClassWithSource; + JVM_DefineClassWithSourceCond; JVM_DesiredAssertionStatus; JVM_DisableCompiler; JVM_DoPrivileged; diff -r 6918603297f7 -r ad6585fd4087 make/solaris/makefiles/mapfile-vers --- a/make/solaris/makefiles/mapfile-vers Tue Sep 01 23:34:08 2009 -0700 +++ b/make/solaris/makefiles/mapfile-vers Fri Sep 04 12:53:02 2009 -0400 @@ -74,6 +74,7 @@ JVM_CurrentTimeMillis; JVM_DefineClass; JVM_DefineClassWithSource; + JVM_DefineClassWithSourceCond; JVM_DesiredAssertionStatus; JVM_DisableCompiler; JVM_DoPrivileged; diff -r 6918603297f7 -r ad6585fd4087 src/share/vm/classfile/classFileParser.cpp --- a/src/share/vm/classfile/classFileParser.cpp Tue Sep 01 23:34:08 2009 -0700 +++ b/src/share/vm/classfile/classFileParser.cpp Fri Sep 04 12:53:02 2009 -0400 @@ -2547,6 +2547,7 @@ KlassHandle host_klass, GrowableArray* cp_patches, symbolHandle& parsed_name, + bool verify, TRAPS) { // So that JVMTI can cache class file in the state before retransformable agents // have modified it @@ -2591,7 +2592,7 @@ instanceKlassHandle nullHandle; // Figure out whether we can skip format checking (matching classic VM behavior) - _need_verify = Verifier::should_verify_for(class_loader()); + _need_verify = Verifier::should_verify_for(class_loader(), verify); // Set the verify flag in stream cfs->set_verify(_need_verify); @@ -3205,6 +3206,9 @@ // Fill in information already parsed this_klass->set_access_flags(access_flags); + if (verify) { + this_klass->set_should_verify_class(); + } jint lh = Klass::instance_layout_helper(instance_size, false); this_klass->set_layout_helper(lh); assert(this_klass->oop_is_instance(), "layout is correct"); @@ -3213,7 +3217,9 @@ //this_klass->set_super(super_klass()); this_klass->set_class_loader(class_loader()); this_klass->set_nonstatic_field_size(nonstatic_field_size); - this_klass->set_has_nonstatic_fields(has_nonstatic_fields); + if (has_nonstatic_fields) { + this_klass->set_has_nonstatic_fields(); + } this_klass->set_static_oop_field_size(fac.static_oop_count); cp->set_pool_holder(this_klass()); this_klass->set_constants(cp()); diff -r 6918603297f7 -r ad6585fd4087 src/share/vm/classfile/classFileParser.hpp --- a/src/share/vm/classfile/classFileParser.hpp Tue Sep 01 23:34:08 2009 -0700 +++ b/src/share/vm/classfile/classFileParser.hpp Fri Sep 04 12:53:02 2009 -0400 @@ -257,9 +257,10 @@ Handle class_loader, Handle protection_domain, symbolHandle& parsed_name, + bool verify, TRAPS) { KlassHandle no_host_klass; - return parseClassFile(name, class_loader, protection_domain, no_host_klass, NULL, parsed_name, THREAD); + return parseClassFile(name, class_loader, protection_domain, no_host_klass, NULL, parsed_name, verify, THREAD); } instanceKlassHandle parseClassFile(symbolHandle name, Handle class_loader, @@ -267,6 +268,7 @@ KlassHandle host_klass, GrowableArray* cp_patches, symbolHandle& parsed_name, + bool verify, TRAPS); // Verifier checks diff -r 6918603297f7 -r ad6585fd4087 src/share/vm/classfile/classLoader.cpp --- a/src/share/vm/classfile/classLoader.cpp Tue Sep 01 23:34:08 2009 -0700 +++ b/src/share/vm/classfile/classLoader.cpp Fri Sep 04 12:53:02 2009 -0400 @@ -874,6 +874,7 @@ class_loader, protection_domain, parsed_name, + false, CHECK_(h)); // add to package table diff -r 6918603297f7 -r ad6585fd4087 src/share/vm/classfile/systemDictionary.cpp --- a/src/share/vm/classfile/systemDictionary.cpp Tue Sep 01 23:34:08 2009 -0700 +++ b/src/share/vm/classfile/systemDictionary.cpp Fri Sep 04 12:53:02 2009 -0400 @@ -970,6 +970,7 @@ host_klass, cp_patches, parsed_name, + true, THREAD); @@ -1025,6 +1026,7 @@ Handle class_loader, Handle protection_domain, ClassFileStream* st, + bool verify, TRAPS) { // Classloaders that support parallelism, e.g. bootstrap classloader, @@ -1055,6 +1057,7 @@ class_loader, protection_domain, parsed_name, + verify, THREAD); const char* pkg = "java/"; diff -r 6918603297f7 -r ad6585fd4087 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Tue Sep 01 23:34:08 2009 -0700 +++ b/src/share/vm/classfile/systemDictionary.hpp Fri Sep 04 12:53:02 2009 -0400 @@ -259,7 +259,9 @@ TRAPS); // Resolve from stream (called by jni_DefineClass and JVM_DefineClass) - static klassOop resolve_from_stream(symbolHandle class_name, Handle class_loader, Handle protection_domain, ClassFileStream* st, TRAPS); + static klassOop resolve_from_stream(symbolHandle class_name, Handle class_loader, + Handle protection_domain, + ClassFileStream* st, bool verify, TRAPS); // Lookup an already loaded class. If not found NULL is returned. static klassOop find(symbolHandle class_name, Handle class_loader, Handle protection_domain, TRAPS); diff -r 6918603297f7 -r ad6585fd4087 src/share/vm/classfile/verifier.cpp --- a/src/share/vm/classfile/verifier.cpp Tue Sep 01 23:34:08 2009 -0700 +++ b/src/share/vm/classfile/verifier.cpp Fri Sep 04 12:53:02 2009 -0400 @@ -53,8 +53,8 @@ // Methods in Verifier -bool Verifier::should_verify_for(oop class_loader) { - return class_loader == NULL ? +bool Verifier::should_verify_for(oop class_loader, bool should_verify_class) { + return (class_loader == NULL || !should_verify_class) ? BytecodeVerificationLocal : BytecodeVerificationRemote; } @@ -68,7 +68,7 @@ return !need_verify; } -bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, TRAPS) { +bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool should_verify_class, TRAPS) { ResourceMark rm(THREAD); HandleMark hm; @@ -81,7 +81,7 @@ // If the class should be verified, first see if we can use the split // verifier. If not, or if verification fails and FailOverToOldVerifier // is set, then call the inference verifier. - if (is_eligible_for_verification(klass)) { + if (is_eligible_for_verification(klass, should_verify_class)) { if (TraceClassInitialization) { tty->print_cr("Start class verification for: %s", klassName); } @@ -141,12 +141,13 @@ } } -bool Verifier::is_eligible_for_verification(instanceKlassHandle klass) { +bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) { symbolOop name = klass->name(); klassOop refl_magic_klass = SystemDictionary::reflect_magic_klass(); - return (should_verify_for(klass->class_loader()) && + return (should_verify_for(klass->class_loader(), should_verify_class) && // return if the class is a bootstrapping class + // or defineClass specified not to verify by default (flags override passed arg) // We need to skip the following four for bootstraping name != vmSymbols::java_lang_Object() && name != vmSymbols::java_lang_Class() && diff -r 6918603297f7 -r ad6585fd4087 src/share/vm/classfile/verifier.hpp --- a/src/share/vm/classfile/verifier.hpp Tue Sep 01 23:34:08 2009 -0700 +++ b/src/share/vm/classfile/verifier.hpp Fri Sep 04 12:53:02 2009 -0400 @@ -34,16 +34,18 @@ * Otherwise, no exception is thrown and the return indicates the * error. */ - static bool verify(instanceKlassHandle klass, Mode mode, TRAPS); + static bool verify(instanceKlassHandle klass, Mode mode, bool should_verify_class, TRAPS); - // Return false if the class is loaded by the bootstrap loader. - static bool should_verify_for(oop class_loader); + // Return false if the class is loaded by the bootstrap loader, + // or if defineClass was called requesting skipping verification + // -Xverify:all/none override this value + static bool should_verify_for(oop class_loader, bool should_verify_class); // Relax certain verifier checks to enable some broken 1.1 apps to run on 1.2. static bool relax_verify_for(oop class_loader); private: - static bool is_eligible_for_verification(instanceKlassHandle klass); + static bool is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class); static symbolHandle inference_verify( instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS); }; diff -r 6918603297f7 -r ad6585fd4087 src/share/vm/code/dependencies.cpp --- a/src/share/vm/code/dependencies.cpp Tue Sep 01 23:34:08 2009 -0700 +++ b/src/share/vm/code/dependencies.cpp Fri Sep 04 12:53:02 2009 -0400 @@ -1464,7 +1464,7 @@ for (ContextStream str(*this); str.next(); ) { klassOop d = str.klass(); assert(!instanceKlass::cast(d)->is_marked_dependent(), "checking"); - instanceKlass::cast(d)->set_is_marked_dependent(true); + instanceKlass::cast(d)->set_is_marked_dependent(); } } @@ -1473,7 +1473,7 @@ // Unmark transitive interfaces for (ContextStream str(*this); str.next(); ) { klassOop d = str.klass(); - instanceKlass::cast(d)->set_is_marked_dependent(false); + instanceKlass::cast(d)->clear_is_marked_dependent(); } } diff -r 6918603297f7 -r ad6585fd4087 src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Tue Sep 01 23:34:08 2009 -0700 +++ b/src/share/vm/oops/instanceKlass.cpp Fri Sep 04 12:53:02 2009 -0400 @@ -110,7 +110,7 @@ // 1) Verify the bytecodes Verifier::Mode mode = throw_verifyerror ? Verifier::ThrowException : Verifier::NoException; - return Verifier::verify(this_oop, mode, CHECK_false); + return Verifier::verify(this_oop, mode, this_oop->should_verify_class(), CHECK_false); } diff -r 6918603297f7 -r ad6585fd4087 src/share/vm/oops/instanceKlass.hpp --- a/src/share/vm/oops/instanceKlass.hpp Tue Sep 01 23:34:08 2009 -0700 +++ b/src/share/vm/oops/instanceKlass.hpp Fri Sep 04 12:53:02 2009 -0400 @@ -114,6 +114,15 @@ initialization_error // error happened during initialization }; + // smaller footprint for boolean flags + enum ClassFlags { + _noflags = 0, // initial value + _rewritten = 0x00000001U, // rewritten + _should_verify = 0x00000002U, // defineClass specified conditional verification + _has_nonstatic_fields = 0x00000004U, // for sizing with UseCompressedOops + _is_marked_dependent = 0x00000008U // used for marking during flushing and deoptimization + }; + public: oop* oop_block_beg() const { return adr_array_klasses(); } oop* oop_block_end() const { return adr_methods_default_annotations() + 1; } @@ -192,9 +201,7 @@ int _static_field_size; // number words used by static fields (oop and non-oop) in this klass int _static_oop_field_size;// number of static oop fields in this klass int _nonstatic_oop_map_size;// number of nonstatic oop-map blocks allocated at end of this klass - bool _is_marked_dependent; // used for marking during flushing and deoptimization - bool _rewritten; // methods rewritten. - bool _has_nonstatic_fields; // for sizing with UseCompressedOops + int _class_flags; // internal class state flags u2 _minor_version; // minor version number of class file u2 _major_version; // major version number of class file ClassState _init_state; // state of class @@ -230,8 +237,8 @@ friend class SystemDictionary; public: - bool has_nonstatic_fields() const { return _has_nonstatic_fields; } - void set_has_nonstatic_fields(bool b) { _has_nonstatic_fields = b; } + bool has_nonstatic_fields() const { return (_class_flags & _has_nonstatic_fields) != 0; } + void set_has_nonstatic_fields() { _class_flags |= _has_nonstatic_fields; } // field sizes int nonstatic_field_size() const { return _nonstatic_field_size; } @@ -338,11 +345,16 @@ bool is_in_error_state() const { return _init_state == initialization_error; } bool is_reentrant_initialization(Thread *thread) { return thread == _init_thread; } int get_init_state() { return _init_state; } // Useful for debugging - bool is_rewritten() const { return _rewritten; } + bool is_rewritten() const { return (_class_flags & _rewritten) != 0; } + + // defineClass specified verification + bool should_verify_class() const { return (_class_flags & _should_verify) != 0; } + void set_should_verify_class() { _class_flags |= _should_verify; } // marking - bool is_marked_dependent() const { return _is_marked_dependent; } - void set_is_marked_dependent(bool value) { _is_marked_dependent = value; } + bool is_marked_dependent() const { return (_class_flags & _is_marked_dependent) != 0; } + void set_is_marked_dependent() { _class_flags |= _is_marked_dependent; } + void clear_is_marked_dependent() { _class_flags &= ~_is_marked_dependent; } // initialization (virtuals from Klass) bool should_be_initialized() const; // means that initialize should be called @@ -715,7 +727,8 @@ #else void set_init_state(ClassState state) { _init_state = state; } #endif - void set_rewritten() { _rewritten = true; } + void clear_class_flags() { _class_flags = _noflags; } + void set_rewritten() { _class_flags |= _rewritten; } void set_init_thread(Thread *thread) { _init_thread = thread; } u2 idnum_allocated_count() const { return _idnum_allocated_count; } diff -r 6918603297f7 -r ad6585fd4087 src/share/vm/oops/instanceKlassKlass.cpp --- a/src/share/vm/oops/instanceKlassKlass.cpp Tue Sep 01 23:34:08 2009 -0700 +++ b/src/share/vm/oops/instanceKlassKlass.cpp Fri Sep 04 12:53:02 2009 -0400 @@ -450,9 +450,9 @@ ik->set_inner_classes(NULL); ik->set_static_oop_field_size(0); ik->set_nonstatic_field_size(0); - ik->set_is_marked_dependent(false); ik->set_init_state(instanceKlass::allocated); ik->set_init_thread(NULL); + ik->clear_class_flags(); ik->set_reference_type(rt); ik->set_oop_map_cache(NULL); ik->set_jni_ids(NULL); diff -r 6918603297f7 -r ad6585fd4087 src/share/vm/prims/jni.cpp --- a/src/share/vm/prims/jni.cpp Tue Sep 01 23:34:08 2009 -0700 +++ b/src/share/vm/prims/jni.cpp Fri Sep 04 12:53:02 2009 -0400 @@ -299,7 +299,8 @@ } } klassOop k = SystemDictionary::resolve_from_stream(class_name, class_loader, - Handle(), &st, CHECK_NULL); + Handle(), &st, true, + CHECK_NULL); if (TraceClassResolution && k != NULL) { trace_class_resolution(k); diff -r 6918603297f7 -r ad6585fd4087 src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp Tue Sep 01 23:34:08 2009 -0700 +++ b/src/share/vm/prims/jvm.cpp Fri Sep 04 12:53:02 2009 -0400 @@ -762,7 +762,11 @@ } // common code for JVM_DefineClass() and JVM_DefineClassWithSource() -static jclass jvm_define_class_common(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source, TRAPS) { +// and JVM_DefineClassWithSourceCond() +static jclass jvm_define_class_common(JNIEnv *env, const char *name, + jobject loader, const jbyte *buf, + jsize len, jobject pd, const char *source, + jboolean verify, TRAPS) { if (source == NULL) source = "__JVM_DefineClass__"; assert(THREAD->is_Java_thread(), "must be a JavaThread"); @@ -803,6 +807,7 @@ Handle protection_domain (THREAD, JNIHandles::resolve(pd)); klassOop k = SystemDictionary::resolve_from_stream(class_name, class_loader, protection_domain, &st, + verify != 0, CHECK_NULL); if (TraceClassResolution && k != NULL) { @@ -816,16 +821,24 @@ JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd)) JVMWrapper2("JVM_DefineClass %s", name); - return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, THREAD); + return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, true, THREAD); JVM_END JVM_ENTRY(jclass, JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source)) JVMWrapper2("JVM_DefineClassWithSource %s", name); - return jvm_define_class_common(env, name, loader, buf, len, pd, source, THREAD); -JVM_END - + return jvm_define_class_common(env, name, loader, buf, len, pd, source, true, THREAD); +JVM_END + +JVM_ENTRY(jclass, JVM_DefineClassWithSourceCond(JNIEnv *env, const char *name, + jobject loader, const jbyte *buf, + jsize len, jobject pd, + const char *source, jboolean verify)) + JVMWrapper2("JVM_DefineClassWithSourceCond %s", name); + + return jvm_define_class_common(env, name, loader, buf, len, pd, source, verify, THREAD); +JVM_END JVM_ENTRY(jclass, JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name)) JVMWrapper("JVM_FindLoadedClass"); diff -r 6918603297f7 -r ad6585fd4087 src/share/vm/prims/jvm.h --- a/src/share/vm/prims/jvm.h Tue Sep 01 23:34:08 2009 -0700 +++ b/src/share/vm/prims/jvm.h Fri Sep 04 12:53:02 2009 -0400 @@ -417,6 +417,17 @@ const jbyte *buf, jsize len, jobject pd, const char *source); +/* Define a class with a source with conditional verification (added HSX 14) + * -Xverify:all will verify anyway, -Xverify:none will not verify, + * -Xverify:remote (default) will obey this conditional + * i.e. true = should_verify_class + */ +JNIEXPORT jclass JNICALL +JVM_DefineClassWithSourceCond(JNIEnv *env, const char *name, + jobject loader, const jbyte *buf, + jsize len, jobject pd, const char *source, + jboolean verify); + /* Define a class with a source (MLVM) */ JNIEXPORT jclass JNICALL JVM_DefineClassWithCP(JNIEnv *env, const char *name, jobject loader, diff -r 6918603297f7 -r ad6585fd4087 src/share/vm/prims/jvmtiRedefineClasses.cpp --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Tue Sep 01 23:34:08 2009 -0700 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Sep 04 12:53:02 2009 -0400 @@ -933,7 +933,7 @@ // description. RedefineVerifyMark rvm(&the_class, &scratch_class, state); Verifier::verify( - scratch_class, Verifier::ThrowException, THREAD); + scratch_class, Verifier::ThrowException, true, THREAD); } if (HAS_PENDING_EXCEPTION) { @@ -959,7 +959,7 @@ // verify what we have done during constant pool merging { RedefineVerifyMark rvm(&the_class, &scratch_class, state); - Verifier::verify(scratch_class, Verifier::ThrowException, THREAD); + Verifier::verify(scratch_class, Verifier::ThrowException, true, THREAD); } if (HAS_PENDING_EXCEPTION) { diff -r 6918603297f7 -r ad6585fd4087 src/share/vm/runtime/vmStructs.cpp --- a/src/share/vm/runtime/vmStructs.cpp Tue Sep 01 23:34:08 2009 -0700 +++ b/src/share/vm/runtime/vmStructs.cpp Fri Sep 04 12:53:02 2009 -0400 @@ -108,7 +108,7 @@ nonstatic_field(instanceKlass, _static_field_size, int) \ nonstatic_field(instanceKlass, _static_oop_field_size, int) \ nonstatic_field(instanceKlass, _nonstatic_oop_map_size, int) \ - nonstatic_field(instanceKlass, _is_marked_dependent, bool) \ + nonstatic_field(instanceKlass, _class_flags, int) \ nonstatic_field(instanceKlass, _minor_version, u2) \ nonstatic_field(instanceKlass, _major_version, u2) \ nonstatic_field(instanceKlass, _init_state, instanceKlass::ClassState) \ @@ -1245,6 +1245,7 @@ declare_integer_type(Bytecodes::Code) \ declare_integer_type(Generation::Name) \ declare_integer_type(instanceKlass::ClassState) \ + declare_integer_type(instanceKlass::ClassFlags) \ declare_integer_type(JavaThreadState) \ declare_integer_type(Location::Type) \ declare_integer_type(Location::Where) \ @@ -1526,6 +1527,16 @@ declare_constant(instanceKlass::initialization_error) \ \ /*********************************/ \ + /* instanceKlass ClassFlags enum */ \ + /*********************************/ \ + \ + declare_constant(instanceKlass::_noflags) \ + declare_constant(instanceKlass::_rewritten) \ + declare_constant(instanceKlass::_should_verify) \ + declare_constant(instanceKlass::_has_nonstatic_fields) \ + declare_constant(instanceKlass::_is_marked_dependent) \ + \ + /*********************************/ \ /* symbolOop - symbol max length */ \ /*********************************/ \ \