Mercurial > hg > release > icedtea7-forest-2.6 > hotspot
changeset 6648:942409603ae4
Merge jdk7u181-b00
author | andrew |
---|---|
date | Thu, 19 Apr 2018 17:55:26 +0100 |
parents | a68f2a94f319 (current diff) 5559874a74ad (diff) |
children | 56142fb6814b |
files | .hgtags src/share/vm/classfile/classFileParser.cpp src/share/vm/classfile/javaClasses.cpp src/share/vm/classfile/javaClasses.hpp src/share/vm/classfile/systemDictionary.cpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/interpreter/linkResolver.cpp src/share/vm/oops/cpCacheOop.cpp src/share/vm/oops/instanceKlass.cpp src/share/vm/oops/instanceKlass.hpp src/share/vm/oops/methodOop.cpp src/share/vm/prims/jvm.cpp |
diffstat | 17 files changed, 292 insertions(+), 138 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Thu Apr 19 04:49:54 2018 +0100 +++ b/.hgtags Thu Apr 19 17:55:26 2018 +0100 @@ -919,3 +919,4 @@ ce3abb5889fb01808cab7489e83c1dc448743b70 jdk7u171-b02 f96baf6b460751580465a599ed2fba0c912e4bad icedtea-2.6.13 79d8447a461c7319969585c363649901b4c2773a icedtea-2.6.14pre01 +205c34770f355f726055a716ecc8991dd3bbd8fd jdk7u181-b00
--- a/src/share/vm/classfile/classFileParser.cpp Thu Apr 19 04:49:54 2018 +0100 +++ b/src/share/vm/classfile/classFileParser.cpp Thu Apr 19 17:55:26 2018 +0100 @@ -1779,8 +1779,7 @@ vmSymbols::SID sid = vmSymbols::find_sid(name); // Privileged code can use all annotations. Other code silently drops some. const bool privileged = class_loader.is_null() || is_anonymous || - class_loader()->klass()->klass_part()->name() == - vmSymbols::sun_misc_Launcher_ExtClassLoader(); + SystemDictionary::is_ext_class_loader(class_loader); switch (sid) { case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature): if (_location != _in_method) break; // only allow for methods
--- a/src/share/vm/classfile/javaClasses.cpp Thu Apr 19 04:49:54 2018 +0100 +++ b/src/share/vm/classfile/javaClasses.cpp Thu Apr 19 17:55:26 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. 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 @@ -2430,6 +2430,32 @@ *offset = value; } +// Support for java_lang_ref_ReferenceQueue + +oop java_lang_ref_ReferenceQueue::NULL_queue() { + instanceKlass* ik = instanceKlass::cast(SystemDictionary::ReferenceQueue_klass()); + oop mirror = ik->java_mirror(); + return mirror->obj_field(static_NULL_queue_offset); +} + +oop java_lang_ref_ReferenceQueue::ENQUEUED_queue() { + instanceKlass* ik = instanceKlass::cast(SystemDictionary::ReferenceQueue_klass()); + oop mirror = ik->java_mirror(); + return mirror->obj_field(static_ENQUEUED_queue_offset); +} + +void java_lang_ref_ReferenceQueue::compute_offsets() { + klassOop k = SystemDictionary::ReferenceQueue_klass(); + compute_offset(static_NULL_queue_offset, + k, + vmSymbols::referencequeue_null_name(), + vmSymbols::referencequeue_signature()); + compute_offset(static_ENQUEUED_queue_offset, + k, + vmSymbols::referencequeue_enqueued_name(), + vmSymbols::referencequeue_signature()); +} + // Support for java_lang_invoke_DirectMethodHandle int java_lang_invoke_DirectMethodHandle::_member_offset; @@ -2938,6 +2964,8 @@ int java_lang_ref_Reference::static_lock_offset; int java_lang_ref_Reference::static_pending_offset; int java_lang_ref_Reference::number_of_fake_oop_fields; +int java_lang_ref_ReferenceQueue::static_NULL_queue_offset; +int java_lang_ref_ReferenceQueue::static_ENQUEUED_queue_offset; int java_lang_ref_SoftReference::timestamp_offset; int java_lang_ref_SoftReference::static_clock_offset; int java_lang_ClassLoader::parent_offset; @@ -3117,6 +3145,8 @@ sun_reflect_UnsafeStaticFieldAccessorImpl::compute_offsets(); } + java_lang_ref_ReferenceQueue::compute_offsets(); + // generated interpreter code wants to know about the offsets we just computed: AbstractAssembler::update_delayed_values(); }
--- a/src/share/vm/classfile/javaClasses.hpp Thu Apr 19 04:49:54 2018 +0100 +++ b/src/share/vm/classfile/javaClasses.hpp Thu Apr 19 17:55:26 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. 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 @@ -860,6 +860,12 @@ static HeapWord* discovered_addr(oop ref) { return ref->obj_field_addr<HeapWord>(discovered_offset); } + static inline oop queue(oop ref) { + return ref->obj_field(queue_offset); + } + static inline void set_queue(oop ref, oop value) { + return ref->obj_field_put(queue_offset, value); + } // Accessors for statics static oop pending_list_lock(); static oop pending_list(); @@ -892,6 +898,20 @@ }; +// Interface to java.lang.ref.ReferenceQueue objects + +class java_lang_ref_ReferenceQueue: public AllStatic { +public: + static int static_NULL_queue_offset; + static int static_ENQUEUED_queue_offset; + + // Accessors + static oop NULL_queue(); + static oop ENQUEUED_queue(); + + static void compute_offsets(); +}; + // Interface to java.lang.invoke.MethodHandle objects class MethodHandleEntry;
--- a/src/share/vm/classfile/systemDictionary.cpp Thu Apr 19 04:49:54 2018 +0100 +++ b/src/share/vm/classfile/systemDictionary.cpp Thu Apr 19 17:55:26 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. 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 @@ -145,6 +145,17 @@ } return false; } + +/** + * Returns true if the passed class loader is the extension class loader. + */ +bool SystemDictionary::is_ext_class_loader(Handle class_loader) { + if (class_loader.is_null()) { + return false; + } + return (class_loader->klass()->klass_part()->name() == vmSymbols::sun_misc_Launcher_ExtClassLoader()); +} + // ---------------------------------------------------------------------------- // Resolving of classes @@ -1892,6 +1903,8 @@ instanceKlass::cast(WK_KLASS(PhantomReference_klass))->set_reference_type(REF_PHANTOM); instanceKlass::cast(WK_KLASS(Cleaner_klass))->set_reference_type(REF_CLEANER); + initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(ReferenceQueue_klass), scan, CHECK); + // JSR 292 classes WKID jsr292_group_start = WK_KLASS_ENUM_NAME(MethodHandle_klass); WKID jsr292_group_end = WK_KLASS_ENUM_NAME(VolatileCallSite_klass);
--- a/src/share/vm/classfile/systemDictionary.hpp Thu Apr 19 04:49:54 2018 +0100 +++ b/src/share/vm/classfile/systemDictionary.hpp Thu Apr 19 17:55:26 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. 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 @@ -128,6 +128,7 @@ do_klass(PhantomReference_klass, java_lang_ref_PhantomReference, Pre ) \ do_klass(Cleaner_klass, sun_misc_Cleaner, Pre ) \ do_klass(Finalizer_klass, java_lang_ref_Finalizer, Pre ) \ + do_klass(ReferenceQueue_klass, java_lang_ref_ReferenceQueue, Pre ) \ \ do_klass(Thread_klass, java_lang_Thread, Pre ) \ do_klass(ThreadGroup_klass, java_lang_ThreadGroup, Pre ) \ @@ -612,6 +613,10 @@ static bool is_parallelCapable(Handle class_loader); static bool is_parallelDefine(Handle class_loader); +public: + static bool is_ext_class_loader(Handle class_loader); + +private: static klassOop find_shared_class(Symbol* class_name); // Setup link to hierarchy @@ -622,7 +627,6 @@ Handle initiating_loader); static void post_class_unload_events(BoolObjectClosure* is_alive); -private: // We pass in the hashtable index so we can calculate it outside of // the SystemDictionary_lock.
--- a/src/share/vm/classfile/vmSymbols.hpp Thu Apr 19 04:49:54 2018 +0100 +++ b/src/share/vm/classfile/vmSymbols.hpp Thu Apr 19 17:55:26 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. 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 @@ -83,6 +83,7 @@ template(java_lang_ref_PhantomReference, "java/lang/ref/PhantomReference") \ template(sun_misc_Cleaner, "sun/misc/Cleaner") \ template(java_lang_ref_Finalizer, "java/lang/ref/Finalizer") \ + template(java_lang_ref_ReferenceQueue, "java/lang/ref/ReferenceQueue") \ template(java_lang_reflect_AccessibleObject, "java/lang/reflect/AccessibleObject") \ template(java_lang_reflect_Method, "java/lang/reflect/Method") \ template(java_lang_reflect_Constructor, "java/lang/reflect/Constructor") \ @@ -379,6 +380,8 @@ template(array_klass_name, "array_klass") \ template(oop_size_name, "oop_size") \ template(static_oop_field_count_name, "static_oop_field_count") \ + template(referencequeue_null_name, "NULL") \ + template(referencequeue_enqueued_name, "ENQUEUED") \ \ /* non-intrinsic name/signature pairs: */ \ template(register_method_name, "register") \ @@ -469,6 +472,7 @@ template(class_signature, "Ljava/lang/Class;") \ template(string_signature, "Ljava/lang/String;") \ template(reference_signature, "Ljava/lang/ref/Reference;") \ + template(referencequeue_signature, "Ljava/lang/ref/ReferenceQueue;") \ template(concurrenthashmap_signature, "Ljava/util/concurrent/ConcurrentHashMap;") \ template(String_StringBuilder_signature, "(Ljava/lang/String;)Ljava/lang/StringBuilder;") \ template(int_StringBuilder_signature, "(I)Ljava/lang/StringBuilder;") \
--- a/src/share/vm/code/dependencies.cpp Thu Apr 19 04:49:54 2018 +0100 +++ b/src/share/vm/code/dependencies.cpp Thu Apr 19 17:55:26 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. 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 @@ -723,6 +723,14 @@ _signature = NULL; initialize(participant); } + ClassHierarchyWalker(klassOop participants[], int num_participants) { + _name = NULL; + _signature = NULL; + initialize(NULL); + for (int i = 0; i < num_participants; ++i) { + add_participant(participants[i]); + } + } // This is common code for two searches: One for concrete subtypes, // the other for concrete method implementations and overrides. @@ -810,8 +818,29 @@ if (doing_subtype_search()) { return Dependencies::is_concrete_klass(k); } else { - methodOop m = instanceKlass::cast(k)->find_method(_name, _signature); - if (m == NULL || !Dependencies::is_concrete_method(m)) return false; + // Search class hierarchy first. + methodOop m = instanceKlass::cast(k)->find_instance_method(_name, _signature); + if (!Dependencies::is_concrete_method(m)) { + // Check for re-abstraction of method + if (!k->klass_part()->is_interface() && m != NULL && m->is_abstract()) { + // Found a matching abstract method 'm' in the class hierarchy. + // This is fine iff 'k' is an abstract class and all concrete subtypes + // of 'k' override 'm' and are participates of the current search. + ClassHierarchyWalker wf(_participants, _num_participants); + klassOop w = wf.find_witness_subtype(k); + if (w != NULL) { + methodOop wm = instanceKlass::cast(w)->find_instance_method(_name, _signature); + if (!Dependencies::is_concrete_method(wm)) { + // Found a concrete subtype 'w' which does not override abstract method 'm'. + // Bail out because 'm' could be called with 'w' as receiver (leading to an + // AbstractMethodError) and thus the method we are looking for is not unique. + _found_methods[_num_participants] = m; + return true; + } + } + } + return false; + } _found_methods[_num_participants] = m; // Note: If add_participant(k) is called, // the method m will already be memoized for it. @@ -1104,15 +1133,12 @@ } bool Dependencies::is_concrete_method(methodOop m) { - // Statics are irrelevant to virtual call sites. - if (m->is_static()) return false; - - // We could also return false if m does not yet appear to be - // executed, if the VM version supports this distinction also. - return !m->is_abstract(); + // NULL is not a concrete method, + // statics are irrelevant to virtual call sites, + // abstract methods are not concrete, + return ! ( m == NULL || m -> is_static() || m -> is_abstract()); } - Klass* Dependencies::find_finalizable_subclass(Klass* k) { if (k->is_interface()) return NULL; if (k->has_finalizer()) return k; @@ -1134,16 +1160,6 @@ return true; } -bool Dependencies::is_concrete_method(ciMethod* m) { - // Statics are irrelevant to virtual call sites. - if (m->is_static()) return false; - - // We could also return false if m does not yet appear to be - // executed, if the VM version supports this distinction also. - return !m->is_abstract(); -} - - bool Dependencies::has_finalizable_subclass(ciInstanceKlass* k) { return k->has_finalizable_subclass(); } @@ -1387,61 +1403,6 @@ return wf.find_witness_definer(ctxk, changes); } -// Find the set of all non-abstract methods under ctxk that match m[0]. -// (The method m[0] must be defined or inherited in ctxk.) -// Include m itself in the set, unless it is abstract. -// Fill the given array m[0..(mlen-1)] with this set, and return the length. -// (The length may be zero if no concrete methods are found anywhere.) -// If there are too many concrete methods to fit in marray, return -1. -int Dependencies::find_exclusive_concrete_methods(klassOop ctxk, - int mlen, - methodOop marray[]) { - methodOop m0 = marray[0]; - ClassHierarchyWalker wf(m0); - assert(wf.check_method_context(ctxk, m0), "proper context"); - wf.record_witnesses(mlen); - bool participants_hide_witnesses = true; - klassOop wit = wf.find_witness_definer(ctxk); - if (wit != NULL) return -1; // Too many witnesses. - int num = wf.num_participants(); - assert(num <= mlen, "oob"); - // Keep track of whether m is also part of the result set. - int mfill = 0; - assert(marray[mfill] == m0, "sanity"); - if (Dependencies::is_concrete_method(m0)) - mfill++; // keep m0 as marray[0], the first result - for (int i = 0; i < num; i++) { - methodOop fm = wf.found_method(i); - if (fm == m0) continue; // Already put this guy in the list. - if (mfill == mlen) { - return -1; // Oops. Too many methods after all! - } - marray[mfill++] = fm; - } -#ifndef PRODUCT - // Make sure the dependency mechanism will pass this discovery: - if (VerifyDependencies) { - // Turn off dependency tracing while actually testing deps. - FlagSetting fs(TraceDependencies, false); - switch (mfill) { - case 1: - guarantee(NULL == (void *)check_unique_concrete_method(ctxk, marray[0]), - "verify dep."); - break; - case 2: - guarantee(NULL == (void *) - check_exclusive_concrete_methods(ctxk, marray[0], marray[1]), - "verify dep."); - break; - default: - ShouldNotReachHere(); // mlen > 2 yet supported - } - } -#endif //PRODUCT - return mfill; -} - - klassOop Dependencies::check_has_no_finalizable_subclasses(klassOop ctxk, KlassDepChange* changes) { Klass* search_at = ctxk->klass_part(); if (changes != NULL) @@ -1453,7 +1414,6 @@ return result->as_klassOop(); } - klassOop Dependencies::check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes) { assert(call_site ->is_a(SystemDictionary::CallSite_klass()), "sanity"); assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "sanity");
--- a/src/share/vm/code/dependencies.hpp Thu Apr 19 04:49:54 2018 +0100 +++ b/src/share/vm/code/dependencies.hpp Thu Apr 19 17:55:26 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. 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 @@ -301,7 +301,6 @@ // not go back into the VM to get their value; they must cache the // bit in the CI, either eagerly or lazily.) static bool is_concrete_klass(ciInstanceKlass* k); // k appears instantiable - static bool is_concrete_method(ciMethod* m); // m appears invocable static bool has_finalizable_subclass(ciInstanceKlass* k); // As a general rule, it is OK to compile under the assumption that @@ -348,7 +347,6 @@ static klassOop find_unique_concrete_subtype(klassOop ctxk); static methodOop find_unique_concrete_method(klassOop ctxk, methodOop m); static int find_exclusive_concrete_subtypes(klassOop ctxk, int klen, klassOop k[]); - static int find_exclusive_concrete_methods(klassOop ctxk, int mlen, methodOop m[]); // Create the encoding which will be stored in an nmethod. void encode_content_bytes();
--- a/src/share/vm/interpreter/linkResolver.cpp Thu Apr 19 04:49:54 2018 +0100 +++ b/src/share/vm/interpreter/linkResolver.cpp Thu Apr 19 17:55:26 2018 +0100 @@ -188,6 +188,7 @@ // // According to JVM spec. $5.4.3c & $5.4.3d +// Look up method in klasses, including static methods void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { methodOop result_oop = klass->uncached_lookup_method(name, signature); @@ -213,8 +214,8 @@ methodOop result_oop = klass->uncached_lookup_method(name, signature); result = methodHandle(THREAD, result_oop); while (!result.is_null() && result->is_static()) { - klass = KlassHandle(THREAD, Klass::cast(result->method_holder())->super()); - result = methodHandle(THREAD, klass->uncached_lookup_method(name, signature)); + KlassHandle super_klass = KlassHandle(THREAD, Klass::cast(result->method_holder())->super()); + result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature)); } }
--- a/src/share/vm/oops/cpCacheOop.cpp Thu Apr 19 04:49:54 2018 +0100 +++ b/src/share/vm/oops/cpCacheOop.cpp Thu Apr 19 17:55:26 2018 +0100 @@ -231,14 +231,13 @@ // virtual method in java.lang.Object. This is a corner case in the spec // but is presumably legal. javac does not generate this code. // - // We set bytecode_1() to _invokeinterface, because that is the - // bytecode # used by the interpreter to see if it is resolved. + // We do not set bytecode_1() to _invokeinterface, because that is the + // bytecode # used by the interpreter to see if it is resolved. In this + // case, the method gets reresolved with caller for each interface call + // because the actual selected method may not be public. + // // We set bytecode_2() to _invokevirtual. // See also interpreterRuntime.cpp. (8/25/2000) - // Only set resolved for the invokeinterface case if method is public. - // Otherwise, the method needs to be reresolved with caller for each - // interface call. - if (method->is_public()) set_bytecode_1(invoke_code); } else { assert(invoke_code == Bytecodes::_invokevirtual, ""); }
--- a/src/share/vm/oops/instanceKlass.cpp Thu Apr 19 04:49:54 2018 +0100 +++ b/src/share/vm/oops/instanceKlass.cpp Thu Apr 19 17:55:26 2018 +0100 @@ -1046,11 +1046,7 @@ } #endif -methodOop instanceKlass::find_method(Symbol* name, Symbol* signature) const { - return instanceKlass::find_method(methods(), name, signature); -} - -methodOop instanceKlass::find_method(objArrayOop methods, Symbol* name, Symbol* signature) { +static int binary_search(objArrayOop methods, Symbol* name) { int len = methods->length(); // methods are sorted, so do binary search int l = 0; @@ -1061,43 +1057,100 @@ assert(m->is_method(), "must be method"); int res = m->name()->fast_compare(name); if (res == 0) { - // found matching name; do linear search to find matching signature - // first, quick check for common case - if (m->signature() == signature) return m; - // search downwards through overloaded methods - int i; - for (i = mid - 1; i >= l; i--) { - methodOop m = (methodOop)methods->obj_at(i); - assert(m->is_method(), "must be method"); - if (m->name() != name) break; - if (m->signature() == signature) return m; - } - // search upwards - for (i = mid + 1; i <= h; i++) { - methodOop m = (methodOop)methods->obj_at(i); - assert(m->is_method(), "must be method"); - if (m->name() != name) break; - if (m->signature() == signature) return m; - } - // not found -#ifdef ASSERT - int index = linear_search(methods, name, signature); - assert(index == -1, err_msg("binary search should have found entry %d", index)); -#endif - return NULL; + return mid; } else if (res < 0) { l = mid + 1; } else { h = mid - 1; } } + return -1; +} + +// find_method looks up the name/signature in the local methods array +methodOop instanceKlass::find_method(Symbol* name, Symbol* signature) const { + return instanceKlass::find_method(methods(), name, signature); +} + +// find_instance_method looks up the name/signature in the local methods array +// and skips over static methods +methodOop instanceKlass::find_instance_method(Symbol* name, Symbol* signature) { + return instanceKlass::find_instance_method(methods(), name, signature); +} + +// find_instance_method looks up the name/signature in the local methods array +// and skips over static methods +methodOop instanceKlass::find_instance_method(objArrayOop methods, Symbol* name, Symbol* signature) { + methodOop meth = instanceKlass::find_method_impl(methods, name, signature, true); + return meth; +} + +// find_method looks up the name/signature in the local methods array +methodOop instanceKlass::find_method(objArrayOop methods, Symbol* name, Symbol* signature) { + return instanceKlass::find_method_impl(methods, name, signature, false); +} + +methodOop instanceKlass::find_method_impl(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static) { + int hit = find_method_index(methods, name, signature, skipping_static); + return hit >= 0 ? (methodOop) methods->obj_at(hit): NULL; +} + +bool instanceKlass::method_matches(methodOop m, Symbol* signature, bool skipping_static) { + return (m->signature() == signature) && (!skipping_static || !m->is_static()); +} + +// Used indirectly by find_method +// find_method_index looks in the local methods array to return the index +// of the matching name/signature +int instanceKlass::find_method_index(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static) { + int hit = binary_search(methods, name); + if (hit != -1) { + methodOop m = (methodOop) methods->obj_at(hit); + + // Do linear search to find matching signature. First, quick check + // for common case + if (method_matches(m, signature, skipping_static)) return hit; + // search downwards through overloaded methods + int i; + for (i = hit - 1; i >= 0; --i) { + methodOop m = (methodOop) methods->obj_at(i); + assert(m->is_method(), "must be method"); + if (m->name() != name) break; + if (method_matches(m, signature, skipping_static)) return i; + } + // search upwards + for (i = hit + 1; i < methods->length(); ++i) { + methodOop m = (methodOop) methods->obj_at(i); + assert(m->is_method(), "must be method"); + if (m->name() != name) break; + if (method_matches(m, signature, skipping_static)) return i; + } + // not found #ifdef ASSERT - int index = linear_search(methods, name, signature); - assert(index == -1, err_msg("binary search should have found entry %d", index)); + int index = skipping_static ? -1 : linear_search(methods, name, signature); + assert(index == -1, err_msg("binary search should have found entry %d", index)); #endif - return NULL; + } + return -1; +} +int instanceKlass::find_method_by_name(Symbol* name, int* end) { + return find_method_by_name(methods(), name, end); } +int instanceKlass::find_method_by_name(objArrayOop methods, Symbol* name, int* end_ptr) { + assert(end_ptr != NULL, "just checking"); + int start = binary_search(methods, name); + int end = start + 1; + if (start != -1) { + while (start - 1 >= 0 && ((methodOop)(methods->obj_at(start - 1)))->name() == name) --start; + while (end < methods->length() && ((methodOop)(methods->obj_at(end)))->name() == name) ++end; + *end_ptr = end; + return start; + } + return -1; +} + +// lookup_method searches both the local methods array and all superclasses methods arrays methodOop instanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature) const { klassOop klass = as_klassOop(); while (klass != NULL) {
--- a/src/share/vm/oops/instanceKlass.hpp Thu Apr 19 04:49:54 2018 +0100 +++ b/src/share/vm/oops/instanceKlass.hpp Thu Apr 19 17:55:26 2018 +0100 @@ -494,6 +494,16 @@ methodOop find_method(Symbol* name, Symbol* signature) const; static methodOop find_method(objArrayOop methods, Symbol* name, Symbol* signature); + // find a local method, but skip static methods + methodOop find_instance_method(Symbol* name, Symbol* signature); + static methodOop find_instance_method(objArrayOop methods, Symbol* name, Symbol* signature); + + // true if method matches signature and conforms to skipping_X conditions. + static bool method_matches(methodOop m, Symbol* signature, bool skipping_static); + + // find a local method index in default_methods (returns -1 if not found) + static int find_method_index(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static); + // lookup operation (returns NULL if not found) methodOop uncached_lookup_method(Symbol* name, Symbol* signature) const; @@ -501,6 +511,13 @@ // (returns NULL if not found) methodOop lookup_method_in_all_interfaces(Symbol* name, Symbol* signature) const; + // Find method indices by name. If a method with the specified name is + // found the index to the first method is returned, and 'end' is filled in + // with the index of first non-name-matching method. If no method is found + // -1 is returned. + int find_method_by_name(Symbol* name, int* end); + static int find_method_by_name(objArrayOop methods, Symbol* name, int* end); + // constant pool constantPoolOop constants() const { return _constants; } void set_constants(constantPoolOop c) { oop_store_without_check((oop*) &_constants, (oop) c); } @@ -973,6 +990,9 @@ // Returns the array class with this class as element type klassOop array_klass_impl(bool or_null, TRAPS); + // find a local method (returns NULL if not found) + static methodOop find_method_impl(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static); + public: // sharing support virtual void remove_unshareable_info();
--- a/src/share/vm/oops/klass.cpp Thu Apr 19 04:49:54 2018 +0100 +++ b/src/share/vm/oops/klass.cpp Thu Apr 19 17:55:26 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. 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 @@ -36,6 +36,19 @@ #include "runtime/atomic.hpp" #include "trace/traceMacros.hpp" +bool Klass::is_cloneable() const { + return _access_flags.is_cloneable() || + is_subtype_of(SystemDictionary::Cloneable_klass()); +} + +void Klass::set_is_cloneable() { + if (oop_is_instance() && instanceKlass::cast(this->as_klassOop())->reference_type() != REF_NONE) { + // Reference cloning should not be intrinsified and always happen in JVM_Clone. + } else { + _access_flags.set_is_cloneable(); + } +} + void Klass::set_name(Symbol* n) { _name = n; if (_name != NULL) _name->increment_refcount();
--- a/src/share/vm/oops/klass.hpp Thu Apr 19 04:49:54 2018 +0100 +++ b/src/share/vm/oops/klass.hpp Thu Apr 19 17:55:26 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. 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 @@ -673,8 +673,8 @@ bool has_final_method() const { return _access_flags.has_final_method(); } void set_has_finalizer() { _access_flags.set_has_finalizer(); } void set_has_final_method() { _access_flags.set_has_final_method(); } - bool is_cloneable() const { return _access_flags.is_cloneable(); } - void set_is_cloneable() { _access_flags.set_is_cloneable(); } + bool is_cloneable() const; + void set_is_cloneable(); bool has_vanilla_constructor() const { return _access_flags.has_vanilla_constructor(); } void set_has_vanilla_constructor() { _access_flags.set_has_vanilla_constructor(); } bool has_miranda_methods () const { return access_flags().has_miranda_methods(); }
--- a/src/share/vm/oops/methodOop.cpp Thu Apr 19 04:49:54 2018 +0100 +++ b/src/share/vm/oops/methodOop.cpp Thu Apr 19 17:55:26 2018 +0100 @@ -1122,13 +1122,13 @@ // because we are not loading from core libraries // exception: the AES intrinsics come from lib/ext/sunjce_provider.jar // which does not use the class default class loader so we check for its loader here - if ((instanceKlass::cast(holder)->class_loader() != NULL) && - instanceKlass::cast(holder)->class_loader()->klass()->klass_part()->name() != vmSymbols::sun_misc_Launcher_ExtClassLoader()) { + instanceKlass* ik = instanceKlass::cast(holder); + if ((ik->class_loader() != NULL) && !SystemDictionary::is_ext_class_loader(ik->class_loader())) { return vmSymbols::NO_SID; // regardless of name, no intrinsics here } // see if the klass name is well-known: - Symbol* klass_name = instanceKlass::cast(holder)->name(); + Symbol* klass_name = ik->name(); return vmSymbols::find_sid(klass_name); }
--- a/src/share/vm/prims/jvm.cpp Thu Apr 19 04:49:54 2018 +0100 +++ b/src/share/vm/prims/jvm.cpp Thu Apr 19 17:55:26 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. 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 @@ -31,6 +31,7 @@ #include "classfile/vmSymbols.hpp" #include "gc_interface/collectedHeap.inline.hpp" #include "memory/oopFactory.hpp" +#include "memory/referenceType.hpp" #include "memory/universe.inline.hpp" #include "oops/fieldStreams.hpp" #include "oops/instanceKlass.hpp" @@ -82,6 +83,10 @@ # include "jvm_bsd.h" #endif +#ifndef SERIALGC +#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" +#endif // !SERIALGC + #include <errno.h> #ifndef USDT2 @@ -574,6 +579,28 @@ JVM_END +static void fixup_cloned_reference(ReferenceType ref_type, oop src, oop clone) { + // If G1 is enabled then we need to register a non-null referent + // with the SATB barrier. +#ifndef SERIALGC + if (UseG1GC) { + oop referent = java_lang_ref_Reference::referent(clone); + if (referent != NULL) { + G1SATBCardTableModRefBS::enqueue(referent); + } + } +#endif // !SERIALGC + if ((java_lang_ref_Reference::next(clone) != NULL) || + (java_lang_ref_Reference::queue(clone) == java_lang_ref_ReferenceQueue::ENQUEUED_queue())) { + // If the source has been enqueued or is being enqueued, don't + // register the clone with a queue. + java_lang_ref_Reference::set_queue(clone, java_lang_ref_ReferenceQueue::NULL_queue()); + } + // discovered and next are list links; the clone is not in those lists. + java_lang_ref_Reference::set_discovered(clone, NULL); + java_lang_ref_Reference::set_next(clone, NULL); +} + JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle)) JVMWrapper("JVM_Clone"); Handle obj(THREAD, JNIHandles::resolve_non_null(handle)); @@ -599,12 +626,17 @@ } // Make shallow object copy + ReferenceType ref_type = REF_NONE; const int size = obj->size(); oop new_obj_oop = NULL; if (obj->is_javaArray()) { const int length = ((arrayOop)obj())->length(); new_obj_oop = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL); } else { + ref_type = instanceKlass::cast(klass())->reference_type(); + assert((ref_type == REF_NONE) == + !klass->is_subclass_of(SystemDictionary::Reference_klass()), + "invariant"); new_obj_oop = CollectedHeap::obj_allocate(klass, size, CHECK_NULL); } // 4839641 (4840070): We must do an oop-atomic copy, because if another thread @@ -627,6 +659,12 @@ assert(bs->has_write_region_opt(), "Barrier set does not have write_region"); bs->write_region(MemRegion((HeapWord*)new_obj_oop, size)); + // If cloning a Reference, set Reference fields to a safe state. + // Fixup must be completed before any safepoint. + if (ref_type != REF_NONE) { + fixup_cloned_reference(ref_type, obj(), new_obj_oop); + } + Handle new_obj(THREAD, new_obj_oop); // Special handling for MemberNames. Since they contain Method* metadata, they // must be registered so that RedefineClasses can fix metadata contained in them. @@ -3488,8 +3526,9 @@ JVM_END -// Return the first non-null class loader up the execution stack, or null -// if only code from the null class loader is on the stack. +// Returns first non-privileged class loader on the stack (excluding reflection +// generated frames) or null if only classes loaded by the boot class loader +// and extension class loader are found on the stack. JVM_ENTRY(jobject, JVM_LatestUserDefinedLoader(JNIEnv *env)) for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) { @@ -3497,7 +3536,7 @@ vfst.skip_reflection_related_frames(); // Only needed for 1.4 reflection klassOop holder = vfst.method()->method_holder(); oop loader = instanceKlass::cast(holder)->class_loader(); - if (loader != NULL) { + if (loader != NULL && !SystemDictionary::is_ext_class_loader(loader)) { return JNIHandles::make_local(env, loader); } }