OpenJDK / jdk / jdk
changeset 40518:eb9dfc05f8c6
Merge
author | duke |
---|---|
date | Wed, 05 Jul 2017 22:07:28 +0200 |
parents | 611ca58fca75 7833915c1537 |
children | e17429a7e843 |
files | jdk/src/java.base/share/classes/java/lang/reflect/AbstractClassLoaderValue.java jdk/src/java.base/share/classes/java/lang/reflect/ClassLoaderValue.java jdk/src/java.desktop/share/classes/sun/java2d/marlin/ArrayCache.java jdk/test/java/lang/reflect/ClassLoaderValue/Driver.java jdk/test/java/lang/reflect/ClassLoaderValue/java.base/java/lang/reflect/ClassLoaderValueTest.java |
diffstat | 619 files changed, 17339 insertions(+), 10866 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags-top-repo Mon Aug 22 18:19:31 2016 +0200 +++ b/.hgtags-top-repo Wed Jul 05 22:07:28 2017 +0200 @@ -374,3 +374,4 @@ f5902d3841b82cac6e7716a20c24e8e916fb14a8 jdk-9+129 d94d54a3192fea79234c3ac55cd0b4052d45e954 jdk-9+130 8728756c2f70a79a90188f4019cfd6b9a275765c jdk-9+131 +a24702d4d5ab0015a5c553ed57f66fce7d85155e jdk-9+132
--- a/common/autoconf/spec.gmk.in Mon Aug 22 18:19:31 2016 +0200 +++ b/common/autoconf/spec.gmk.in Wed Jul 05 22:07:28 2017 +0200 @@ -251,8 +251,6 @@ # Legacy support USE_NEW_HOTSPOT_BUILD:=@USE_NEW_HOTSPOT_BUILD@ -MACOSX_UNIVERSAL=@MACOSX_UNIVERSAL@ - # JDK_OUTPUTDIR specifies where a working jvm is built. # You can run $(JDK_OUTPUTDIR)/bin/java # Though the layout of the contents of $(JDK_OUTPUTDIR) is not
--- a/corba/.hgtags Mon Aug 22 18:19:31 2016 +0200 +++ b/corba/.hgtags Wed Jul 05 22:07:28 2017 +0200 @@ -374,3 +374,4 @@ c3e83ccab3bb1733ae903d681879a33f85ed465c jdk-9+129 77f9692d5976ae155773dd3e07533616bb95bae1 jdk-9+130 f7e1d5337c2e550fe553df7a3886bbed80292ecd jdk-9+131 +1ab4b9399c4cba584f66c1c088188f2f565fbf9c jdk-9+132
--- a/corba/src/java.corba/share/classes/module-info.java Mon Aug 22 18:19:31 2016 +0200 +++ b/corba/src/java.corba/share/classes/module-info.java Wed Jul 05 22:07:28 2017 +0200 @@ -23,6 +23,9 @@ * questions. */ +/** + * Defines the Java binding of the OMG CORBA APIs, and the RMI-IIOP API. + */ module java.corba { requires public java.desktop; requires public java.rmi;
--- a/hotspot/.hgtags Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/.hgtags Wed Jul 05 22:07:28 2017 +0200 @@ -534,3 +534,4 @@ e96b34b76d863ed1fa04e0eeb3f297ac17b490fd jdk-9+129 7d54c7056328b6a2bf4877458b8f4d8cd870f93b jdk-9+130 943bf73b49c33c2d7cbd796f6a4ae3c7a00ae932 jdk-9+131 +713951c08aa26813375175c2ab6cc99ff2a56903 jdk-9+132
--- a/hotspot/make/Dist.gmk Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/make/Dist.gmk Wed Jul 05 22:07:28 2017 +0200 @@ -46,15 +46,6 @@ endif ################################################################################ -# Functions to setup copying of files for variants - -# Support macro for SetupDistLibFile -define macosx_universalize - $(MKDIR) -p $(@D) - $(LIPO) -create -output $@ $< -endef - -################################################################################ # Setup make rules to copy a native library and associated data. # # Parameter 1 is the name of the rule. This name is used as variable prefix, @@ -74,16 +65,9 @@ $1_LIB_NAME := $(LIBRARY_PREFIX)$$($1_NAME) $1_TARGET_DIR := $$(DIST_OUTPUTDIR)/$$(LIB_SUBDIR)/$$($1_VARIANT_TARGET_DIR) - ifeq ($(OPENJDK_TARGET_OS), macosx) - # We must use the 'universalize' macro to run lipo on shared libraries, at - # least until JDK-8069540 is fixed. - $1_MACRO := macosx_universalize - endif - # Copy the the native library. $$(eval $$(call SetupCopyFiles, $1_COPY_LIB, \ DEST := $$($1_TARGET_DIR), \ - MACRO := $$($1_MACRO), \ FILES := $$(wildcard \ $$($1_SRC_DIR)/$$($1_LIB_NAME)$(SHARED_LIBRARY_SUFFIX)), \ ))
--- a/hotspot/make/test/JtregNative.gmk Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/make/test/JtregNative.gmk Wed Jul 05 22:07:28 2017 +0200 @@ -50,7 +50,6 @@ $(HOTSPOT_TOPDIR)/test/runtime/BoolReturn \ $(HOTSPOT_TOPDIR)/test/compiler/floatingpoint/ \ $(HOTSPOT_TOPDIR)/test/compiler/calls \ - $(HOTSPOT_TOPDIR)/test/compiler/native \ $(HOTSPOT_TOPDIR)/test/serviceability/jvmti/GetNamedModule \ $(HOTSPOT_TOPDIR)/test/testlibrary/jvmti \ $(HOTSPOT_TOPDIR)/test/compiler/jvmci/jdk.vm.ci.code.test \
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -110,17 +110,7 @@ // Entry frame checks if (is_entry_frame()) { // an entry frame must have a valid fp. - - if (!fp_safe) return false; - - // Validate the JavaCallWrapper an entry frame must have - - address jcw = (address)entry_frame_call_wrapper(); - - bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > fp); - - return jcw_safe; - + return fp_safe && is_entry_frame_valid(thread); } intptr_t* sender_sp = NULL; @@ -210,15 +200,8 @@ } // construct the potential sender - frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc); - - // Validate the JavaCallWrapper an entry frame must have - address jcw = (address)sender.entry_frame_call_wrapper(); - - bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > (address)sender.fp()); - - return jcw_safe; + return sender.is_entry_frame_valid(thread); } CompiledMethod* nm = sender_blob->as_compiled_method_or_null();
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -225,19 +225,7 @@ // Entry frame checks if (is_entry_frame()) { // an entry frame must have a valid fp. - - if (!fp_safe) { - return false; - } - - // Validate the JavaCallWrapper an entry frame must have - - address jcw = (address)entry_frame_call_wrapper(); - - bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > _FP); - - return jcw_safe; - + return fp_safe && is_entry_frame_valid(thread); } intptr_t* younger_sp = sp(); @@ -290,14 +278,8 @@ return false; } - if( sender.is_entry_frame()) { - // Validate the JavaCallWrapper an entry frame must have - - address jcw = (address)sender.entry_frame_call_wrapper(); - - bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > sender_fp); - - return jcw_safe; + if (sender.is_entry_frame()) { + return sender.is_entry_frame_valid(thread); } // If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size @@ -357,12 +339,6 @@ _cb = CodeCache::find_blob(_pc); } _deopt_state = unknown; -#ifdef ASSERT - if ( _cb != NULL && _cb->is_compiled()) { - // Without a valid unextended_sp() we can't convert the pc to "original" - assert(!((CompiledMethod*)_cb)->is_deopt_pc(_pc), "invariant broken"); - } -#endif // ASSERT } frame::frame(intptr_t* sp, unpatchable_t, address pc, CodeBlob* cb) { @@ -534,6 +510,7 @@ void frame::patch_pc(Thread* thread, address pc) { + vmassert(_deopt_state != unknown, "frame is unpatchable"); if(thread == Thread::current()) { StubRoutines::Sparc::flush_callers_register_windows_func()(); }
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -108,17 +108,7 @@ // Entry frame checks if (is_entry_frame()) { // an entry frame must have a valid fp. - - if (!fp_safe) return false; - - // Validate the JavaCallWrapper an entry frame must have - - address jcw = (address)entry_frame_call_wrapper(); - - bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > fp); - - return jcw_safe; - + return fp_safe && is_entry_frame_valid(thread); } intptr_t* sender_sp = NULL; @@ -209,15 +199,8 @@ } // construct the potential sender - frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc); - - // Validate the JavaCallWrapper an entry frame must have - address jcw = (address)sender.entry_frame_call_wrapper(); - - bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > (address)sender.fp()); - - return jcw_safe; + return sender.is_entry_frame_valid(thread); } CompiledMethod* nm = sender_blob->as_compiled_method_or_null();
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -1071,6 +1071,9 @@ NOT_LP64(get_thread(rthread);) + cmpl(Address(rthread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_enabled); + jcc(Assembler::equal, no_reserved_zone_enabling); + cmpptr(rbx, Address(rthread, JavaThread::reserved_stack_activation_offset())); jcc(Assembler::lessEqual, no_reserved_zone_enabling);
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java Wed Jul 05 22:07:28 2017 +0200 @@ -255,7 +255,8 @@ } buildAttachArgs(newArgs, pid, exe, core, false); - JStack.main(newArgs.toArray(new String[newArgs.size()])); + JStack jstack = new JStack(false, false); + jstack.runWithArgs(newArgs.toArray(new String[newArgs.size()])); } private static void runJMAP(String[] oldArgs) {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/BreakpointInfo.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/BreakpointInfo.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2016 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, 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
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/MethodCounters.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/MethodCounters.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, 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
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64Frame.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64Frame.java Wed Jul 05 22:07:28 2017 +0200 @@ -46,7 +46,6 @@ private static final int SENDER_SP_OFFSET = 0; // Interpreter frames - private static final int INTERPRETER_FRAME_MIRROR_OFFSET = -3; // for native calls only private static final int INTERPRETER_FRAME_SENDER_SP_OFFSET = -4; private static final int INTERPRETER_FRAME_LAST_SP_OFFSET = INTERPRETER_FRAME_SENDER_SP_OFFSET - 1; private static final int INTERPRETER_FRAME_MDX_OFFSET = INTERPRETER_FRAME_LAST_SP_OFFSET -1; @@ -55,7 +54,8 @@ private static final int INTERPRETER_FRAME_CACHE_OFFSET =INTERPRETER_FRAME_BCX_OFFSET - 1; private static final int INTERPRETER_FRAME_MONITORS_OFFSET = INTERPRETER_FRAME_CACHE_OFFSET - 1; private static final int INTERPRETER_FRAME_LOCALS_OFFSET = INTERPRETER_FRAME_MONITORS_OFFSET - 1; - private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1; + private static final int INTERPRETER_FRAME_MIRROR_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1; + private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_MIRROR_OFFSET - 1; private static final int INTERPRETER_FRAME_INITIAL_SP_OFFSET = INTERPRETER_FRAME_BCX_OFFSET - 1; // FIXME: probably wrong, but unused anyway private static final int INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET; private static final int INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java Wed Jul 05 22:07:28 2017 +0200 @@ -714,11 +714,7 @@ /** 2 words, also used to save float regs across calls to C */ public static final int INTERPRETER_FRAME_D_SCRATCH_FP_OFFSET = -2; public static final int INTERPRETER_FRAME_L_SCRATCH_FP_OFFSET = -4; - /** For native calls only */ - public static final int INTERPRETER_FRAME_PADDING_OFFSET = -5; - /** For native calls only */ - public static final int INTERPRETER_FRAME_MIRROR_OFFSET = -6; - /** Should be same as above, and should be zero mod 8 */ + public static final int INTERPRETER_FRAME_MIRROR_OFFSET = -5; public static final int INTERPRETER_FRAME_VM_LOCALS_FP_OFFSET = -6; public static final int INTERPRETER_FRAME_VM_LOCAL_WORDS = -INTERPRETER_FRAME_VM_LOCALS_FP_OFFSET;
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java Wed Jul 05 22:07:28 2017 +0200 @@ -48,10 +48,10 @@ private static final int SENDER_SP_OFFSET = 2; // Interpreter frames - private static final int INTERPRETER_FRAME_MIRROR_OFFSET = 2; // for native calls only private static final int INTERPRETER_FRAME_SENDER_SP_OFFSET = -1; private static final int INTERPRETER_FRAME_LAST_SP_OFFSET = INTERPRETER_FRAME_SENDER_SP_OFFSET - 1; private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_LAST_SP_OFFSET - 1; + private static int INTERPRETER_FRAME_MIRROR_OFFSET; private static int INTERPRETER_FRAME_MDX_OFFSET; // Non-core builds only private static int INTERPRETER_FRAME_CACHE_OFFSET; private static int INTERPRETER_FRAME_LOCALS_OFFSET; @@ -74,7 +74,8 @@ } private static synchronized void initialize(TypeDataBase db) { - INTERPRETER_FRAME_MDX_OFFSET = INTERPRETER_FRAME_METHOD_OFFSET - 1; + INTERPRETER_FRAME_MIRROR_OFFSET = INTERPRETER_FRAME_METHOD_OFFSET - 1; + INTERPRETER_FRAME_MDX_OFFSET = INTERPRETER_FRAME_MIRROR_OFFSET - 1; INTERPRETER_FRAME_CACHE_OFFSET = INTERPRETER_FRAME_MDX_OFFSET - 1; INTERPRETER_FRAME_LOCALS_OFFSET = INTERPRETER_FRAME_CACHE_OFFSET - 1; INTERPRETER_FRAME_BCX_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1;
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java Wed Jul 05 22:07:28 2017 +0200 @@ -26,6 +26,7 @@ import java.lang.reflect.Modifier; import java.util.*; +import java.util.stream.*; import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.oops.*; import sun.jvm.hotspot.runtime.*; @@ -204,15 +205,29 @@ } } - protected Object getHashtable(Instance oop, boolean isProperties) { + private void setPropertiesEntry(java.util.Properties p, Oop oop) { + InstanceKlass ik = (InstanceKlass)oop.getKlass(); + OopField keyField = (OopField)ik.findField("key", "Ljava/lang/Object;"); + OopField valueField = (OopField)ik.findField("val", "Ljava/lang/Object;"); + + try { + p.setProperty((String)readObject(keyField.getValue(oop)), + (String)readObject(valueField.getValue(oop))); + } catch (ClassNotFoundException ce) { + if (DEBUG) { + debugPrintStackTrace(ce); + } + } + } + + protected Object getHashtable(Instance oop) { InstanceKlass k = (InstanceKlass)oop.getKlass(); OopField tableField = (OopField)k.findField("table", "[Ljava/util/Hashtable$Entry;"); if (tableField == null) { debugPrintln("Could not find field of [Ljava/util/Hashtable$Entry;"); return null; } - java.util.Hashtable table = (isProperties) ? new java.util.Properties() - : new java.util.Hashtable(); + java.util.Hashtable table = new java.util.Hashtable(); ObjArray kvs = (ObjArray)tableField.getValue(oop); long size = kvs.getLength(); debugPrintln("Hashtable$Entry Size = " + size); @@ -225,6 +240,39 @@ return table; } + private Properties getProperties(Instance oop) { + InstanceKlass k = (InstanceKlass)oop.getKlass(); + OopField mapField = (OopField)k.findField("map", "Ljava/util/concurrent/ConcurrentHashMap;"); + if (mapField == null) { + debugPrintln("Could not find field of Ljava/util/concurrent/ConcurrentHashMap"); + return null; + } + + Instance mapObj = (Instance)mapField.getValue(oop); + if (mapObj == null) { + debugPrintln("Could not get map field from java.util.Properties"); + return null; + } + + InstanceKlass mk = (InstanceKlass)mapObj.getKlass(); + OopField tableField = (OopField)mk.findField("table", "[Ljava/util/concurrent/ConcurrentHashMap$Node;"); + if (tableField == null) { + debugPrintln("Could not find field of [Ljava/util/concurrent/ConcurrentHashMap$Node"); + return null; + } + + java.util.Properties props = new java.util.Properties(); + ObjArray kvs = (ObjArray)tableField.getValue(mapObj); + long size = kvs.getLength(); + debugPrintln("ConcurrentHashMap$Node Size = " + size); + LongStream.range(0, size) + .mapToObj(kvs::getObjAt) + .filter(o -> o != null) + .forEach(o -> setPropertiesEntry(props, o)); + + return props; + } + public Object readInstance(Instance oop) throws ClassNotFoundException { Object result = getFromObjTable(oop); if (result == null) { @@ -240,11 +288,11 @@ } if (kls.getName().equals(javaUtilHashtable())) { - return getHashtable(oop, false); + return getHashtable(oop); } if (kls.getName().equals(javaUtilProperties())) { - return getHashtable(oop, true); + return getProperties(oop); } Class clz = readClass(kls);
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Wed Jul 05 22:07:28 2017 +0200 @@ -265,9 +265,10 @@ native HotSpotResolvedObjectTypeImpl resolveTypeInPool(HotSpotConstantPool constantPool, int cpi) throws LinkageError; /** - * Looks up and attempts to resolve the {@code JVM_CONSTANT_Field} entry for at index {@code cpi} in - * {@code constantPool}. For some opcodes, checks are performed that require the {@code method} - * that contains {@code opcode} to be specified. The values returned in {@code info} are: + * Looks up and attempts to resolve the {@code JVM_CONSTANT_Field} entry for at index + * {@code cpi} in {@code constantPool}. For some opcodes, checks are performed that require the + * {@code method} that contains {@code opcode} to be specified. The values returned in + * {@code info} are: * * <pre> * [(int) flags, // only valid if field is resolved @@ -556,20 +557,18 @@ native HotSpotResolvedJavaMethodImpl getResolvedJavaMethod(Object base, long displacement); /** - * Read a HotSpot ConstantPool* value from the memory location described by {@code base} plus - * {@code displacement} and return the {@link HotSpotConstantPool} wrapping it. This method does - * no checking that the memory location actually contains a valid pointer and may crash the VM - * if an invalid location is provided. If the {@code base} is null then {@code displacement} is - * used by itself. If {@code base} is a {@link HotSpotResolvedJavaMethodImpl}, - * {@link HotSpotConstantPool} or {@link HotSpotResolvedObjectTypeImpl} then the metaspace - * pointer is fetched from that object and added to {@code displacement}. Any other non-null - * object type causes an {@link IllegalArgumentException} to be thrown. + * Gets the {@code ConstantPool*} associated with {@code object} and returns a + * {@link HotSpotConstantPool} wrapping it. * - * @param base an object to read from or null - * @param displacement - * @return null or the resolved method for this location + * @param object a {@link HotSpotResolvedJavaMethodImpl} or + * {@link HotSpotResolvedObjectTypeImpl} object + * @return a {@link HotSpotConstantPool} wrapping the {@code ConstantPool*} associated with + * {@code object} + * @throws NullPointerException if {@code object == null} + * @throws IllegalArgumentException if {@code object} is neither a + * {@link HotSpotResolvedJavaMethodImpl} nor a {@link HotSpotResolvedObjectTypeImpl} */ - native HotSpotConstantPool getConstantPool(Object base, long displacement); + native HotSpotConstantPool getConstantPool(Object object); /** * Read a HotSpot Klass* value from the memory location described by {@code base} plus
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java Wed Jul 05 22:07:28 2017 +0200 @@ -121,7 +121,7 @@ if (metaspaceConstantPool == holder.getConstantPool().getMetaspaceConstantPool()) { this.constantPool = holder.getConstantPool(); } else { - this.constantPool = compilerToVM().getConstantPool(null, constMethod + config.constMethodConstantsOffset); + this.constantPool = compilerToVM().getConstantPool(this); } final int nameIndex = UNSAFE.getChar(constMethod + config.constMethodNameIndexOffset);
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Wed Jul 05 22:07:28 2017 +0200 @@ -445,7 +445,7 @@ * operating on the latest one and that HotSpotResolvedJavaMethodImpls will be able to * use the shared copy instead of creating their own instance. */ - constantPool = compilerToVM().getConstantPool(this, config().instanceKlassConstantsOffset); + constantPool = compilerToVM().getConstantPool(this); } return constantPool; }
--- a/hotspot/src/os/aix/vm/os_aix.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/os/aix/vm/os_aix.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -2686,7 +2686,8 @@ // - sets target osthread state to continue // - sends signal to end the sigsuspend loop in the SR_handler // -// Note that the SR_lock plays no role in this suspend/resume protocol. +// Note that the SR_lock plays no role in this suspend/resume protocol, +// but is checked for NULL in SR_handler as a thread termination indicator. // static void resume_clear_context(OSThread *osthread) { @@ -2718,9 +2719,22 @@ // after sigsuspend. int old_errno = errno; - Thread* thread = Thread::current(); + Thread* thread = Thread::current_or_null_safe(); + assert(thread != NULL, "Missing current thread in SR_handler"); + + // On some systems we have seen signal delivery get "stuck" until the signal + // mask is changed as part of thread termination. Check that the current thread + // has not already terminated (via SR_lock()) - else the following assertion + // will fail because the thread is no longer a JavaThread as the ~JavaThread + // destructor has completed. + + if (thread->SR_lock() == NULL) { + return; + } + + assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); + OSThread* osthread = thread->osthread(); - assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); os::SuspendResume::State current = osthread->sr.state(); if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -2716,7 +2716,8 @@ // - sets target osthread state to continue // - sends signal to end the sigsuspend loop in the SR_handler // -// Note that the SR_lock plays no role in this suspend/resume protocol. +// Note that the SR_lock plays no role in this suspend/resume protocol, +// but is checked for NULL in SR_handler as a thread termination indicator. static void resume_clear_context(OSThread *osthread) { osthread->set_ucontext(NULL); @@ -2746,9 +2747,22 @@ // after sigsuspend. int old_errno = errno; - Thread* thread = Thread::current(); + Thread* thread = Thread::current_or_null_safe(); + assert(thread != NULL, "Missing current thread in SR_handler"); + + // On some systems we have seen signal delivery get "stuck" until the signal + // mask is changed as part of thread termination. Check that the current thread + // has not already terminated (via SR_lock()) - else the following assertion + // will fail because the thread is no longer a JavaThread as the ~JavaThread + // destructor has completed. + + if (thread->SR_lock() == NULL) { + return; + } + + assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); + OSThread* osthread = thread->osthread(); - assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); os::SuspendResume::State current = osthread->sr.state(); if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
--- a/hotspot/src/os/linux/vm/os_linux.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -3971,7 +3971,8 @@ // - sets target osthread state to continue // - sends signal to end the sigsuspend loop in the SR_handler // -// Note that the SR_lock plays no role in this suspend/resume protocol. +// Note that the SR_lock plays no role in this suspend/resume protocol, +// but is checked for NULL in SR_handler as a thread termination indicator. static void resume_clear_context(OSThread *osthread) { osthread->set_ucontext(NULL); @@ -4004,8 +4005,20 @@ Thread* thread = Thread::current_or_null_safe(); assert(thread != NULL, "Missing current thread in SR_handler"); + + // On some systems we have seen signal delivery get "stuck" until the signal + // mask is changed as part of thread termination. Check that the current thread + // has not already terminated (via SR_lock()) - else the following assertion + // will fail because the thread is no longer a JavaThread as the ~JavaThread + // destructor has completed. + + if (thread->SR_lock() == NULL) { + return; + } + + assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); + OSThread* osthread = thread->osthread(); - assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); os::SuspendResume::State current = osthread->sr.state(); if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
--- a/hotspot/src/os/posix/vm/os_posix.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/os/posix/vm/os_posix.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -93,10 +93,6 @@ } int os::get_native_stack(address* stack, int frames, int toSkip) { -#ifdef _NMT_NOINLINE_ - toSkip++; -#endif - int frame_idx = 0; int num_of_frames; // number of frames captured frame fr = os::current_frame();
--- a/hotspot/src/os/windows/vm/os_windows.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -318,9 +318,6 @@ // only supported on Windows XP or later. // int os::get_native_stack(address* stack, int frames, int toSkip) { -#ifdef _NMT_NOINLINE_ - toSkip++; -#endif int captured = RtlCaptureStackBackTrace(toSkip + 1, frames, (PVOID*)stack, NULL); for (int index = captured; index < frames; index ++) { stack[index] = NULL;
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -417,7 +417,15 @@ #else register intptr_t **ebp __asm__ (SPELL_REG_FP); #endif - return (intptr_t*) *ebp; // we want what it points to. + // ebp is for this frame (_get_previous_fp). We want the ebp for the + // caller of os::current_frame*(), so go up two frames. However, for + // optimized builds, _get_previous_fp() will be inlined, so only go + // up 1 frame in that case. +#ifdef _NMT_NOINLINE_ + return **(intptr_t***)ebp; +#else + return *ebp; +#endif }
--- a/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -238,6 +238,28 @@ } } + // Make the signal handler transaction-aware by checking the existence of a + // second (transactional) context with MSR TS bits active. If the signal is + // caught during a transaction, then just return to the HTM abort handler. + // Please refer to Linux kernel document powerpc/transactional_memory.txt, + // section "Signals". + if (uc && uc->uc_link) { + ucontext_t* second_uc = uc->uc_link; + + // MSR TS bits are 29 and 30 (Power ISA, v2.07B, Book III-S, pp. 857-858, + // 3.2.1 "Machine State Register"), however note that ISA notation for bit + // numbering is MSB 0, so for normal bit numbering (LSB 0) they come to be + // bits 33 and 34. It's not related to endianness, just a notation matter. + if (second_uc->uc_mcontext.regs->msr & 0x600000000) { + if (TraceTraps) { + tty->print_cr("caught signal in transaction, " + "ignoring to jump to abort handler"); + } + // Return control to the HTM abort handler. + return true; + } + } + JavaThread* thread = NULL; VMThread* vmthread = NULL; if (os::Linux::signal_handlers_are_installed) {
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -235,7 +235,15 @@ #else register intptr_t **ebp __asm__ (SPELL_REG_FP); #endif - return (intptr_t*) *ebp; // we want what it points to. + // ebp is for this frame (_get_previous_fp). We want the ebp for the + // caller of os::current_frame*(), so go up two frames. However, for + // optimized builds, _get_previous_fp() will be inlined, so only go + // up 1 frame in that case. +#ifdef _NMT_NOINLINE_ + return **(intptr_t***)ebp; +#else + return *ebp; +#endif }
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -292,15 +292,19 @@ frame os::current_frame() { intptr_t* fp = _get_current_fp(); // it's inlined so want current fp + // fp is for os::current_frame. We want the fp for our caller. frame myframe((intptr_t*)os::current_stack_pointer(), (intptr_t*)fp, CAST_FROM_FN_PTR(address, os::current_frame)); - if (os::is_first_C_frame(&myframe)) { + frame caller_frame = os::get_sender_for_C_frame(&myframe); + + if (os::is_first_C_frame(&caller_frame)) { // stack is not walkable frame ret; // This will be a null useless frame return ret; } else { - return os::get_sender_for_C_frame(&myframe); + // return frame for our caller's caller + return os::get_sender_for_C_frame(&caller_frame); } }
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -496,7 +496,15 @@ __asm { mov frameptr, ebp }; + // ebp (frameptr) is for this frame (_get_previous_fp). We want the ebp for the + // caller of os::current_frame*(), so go up two frames. However, for + // optimized builds, _get_previous_fp() will be inlined, so only go + // up 1 frame in that case. +#ifdef _NMT_NOINLINE_ + return **(intptr_t***)frameptr; +#else return *frameptr; +#endif } #endif // !AMD64
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -126,13 +126,17 @@ // ClassLoaderData, no other non-GC thread has knowledge of the anonymous class while // it is being defined, therefore _keep_alive is not volatile or atomic. void ClassLoaderData::inc_keep_alive() { - assert(_keep_alive >= 0, "Invalid keep alive count"); - _keep_alive++; + if (is_anonymous()) { + assert(_keep_alive >= 0, "Invalid keep alive increment count"); + _keep_alive++; + } } void ClassLoaderData::dec_keep_alive() { - assert(_keep_alive > 0, "Invalid keep alive count"); - _keep_alive--; + if (is_anonymous()) { + assert(_keep_alive > 0, "Invalid keep alive decrement count"); + _keep_alive--; + } } void ClassLoaderData::oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) { @@ -1173,7 +1177,7 @@ if (class_loader() == NULL) { out->print("NULL class_loader"); } else { - out->print("class loader " INTPTR_FORMAT, p2i(this)); + out->print("class loader " INTPTR_FORMAT " ", p2i(this)); class_loader()->print_value_on(out); } }
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp Wed Jul 05 22:07:28 2017 +0200 @@ -176,9 +176,9 @@ Mutex* _metaspace_lock; // Locks the metaspace for allocations and setup. bool _unloading; // true if this class loader goes away bool _is_anonymous; // if this CLD is for an anonymous class - int _keep_alive; // if this CLD is kept alive without a keep_alive_object(). - // Currently used solely for anonymous classes. - // _keep_alive does not need to be volatile or + s2 _keep_alive; // if this CLD is kept alive without a keep_alive_object(). + // Used for anonymous classes and the boot class + // loader. _keep_alive does not need to be volatile or // atomic since there is one unique CLD per anonymous class. volatile int _claimed; // true if claimed, for example during GC traces. // To avoid applying oop closure more than once. @@ -289,6 +289,8 @@ return _unloading; } + // Used to refcount an anonymous class's CLD in order to + // indicate their aliveness without a keep_alive_object(). void inc_keep_alive(); void dec_keep_alive();
--- a/hotspot/src/share/vm/code/dependencies.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/code/dependencies.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -1082,12 +1082,11 @@ if (!(m->is_public() || m->is_protected())) // The override story is complex when packages get involved. return true; // Must punt the assertion to true. - Klass* k = ctxk; - Method* lm = k->lookup_method(m->name(), m->signature()); - if (lm == NULL && k->is_instance_klass()) { + Method* lm = ctxk->lookup_method(m->name(), m->signature()); + if (lm == NULL && ctxk->is_instance_klass()) { // It might be an interface method - lm = InstanceKlass::cast(k)->lookup_method_in_ordered_interfaces(m->name(), - m->signature()); + lm = InstanceKlass::cast(ctxk)->lookup_method_in_ordered_interfaces(m->name(), + m->signature()); } if (lm == m) // Method m is inherited into ctxk. @@ -1101,11 +1100,19 @@ // Static methods don't override non-static so punt return true; } - if ( !Dependencies::is_concrete_method(lm, k) - && !Dependencies::is_concrete_method(m, ctxk) - && lm->method_holder()->is_subtype_of(m->method_holder())) - // Method m is overridden by lm, but both are non-concrete. - return true; + if (!Dependencies::is_concrete_method(lm, ctxk) && + !Dependencies::is_concrete_method(m, ctxk)) { + // They are both non-concrete + if (lm->method_holder()->is_subtype_of(m->method_holder())) { + // Method m is overridden by lm, but both are non-concrete. + return true; + } + if (lm->method_holder()->is_interface() && m->method_holder()->is_interface() && + ctxk->is_subtype_of(m->method_holder()) && ctxk->is_subtype_of(lm->method_holder())) { + // Interface method defined in multiple super interfaces + return true; + } + } } ResourceMark rm; tty->print_cr("Dependency method not found in the associated context:");
--- a/hotspot/src/share/vm/gc/g1/g1Analytics.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1Analytics.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -316,8 +316,12 @@ return get_new_size_prediction(_pending_cards_seq); } +double G1Analytics::oldest_known_gc_end_time_sec() const { + return _recent_prev_end_times_for_all_gcs_sec->oldest(); +} + double G1Analytics::last_known_gc_end_time_sec() const { - return _recent_prev_end_times_for_all_gcs_sec->oldest(); + return _recent_prev_end_times_for_all_gcs_sec->last(); } void G1Analytics::update_recent_gc_times(double end_time_sec,
--- a/hotspot/src/share/vm/gc/g1/g1Analytics.hpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1Analytics.hpp Wed Jul 05 22:07:28 2017 +0200 @@ -155,6 +155,7 @@ void update_recent_gc_times(double end_time_sec, double elapsed_ms); void compute_pause_time_ratio(double interval_ms, double pause_time_ms); + double oldest_known_gc_end_time_sec() const; double last_known_gc_end_time_sec() const; };
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -28,6 +28,7 @@ #include "classfile/symbolTable.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" +#include "gc/g1/g1Analytics.hpp" #include "gc/g1/bufferingOopClosure.hpp" #include "gc/g1/concurrentG1Refine.hpp" #include "gc/g1/concurrentG1RefineThread.hpp" @@ -2473,8 +2474,19 @@ } jlong G1CollectedHeap::millis_since_last_gc() { - // assert(false, "NYI"); - return 0; + jlong now = os::elapsed_counter() / NANOSECS_PER_MILLISEC; + const G1Analytics* analytics = _g1_policy->analytics(); + double last = analytics->last_known_gc_end_time_sec(); + jlong ret_val = now - (last * 1000); + if (ret_val < 0) { + // See the notes in GenCollectedHeap::millis_since_last_gc() + // for more information about the implementation. + log_warning(gc)("Detected clock going backwards. " + "Milliseconds since last GC would be " JLONG_FORMAT + ". returning zero instead.", ret_val); + return 0; + } + return ret_val; } void G1CollectedHeap::prepare_for_verify() {
--- a/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -604,7 +604,7 @@ _analytics->report_alloc_rate_ms(alloc_rate_ms); double interval_ms = - (end_time_sec - _analytics->last_known_gc_end_time_sec()) * 1000.0; + (end_time_sec - _analytics->oldest_known_gc_end_time_sec()) * 1000.0; _analytics->update_recent_gc_times(end_time_sec, pause_time_ms); _analytics->compute_pause_time_ratio(interval_ms, pause_time_ms); }
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -1256,21 +1256,21 @@ }; jlong GenCollectedHeap::millis_since_last_gc() { - // We need a monotonically non-decreasing time in ms but - // os::javaTimeMillis() does not guarantee monotonicity. + // javaTimeNanos() is guaranteed to be monotonically non-decreasing + // provided the underlying platform provides such a time source + // (and it is bug free). So we still have to guard against getting + // back a time later than 'now'. jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC; GenTimeOfLastGCClosure tolgc_cl(now); // iterate over generations getting the oldest // time that a generation was collected generation_iterate(&tolgc_cl, false); - // javaTimeNanos() is guaranteed to be monotonically non-decreasing - // provided the underlying platform provides such a time source - // (and it is bug free). So we still have to guard against getting - // back a time later than 'now'. jlong retVal = now - tolgc_cl.time(); if (retVal < 0) { - NOT_PRODUCT(log_warning(gc)("time warp: " JLONG_FORMAT, retVal);) + log_warning(gc)("Detected clock going backwards. " + "Milliseconds since last GC would be " JLONG_FORMAT + ". returning zero instead.", retVal); return 0; } return retVal;
--- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -461,31 +461,26 @@ return JNIHandles::make_local(THREAD, result); } -C2V_VMENTRY(jobject, getConstantPool, (JNIEnv *, jobject, jobject base, jlong offset)) +C2V_VMENTRY(jobject, getConstantPool, (JNIEnv *, jobject, jobject object_handle)) constantPoolHandle cp; - oop base_object = JNIHandles::resolve(base); - jlong base_address = 0; - if (base_object != NULL) { - if (base_object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) { - base_address = HotSpotResolvedJavaMethodImpl::metaspaceMethod(base_object); - } else if (base_object->is_a(SystemDictionary::HotSpotConstantPool_klass())) { - base_address = HotSpotConstantPool::metaspaceConstantPool(base_object); - } else if (base_object->is_a(SystemDictionary::HotSpotResolvedObjectTypeImpl_klass())) { - base_address = (jlong) CompilerToVM::asKlass(base_object); - } else { - THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), - err_msg("Unexpected type: %s", base_object->klass()->external_name())); - } + oop object = JNIHandles::resolve(object_handle); + if (object == NULL) { + THROW_0(vmSymbols::java_lang_NullPointerException()); } - cp = *((ConstantPool**) (intptr_t) (base_address + offset)); - if (!cp.is_null()) { - JavaValue method_result(T_OBJECT); - JavaCallArguments args; - args.push_long((jlong) (address) cp()); - JavaCalls::call_static(&method_result, SystemDictionary::HotSpotConstantPool_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::constantPool_fromMetaspace_signature(), &args, CHECK_NULL); - return JNIHandles::make_local(THREAD, (oop)method_result.get_jobject()); + if (object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) { + cp = CompilerToVM::asMethod(object)->constMethod()->constants(); + } else if (object->is_a(SystemDictionary::HotSpotResolvedObjectTypeImpl_klass())) { + cp = InstanceKlass::cast(CompilerToVM::asKlass(object))->constants(); + } else { + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), + err_msg("Unexpected type: %s", object->klass()->external_name())); } - return NULL; + assert(!cp.is_null(), "npe"); + JavaValue method_result(T_OBJECT); + JavaCallArguments args; + args.push_long((jlong) (address) cp()); + JavaCalls::call_static(&method_result, SystemDictionary::HotSpotConstantPool_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::constantPool_fromMetaspace_signature(), &args, CHECK_NULL); + return JNIHandles::make_local(THREAD, (oop)method_result.get_jobject()); } C2V_VMENTRY(jobject, getResolvedJavaType, (JNIEnv *, jobject, jobject base, jlong offset, jboolean compressed)) @@ -1522,7 +1517,7 @@ {CC "getMaxCallTargetOffset", CC "(J)J", FN_PTR(getMaxCallTargetOffset)}, {CC "getResolvedJavaMethodAtSlot", CC "(" CLASS "I)" HS_RESOLVED_METHOD, FN_PTR(getResolvedJavaMethodAtSlot)}, {CC "getResolvedJavaMethod", CC "(Ljava/lang/Object;J)" HS_RESOLVED_METHOD, FN_PTR(getResolvedJavaMethod)}, - {CC "getConstantPool", CC "(Ljava/lang/Object;J)" HS_CONSTANT_POOL, FN_PTR(getConstantPool)}, + {CC "getConstantPool", CC "(Ljava/lang/Object;)" HS_CONSTANT_POOL, FN_PTR(getConstantPool)}, {CC "getResolvedJavaType", CC "(Ljava/lang/Object;JZ)" HS_RESOLVED_KLASS, FN_PTR(getResolvedJavaType)}, {CC "readConfiguration", CC "()[" OBJECT, FN_PTR(readConfiguration)}, {CC "installCode", CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE HS_SPECULATION_LOG ")I", FN_PTR(installCode)},
--- a/hotspot/src/share/vm/logging/logTagSet.hpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/logging/logTagSet.hpp Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, 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
--- a/hotspot/src/share/vm/oops/methodCounters.hpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/oops/methodCounters.hpp Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, 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
--- a/hotspot/src/share/vm/opto/arraycopynode.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/opto/arraycopynode.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -630,6 +630,12 @@ } bool ArrayCopyNode::may_modify_helper(const TypeOopPtr *t_oop, Node* n, PhaseTransform *phase, ArrayCopyNode*& ac) { + if (n->Opcode() == Op_StoreCM || + n->Opcode() == Op_StoreB) { + // Ignore card mark stores + n = n->in(MemNode::Memory); + } + if (n->is_Proj()) { n = n->in(0); if (n->is_Call() && n->as_Call()->may_modify(t_oop, phase)) { @@ -657,9 +663,6 @@ } } } - } else if (n->Opcode() == Op_StoreCM) { - // Ignore card mark stores - return may_modify_helper(t_oop, n->in(MemNode::Memory), phase, ac); } }
--- a/hotspot/src/share/vm/opto/cfgnode.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/opto/cfgnode.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -1703,29 +1703,51 @@ } if (uncasted) { - // Add a cast node between the phi to be removed and its unique input. + // Add cast nodes between the phi to be removed and its unique input. // Wait until after parsing for the type information to propagate from the casts. assert(can_reshape, "Invalid during parsing"); const Type* phi_type = bottom_type(); assert(phi_type->isa_int() || phi_type->isa_ptr(), "bad phi type"); - int opcode; - // Determine the type of cast to be added. + // Add casts to carry the control dependency of the Phi that is + // going away + Node* cast = NULL; if (phi_type->isa_int()) { - opcode = Op_CastII; + cast = ConstraintCastNode::make_cast(Op_CastII, r, uin, phi_type, true); } else { const Type* uin_type = phase->type(uin); - if ((phi_type->join(TypePtr::NOTNULL) == uin_type->join(TypePtr::NOTNULL)) || - (!phi_type->isa_oopptr() && !uin_type->isa_oopptr())) { - opcode = Op_CastPP; + if (!phi_type->isa_oopptr() && !uin_type->isa_oopptr()) { + cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true); } else { - opcode = Op_CheckCastPP; + // Use a CastPP for a cast to not null and a CheckCastPP for + // a cast to a new klass (and both if both null-ness and + // klass change). + + // If the type of phi is not null but the type of uin may be + // null, uin's type must be casted to not null + if (phi_type->join(TypePtr::NOTNULL) == phi_type->remove_speculative() && + uin_type->join(TypePtr::NOTNULL) != uin_type->remove_speculative()) { + cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, TypePtr::NOTNULL, true); + } + + // If the type of phi and uin, both casted to not null, + // differ the klass of uin must be (check)cast'ed to match + // that of phi + if (phi_type->join_speculative(TypePtr::NOTNULL) != uin_type->join_speculative(TypePtr::NOTNULL)) { + Node* n = uin; + if (cast != NULL) { + cast = phase->transform(cast); + n = cast; + } + cast = ConstraintCastNode::make_cast(Op_CheckCastPP, r, n, phi_type, true); + } + if (cast == NULL) { + cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true); + } } } - // Add a cast to carry the control dependency of the Phi that is - // going away - Node* cast = ConstraintCastNode::make_cast(opcode, r, uin, phi_type, true); + assert(cast != NULL, "cast should be set"); cast = phase->transform(cast); - // set all inputs to the new cast so the Phi is removed by Identity + // set all inputs to the new cast(s) so the Phi is removed by Identity PhaseIterGVN* igvn = phase->is_IterGVN(); for (uint i = 1; i < req(); i++) { set_req_X(i, cast, igvn);
--- a/hotspot/src/share/vm/prims/unsafe.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/prims/unsafe.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -861,6 +861,13 @@ } const Klass* host_klass = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(host_class)); + + // Make sure it's the real host class, not another anonymous class. + while (host_klass != NULL && host_klass->is_instance_klass() && + InstanceKlass::cast(host_klass)->is_anonymous()) { + host_klass = InstanceKlass::cast(host_klass)->host_klass(); + } + // Primitive types have NULL Klass* fields in their java.lang.Class instances. if (host_klass == NULL) { THROW_0(vmSymbols::java_lang_IllegalArgumentException());
--- a/hotspot/src/share/vm/prims/whitebox.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/prims/whitebox.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -679,7 +679,7 @@ WB_END WB_ENTRY(jboolean, WB_IsIntrinsicAvailable(JNIEnv* env, jobject o, jobject method, jobject compilation_context, jint compLevel)) - if (compLevel < CompLevel_none || compLevel > CompLevel_highest_tier) { + if (compLevel < CompLevel_none || compLevel > MIN2((CompLevel) TieredStopAtLevel, CompLevel_highest_tier)) { return false; // Intrinsic is not available on a non-existent compilation level. } jmethodID method_id, compilation_context_id; @@ -689,6 +689,7 @@ DirectiveSet* directive; AbstractCompiler* comp = CompileBroker::compiler((int)compLevel); + assert(comp != NULL, "compiler not available"); if (compilation_context != NULL) { compilation_context_id = reflected_method_to_jmid(thread, env, compilation_context); CHECK_JNI_EXCEPTION_(env, JNI_FALSE); @@ -698,7 +699,7 @@ // Calling with NULL matches default directive directive = DirectivesStack::getDefaultDirective(comp); } - bool result = CompileBroker::compiler(compLevel)->is_intrinsic_available(mh, directive); + bool result = comp->is_intrinsic_available(mh, directive); DirectivesStack::release(directive); return result; WB_END
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -55,7 +55,8 @@ // Simple log n seems to grow too slowly for tiered, try something faster: log n * log log n int log_cpu = log2_intptr(os::active_processor_count()); int loglog_cpu = log2_intptr(MAX2(log_cpu, 1)); - count = MAX2(log_cpu * loglog_cpu, 1) * 3 / 2; + count = MAX2(log_cpu * loglog_cpu * 3 / 2, 2); + FLAG_SET_ERGO(intx, CICompilerCount, count); } #else // On 32-bit systems, the number of compiler threads is limited to 3. @@ -67,12 +68,18 @@ /// available to the VM and thus cause the VM to crash. if (FLAG_IS_DEFAULT(CICompilerCount)) { count = 3; + FLAG_SET_ERGO(intx, CICompilerCount, count); } #endif - set_c1_count(MAX2(count / 3, 1)); - set_c2_count(MAX2(count - c1_count(), 1)); - FLAG_SET_ERGO(intx, CICompilerCount, c1_count() + c2_count()); + if (TieredStopAtLevel < CompLevel_full_optimization) { + // No C2 compiler thread required + set_c1_count(count); + } else { + set_c1_count(MAX2(count / 3, 1)); + set_c2_count(MAX2(count - c1_count(), 1)); + } + assert(count == c1_count() + c2_count(), "inconsistent compiler thread count"); // Some inlining tuning #ifdef X86
--- a/hotspot/src/share/vm/runtime/frame.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/runtime/frame.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -225,6 +225,19 @@ return NULL; } +bool frame::is_entry_frame_valid(JavaThread* thread) const { + // Validate the JavaCallWrapper an entry frame must have + address jcw = (address)entry_frame_call_wrapper(); + bool jcw_safe = (jcw < thread->stack_base()) && (jcw > (address)fp()); // less than stack base + if (!jcw_safe) { + return false; + } + + // Validate sp saved in the java frame anchor + JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor(); + return (jfa->last_Java_sp() > sp()); +} + bool frame::should_be_deoptimized() const { if (_deopt_state == is_deoptimized || !is_compiled_frame() ) return false;
--- a/hotspot/src/share/vm/runtime/frame.hpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/runtime/frame.hpp Wed Jul 05 22:07:28 2017 +0200 @@ -166,6 +166,8 @@ frame sender_for_interpreter_frame(RegisterMap* map) const; frame sender_for_native_frame(RegisterMap* map) const; + bool is_entry_frame_valid(JavaThread* thread) const; + // All frames: // A low-level interface for vframes:
--- a/hotspot/src/share/vm/runtime/globals.hpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 22:07:28 2017 +0200 @@ -2411,7 +2411,7 @@ product(intx, CICompilerCount, CI_COMPILER_COUNT, \ "Number of compiler threads to run") \ range(0, max_jint) \ - constraint(CICompilerCountConstraintFunc, AtParse) \ + constraint(CICompilerCountConstraintFunc, AfterErgo) \ \ product(intx, CompilationPolicyChoice, 0, \ "which compilation policy (0-3)") \
--- a/hotspot/src/share/vm/runtime/reflection.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/runtime/reflection.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -660,11 +660,13 @@ } const Klass* host_class = current_class; - while (host_class->is_instance_klass() && - InstanceKlass::cast(host_class)->is_anonymous()) { - const Klass* next_host_class = InstanceKlass::cast(host_class)->host_klass(); - if (next_host_class == NULL) break; - host_class = next_host_class; + if (host_class->is_instance_klass() && + InstanceKlass::cast(host_class)->is_anonymous()) { + host_class = InstanceKlass::cast(host_class)->host_klass(); + assert(host_class != NULL, "Anonymous class has null host class"); + assert(!(host_class->is_instance_klass() && + InstanceKlass::cast(host_class)->is_anonymous()), + "host_class should not be anonymous"); } if (host_class == field_class) { return true;
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -147,12 +147,18 @@ // performed on 32-bit systems because it can lead to exhaustion // of the virtual memory address space available to the JVM. if (CICompilerCountPerCPU) { - count = MAX2(log2_intptr(os::active_processor_count()), 1) * 3 / 2; + count = MAX2(log2_intptr(os::active_processor_count()) * 3 / 2, 2); + FLAG_SET_ERGO(intx, CICompilerCount, count); } #endif - set_c1_count(MAX2(count / 3, 1)); - set_c2_count(MAX2(count - c1_count(), 1)); - FLAG_SET_ERGO(intx, CICompilerCount, c1_count() + c2_count()); + if (TieredStopAtLevel < CompLevel_full_optimization) { + // No C2 compiler thread required + set_c1_count(count); + } else { + set_c1_count(MAX2(count / 3, 1)); + set_c2_count(MAX2(count - c1_count(), 1)); + } + assert(count == c1_count() + c2_count(), "inconsistent compiler thread count"); } void SimpleThresholdPolicy::set_carry_if_necessary(InvocationCounter *counter) {
--- a/hotspot/src/share/vm/runtime/thread.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -374,11 +374,14 @@ delete handle_area(); delete metadata_handles(); + // SR_handler uses this as a termination indicator - + // needs to happen before os::free_thread() + delete _SR_lock; + _SR_lock = NULL; + // osthread() can be NULL, if creation of thread failed. if (osthread() != NULL) os::free_thread(osthread()); - delete _SR_lock; - // clear Thread::current if thread is deleting itself. // Needed to ensure JNI correctly detects non-attached threads. if (this == Thread::current()) {
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -2643,7 +2643,7 @@ /* DEFAULT_CACHE_LINE_SIZE (globalDefinitions.hpp) */ \ /***************************************************/ \ \ - declare_constant(DEFAULT_CACHE_LINE_SIZE) \ + declare_preprocessor_constant("DEFAULT_CACHE_LINE_SIZE", DEFAULT_CACHE_LINE_SIZE) \ \ declare_constant(Deoptimization::Unpack_deopt) \ declare_constant(Deoptimization::Unpack_exception) \
--- a/hotspot/src/share/vm/utilities/nativeCallStack.cpp Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/src/share/vm/utilities/nativeCallStack.cpp Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, 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 @@ -33,6 +33,19 @@ _hash_value(0) { if (fillStack) { + // We need to skip the NativeCallStack::NativeCallStack frame if a tail call is NOT used + // to call os::get_native_stack. A tail call is used if _NMT_NOINLINE_ is not defined + // (which means this is not a slowdebug build), and we are on 64-bit (except Windows). + // This is not necessarily a rule, but what has been obvserved to date. +#define TAIL_CALL (!defined(_NMT_NOINLINE_) && !defined(WINDOWS) && defined(_LP64)) +#if !TAIL_CALL + toSkip++; +#if (defined(_NMT_NOINLINE_) && defined(BSD) && defined(_LP64)) + // Mac OS X slowdebug builds have this odd behavior where NativeCallStack::NativeCallStack + // appears as two frames, so we need to skip an extra frame. + toSkip++; +#endif +#endif os::get_native_stack(_stack, NMT_TrackingStackDepth, toSkip); } else { for (int index = 0; index < NMT_TrackingStackDepth; index ++) {
--- a/hotspot/test/Makefile Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/Makefile Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1995, 2016, 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 @@ -226,6 +226,9 @@ ( \ jtregExitCode=$$? && \ _summary="$(SUMMARY_TXT)"; \ + if [ $${jtregExitCode} = 1 ] ; then \ + jtregExitCode=0; \ + fi; \ $(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST) $(EXITCODE); \ $(ECHO) "$${jtregExitCode}" > $(EXITCODE); \ if [ -r "$${_summary}" ] ; then \
--- a/hotspot/test/TEST.groups Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/TEST.groups Wed Jul 05 22:07:28 2017 +0200 @@ -167,7 +167,7 @@ gc/survivorAlignment \ runtime/InternalApi/ThreadCpuTimesDeadlock.java \ runtime/NMT/JcmdSummaryDiff.java \ - runtime/RedefineTests/RedefineAnnotations.java + runtime/RedefineTests/RedefineAnnotations.java \ serviceability/sa/jmap-hashcode/Test8028623.java \ serviceability/threads/TestFalseDeadLock.java \ compiler/codecache/jmx \ @@ -282,7 +282,7 @@ -compiler/c2/Test6905845.java \ -compiler/c2/cr6340864 \ -compiler/c2/cr6589834 \ - -compiler/c2/cr8004867 + -compiler/c2/cr8004867 \ -compiler/c2/stemmer \ -compiler/c2/Test6792161.java \ -compiler/c2/Test6603011.java \
--- a/hotspot/test/compiler/arguments/CheckCICompilerCount.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/compiler/arguments/CheckCICompilerCount.java Wed Jul 05 22:07:28 2017 +0200 @@ -23,8 +23,7 @@ /* * @test CheckCheckCICompilerCount - * @bug 8130858 - * @bug 8132525 + * @bug 8130858 8132525 8162881 * @summary Check that correct range of values for CICompilerCount are allowed depending on whether tiered is enabled or not * @library /testlibrary / * @modules java.base/jdk.internal.misc @@ -54,6 +53,13 @@ "-version" }, { + "-server", + "-XX:+PrintFlagsFinal", + "-XX:CICompilerCount=1", + "-XX:-TieredCompilation", + "-version" + }, + { "-client", "-XX:-TieredCompilation", "-XX:+PrintFlagsFinal", @@ -66,30 +72,31 @@ "-XX:+PrintFlagsFinal", "-XX:CICompilerCount=1", "-version" + }, + { + "-client", + "-XX:+PrintFlagsFinal", + "-XX:CICompilerCount=1", + "-XX:-TieredCompilation", + "-version" } }; - private static final String[][] NON_TIERED_EXPECTED_OUTPUTS = { - { + private static final String[] NON_TIERED_EXPECTED_OUTPUTS = { "CICompilerCount (0) must be at least 1", - "Improperly specified VM option 'CICompilerCount=0'" - }, - { + "intx CICompilerCount = 1 {product} {command line}", + "intx CICompilerCount = 1 {product} {command line}", + "CICompilerCount (0) must be at least 1", + "intx CICompilerCount = 1 {product} {command line}", "intx CICompilerCount = 1 {product} {command line}" - }, - { - "CICompilerCount (0) must be at least 1", - "Improperly specified VM option 'CICompilerCount=0'" - }, - { - "intx CICompilerCount = 1 {product} {command line}" - } }; private static final int[] NON_TIERED_EXIT = { 1, 0, + 0, 1, + 0, 0 }; @@ -104,6 +111,22 @@ { "-server", "-XX:+TieredCompilation", + "-XX:TieredStopAtLevel=1", + "-XX:+PrintFlagsFinal", + "-XX:CICompilerCount=1", + "-version" + }, + { + "-server", + "-XX:+TieredCompilation", + "-XX:+PrintFlagsFinal", + "-XX:CICompilerCount=1", + "-XX:TieredStopAtLevel=1", + "-version" + }, + { + "-server", + "-XX:+TieredCompilation", "-XX:+PrintFlagsFinal", "-XX:CICompilerCount=2", "-version" @@ -118,37 +141,51 @@ { "-client", "-XX:+TieredCompilation", + "-XX:TieredStopAtLevel=1", + "-XX:+PrintFlagsFinal", + "-XX:CICompilerCount=1", + "-version" + }, + { + "-client", + "-XX:+TieredCompilation", + "-XX:+PrintFlagsFinal", + "-XX:CICompilerCount=1", + "-XX:TieredStopAtLevel=1", + "-version" + }, + { + "-client", + "-XX:+TieredCompilation", "-XX:+PrintFlagsFinal", "-XX:CICompilerCount=2", "-version" } }; - private static final String[][] TIERED_EXPECTED_OUTPUTS = { - { + private static final String[] TIERED_EXPECTED_OUTPUTS = { "CICompilerCount (1) must be at least 2", - "Improperly specified VM option 'CICompilerCount=1'" - }, - { - "intx CICompilerCount = 2 {product} {command line, ergonomic}" - }, - { + "intx CICompilerCount = 1 {product} {command line}", + "intx CICompilerCount = 1 {product} {command line}", + "intx CICompilerCount = 2 {product} {command line}", "CICompilerCount (1) must be at least 2", - "Improperly specified VM option 'CICompilerCount=1'" - }, - { - "intx CICompilerCount = 2 {product} {command line, ergonomic}" - } + "intx CICompilerCount = 1 {product} {command line}", + "intx CICompilerCount = 1 {product} {command line}", + "intx CICompilerCount = 2 {product} {command line}", }; private static final int[] TIERED_EXIT = { 1, 0, + 0, + 0, 1, + 0, + 0, 0 }; - private static void verifyValidOption(String[] arguments, String[] expected_outputs, int exit, boolean tiered) throws Exception { + private static void verifyValidOption(String[] arguments, String expected_output, int exit, boolean tiered) throws Exception { ProcessBuilder pb; OutputAnalyzer out; @@ -157,9 +194,7 @@ try { out.shouldHaveExitValue(exit); - for (String expected_output : expected_outputs) { - out.shouldContain(expected_output); - } + out.shouldContain(expected_output); } catch (RuntimeException e) { // Check if tiered compilation is available in this JVM // Version. Throw exception only if it is available.
--- a/hotspot/test/compiler/arraycopy/TestEliminatedArrayCopyDeopt.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/compiler/arraycopy/TestEliminatedArrayCopyDeopt.java Wed Jul 05 22:07:28 2017 +0200 @@ -25,7 +25,6 @@ * @test * @bug 8130847 8156760 * @summary Eliminated instance/array written to by an array copy variant must be correctly initialized when reallocated at a deopt - * @ignore 8136818 * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement * compiler.arraycopy.TestEliminatedArrayCopyDeopt * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement
--- a/hotspot/test/compiler/c2/Test6792161.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/compiler/c2/Test6792161.java Wed Jul 05 22:07:28 2017 +0200 @@ -27,7 +27,7 @@ * @bug 6792161 * @summary assert("No dead instructions after post-alloc") * - * @run main/othervm/timeout=600 -Xcomp -XX:MaxInlineSize=120 compiler.c2.Test6792161 + * @run main/othervm/timeout=600 -Xcomp -XX:-TieredCompilation -XX:MaxInlineSize=120 compiler.c2.Test6792161 */ package compiler.c2;
--- a/hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java Wed Jul 05 22:07:28 2017 +0200 @@ -36,6 +36,11 @@ * -XX:CompileCommand=compileonly,null::* -XX:-UseLargePages * -XX:+SegmentedCodeCache * compiler.codecache.jmx.InitialAndMaxUsageTest + * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:CompileCommand=compileonly,null::* -XX:-UseLargePages + * -XX:-SegmentedCodeCache + * compiler.codecache.jmx.InitialAndMaxUsageTest */ package compiler.codecache.jmx; @@ -70,10 +75,16 @@ } } - private void fillWithSize(long size, List<Long> blobs) { + private void fillWithSize(long size, List<Long> blobs, MemoryPoolMXBean bean) { long blob; - while ((blob = CodeCacheUtils.WB.allocateCodeBlob(size, btype.id)) - != 0L) { + /* Don't fill too much to have space for adapters. So, stop after crossing 95% and + don't allocate in case we'll cross 97% on next allocation. We can hit situation + like 94% -> (1 allocation) -> 100% otherwise. So, check if + <Usage + allocatedSize> is less than 97%, then allocate in case it is, then, stop + further allocations with given size in case <Usage> more than 95% */ + while (((double) bean.getUsage().getUsed() + size <= (CACHE_USAGE_COEF + 0.02d) * maxSize) + && (blob = CodeCacheUtils.WB.allocateCodeBlob(size, btype.id)) != 0L + && ((double) bean.getUsage().getUsed() <= CACHE_USAGE_COEF * maxSize)) { blobs.add(blob); } } @@ -90,13 +101,13 @@ Asserts.assertEQ(initialUsage, 0L, "Unexpected initial usage"); } ArrayList<Long> blobs = new ArrayList<>(); - long minAllocationUnit = Math.max(0, CodeCacheUtils.MIN_ALLOCATION - headerSize); + long minAllocationUnit = Math.max(1, CodeCacheUtils.MIN_ALLOCATION - headerSize); /* now filling code cache with large-sized allocation first, since lots of small allocations takes too much time, so, just a small optimization */ try { for (int coef = 1000000; coef > 0; coef /= 10) { - fillWithSize(coef * minAllocationUnit, blobs); + fillWithSize(coef * minAllocationUnit, blobs, bean); } Asserts.assertGT((double) bean.getUsage().getUsed(), CACHE_USAGE_COEF * maxSize, String.format("Unable to fill "
--- a/hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java Wed Jul 05 22:07:28 2017 +0200 @@ -31,11 +31,11 @@ * @build compiler.codecache.jmx.ThresholdNotificationsTest * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing * -XX:+WhiteBoxAPI -XX:-MethodFlushing -XX:CompileCommand=compileonly,null::* * -XX:+SegmentedCodeCache * compiler.codecache.jmx.ThresholdNotificationsTest - * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing * -XX:+WhiteBoxAPI -XX:-MethodFlushing -XX:CompileCommand=compileonly,null::* * -XX:-SegmentedCodeCache * compiler.codecache.jmx.ThresholdNotificationsTest @@ -63,7 +63,9 @@ public static void main(String[] args) { for (BlobType bt : BlobType.getAvailable()) { - new ThresholdNotificationsTest(bt).runTest(); + if (CodeCacheUtils.isCodeHeapPredictable(bt)) { + new ThresholdNotificationsTest(bt).runTest(); + } } }
--- a/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededTest.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededTest.java Wed Jul 05 22:07:28 2017 +0200 @@ -63,7 +63,9 @@ public static void main(String[] args) { int iterationsCount = Integer.getInteger("jdk.test.lib.iterations", 1); for (BlobType btype : BlobType.getAvailable()) { - new UsageThresholdExceededTest(btype, iterationsCount).runTest(); + if (CodeCacheUtils.isCodeHeapPredictable(btype)) { + new UsageThresholdExceededTest(btype, iterationsCount).runTest(); + } } }
--- a/hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java Wed Jul 05 22:07:28 2017 +0200 @@ -29,9 +29,9 @@ * @modules java.base/jdk.internal.misc * java.management * + * @build compiler.codecache.jmx.UsageThresholdIncreasedTest * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @build compiler.codecache.jmx.UsageThresholdIncreasedTest * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:-UseCodeCacheFlushing -XX:-MethodFlushing * -XX:CompileCommand=compileonly,null::*
--- a/hotspot/test/compiler/codecache/stress/RandomAllocationTest.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/compiler/codecache/stress/RandomAllocationTest.java Wed Jul 05 22:07:28 2017 +0200 @@ -24,6 +24,7 @@ /* * @test RandomAllocationTest + * @key stress * @summary stressing code cache by allocating randomly sized "dummy" code blobs * @library /testlibrary /test/lib / * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/codecache/stress/UnexpectedDeoptimizationTest.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/compiler/codecache/stress/UnexpectedDeoptimizationTest.java Wed Jul 05 22:07:28 2017 +0200 @@ -24,6 +24,7 @@ /* * @test UnexpectedDeoptimizationTest + * @key stress * @summary stressing code cache by forcing unexpected deoptimizations * @library /testlibrary /test/lib / * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/codegen/aes/TestAESMain.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/compiler/codegen/aes/TestAESMain.java Wed Jul 05 22:07:28 2017 +0200 @@ -25,6 +25,7 @@ /** * @test * @bug 7184394 + * @key stress * @summary add intrinsics to use AES instructions * @library /testlibrary / * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/floatingpoint/ModNaN.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/compiler/floatingpoint/ModNaN.java Wed Jul 05 22:07:28 2017 +0200 @@ -26,7 +26,6 @@ * @bug 8015396 * @summary double a%b returns NaN for some (a,b) (|a| < inf, |b|>0) (on Core i7 980X) * - * @ignore 8145543 * @run main compiler.floatingpoint.ModNaN */
--- a/hotspot/test/compiler/intrinsics/IntrinsicAvailableTest.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/compiler/intrinsics/IntrinsicAvailableTest.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -114,7 +114,7 @@ public void test() throws Exception { Executable intrinsicMethod = testCase.getExecutable(); - if (Platform.isServer()) { + if (Platform.isServer() && (TIERED_STOP_AT_LEVEL == COMP_LEVEL_FULL_OPTIMIZATION)) { if (TIERED_COMPILATION) { checkIntrinsicForCompilationLevel(intrinsicMethod, COMP_LEVEL_SIMPLE); }
--- a/hotspot/test/compiler/intrinsics/IntrinsicDisabledTest.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/compiler/intrinsics/IntrinsicDisabledTest.java Wed Jul 05 22:07:28 2017 +0200 @@ -59,9 +59,9 @@ private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4; /* Determine if tiered compilation is enabled. */ - private static boolean isTieredCompilationEnabled() { - return Boolean.valueOf(Objects.toString(wb.getVMFlag("TieredCompilation"))); - } + private static final boolean TIERED_COMPILATION = wb.getBooleanVMFlag("TieredCompilation"); + + private static final int TIERED_STOP_AT_LEVEL = wb.getIntxVMFlag("TieredStopAtLevel").intValue(); /* This test uses several methods from jdk.internal.misc.Unsafe. The method * getMethod() returns a different Executable for each different @@ -202,8 +202,8 @@ } public static void main(String args[]) { - if (Platform.isServer()) { - if (isTieredCompilationEnabled()) { + if (Platform.isServer() && (TIERED_STOP_AT_LEVEL == COMP_LEVEL_FULL_OPTIMIZATION)) { + if (TIERED_COMPILATION) { test(COMP_LEVEL_SIMPLE); } test(COMP_LEVEL_FULL_OPTIMIZATION);
--- a/hotspot/test/compiler/jvmci/common/patches/jdk.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/compiler/jvmci/common/patches/jdk.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java Wed Jul 05 22:07:28 2017 +0200 @@ -273,8 +273,8 @@ return CTVM.getResolvedJavaMethod(base, displacement); } - public static HotSpotConstantPool getConstantPool(Object base, long displacement) { - return CTVM.getConstantPool(base, displacement); + public static HotSpotConstantPool getConstantPool(Object object) { + return CTVM.getConstantPool(object); } public static HotSpotResolvedObjectType getResolvedJavaType(Object base,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/common/testcases/DuplicateSimpleSingleImplementerInterface.java Wed Jul 05 22:07:28 2017 +0200 @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.jvmci.common.testcases; + +public interface DuplicateSimpleSingleImplementerInterface { + void interfaceMethod(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/common/testcases/MultipleSuperImplementers.java Wed Jul 05 22:07:28 2017 +0200 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.jvmci.common.testcases; + +public abstract class MultipleSuperImplementers implements DuplicateSimpleSingleImplementerInterface, SimpleSingleImplementerInterface { + public void finalize() { + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/common/testcases/SimpleSingleImplementerInterface.java Wed Jul 05 22:07:28 2017 +0200 @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.jvmci.common.testcases; + +public interface SimpleSingleImplementerInterface { + void interfaceMethod(); +}
--- a/hotspot/test/compiler/jvmci/compilerToVM/FindUniqueConcreteMethodTest.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/compiler/jvmci/compilerToVM/FindUniqueConcreteMethodTest.java Wed Jul 05 22:07:28 2017 +0200 @@ -32,6 +32,8 @@ * java.base/jdk.internal.org.objectweb.asm.tree * jdk.vm.ci/jdk.vm.ci.hotspot * jdk.vm.ci/jdk.vm.ci.code + * jdk.vm.ci/jdk.vm.ci.meta + * jdk.vm.ci/jdk.vm.ci.runtime * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @build compiler.jvmci.compilerToVM.FindUniqueConcreteMethodTest * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI @@ -41,7 +43,10 @@ package compiler.jvmci.compilerToVM; import compiler.jvmci.common.CTVMUtilities; +import compiler.jvmci.common.testcases.DuplicateSimpleSingleImplementerInterface; +import compiler.jvmci.common.testcases.SimpleSingleImplementerInterface; import compiler.jvmci.common.testcases.MultipleImplementer1; +import compiler.jvmci.common.testcases.MultipleSuperImplementers; import compiler.jvmci.common.testcases.SingleImplementer; import compiler.jvmci.common.testcases.SingleImplementerInterface; import compiler.jvmci.common.testcases.SingleSubclass; @@ -96,6 +101,11 @@ // static method result.add(new TestCase(false, SingleSubclass.class, SingleSubclass.class, "staticMethod")); + // interface method + result.add(new TestCase(false, MultipleSuperImplementers.class, + DuplicateSimpleSingleImplementerInterface.class, "interfaceMethod", false)); + result.add(new TestCase(false, MultipleSuperImplementers.class, + SimpleSingleImplementerInterface.class, "interfaceMethod", false)); return result; } @@ -103,7 +113,7 @@ System.out.println(tcase); Method method = tcase.holder.getDeclaredMethod(tcase.methodName); HotSpotResolvedJavaMethod testMethod = CTVMUtilities - .getResolvedMethod(tcase.receiver, method); + .getResolvedMethod(tcase.methodFromReceiver ? tcase.receiver : tcase.holder, method); HotSpotResolvedObjectType resolvedType = CompilerToVMHelper .lookupType(Utils.toJVMTypeSignature(tcase.receiver), getClass(), /* resolve = */ true); @@ -118,20 +128,25 @@ public final Class<?> holder; public final String methodName; public final boolean isPositive; + public final boolean methodFromReceiver; public TestCase(boolean isPositive, Class<?> clazz, Class<?> holder, - String methodName) { + String methodName, boolean methodFromReceiver) { this.receiver = clazz; this.methodName = methodName; this.isPositive = isPositive; this.holder = holder; + this.methodFromReceiver = methodFromReceiver; + } + + public TestCase(boolean isPositive, Class<?> clazz, Class<?> holder, String methodName) { + this(isPositive, clazz, holder, methodName, true); } @Override public String toString() { - return String.format("CASE: receiver=%s, holder=%s, method=%s," - + " isPositive=%s", receiver.getName(), - holder.getName(), methodName, isPositive); + return String.format("CASE: receiver=%s, holder=%s, method=%s, isPositive=%s, methodFromReceiver=%s", + receiver.getName(), holder.getName(), methodName, isPositive, methodFromReceiver); } } }
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetConstantPoolTest.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetConstantPoolTest.java Wed Jul 05 22:07:28 2017 +0200 @@ -29,187 +29,76 @@ * @library /testlibrary /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc - * @modules jdk.vm.ci/jdk.vm.ci.hotspot + * @modules java.base/jdk.internal.org.objectweb.asm + java.base/jdk.internal.org.objectweb.asm.tree + jdk.vm.ci/jdk.vm.ci.hotspot * jdk.vm.ci/jdk.vm.ci.meta + * jdk.vm.ci/jdk.vm.ci.code * * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper - * @build jdk.vm.ci/jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject * @build compiler.jvmci.compilerToVM.GetConstantPoolTest - * @build sun.hotspot.WhiteBox - * @run driver ClassFileInstaller sun.hotspot.WhiteBox - * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. - * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+UnlockDiagnosticVMOptions * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI * compiler.jvmci.compilerToVM.GetConstantPoolTest */ package compiler.jvmci.compilerToVM; -import jdk.internal.misc.Unsafe; import jdk.test.lib.Utils; +import compiler.jvmci.common.CTVMUtilities; +import compiler.jvmci.common.testcases.TestCase; import jdk.vm.ci.hotspot.CompilerToVMHelper; import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; -import jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject; +import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; import jdk.vm.ci.meta.ConstantPool; -import sun.hotspot.WhiteBox; import java.lang.reflect.Field; +import java.lang.reflect.Executable; /** * Tests for jdk.vm.ci.hotspot.CompilerToVM::getConstantPool method */ public class GetConstantPoolTest { - private static enum TestCase { - NULL_BASE { - @Override - ConstantPool getConstantPool() { - return CompilerToVMHelper.getConstantPool(null, - getPtrToCpAddress()); - } - }, - JAVA_METHOD_BASE { - @Override - ConstantPool getConstantPool() { - HotSpotResolvedJavaMethod methodInstance - = CompilerToVMHelper.getResolvedJavaMethodAtSlot( - TEST_CLASS, 0); - Field field; - try { - // jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl.metaspaceMethod - field = methodInstance.getClass() - .getDeclaredField("metaspaceMethod"); - field.setAccessible(true); - field.set(methodInstance, getPtrToCpAddress()); - } catch (ReflectiveOperationException e) { - throw new Error("TESTBUG : " + e, e); - } - return CompilerToVMHelper.getConstantPool(methodInstance, 0L); - } - }, - CONSTANT_POOL_BASE { - @Override - ConstantPool getConstantPool() { - ConstantPool cpInst; - try { - cpInst = CompilerToVMHelper.getConstantPool(null, - getPtrToCpAddress()); - Field field = CompilerToVMHelper.HotSpotConstantPoolClass() - .getDeclaredField("metaspaceConstantPool"); - field.setAccessible(true); - field.set(cpInst, getPtrToCpAddress()); - } catch (ReflectiveOperationException e) { - throw new Error("TESTBUG : " + e.getMessage(), e); - } - return CompilerToVMHelper.getConstantPool(cpInst, 0L); - } - }, - CONSTANT_POOL_BASE_IN_TWO { - @Override - ConstantPool getConstantPool() { - long ptr = getPtrToCpAddress(); - ConstantPool cpInst; - try { - cpInst = CompilerToVMHelper.getConstantPool(null, ptr); - Field field = CompilerToVMHelper.HotSpotConstantPoolClass() - .getDeclaredField("metaspaceConstantPool"); - field.setAccessible(true); - field.set(cpInst, ptr / 2L); - } catch (ReflectiveOperationException e) { - throw new Error("TESTBUG : " + e.getMessage(), e); - } - return CompilerToVMHelper.getConstantPool(cpInst, - ptr - ptr / 2L); - } - }, - CONSTANT_POOL_BASE_ZERO { - @Override - ConstantPool getConstantPool() { - long ptr = getPtrToCpAddress(); - ConstantPool cpInst; - try { - cpInst = CompilerToVMHelper.getConstantPool(null, ptr); - Field field = CompilerToVMHelper.HotSpotConstantPoolClass() - .getDeclaredField("metaspaceConstantPool"); - field.setAccessible(true); - field.set(cpInst, 0L); - } catch (ReflectiveOperationException e) { - throw new Error("TESTBUG : " + e.getMessage(), e); - } - return CompilerToVMHelper.getConstantPool(cpInst, ptr); - } - }, - ; - abstract ConstantPool getConstantPool(); + public static void testMethod(Executable executable) { + test(CTVMUtilities.getResolvedMethod(executable)); } - private static final WhiteBox WB = WhiteBox.getWhiteBox(); - private static final Unsafe UNSAFE = Utils.getUnsafe(); + public static void testClass(Class cls) { + HotSpotResolvedObjectType type = CompilerToVMHelper + .lookupType(Utils.toJVMTypeSignature(cls), + GetConstantPoolTest.class, /* resolve = */ true); + test(type); + } - private static final Class TEST_CLASS = GetConstantPoolTest.class; - private static final long CP_ADDRESS - = WB.getConstantPool(GetConstantPoolTest.class); - - public void test(TestCase testCase) { - System.out.println(testCase.name()); - ConstantPool cp = testCase.getConstantPool(); - String cpStringRep = cp.toString(); - String cpClassSimpleName - = CompilerToVMHelper.HotSpotConstantPoolClass().getSimpleName(); - if (!cpStringRep.contains(cpClassSimpleName) - || !cpStringRep.contains(TEST_CLASS.getName())) { - String msg = String.format("%s : " - + " Constant pool is not valid." - + " String representation should contain \"%s\" and \"%s\"", - testCase.name(), cpClassSimpleName, - TEST_CLASS.getName()); - throw new AssertionError(msg); - } + private static void test(Object object) { + ConstantPool cp = CompilerToVMHelper.getConstantPool(object); + System.out.println(object + " -> " + cp); } public static void main(String[] args) { - GetConstantPoolTest test = new GetConstantPoolTest(); - for (TestCase testCase : TestCase.values()) { - test.test(testCase); - } - testObjectBase(); - testMetaspaceWrapperBase(); + TestCase.getAllClasses().forEach(GetConstantPoolTest::testClass); + TestCase.getAllExecutables().forEach(GetConstantPoolTest::testMethod); + testNull(); + testObject(); } - private static void testObjectBase() { + private static void testNull() { try { - Object cp = CompilerToVMHelper.getConstantPool(new Object(), 0L); - throw new AssertionError("Test OBJECT_BASE." + Object cp = CompilerToVMHelper.getConstantPool(null); + throw new AssertionError("Test OBJECT." + + " Expected IllegalArgumentException has not been caught"); + } catch (NullPointerException npe) { + // expected + } + } + private static void testObject() { + try { + Object cp = CompilerToVMHelper.getConstantPool(new Object()); + throw new AssertionError("Test OBJECT." + " Expected IllegalArgumentException has not been caught"); } catch (IllegalArgumentException iae) { // expected } } - private static void testMetaspaceWrapperBase() { - try { - Object cp = CompilerToVMHelper.getConstantPool( - new PublicMetaspaceWrapperObject() { - @Override - public long getMetaspacePointer() { - return getPtrToCpAddress(); - } - }, 0L); - throw new AssertionError("Test METASPACE_WRAPPER_BASE." - + " Expected IllegalArgumentException has not been caught"); - } catch (IllegalArgumentException iae) { - // expected - } - } - - private static long getPtrToCpAddress() { - Field field; - try { - field = TEST_CLASS.getDeclaredField("CP_ADDRESS"); - } catch (NoSuchFieldException nsfe) { - throw new Error("TESTBUG : cannot find field \"CP_ADDRESS\" : " - + nsfe.getMessage(), nsfe); - } - Object base = UNSAFE.staticFieldBase(field); - return WB.getObjectAddress(base) + UNSAFE.staticFieldOffset(field); - } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/runtime/cr8015436/Driver8015436.java Wed Jul 05 22:07:28 2017 +0200 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.runtime.cr8015436; + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class Driver8015436 { + public static void main(String args[]) { + OutputAnalyzer oa; + try { + oa = ProcessTools.executeProcess(ProcessTools.createJavaProcessBuilder( + /* add test vm options */ true, Test8015436.class.getName())); + } catch (Exception ex) { + throw new Error("TESTBUG: exception while running child process: " + ex, ex); + } + oa.shouldHaveExitValue(0); + oa.shouldContain(Test8015436.SOME_MTD_INVOKED); + oa.shouldContain(Test8015436.DEFAULT_MTD_INVOKED_DIRECTLY); + oa.shouldContain(Test8015436.DEFAULT_MTD_INVOKED_MH); + } +}
--- a/hotspot/test/compiler/runtime/cr8015436/Test8015436.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/compiler/runtime/cr8015436/Test8015436.java Wed Jul 05 22:07:28 2017 +0200 @@ -25,8 +25,12 @@ * @test * @bug 8015436 * @summary the IK _initial_method_idnum value must be adjusted if overpass methods are added + * @library /test/lib/share/classes / + * @modules java.base/jdk.internal.misc + * @build compiler.runtime.cr8015436.Test8015436 + * compiler.runtime.cr8015436.Driver8015436 * - * @run main compiler.runtime.cr8015436.Test8015436 + * @run driver compiler.runtime.cr8015436.Driver8015436 */ /* @@ -45,20 +49,24 @@ import java.lang.invoke.MethodType; public class Test8015436 implements InterfaceWithDefaultMethod { + public static final String SOME_MTD_INVOKED = "someMethod() invoked"; + public static final String DEFAULT_MTD_INVOKED_DIRECTLY = "defaultMethod() invoked directly"; + public static final String DEFAULT_MTD_INVOKED_MH = "defaultMethod() invoked via a MethodHandle"; + @Override public void someMethod() { - System.out.println("someMethod() invoked"); + System.out.println(SOME_MTD_INVOKED); } public static void main(String[] args) throws Throwable { Test8015436 testObj = new Test8015436(); testObj.someMethod(); - testObj.defaultMethod("invoked directly"); + testObj.defaultMethod(DEFAULT_MTD_INVOKED_DIRECTLY); MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodType mt = MethodType.methodType(void.class, String.class); MethodHandle mh = lookup.findVirtual(Test8015436.class, "defaultMethod", mt); - mh.invokeExact(testObj, "invoked via a MethodHandle"); + mh.invokeExact(testObj, DEFAULT_MTD_INVOKED_MH); } } @@ -66,7 +74,7 @@ public void someMethod(); default public void defaultMethod(String str){ - System.out.println("defaultMethod() " + str); + System.out.println(str); } } /*
--- a/hotspot/test/gc/g1/ihop/TestIHOPErgo.java Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/gc/g1/ihop/TestIHOPErgo.java Wed Jul 05 22:07:28 2017 +0200 @@ -24,6 +24,7 @@ /* * @test TestIHOPErgo * @bug 8148397 + * @key stress * @summary Test checks that behavior of Adaptive and Static IHOP at concurrent cycle initiation * @requires vm.gc.G1 * @requires !vm.flightRecorder
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/NMT/CheckForProperDetailStackTrace.java Wed Jul 05 22:07:28 2017 +0200 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2016, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + /* + * @test + * @key nmt + * @summary Running with NMT detail should produce expected stack traces. + * @library /testlibrary + * @modules java.base/jdk.internal.misc + * java.management + */ + +import jdk.test.lib.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CheckForProperDetailStackTrace { + /* The stack trace we look for by default. Note that :: has been replaced by .* + to make sure it maches even if the symbol is not unmangled. */ + public static String stackTraceDefault = + ".*ModuleEntryTable.*new_entry.*\n" + + ".*ModuleEntryTable.*locked_create_entry_or_null.*\n" + + ".*Modules.*define_module.*\n" + + ".*JVM_DefineModule.*\n"; + + /* The stack trace we look for on Solaris and Windows slowdebug builds. For some + reason ALWAYSINLINE for AllocateHeap is ignored, so it appears in the stack strace. */ + public static String stackTraceAllocateHeap = + ".*AllocateHeap.*\n" + + ".*ModuleEntryTable.*new_entry.*\n" + + ".*ModuleEntryTable.*locked_create_entry_or_null.*\n" + + ".*Modules.*define_module.*\n"; + + /* A symbol that should always be present in NMT detail output. */ + private static String expectedSymbol = + "locked_create_entry_or_null"; + + private static final String jdkDebug = System.getProperty("jdk.debug"); + private static boolean isSlowDebugBuild() { + return (jdkDebug.toLowerCase().equals("slowdebug")); + } + + public static void main(String args[]) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:NativeMemoryTracking=detail", + "-XX:+PrintNMTStatistics", + "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + output.shouldHaveExitValue(0); + + // We should never see either of these frames because they are supposed to be skipped. */ + output.shouldNotContain("NativeCallStack::NativeCallStack"); + output.shouldNotContain("os::get_native_stack"); + + // AllocateHeap shouldn't be in the output because it is suppose to always be inlined. + // We check for that here, but allow it for Windows and Solaris slowdebug builds because + // the compiler ends up not inlining AllocateHeap. + Boolean okToHaveAllocateHeap = + isSlowDebugBuild() && (Platform.isSolaris() || Platform.isWindows()); + if (!okToHaveAllocateHeap) { + output.shouldNotContain("AllocateHeap"); + } + + // See if we have any stack trace symbols in the output + boolean hasSymbols = + output.getStdout().contains(expectedSymbol) || output.getStderr().contains(expectedSymbol); + if (!hasSymbols) { + // It's ok for ARM not to have symbols, because it does not support NMT detail + // when targeting thumb2. It's also ok for Windows not to have symbols, because + // they are only available if the symbols file is included with the build. + if (Platform.isWindows() || Platform.isARM()) { + return; // we are done + } + output.reportDiagnosticSummary(); + throw new RuntimeException("Expected symbol missing missing from output: " + expectedSymbol); + } + + /* Make sure the expected NMT detail stack trace is found. */ + String expectedStackTrace = + (okToHaveAllocateHeap ? stackTraceAllocateHeap : stackTraceDefault); + if (!stackTraceMatches(expectedStackTrace, output)) { + output.reportDiagnosticSummary(); + throw new RuntimeException("Expected stack trace missing missing from output: " + expectedStackTrace); + } + } + + public static boolean stackTraceMatches(String stackTrace, OutputAnalyzer output) { + Matcher stdoutMatcher = Pattern.compile(stackTrace, Pattern.MULTILINE).matcher(output.getStdout()); + Matcher stderrMatcher = Pattern.compile(stackTrace, Pattern.MULTILINE).matcher(output.getStderr()); + return (stdoutMatcher.find() || stderrMatcher.find()); + } +}
--- a/hotspot/test/runtime/StackGuardPages/exeinvoke.c Mon Aug 22 18:19:31 2016 +0200 +++ b/hotspot/test/runtime/StackGuardPages/exeinvoke.c Wed Jul 05 22:07:28 2017 +0200 @@ -242,7 +242,7 @@ CLASS_PATH_OPT, javaclasspath); options[0].optionString = "-Xint"; - options[1].optionString = "-Xss328k"; + options[1].optionString = "-Xss1M"; options[2].optionString = javaclasspathopt; vm_args.version = JNI_VERSION_1_2;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/Unsafe/NestedUnsafe.java Wed Jul 05 22:07:28 2017 +0200 @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2016, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Creates an anonymous class inside of an anonymous class. + * @library /testlibrary + * @modules java.base/jdk.internal.misc + * java.compiler + * java.management + * @run main NestedUnsafe + */ + +import java.security.ProtectionDomain; +import java.io.InputStream; +import java.lang.*; +import jdk.test.lib.*; +import jdk.internal.misc.Unsafe; +import static jdk.test.lib.Asserts.*; + +// package p; + +public class NestedUnsafe { + // The String concatenation should create the nested anonymous class. + static byte klassbuf[] = InMemoryJavaCompiler.compile("TestClass", + "public class TestClass { " + + " public static void concat(String one, String two) throws Throwable { " + + " System.out.println(one + two);" + + " } } "); + + public static void main(String args[]) throws Exception { + Unsafe unsafe = Utils.getUnsafe(); + + Class klass = unsafe.defineAnonymousClass(NestedUnsafe.class, klassbuf, new Object[0]); + unsafe.ensureClassInitialized(klass); + Class[] cArgs = new Class[2]; + cArgs[0] = String.class; + cArgs[1] = String.class; + try { + klass.getMethod("concat", cArgs).invoke(null, "AA", "BB"); + } catch (Throwable ex) { + throw new RuntimeException("Exception: " + ex.toString()); + } + + // The anonymous class calls defineAnonymousClass creating a nested anonymous class. + byte klassbuf2[] = InMemoryJavaCompiler.compile("TestClass2", + "import jdk.internal.misc.Unsafe; " + + "public class TestClass2 { " + + " public static void doit() throws Throwable { " + + " Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe(); " + + " Class klass2 = unsafe.defineAnonymousClass(TestClass2.class, NestedUnsafe.klassbuf, new Object[0]); " + + " unsafe.ensureClassInitialized(klass2); " + + " Class[] dArgs = new Class[2]; " + + " dArgs[0] = String.class; " + + " dArgs[1] = String.class; " + + " try { " + + " klass2.getMethod(\"concat\", dArgs).invoke(null, \"CC\", \"DD\"); " + + " } catch (Throwable ex) { " + + " throw new RuntimeException(\"Exception: \" + ex.toString()); " + + " } " + + "} } ", + "-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED"); + Class klass2 = unsafe.defineAnonymousClass(NestedUnsafe.class, klassbuf2, new Object[0]); + try { + klass2.getMethod("doit").invoke(null); + } catch (Throwable ex) { + throw new RuntimeException("Exception: " + ex.toString()); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/sa/sadebugd/SADebugDTest.java Wed Jul 05 22:07:28 2017 +0200 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2016, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Checks that the jshdb debugd utility sucessfully starts + * and tries to attach to a running process + * @modules java.base/jdk.internal.misc + * @library /test/lib/share/classes + * + * @ignore 8163805 + * @run main/othervm SADebugDTest + */ +import java.io.File; +import java.util.concurrent.CountDownLatch; +import java.io.InputStreamReader; +import java.io.BufferedReader; +import java.io.Reader; +import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; +import static jdk.test.lib.Asserts.assertTrue; +import static jdk.test.lib.Platform.shouldSAAttach; +import static jdk.test.lib.process.ProcessTools.startProcess; + +public class SADebugDTest { + + private static final String GOLDEN = "Attaching to process ID %d and starting RMI services, please wait..."; + + private static final String JAVA_HOME = (System.getProperty("test.jdk") != null) + ? System.getProperty("test.jdk") : System.getProperty("java.home"); + + private static final String JAVA_BIN_DIR + = JAVA_HOME + File.separator + "bin" + File.separator; + + private static final String JHSDB = JAVA_BIN_DIR + "jhsdb"; + + public static void main(String[] args) throws Exception { + + if (!shouldSAAttach()) { + log("Not possible to attach the SA. Skipping the test"); + return; + } + + long ourPid = ProcessHandle.current().getPid(); + + // The string we are expecting in the debugd ouput + String golden = String.format(GOLDEN, ourPid); + + // We are going to run 'jhsdb debugd <our pid>' + // The startProcess will block untl the 'golden' string appears in either process' stdout or stderr + // In case of timeout startProcess kills the debugd process + ProcessBuilder pb = new ProcessBuilder(); + pb.command(JHSDB, "debugd", String.valueOf(ourPid)); + Process debugd = startProcess("debugd", pb, null, (line) -> line.trim().contains(golden), 0, TimeUnit.SECONDS); + + // If we are here, this means we have received the golden line and the test has passed + // The debugd remains running, we have to kill it + debugd.destroy(); + + } + + private static void log(String string) { + System.out.println(string); + } + +}
--- a/jaxp/.hgtags Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/.hgtags Wed Jul 05 22:07:28 2017 +0200 @@ -374,3 +374,4 @@ 74241304e87b0d463391a8ecab40979b5af86dc2 jdk-9+129 e66cdc2de6b02443911d386fc9217b0d824d0686 jdk-9+130 874082a9b565a7092a40bfa934a6e3e3c3455a60 jdk-9+131 +907445d85e680ea410fe2c83c0ec64b5508e4f3e jdk-9+132
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources.java Wed Jul 05 22:07:28 2017 +0200 @@ -17,9 +17,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * $Id: XSLTErrorResources.java,v 1.2.4.1 2005/09/13 09:55:37 pvedula Exp $ - */ package com.sun.org.apache.xalan.internal.res; import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java Wed Jul 05 22:07:28 2017 +0200 @@ -17,9 +17,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * $Id: ErrorMessages.java,v 1.2.4.1 2005/09/15 09:59:41 pvedula Exp $ - */ package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java Wed Jul 05 22:07:28 2017 +0200 @@ -17,9 +17,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * $Id: ErrorMessages.java,v 1.2.4.1 2005/09/14 05:06:42 pvedula Exp $ - */ package com.sun.org.apache.xalan.internal.xsltc.runtime;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AbortException.java Wed Jul 05 22:07:28 2017 +0200 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.org.apache.xerces.internal.dom; + +public class AbortException extends RuntimeException { + + private static final long serialVersionUID = 2608302175475740417L; + + /** + * Constructor AbortException + */ + public AbortException() { super(null, null, false, false); } +}
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java Wed Jul 05 22:07:28 2017 +0200 @@ -26,6 +26,7 @@ import java.io.StringReader; import java.util.Vector; +import com.sun.org.apache.xerces.internal.dom.AbortException; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.RevalidationHandler; import com.sun.org.apache.xerces.internal.impl.dtd.DTDGrammar; @@ -157,11 +158,6 @@ // attribute value normalization final XMLString fNormalizedValue = new XMLString(new char[16], 0, 0); - /** - * If the user stops the process, this exception will be thrown. - */ - public static final RuntimeException abort = new RuntimeException(); - //DTD validator private XMLDTDValidator fDTDValidator; @@ -242,11 +238,8 @@ XMLGrammarDescription.XML_SCHEMA, fValidationHandler); fValidationHandler = null; } - } - catch (RuntimeException e) { - if( e==abort ) - return; // processing aborted by the user - throw e; // otherwise re-throw. + } catch (AbortException e) { + return; } } @@ -1371,10 +1364,10 @@ error.fRelatedData = locator.fRelatedNode; if(!errorHandler.handleError(error)) - throw abort; + throw new AbortException(); } if( severity==DOMError.SEVERITY_FATAL_ERROR ) - throw abort; + throw new AbortException(); } protected final void updateQName (Node node, QName qname){ @@ -2043,5 +2036,4 @@ return null; } - } // DOMNormalizer class
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/DOMMessages.properties Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/DOMMessages.properties Wed Jul 05 22:07:28 2017 +0200 @@ -2,8 +2,6 @@ # DOM implementation. # # The messages are arranged in key and value tuples in a ListResourceBundle. -# -# @version $Id: DOMMessages.properties,v 1.2 2005-08-16 22:51:51 jeffsuttor Exp $ BadMessageKey = The error message corresponding to the message key can not be found. FormatFailed = An internal error occurred while formatting the following message:\n
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/DatatypeMessages.properties Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/DatatypeMessages.properties Wed Jul 05 22:07:28 2017 +0200 @@ -1,8 +1,6 @@ # This file stores localized messages for the Xerces JAXP Datatype API implementation. # # The messages are arranged in key and value tuples in a ListResourceBundle. -# -# @version $Id: DatatypeMessages.properties 3021 2011-03-01 00:12:28Z joehw $ BadMessageKey = The error message corresponding to the message key can not be found. FormatFailed = An internal error occurred while formatting the following message:\n
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/JAXPValidationMessages.properties Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/JAXPValidationMessages.properties Wed Jul 05 22:07:28 2017 +0200 @@ -1,8 +1,6 @@ # This file stores localized messages for the Xerces JAXP Validation API implementation. # # The messages are arranged in key and value tuples in a ListResourceBundle. -# -# @version $Id: JAXPValidationMessages.properties 3021 2011-03-01 00:12:28Z joehw $ # Messages for message reporting BadMessageKey = The error message corresponding to the message key can not be found.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/SAXMessages.properties Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/SAXMessages.properties Wed Jul 05 22:07:28 2017 +0200 @@ -2,8 +2,6 @@ # SAX implementation. # # The messages are arranged in key and value tuples in a ListResourceBundle. -# -# @version $Id: SAXMessages.properties 3021 2011-03-01 00:12:28Z joehw $ BadMessageKey = The error message corresponding to the message key can not be found.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties Wed Jul 05 22:07:28 2017 +0200 @@ -1,7 +1,5 @@ # This file contains error and warning messages related to XML Schema # The messages are arranged in key and value tuples in a ListResourceBundle. -# -# @version $Id: XMLSchemaMessages.properties 3021 2011-03-01 00:12:28Z joehw $ BadMessageKey = The error message corresponding to the message key can not be found. FormatFailed = An internal error occurred while formatting the following message:\n
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSerializerMessages.properties Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSerializerMessages.properties Wed Jul 05 22:07:28 2017 +0200 @@ -4,8 +4,6 @@ # # As usual with properties files, the messages are arranged in # key/value tuples. -# -# @version $Id: XMLSerializerMessages.properties 3021 2011-03-01 00:12:28Z joehw $ BadMessageKey = The error message corresponding to the message key can not be found. FormatFailed = An internal error occurred while formatting the following message:\n
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XPointerMessages.properties Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XPointerMessages.properties Wed Jul 05 22:07:28 2017 +0200 @@ -1,8 +1,6 @@ # This file stores localized messages for the Xerces XPointer implementation. # # The messages are arranged in key and value tuples in a ListResourceBundle. -# -# @version $Id: XPointerMessages.properties 3021 2011-03-01 00:12:28Z joehw $ # Messages for message reporting BadMessageKey = The error message corresponding to the message key can not be found. @@ -24,4 +22,4 @@ InvalidElementSchemeXPointer = InvalidElementSchemeXPointer: The Element Scheme XPointer expression ''{0}'' is invalid. XPointerElementSchemeProcessingError = XPointerElementSchemeProcessingError: An error occurred while processing the XPointer element() Scheme expression. InvalidNCNameInElementSchemeData = InvalidNCNameInElementSchemeData: The element() Scheme contains a ShortHand Pointer ''{0}'' with an invalid NCName. -InvalidChildSequenceCharacter = InvalidChildSequenceCharacter: The element() Scheme contains an invalid child sequence character ''{0}''. \ No newline at end of file +InvalidChildSequenceCharacter = InvalidChildSequenceCharacter: The element() Scheme contains an invalid child sequence character ''{0}''.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources.java Wed Jul 05 22:07:28 2017 +0200 @@ -17,9 +17,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * $Id: XMLErrorResources.java,v 1.2.4.1 2005/09/15 07:45:37 suresh_emailid Exp $ - */ package com.sun.org.apache.xml.internal.res;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/DOMSerializerImpl.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/DOMSerializerImpl.java Wed Jul 05 22:07:28 2017 +0200 @@ -28,6 +28,7 @@ import java.lang.reflect.Method; import java.util.ArrayList; +import com.sun.org.apache.xerces.internal.dom.AbortException; import com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl; import com.sun.org.apache.xerces.internal.dom.DOMErrorImpl; import com.sun.org.apache.xerces.internal.dom.DOMLocatorImpl; @@ -501,11 +502,9 @@ } catch (LSException lse) { // Rethrow LSException. throw lse; + } catch (AbortException e) { + return null; } catch (RuntimeException e) { - if (e == DOMNormalizer.abort) { - // stopped at user request - return null; - } throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace(); } catch (IOException ioe) { // REVISIT: A generic IOException doesn't provide enough information @@ -733,11 +732,9 @@ } catch (LSException lse) { // Rethrow LSException. throw lse; + } catch (AbortException e) { + return false; } catch (RuntimeException e) { - if (e == DOMNormalizer.abort) { - // stopped at user request - return false; - } throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace(); } catch (Exception e) { if (ser.fDOMErrorHandler != null) { @@ -833,11 +830,9 @@ } catch (LSException lse) { // Rethrow LSException. throw lse; + } catch (AbortException e) { + return false; } catch (RuntimeException e) { - if (e == DOMNormalizer.abort) { - // stopped at user request - return false; - } throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace(); } catch (Exception e) { if (ser.fDOMErrorHandler != null) {
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages.java Wed Jul 05 22:07:28 2017 +0200 @@ -19,9 +19,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * $Id: SerializerMessages.java,v 1.1.4.1 2005/09/08 11:03:11 suresh_emailid Exp $ - */ package com.sun.org.apache.xml.internal.serializer.utils; import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImplUtil.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImplUtil.java Wed Jul 05 22:07:28 2017 +0200 @@ -28,6 +28,7 @@ import com.sun.org.apache.xalan.internal.res.XSLMessages; import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import com.sun.org.apache.xml.internal.dtm.DTM; +import com.sun.org.apache.xpath.internal.axes.LocPathIterator; import com.sun.org.apache.xpath.internal.objects.XObject; import com.sun.org.apache.xpath.internal.res.XPATHErrorResources; import java.io.IOException; @@ -73,6 +74,12 @@ XObject eval(Object contextItem, com.sun.org.apache.xpath.internal.XPath xpath) throws javax.xml.transform.TransformerException { com.sun.org.apache.xpath.internal.XPathContext xpathSupport; + if (contextItem == null && xpath.getExpression() instanceof LocPathIterator) { + // the operation must have no dependency on the context that is null + throw new TransformerException(XSLMessages.createXPATHMessage( + XPATHErrorResources.ER_CONTEXT_CAN_NOT_BE_NULL, + new Object[] {})); + } if (functionResolver != null) { JAXPExtensionsProvider jep = new JAXPExtensionsProvider( functionResolver, featureSecureProcessing, featureManager);
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java Wed Jul 05 22:07:28 2017 +0200 @@ -17,9 +17,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * $Id: XPATHErrorResources.java,v 1.2.4.1 2005/09/15 01:29:15 jeffsuttor Exp $ - */ package com.sun.org.apache.xpath.internal.res; import java.util.ListResourceBundle; @@ -93,6 +90,7 @@ public static final String ER_CURRENT_TAKES_NO_ARGS = "ER_CURRENT_TAKES_NO_ARGS"; public static final String ER_DOCUMENT_REPLACED = "ER_DOCUMENT_REPLACED"; + public static final String ER_CONTEXT_CAN_NOT_BE_NULL = "ER_CONTEXT_CAN_NOT_BE_NULL"; public static final String ER_CONTEXT_HAS_NO_OWNERDOC = "ER_CONTEXT_HAS_NO_OWNERDOC"; public static final String ER_LOCALNAME_HAS_TOO_MANY_ARGS = @@ -368,6 +366,9 @@ { ER_DOCUMENT_REPLACED, "document() function implementation has been replaced by com.sun.org.apache.xalan.internal.xslt.FuncDocument!"}, + { ER_CONTEXT_CAN_NOT_BE_NULL, + "The context can not be null when the operation is context-dependent."}, + { ER_CONTEXT_HAS_NO_OWNERDOC, "context does not have an owner document!"},
--- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPath.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPath.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -34,18 +34,20 @@ * * <a name="XPath-evaluation"></a> * <table border="1" cellpadding="2"> - * <thead> - * <tr> - * <th colspan="2">Evaluation of XPath Expressions.</th> - * </tr> - * </thead> - * <tr> - * <td>context</td> - * <td> - * If a request is made to evaluate the expression in the absence - * of a context item, an empty document node will be used for the context. - * For the purposes of evaluating XPath expressions, a DocumentFragment - * is treated like a Document node. + * <thead> + * <tr> + * <th colspan="2">Evaluation of XPath Expressions.</th> + * </tr> + * </thead> + * <tr> + * <td>context</td> + * <td> + * The type of the context is implementation-dependent. If the value is + * null, the operation must have no dependency on the context, otherwise + * an XPathExpressionException will be thrown. + * + * For the purposes of evaluating XPath expressions, a DocumentFragment + * is treated like a Document node. * </td> * </tr> * <tr>
--- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpression.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpression.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -33,19 +33,20 @@ * * <a name="XPathExpression-evaluation"></a> * <table border="1" cellpadding="2"> - * <thead> - * <tr> - * <th colspan="2">Evaluation of XPath Expressions.</th> - * </tr> - * </thead> - * <tbody> - * <tr> - * <td>context</td> - * <td> - * If a request is made to evaluate the expression in the absence - * of a context item, an empty document node will be used for the context. - * For the purposes of evaluating XPath expressions, a DocumentFragment - * is treated like a Document node. + * <thead> + * <tr> + * <th colspan="2">Evaluation of XPath Expressions.</th> + * </tr> + * </thead> + * <tr> + * <td>context</td> + * <td> + * The type of the context is implementation-dependent. If the value is + * null, the operation must have no dependency on the context, otherwise + * an XPathExpressionException will be thrown. + * + * For the purposes of evaluating XPath expressions, a DocumentFragment + * is treated like a Document node. * </td> * </tr> * <tr>
--- a/jaxp/src/java.xml/share/classes/module-info.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/src/java.xml/share/classes/module-info.java Wed Jul 05 22:07:28 2017 +0200 @@ -23,6 +23,10 @@ * questions. */ +/** + * Defines the Java API for XML Processing (JAXP), the Streaming API for XML (StAX), + * the Simple API for XML (SAX), and the W3C Document Object Model (DOM) API. + */ module java.xml { exports javax.xml; exports javax.xml.catalog;
--- a/jaxp/test/javax/xml/jaxp/unittest/xpath/XPathTest.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxp/test/javax/xml/jaxp/unittest/xpath/XPathTest.java Wed Jul 05 22:07:28 2017 +0200 @@ -24,11 +24,17 @@ package xpath; import javax.xml.namespace.NamespaceContext; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; - +import org.testng.annotations.DataProvider; import org.testng.annotations.Listeners; import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Node; /* * @test @@ -36,19 +42,105 @@ * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest * @run testng/othervm -DrunSecMngr=true xpath.XPathTest * @run testng/othervm xpath.XPathTest - * @summary Test XPath.getNamespaceContext() is supported. + * @summary Test XPath functions. See details for each test. */ @Listeners({jaxp.library.BasePolicy.class}) public class XPathTest { + /* + @bug 6211561 + * Verifies the specification for XPath and XPathExpression: + * If a null value is provided for item (the context), + * the expression must have no dependency on the context. + */ + @Test(dataProvider = "noContextDependency") + public void testNoContextDependency1(String expression, Object item) throws XPathExpressionException { + XPath xPath = XPathFactory.newInstance().newXPath(); + xPath.evaluate(expression, item, XPathConstants.STRING); + } + + @Test(dataProvider = "noContextDependency") + public void testNoContextDependency2(String expression, Object item) throws XPathExpressionException { + XPath xPath = XPathFactory.newInstance().newXPath(); + xPath.evaluateExpression(expression, item, String.class); + } + + /* + @bug 6211561 + * Verifies the specification for XPath and XPathExpression: + * If a null value is provided for item (the context) that the operation + * depends on, XPathExpressionException will be thrown + */ + @Test(dataProvider = "hasContextDependency", expectedExceptions = XPathExpressionException.class) + public void testHasContextDependency1(String expression, Object item) throws XPathExpressionException { + XPath xPath = XPathFactory.newInstance().newXPath(); + xPath.evaluate(expression, item, XPathConstants.STRING); + } + + @Test(dataProvider = "hasContextDependency", expectedExceptions = XPathExpressionException.class) + public void testHasContextDependency2(String expression, Object item) throws XPathExpressionException { + XPath xPath = XPathFactory.newInstance().newXPath(); + xPath.evaluateExpression(expression, item, String.class); + } + + /* + @bug 6376058 + Verifies that XPath.getNamespaceContext() is supported. + */ @Test public void testNamespaceContext() { - XPathFactory xPathFactory = XPathFactory.newInstance(); XPath xPath = xPathFactory.newXPath(); + NamespaceContext namespaceContext = xPath.getNamespaceContext(); + } - NamespaceContext namespaceContext = xPath.getNamespaceContext(); + /* + * DataProvider: the expression has no dependency on the context + */ + @DataProvider(name = "noContextDependency") + public Object[][] getExpressionContext() throws Exception { + return new Object[][]{ + {"1+1", (Node)null}, + {"5 mod 2", (Node)null}, + {"8 div 2", (Node)null}, + {"/node", getEmptyDocument()} + }; + } + /* + * DataProvider: the expression has dependency on the context, but the context + * is null. + */ + @DataProvider(name = "hasContextDependency") + public Object[][] getExpressionContext1() throws Exception { + return new Object[][]{ + {"/node", (Node)null}, + {"//@lang", (Node)null}, + {"bookstore//book", (Node)null}, + {"/bookstore/book[last()]", (Node)null}, + {"//title[@lang='en']", (Node)null}, + {"/bookstore/book[price>9.99]", (Node)null}, + {"/bookstore/book[price>8.99 and price<9.99]", (Node)null}, + {"/bookstore/*", (Node)null}, + {"//title[@*]", (Node)null}, + {"//title | //price", (Node)null}, + {"//book/title | //book/price", (Node)null}, + {"/bookstore/book/title | //price", (Node)null}, + {"child::book", (Node)null}, + {"child::text()", (Node)null}, + {"child::*/child::price", (Node)null} + }; + } + + /** + * Returns an empty {@link org.w3c.dom.Document}. + * @return a DOM Document, null in case of Exception + */ + public Document getEmptyDocument() { + try { + return DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + } catch (ParserConfigurationException e) { + return null; + } } } -
--- a/jaxws/.hgtags Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxws/.hgtags Wed Jul 05 22:07:28 2017 +0200 @@ -377,3 +377,4 @@ 46a02f57218e4a8c334dbccf656fb048f823f163 jdk-9+129 39c6293131d91aec7f2f5120395e070a937b8858 jdk-9+130 783e7e2c587f2c7e1b9998a46d90ec196ab2a195 jdk-9+131 +9fff2477a4cadf2a9618a76f1f4fe0f20bb5ff3b jdk-9+132
--- a/jaxws/src/java.activation/share/classes/module-info.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxws/src/java.activation/share/classes/module-info.java Wed Jul 05 22:07:28 2017 +0200 @@ -23,6 +23,9 @@ * questions. */ +/** + * Defines the JavaBeans Activation Framework (JAF) API. + */ module java.activation { requires public java.datatransfer; // dependence on java.beans.Beans to be eliminated
--- a/jaxws/src/java.annotations.common/share/classes/module-info.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxws/src/java.annotations.common/share/classes/module-info.java Wed Jul 05 22:07:28 2017 +0200 @@ -23,6 +23,10 @@ * questions. */ +/** + * Defines a subset of the Common Annotations API to support programs running + * on the Java SE Platform. + */ module java.annotations.common { exports javax.annotation; }
--- a/jaxws/src/java.xml.bind/share/classes/module-info.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxws/src/java.xml.bind/share/classes/module-info.java Wed Jul 05 22:07:28 2017 +0200 @@ -23,6 +23,9 @@ * questions. */ +/** + * Defines the Java Architecture for XML Binding (JAXB) API. + */ module java.xml.bind { requires public java.activation; requires public java.xml;
--- a/jaxws/src/java.xml.ws/share/classes/module-info.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jaxws/src/java.xml.ws/share/classes/module-info.java Wed Jul 05 22:07:28 2017 +0200 @@ -23,6 +23,10 @@ * questions. */ +/** + * Defines the Java API for XML-Based Web Services (JAX-WS), and + * the Web Services Metadata API. + */ module java.xml.ws { requires public java.activation; requires public java.xml;
--- a/jdk/.hgtags Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/.hgtags Wed Jul 05 22:07:28 2017 +0200 @@ -374,3 +374,4 @@ 47699aa2e69ec2702542dc73eb01de3bfb61aea0 jdk-9+129 6c827500e34587061af97ad6fef0e859280255c5 jdk-9+130 8c57f4c293bbc5609928308a6d91ba765760b5f9 jdk-9+131 +d5c70818cd8a82e76632c8c815bdb4f75f53aeaf jdk-9+132
--- a/jdk/make/copy/Copy-java.base.gmk Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/make/copy/Copy-java.base.gmk Wed Jul 05 22:07:28 2017 +0200 @@ -183,7 +183,7 @@ DEF_POLICY_SRC_LIST := $(DEF_POLICY_SRC) -ifeq ($(OPENJDK_TARGET_OS), windows) +ifneq ($(filter $(OPENJDK_TARGET_OS), windows solaris), ) DEF_POLICY_SRC_LIST += $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/lib/security/default.policy endif
--- a/jdk/src/java.base/macosx/classes/apple/security/AppleProvider.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/macosx/classes/apple/security/AppleProvider.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, 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 @@ -26,6 +26,7 @@ package apple.security; import java.security.*; +import static sun.security.util.SecurityConstants.PROVIDER_VER; /** * The Apple Security Provider. @@ -74,7 +75,7 @@ public AppleProvider() { /* We are the Apple provider */ - super("Apple", 9.0d, info); + super("Apple", PROVIDER_VER, info); final Provider p = this; AccessController.doPrivileged(new PrivilegedAction<Void>() {
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, 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 @@ -107,7 +107,12 @@ throw new InvalidKeySpecException("Key length is negative"); } try { - this.prf = Mac.getInstance(prfAlgo, SunJCE.getInstance()); + this.prf = Mac.getInstance(prfAlgo); + // SunPKCS11 requires a non-empty PBE password + if (passwdBytes.length == 0 && + this.prf.getProvider().getName().startsWith("SunPKCS11")) { + this.prf = Mac.getInstance(prfAlgo, SunJCE.getInstance()); + } } catch (NoSuchAlgorithmException nsae) { // not gonna happen; re-throw just in case InvalidKeySpecException ike = new InvalidKeySpecException();
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -28,6 +28,7 @@ import java.security.AccessController; import java.security.Provider; import java.security.SecureRandom; +import static sun.security.util.SecurityConstants.PROVIDER_VER; /** @@ -104,7 +105,7 @@ public SunJCE() { /* We are the "SunJCE" provider */ - super("SunJCE", 9.0d, info); + super("SunJCE", PROVIDER_VER, info); final String BLOCK_MODES = "ECB|CBC|PCBC|CTR|CTS|CFB|OFB" + "|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64" +
--- a/jdk/src/java.base/share/classes/java/io/BufferedReader.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/io/BufferedReader.java Wed Jul 05 22:07:28 2017 +0200 @@ -560,7 +560,7 @@ * @since 1.8 */ public Stream<String> lines() { - Iterator<String> iter = new Iterator<String>() { + Iterator<String> iter = new Iterator<>() { String nextLine = null; @Override
--- a/jdk/src/java.base/share/classes/java/io/ByteArrayOutputStream.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/io/ByteArrayOutputStream.java Wed Jul 05 22:07:28 2017 +0200 @@ -187,7 +187,7 @@ * @return the current contents of this output stream, as a byte array. * @see java.io.ByteArrayOutputStream#size() */ - public synchronized byte toByteArray()[] { + public synchronized byte[] toByteArray() { return Arrays.copyOf(buf, count); }
--- a/jdk/src/java.base/share/classes/java/io/CharArrayWriter.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/io/CharArrayWriter.java Wed Jul 05 22:07:28 2017 +0200 @@ -165,7 +165,7 @@ * * @param csq * The character sequence to append. If {@code csq} is - * {@code null}, then the four characters "{@code null}" are + * {@code null}, then the four characters {@code "null"} are * appended to this writer. * * @return This writer @@ -173,7 +173,7 @@ * @since 1.5 */ public CharArrayWriter append(CharSequence csq) { - String s = (csq == null ? "null" : csq.toString()); + String s = String.valueOf(csq); write(s, 0, s.length()); return this; } @@ -193,7 +193,7 @@ * The character sequence from which a subsequence will be * appended. If {@code csq} is {@code null}, then characters * will be appended as if {@code csq} contained the four - * characters "{@code null}". + * characters {@code "null"}. * * @param start * The index of the first character in the subsequence @@ -212,9 +212,8 @@ * @since 1.5 */ public CharArrayWriter append(CharSequence csq, int start, int end) { - String s = (csq == null ? "null" : csq).subSequence(start, end).toString(); - write(s, 0, s.length()); - return this; + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } /** @@ -251,7 +250,7 @@ * * @return an array of chars copied from the input data. */ - public char toCharArray()[] { + public char[] toCharArray() { synchronized (lock) { return Arrays.copyOf(buf, count); }
--- a/jdk/src/java.base/share/classes/java/io/FileSystem.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/io/FileSystem.java Wed Jul 05 22:07:28 2017 +0200 @@ -228,13 +228,8 @@ static boolean useCanonPrefixCache = true; private static boolean getBooleanProperty(String prop, boolean defaultVal) { - String val = System.getProperty(prop); - if (val == null) return defaultVal; - if (val.equalsIgnoreCase("true")) { - return true; - } else { - return false; - } + return Boolean.parseBoolean(System.getProperty(prop, + String.valueOf(defaultVal))); } static {
--- a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java Wed Jul 05 22:07:28 2017 +0200 @@ -1265,22 +1265,21 @@ WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); Boolean result = Caches.subclassAudits.get(key); if (result == null) { - result = Boolean.valueOf(auditSubclass(cl)); + result = auditSubclass(cl); Caches.subclassAudits.putIfAbsent(key, result); } - if (result.booleanValue()) { - return; + if (!result) { + sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); } - sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); } /** * Performs reflective checks on given subclass to verify that it doesn't - * override security-sensitive non-final methods. Returns true if subclass - * is "safe", false otherwise. + * override security-sensitive non-final methods. Returns TRUE if subclass + * is "safe", FALSE otherwise. */ - private static boolean auditSubclass(final Class<?> subcl) { - Boolean result = AccessController.doPrivileged( + private static Boolean auditSubclass(Class<?> subcl) { + return AccessController.doPrivileged( new PrivilegedAction<>() { public Boolean run() { for (Class<?> cl = subcl; @@ -1303,7 +1302,6 @@ } } ); - return result.booleanValue(); } /**
--- a/jdk/src/java.base/share/classes/java/io/ObjectOutputStream.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/io/ObjectOutputStream.java Wed Jul 05 22:07:28 2017 +0200 @@ -1050,22 +1050,21 @@ WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); Boolean result = Caches.subclassAudits.get(key); if (result == null) { - result = Boolean.valueOf(auditSubclass(cl)); + result = auditSubclass(cl); Caches.subclassAudits.putIfAbsent(key, result); } - if (result.booleanValue()) { - return; + if (!result) { + sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); } - sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); } /** * Performs reflective checks on given subclass to verify that it doesn't - * override security-sensitive non-final methods. Returns true if subclass - * is "safe", false otherwise. + * override security-sensitive non-final methods. Returns TRUE if subclass + * is "safe", FALSE otherwise. */ - private static boolean auditSubclass(final Class<?> subcl) { - Boolean result = AccessController.doPrivileged( + private static Boolean auditSubclass(Class<?> subcl) { + return AccessController.doPrivileged( new PrivilegedAction<>() { public Boolean run() { for (Class<?> cl = subcl; @@ -1088,7 +1087,6 @@ } } ); - return result.booleanValue(); } /**
--- a/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java Wed Jul 05 22:07:28 2017 +0200 @@ -1509,11 +1509,9 @@ private static String getPackageName(Class<?> cl) { String s = cl.getName(); int i = s.lastIndexOf('['); - if (i >= 0) { - s = s.substring(i + 2); - } - i = s.lastIndexOf('.'); - return (i >= 0) ? s.substring(0, i) : ""; + i = (i < 0) ? 0 : i + 2; + int j = s.lastIndexOf('.'); + return (i < j) ? s.substring(i, j) : ""; } /** @@ -1535,14 +1533,14 @@ private static String getMethodSignature(Class<?>[] paramTypes, Class<?> retType) { - StringBuilder sbuf = new StringBuilder(); - sbuf.append('('); + StringBuilder sb = new StringBuilder(); + sb.append('('); for (int i = 0; i < paramTypes.length; i++) { - appendClassSignature(sbuf, paramTypes[i]); + appendClassSignature(sb, paramTypes[i]); } - sbuf.append(')'); - appendClassSignature(sbuf, retType); - return sbuf.toString(); + sb.append(')'); + appendClassSignature(sb, retType); + return sb.toString(); } /**
--- a/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java Wed Jul 05 22:07:28 2017 +0200 @@ -233,22 +233,16 @@ @Override public Writer append(CharSequence csq, int start, int end) throws IOException { - if (csq == null) { - write("null".subSequence(start, end).toString()); - return this; - } else { - return append(csq.subSequence(start, end)); - } + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } @Override public Writer append(CharSequence csq) throws IOException { - if (csq == null) { - se.write("null"); - } else if (csq instanceof CharBuffer) { + if (csq instanceof CharBuffer) { se.write((CharBuffer) csq); } else { - se.write(csq.toString()); + se.write(String.valueOf(csq)); } return this; }
--- a/jdk/src/java.base/share/classes/java/io/PrintStream.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/io/PrintStream.java Wed Jul 05 22:07:28 2017 +0200 @@ -568,7 +568,7 @@ * @param b The {@code boolean} to be printed */ public void print(boolean b) { - write(b ? "true" : "false"); + write(String.valueOf(b)); } /** @@ -663,10 +663,7 @@ * @param s The {@code String} to be printed */ public void print(String s) { - if (s == null) { - s = "null"; - } - write(s); + write(String.valueOf(s)); } /** @@ -1068,10 +1065,7 @@ * @since 1.5 */ public PrintStream append(CharSequence csq) { - if (csq == null) - print("null"); - else - print(csq.toString()); + print(String.valueOf(csq)); return this; } @@ -1111,9 +1105,8 @@ * @since 1.5 */ public PrintStream append(CharSequence csq, int start, int end) { - CharSequence cs = (csq == null ? "null" : csq); - write(cs.subSequence(start, end).toString()); - return this; + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } /**
--- a/jdk/src/java.base/share/classes/java/io/PrintWriter.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/io/PrintWriter.java Wed Jul 05 22:07:28 2017 +0200 @@ -504,7 +504,7 @@ * @param b The {@code boolean} to be printed */ public void print(boolean b) { - write(b ? "true" : "false"); + write(String.valueOf(b)); } /** @@ -599,10 +599,7 @@ * @param s The {@code String} to be printed */ public void print(String s) { - if (s == null) { - s = "null"; - } - write(s); + write(String.valueOf(s)); } /** @@ -1005,10 +1002,7 @@ * @since 1.5 */ public PrintWriter append(CharSequence csq) { - if (csq == null) - write("null"); - else - write(csq.toString()); + write(String.valueOf(csq)); return this; } @@ -1047,9 +1041,8 @@ * @since 1.5 */ public PrintWriter append(CharSequence csq, int start, int end) { - CharSequence cs = (csq == null ? "null" : csq); - write(cs.subSequence(start, end).toString()); - return this; + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } /**
--- a/jdk/src/java.base/share/classes/java/io/SequenceInputStream.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/io/SequenceInputStream.java Wed Jul 05 22:07:28 2017 +0200 @@ -65,12 +65,7 @@ */ public SequenceInputStream(Enumeration<? extends InputStream> e) { this.e = e; - try { - nextStream(); - } catch (IOException ex) { - // This should never happen - throw new Error("panic"); - } + peekNextStream(); } /** @@ -86,16 +81,10 @@ */ public SequenceInputStream(InputStream s1, InputStream s2) { Vector<InputStream> v = new Vector<>(2); - v.addElement(s1); v.addElement(s2); e = v.elements(); - try { - nextStream(); - } catch (IOException ex) { - // This should never happen - throw new Error("panic"); - } + peekNextStream(); } /** @@ -105,14 +94,17 @@ if (in != null) { in.close(); } + peekNextStream(); + } + private void peekNextStream() { if (e.hasMoreElements()) { in = (InputStream) e.nextElement(); if (in == null) throw new NullPointerException(); + } else { + in = null; } - else in = null; - } /**
--- a/jdk/src/java.base/share/classes/java/io/StringBufferInputStream.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/io/StringBufferInputStream.java Wed Jul 05 22:07:28 2017 +0200 @@ -108,6 +108,7 @@ * <code>-1</code> if there is no more data because the end of * the stream has been reached. */ + @SuppressWarnings("deprecation") public synchronized int read(byte b[], int off, int len) { if (b == null) { throw new NullPointerException(); @@ -126,12 +127,8 @@ if (len <= 0) { return 0; } - String s = buffer; - int cnt = len; - while (--cnt >= 0) { - b[off++] = (byte)s.charAt(pos++); - } - + buffer.getBytes(pos, pos + len, b, off); + pos += len; return len; }
--- a/jdk/src/java.base/share/classes/java/io/StringReader.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/io/StringReader.java Wed Jul 05 22:07:28 2017 +0200 @@ -142,8 +142,8 @@ */ public boolean ready() throws IOException { synchronized (lock) { - ensureOpen(); - return true; + ensureOpen(); + return true; } }
--- a/jdk/src/java.base/share/classes/java/io/StringWriter.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/io/StringWriter.java Wed Jul 05 22:07:28 2017 +0200 @@ -139,7 +139,7 @@ * * @param csq * The character sequence to append. If {@code csq} is - * {@code null}, then the four characters "{@code null}" are + * {@code null}, then the four characters {@code "null"} are * appended to this writer. * * @return This writer @@ -147,10 +147,7 @@ * @since 1.5 */ public StringWriter append(CharSequence csq) { - if (csq == null) - write("null"); - else - write(csq.toString()); + write(String.valueOf(csq)); return this; } @@ -170,7 +167,7 @@ * The character sequence from which a subsequence will be * appended. If {@code csq} is {@code null}, then characters * will be appended as if {@code csq} contained the four - * characters "{@code null}". + * characters {@code "null"}. * * @param start * The index of the first character in the subsequence @@ -189,9 +186,8 @@ * @since 1.5 */ public StringWriter append(CharSequence csq, int start, int end) { - CharSequence cs = (csq == null ? "null" : csq); - write(cs.subSequence(start, end).toString()); - return this; + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } /**
--- a/jdk/src/java.base/share/classes/java/io/Writer.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/io/Writer.java Wed Jul 05 22:07:28 2017 +0200 @@ -221,7 +221,7 @@ * * @param csq * The character sequence to append. If {@code csq} is - * {@code null}, then the four characters "{@code null}" are + * {@code null}, then the four characters {@code "null"} are * appended to this writer. * * @return This writer @@ -232,10 +232,7 @@ * @since 1.5 */ public Writer append(CharSequence csq) throws IOException { - if (csq == null) - write("null"); - else - write(csq.toString()); + write(String.valueOf(csq)); return this; } @@ -256,7 +253,7 @@ * The character sequence from which a subsequence will be * appended. If {@code csq} is {@code null}, then characters * will be appended as if {@code csq} contained the four - * characters "{@code null}". + * characters {@code "null"}. * * @param start * The index of the first character in the subsequence @@ -278,9 +275,8 @@ * @since 1.5 */ public Writer append(CharSequence csq, int start, int end) throws IOException { - CharSequence cs = (csq == null ? "null" : csq); - write(cs.subSequence(start, end).toString()); - return this; + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } /**
--- a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Wed Jul 05 22:07:28 2017 +0200 @@ -36,7 +36,6 @@ import java.lang.invoke.LambdaForm.NamedFunction; import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.Field; -import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.function.Function; @@ -308,7 +307,7 @@ /*non-public*/ char fieldTypeChar(int i) { return typeChars.charAt(i); } - Object fieldSignature() { + String fieldSignature() { return typeChars; } public Class<? extends BoundMethodHandle> fieldHolder() {
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java Wed Jul 05 22:07:28 2017 +0200 @@ -27,6 +27,7 @@ import java.util.Arrays; import static java.lang.invoke.LambdaForm.*; +import static java.lang.invoke.LambdaForm.Kind.*; import static java.lang.invoke.MethodHandleStatics.*; /** @@ -96,14 +97,8 @@ int whichCache, Object constraint, NamedFunction getTargetFn) { - String debugString; - switch(whichCache) { - case MethodTypeForm.LF_REBIND: debugString = "BMH.reinvoke"; break; - case MethodTypeForm.LF_DELEGATE: debugString = "MH.delegate"; break; - default: debugString = "MH.reinvoke"; break; - } // No pre-action needed. - return makeReinvokerForm(target, whichCache, constraint, debugString, true, getTargetFn, null); + return makeReinvokerForm(target, whichCache, constraint, null, true, getTargetFn, null); } /** Create a LF which simply reinvokes a target of the given basic type. */ static LambdaForm makeReinvokerForm(MethodHandle target, @@ -114,6 +109,10 @@ NamedFunction getTargetFn, NamedFunction preActionFn) { MethodType mtype = target.type().basicType(); + Kind kind = whichKind(whichCache); + if (debugString == null) { + debugString = kind.defaultLambdaName; + } boolean customized = (whichCache < 0 || mtype.parameterSlotCount() > MethodType.MAX_MH_INVOKER_ARITY); boolean hasPreAction = (preActionFn != null); @@ -145,13 +144,21 @@ targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH names[REINVOKE] = new LambdaForm.Name(mtype, targetArgs); } - form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline); + form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline, kind); if (!customized) { form = mtype.form().setCachedLambdaForm(whichCache, form); } return form; } + private static Kind whichKind(int whichCache) { + switch(whichCache) { + case MethodTypeForm.LF_REBIND: return BOUND_REINVOKER; + case MethodTypeForm.LF_DELEGATE: return DELEGATE; + default: return REINVOKER; + } + } + static final NamedFunction NF_getTarget; static { try { @@ -160,5 +167,13 @@ } catch (ReflectiveOperationException ex) { throw newInternalError(ex); } + // The Holder class will contain pre-generated DelegatingMethodHandles resolved + // speculatively using MemberName.getFactory().resolveOrNull. However, that + // doesn't initialize the class, which subtly breaks inlining etc. By forcing + // initialization of the Holder class we avoid these issues. + UNSAFE.ensureClassInitialized(Holder.class); } + + /* Placeholder class for DelegatingMethodHandles generated ahead of time */ + final class Holder {} }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Wed Jul 05 22:07:28 2017 +0200 @@ -38,6 +38,7 @@ import java.util.Objects; import static java.lang.invoke.LambdaForm.*; +import static java.lang.invoke.LambdaForm.Kind.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleStatics.UNSAFE; import static java.lang.invoke.MethodHandleStatics.newInternalError; @@ -189,14 +190,15 @@ static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) { boolean needsInit = (which == LF_INVSTATIC_INIT); boolean doesAlloc = (which == LF_NEWINVSPECIAL); - String linkerName, lambdaName; + String linkerName; + LambdaForm.Kind kind; switch (which) { - case LF_INVVIRTUAL: linkerName = "linkToVirtual"; lambdaName = "DMH.invokeVirtual"; break; - case LF_INVSTATIC: linkerName = "linkToStatic"; lambdaName = "DMH.invokeStatic"; break; - case LF_INVSTATIC_INIT:linkerName = "linkToStatic"; lambdaName = "DMH.invokeStaticInit"; break; - case LF_INVSPECIAL: linkerName = "linkToSpecial"; lambdaName = "DMH.invokeSpecial"; break; - case LF_INVINTERFACE: linkerName = "linkToInterface"; lambdaName = "DMH.invokeInterface"; break; - case LF_NEWINVSPECIAL: linkerName = "linkToSpecial"; lambdaName = "DMH.newInvokeSpecial"; break; + case LF_INVVIRTUAL: linkerName = "linkToVirtual"; kind = DIRECT_INVOKE_VIRTUAL; break; + case LF_INVSTATIC: linkerName = "linkToStatic"; kind = DIRECT_INVOKE_STATIC; break; + case LF_INVSTATIC_INIT:linkerName = "linkToStatic"; kind = DIRECT_INVOKE_STATIC_INIT; break; + case LF_INVSPECIAL: linkerName = "linkToSpecial"; kind = DIRECT_INVOKE_SPECIAL; break; + case LF_INVINTERFACE: linkerName = "linkToInterface"; kind = DIRECT_INVOKE_INTERFACE; break; + case LF_NEWINVSPECIAL: linkerName = "linkToSpecial"; kind = DIRECT_NEW_INVOKE_SPECIAL; break; default: throw new InternalError("which="+which); } @@ -240,11 +242,11 @@ result = NEW_OBJ; } names[LINKER_CALL] = new Name(linker, outArgs); - lambdaName += "_" + shortenSignature(basicTypeSignature(mtype)); - LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result); + String lambdaName = kind.defaultLambdaName + "_" + shortenSignature(basicTypeSignature(mtype)); + LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result, kind); // This is a tricky bit of code. Don't send it through the LF interpreter. - lform.compileToBytecode(Holder.class); + lform.compileToBytecode(); return lform; } @@ -705,7 +707,7 @@ } static { - // The DMH class will contain pre-generated DirectMethodHandles resolved + // The Holder class will contain pre-generated DirectMethodHandles resolved // speculatively using MemberName.getFactory().resolveOrNull. However, that // doesn't initialize the class, which subtly breaks inlining etc. By forcing // initialization of the Holder class we avoid these issues. @@ -713,5 +715,5 @@ } /* Placeholder class for DirectMethodHandles generated ahead of time */ - private final class Holder {} + final class Holder {} }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java Wed Jul 05 22:07:28 2017 +0200 @@ -29,21 +29,82 @@ import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.Opcodes; +import java.util.ArrayList; +import java.util.HashSet; + /** * Helper class to assist the GenerateJLIClassesPlugin to get access to * generate classes ahead of time. */ class GenerateJLIClassesHelper { - static byte[] generateDMHClassBytes(String className, + static byte[] generateBasicFormsClassBytes(String className) { + ArrayList<LambdaForm> forms = new ArrayList<>(); + ArrayList<String> names = new ArrayList<>(); + HashSet<String> dedupSet = new HashSet<>(); + for (LambdaForm.BasicType type : LambdaForm.BasicType.values()) { + LambdaForm zero = LambdaForm.zeroForm(type); + String name = zero.kind.defaultLambdaName + + "_" + zero.returnType().basicTypeChar(); + if (dedupSet.add(name)) { + names.add(name); + forms.add(zero); + } + + LambdaForm identity = LambdaForm.identityForm(type); + name = identity.kind.defaultLambdaName + + "_" + identity.returnType().basicTypeChar(); + if (dedupSet.add(name)) { + names.add(name); + forms.add(identity); + } + } + return generateCodeBytesForLFs(className, + names.toArray(new String[0]), + forms.toArray(new LambdaForm[0])); + } + + static byte[] generateDirectMethodHandleHolderClassBytes(String className, MethodType[] methodTypes, int[] types) { LambdaForm[] forms = new LambdaForm[methodTypes.length]; + String[] names = new String[methodTypes.length]; for (int i = 0; i < forms.length; i++) { forms[i] = DirectMethodHandle.makePreparedLambdaForm(methodTypes[i], types[i]); - methodTypes[i] = forms[i].methodType(); + names[i] = forms[i].kind.defaultLambdaName; } - return generateCodeBytesForLFs(className, forms, methodTypes); + return generateCodeBytesForLFs(className, names, forms); + } + + static byte[] generateDelegatingMethodHandleHolderClassBytes(String className, + MethodType[] methodTypes) { + + HashSet<MethodType> dedupSet = new HashSet<>(); + ArrayList<LambdaForm> forms = new ArrayList<>(); + ArrayList<String> names = new ArrayList<>(); + for (int i = 0; i < methodTypes.length; i++) { + // generate methods representing the DelegatingMethodHandle + if (dedupSet.add(methodTypes[i])) { + // reinvokers are variant with the associated SpeciesData + // and shape of the target LF, but we can easily pregenerate + // the basic reinvokers associated with Species_L. Ultimately we + // may want to consider pregenerating more of these, which will + // require an even more complex naming scheme + LambdaForm reinvoker = makeReinvokerFor(methodTypes[i]); + forms.add(reinvoker); + String speciesSig = BoundMethodHandle + .speciesData(reinvoker).fieldSignature(); + assert(speciesSig.equals("L")); + names.add(reinvoker.kind.defaultLambdaName + "_" + speciesSig); + + LambdaForm delegate = makeDelegateFor(methodTypes[i]); + forms.add(delegate); + names.add(delegate.kind.defaultLambdaName); + } + } + return generateCodeBytesForLFs(className, + names.toArray(new String[0]), + forms.toArray(new LambdaForm[0])); } /* @@ -51,22 +112,45 @@ * a class with a specified name. */ private static byte[] generateCodeBytesForLFs(String className, - LambdaForm[] forms, MethodType[] types) { - assert(forms.length == types.length); + String[] names, LambdaForm[] forms) { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES); cw.visit(Opcodes.V1_8, Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER, className, null, InvokerBytecodeGenerator.INVOKER_SUPER_NAME, null); cw.visitSource(className.substring(className.lastIndexOf('/') + 1), null); + for (int i = 0; i < forms.length; i++) { - InvokerBytecodeGenerator g - = new InvokerBytecodeGenerator(className, forms[i], types[i]); - g.setClassWriter(cw); - g.addMethod(); + addMethod(className, names[i], forms[i], + forms[i].methodType(), cw); } return cw.toByteArray(); } + private static void addMethod(String className, String methodName, LambdaForm form, + MethodType type, ClassWriter cw) { + InvokerBytecodeGenerator g + = new InvokerBytecodeGenerator(className, methodName, form, type); + g.setClassWriter(cw); + g.addMethod(); + } + + private static LambdaForm makeReinvokerFor(MethodType type) { + MethodHandle emptyHandle = MethodHandles.empty(type); + return DelegatingMethodHandle.makeReinvokerForm(emptyHandle, + MethodTypeForm.LF_REBIND, + BoundMethodHandle.speciesData_L(), + BoundMethodHandle.speciesData_L().getterFunction(0)); + } + + private static LambdaForm makeDelegateFor(MethodType type) { + MethodHandle handle = MethodHandles.empty(type); + return DelegatingMethodHandle.makeReinvokerForm( + handle, + MethodTypeForm.LF_DELEGATE, + DelegatingMethodHandle.class, + DelegatingMethodHandle.NF_getTarget); + } + static Map.Entry<String, byte[]> generateConcreteBMHClassBytes( final String types) { for (char c : types.toCharArray()) {
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Wed Jul 05 22:07:28 2017 +0200 @@ -46,6 +46,7 @@ import static java.lang.invoke.LambdaForm.*; import static java.lang.invoke.LambdaForm.BasicType.*; +import static java.lang.invoke.LambdaForm.Kind.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleStatics.*; @@ -125,9 +126,15 @@ } /** For generating customized code for a single LambdaForm. */ - InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) { + private InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) { + this(className, form.debugName, form, invokerType); + } + + /** For generating customized code for a single LambdaForm. */ + InvokerBytecodeGenerator(String className, String invokerName, + LambdaForm form, MethodType invokerType) { this(form, form.names.length, - className, form.debugName, invokerType); + className, invokerName, invokerType); // Create an array to map name indexes to locals indexes. Name[] names = form.names; for (int i = 0, index = 0; i < localsMap.length; i++) { @@ -597,10 +604,47 @@ return c.getName().replace('.', '/'); } + private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) { + MemberName member = new MemberName(holder, name, type, REF_invokeStatic); + MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder); + + return resolvedMember; + } + + private static MemberName lookupPregenerated(LambdaForm form) { + if (form.customized != null) { + // No pre-generated version for customized LF + return null; + } + MethodType invokerType = form.methodType(); + String name = form.kind.methodName; + switch (form.kind) { + case BOUND_REINVOKER: { + name = name + "_" + BoundMethodHandle.speciesData(form).fieldSignature(); + return resolveFrom(name, invokerType, DelegatingMethodHandle.Holder.class); + } + case DELEGATE: return resolveFrom(name, invokerType, DelegatingMethodHandle.Holder.class); + case ZERO: // fall-through + case IDENTITY: { + name = name + "_" + form.returnType().basicTypeChar(); + return resolveFrom(name, invokerType, LambdaForm.Holder.class); + } + case DIRECT_INVOKE_INTERFACE: // fall-through + case DIRECT_INVOKE_SPECIAL: // fall-through + case DIRECT_INVOKE_STATIC: // fall-through + case DIRECT_INVOKE_STATIC_INIT: // fall-through + case DIRECT_INVOKE_VIRTUAL: return resolveFrom(name, invokerType, DirectMethodHandle.Holder.class); + } + return null; + } + /** * Generate customized bytecode for a given LambdaForm. */ static MemberName generateCustomizedCode(LambdaForm form, MethodType invokerType) { + MemberName pregenerated = lookupPregenerated(form); + if (pregenerated != null) return pregenerated; // pre-generated bytecode + InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("MH", form, invokerType); return g.loadMethod(g.generateCustomizedCodeBytes()); }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Wed Jul 05 22:07:28 2017 +0200 @@ -41,6 +41,7 @@ import static java.lang.invoke.LambdaForm.BasicType.*; import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic; import static java.lang.invoke.MethodHandleStatics.*; +import java.util.Objects; /** * The symbolic, non-executable form of a method handle's invocation semantics. @@ -127,6 +128,7 @@ final MethodHandle customized; @Stable final Name[] names; final String debugName; + final Kind kind; MemberName vmentry; // low-level behavior, or null if not yet prepared private boolean isCompiled; @@ -266,12 +268,48 @@ } } + enum Kind { + GENERIC(""), + ZERO("zero"), + IDENTITY("identity"), + BOUND_REINVOKER("BMH.reinvoke"), + REINVOKER("MH.reinvoke"), + DELEGATE("MH.delegate"), + DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual"), + DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial"), + DIRECT_INVOKE_STATIC("DMH.invokeStatic"), + DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial"), + DIRECT_INVOKE_INTERFACE("DMH.invokeInterface"), + DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit"); + + final String defaultLambdaName; + final String methodName; + + private Kind(String defaultLambdaName) { + this.defaultLambdaName = defaultLambdaName; + int p = defaultLambdaName.indexOf('.'); + if (p > -1) { + this.methodName = defaultLambdaName.substring(p + 1); + } else { + this.methodName = defaultLambdaName; + } + } + } + LambdaForm(String debugName, int arity, Name[] names, int result) { - this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null); + this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC); + } + LambdaForm(String debugName, + int arity, Name[] names, int result, Kind kind) { + this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null, kind); } LambdaForm(String debugName, int arity, Name[] names, int result, boolean forceInline, MethodHandle customized) { + this(debugName, arity, names, result, forceInline, customized, Kind.GENERIC); + } + LambdaForm(String debugName, + int arity, Name[] names, int result, boolean forceInline, MethodHandle customized, Kind kind) { assert(namesOK(arity, names)); this.arity = arity; this.result = fixResult(result, names); @@ -279,6 +317,7 @@ this.debugName = fixDebugName(debugName); this.forceInline = forceInline; this.customized = customized; + this.kind = kind; int maxOutArity = normalize(); if (maxOutArity > MethodType.MAX_MH_INVOKER_ARITY) { // Cannot use LF interpreter on very high arity expressions. @@ -288,11 +327,15 @@ } LambdaForm(String debugName, int arity, Name[] names) { - this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null); + this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC); } LambdaForm(String debugName, int arity, Name[] names, boolean forceInline) { - this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null); + this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, Kind.GENERIC); + } + LambdaForm(String debugName, + int arity, Name[] names, boolean forceInline, Kind kind) { + this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, kind); } LambdaForm(String debugName, Name[] formals, Name[] temps, Name result) { @@ -325,6 +368,7 @@ this.debugName = "LF.zero"; this.forceInline = true; this.customized = null; + this.kind = Kind.GENERIC; assert(nameRefsAreLegal()); assert(isEmpty()); String sig = null; @@ -395,7 +439,7 @@ /** Customize LambdaForm for a particular MethodHandle */ LambdaForm customize(MethodHandle mh) { - LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh); + LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh, kind); if (COMPILE_THRESHOLD >= 0 && isCompiled) { // If shared LambdaForm has been compiled, compile customized version as well. customForm.compileToBytecode(); @@ -773,28 +817,6 @@ } } - /** - * Generate optimizable bytecode for this form after first looking for a - * pregenerated version in a specified class. - */ - void compileToBytecode(Class<?> lookupClass) { - if (vmentry != null && isCompiled) { - return; // already compiled somehow - } - MethodType invokerType = methodType(); - assert(vmentry == null || vmentry.getMethodType().basicType().equals(invokerType)); - int dot = debugName.indexOf('.'); - String methodName = (dot > 0) ? debugName.substring(dot + 1) : debugName; - MemberName member = new MemberName(lookupClass, methodName, invokerType, REF_invokeStatic); - MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, lookupClass); - if (resolvedMember != null) { - vmentry = resolvedMember; - isCompiled = true; - } else { - compileToBytecode(); - } - } - private static void computeInitialPreparedForms() { // Find all predefined invokers and associate them with canonical empty lambda forms. for (MemberName m : MemberName.getFactory().getMethods(LambdaForm.class, false, null, null, null)) { @@ -1828,7 +1850,7 @@ // bootstrap dependency on this method in case we're interpreting LFs if (isVoid) { Name[] idNames = new Name[] { argument(0, L_TYPE) }; - idForm = new LambdaForm(idMem.getName(), 1, idNames, VOID_RESULT); + idForm = new LambdaForm(idMem.getName(), 1, idNames, VOID_RESULT, Kind.IDENTITY); idForm.compileToBytecode(); idFun = new NamedFunction(idMem, SimpleMethodHandle.make(idMem.getInvocationType(), idForm)); @@ -1836,15 +1858,17 @@ zeFun = idFun; } else { Name[] idNames = new Name[] { argument(0, L_TYPE), argument(1, type) }; - idForm = new LambdaForm(idMem.getName(), 2, idNames, 1); + idForm = new LambdaForm(idMem.getName(), 2, idNames, 1, Kind.IDENTITY); idForm.compileToBytecode(); - idFun = new NamedFunction(idMem, SimpleMethodHandle.make(idMem.getInvocationType(), idForm)); + idFun = new NamedFunction(idMem, MethodHandleImpl.makeIntrinsic( + idMem.getInvocationType(), idForm, MethodHandleImpl.Intrinsic.IDENTITY)); Object zeValue = Wrapper.forBasicType(btChar).zero(); Name[] zeNames = new Name[] { argument(0, L_TYPE), new Name(idFun, zeValue) }; - zeForm = new LambdaForm(zeMem.getName(), 1, zeNames, 1); + zeForm = new LambdaForm(zeMem.getName(), 1, zeNames, 1, Kind.ZERO); zeForm.compileToBytecode(); - zeFun = new NamedFunction(zeMem, SimpleMethodHandle.make(zeMem.getInvocationType(), zeForm)); + zeFun = new NamedFunction(zeMem, MethodHandleImpl.makeIntrinsic( + zeMem.getInvocationType(), zeForm, MethodHandleImpl.Intrinsic.ZERO)); } LF_zero[ord] = zeForm; @@ -1901,8 +1925,17 @@ if (USE_PREDEFINED_INTERPRET_METHODS) computeInitialPreparedForms(); NamedFunction.initializeInvokers(); + + // The Holder class will contain pre-generated forms resolved + // using MemberName.getFactory(). However, that doesn't initialize the + // class, which subtly breaks inlining etc. By forcing + // initialization of the Holder class we avoid these issues. + UNSAFE.ensureClassInitialized(Holder.class); } + /* Placeholder class for zero and identity forms generated ahead of time */ + final class Holder {} + // The following hack is necessary in order to suppress TRACE_INTERPRETER // during execution of the static initializes of this class. // Turning on TRACE_INTERPRETER too early will cause
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Wed Jul 05 22:07:28 2017 +0200 @@ -1718,10 +1718,19 @@ } @Override - public byte[] generateDMHClassBytes(String className, - MethodType[] methodTypes, int[] types) { + public byte[] generateDirectMethodHandleHolderClassBytes( + String className, MethodType[] methodTypes, int[] types) { return GenerateJLIClassesHelper - .generateDMHClassBytes(className, methodTypes, types); + .generateDirectMethodHandleHolderClassBytes( + className, methodTypes, types); + } + + @Override + public byte[] generateDelegatingMethodHandleHolderClassBytes( + String className, MethodType[] methodTypes) { + return GenerateJLIClassesHelper + .generateDelegatingMethodHandleHolderClassBytes( + className, methodTypes); } @Override @@ -1730,6 +1739,12 @@ return GenerateJLIClassesHelper .generateConcreteBMHClassBytes(types); } + + @Override + public byte[] generateBasicFormsClassBytes(final String className) { + return GenerateJLIClassesHelper + .generateBasicFormsClassBytes(className); + } }); } @@ -1925,7 +1940,7 @@ * @return whether the counter has reached the limit. */ static boolean countedLoopPredicate(int counter, int limit) { - return counter <= limit; + return counter < limit; } /**
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Wed Jul 05 22:07:28 2017 +0200 @@ -4583,7 +4583,8 @@ * // assume MH_decrement is a handle to x-1 of type int * MethodHandle[] * indexVar = {start, MH_increment}, // i = start; i = i+1 - * loopLimit = {end, null, MH_lessThan, returnVar }, // i<end + * loopLimit = {end, null, + * filterArgument(MH_lessThan, 0, MH_decrement), returnVar}, // i-1<end * bodyClause = {init, * filterArgument(dropArguments(body, 1, int.class), 0, MH_decrement}; // v = body(i-1, v) * return loop(indexVar, loopLimit, bodyClause); @@ -4619,12 +4620,12 @@ MethodHandle actualBody = body == null ? dropArguments(defaultResultHandle, 0, int.class) : body; MethodHandle returnVar = dropArguments(defaultResultHandle, 0, int.class, int.class); MethodHandle actualEnd = end == null ? constant(int.class, 0) : end; + MethodHandle decr = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_decrementCounter); MethodHandle[] indexVar = {start, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopStep)}; MethodHandle[] loopLimit = {actualEnd, null, - MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopPred), returnVar}; - MethodHandle[] bodyClause = {actualInit, - filterArgument(dropArguments(actualBody, 1, int.class), 0, - MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_decrementCounter))}; + filterArgument(MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopPred), 0, decr), + returnVar}; + MethodHandle[] bodyClause = {actualInit, filterArgument(dropArguments(actualBody, 1, int.class), 0, decr)}; return loop(indexVar, loopLimit, bodyClause); }
--- a/jdk/src/java.base/share/classes/java/lang/reflect/AbstractClassLoaderValue.java Mon Aug 22 18:19:31 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,431 +0,0 @@ -/* - * Copyright (c) 2016, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.lang.reflect; - -import jdk.internal.loader.BootLoader; -import jdk.internal.misc.JavaLangAccess; -import jdk.internal.misc.SharedSecrets; - -import java.util.Iterator; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.BiFunction; -import java.util.function.Supplier; - -/** - * AbstractClassLoaderValue is a superclass of root-{@link ClassLoaderValue} - * and {@link Sub sub}-ClassLoaderValue. - * - * @param <CLV> the type of concrete ClassLoaderValue (this type) - * @param <V> the type of values associated with ClassLoaderValue - */ -abstract class AbstractClassLoaderValue<CLV extends AbstractClassLoaderValue<CLV, V>, V> { - - /** - * Sole constructor. - */ - AbstractClassLoaderValue() {} - - /** - * Returns the key component of this ClassLoaderValue. The key component of - * the root-{@link ClassLoaderValue} is the ClassLoaderValue itself, - * while the key component of a {@link #sub(Object) sub}-ClassLoaderValue - * is what was given to construct it. - * - * @return the key component of this ClassLoaderValue. - */ - public abstract Object key(); - - /** - * Constructs new sub-ClassLoaderValue of this ClassLoaderValue with given - * key component. - * - * @param key the key component of the sub-ClassLoaderValue. - * @param <K> the type of the key component. - * @return a sub-ClassLoaderValue of this ClassLoaderValue for given key - */ - public <K> Sub<K> sub(K key) { - return new Sub<>(key); - } - - /** - * Returns {@code true} if this ClassLoaderValue is equal to given {@code clv} - * or if this ClassLoaderValue was derived from given {@code clv} by a chain - * of {@link #sub(Object)} invocations. - * - * @param clv the ClassLoaderValue to test this against - * @return if this ClassLoaderValue is equal to given {@code clv} or - * its descendant - */ - public abstract boolean isEqualOrDescendantOf(AbstractClassLoaderValue<?, V> clv); - - /** - * Returns the value associated with this ClassLoaderValue and given ClassLoader - * or {@code null} if there is none. - * - * @param cl the ClassLoader for the associated value - * @return the value associated with this ClassLoaderValue and given ClassLoader - * or {@code null} if there is none. - */ - public V get(ClassLoader cl) { - Object val = AbstractClassLoaderValue.<CLV>map(cl).get(this); - try { - return extractValue(val); - } catch (Memoizer.RecursiveInvocationException e) { - // propagate recursive get() for the same key that is just - // being calculated in computeIfAbsent() - throw e; - } catch (Throwable t) { - // don't propagate exceptions thrown from Memoizer - pretend - // that there was no entry - // (computeIfAbsent invocation will try to remove it anyway) - return null; - } - } - - /** - * Associates given value {@code v} with this ClassLoaderValue and given - * ClassLoader and returns {@code null} if there was no previously associated - * value or does nothing and returns previously associated value if there - * was one. - * - * @param cl the ClassLoader for the associated value - * @param v the value to associate - * @return previously associated value or null if there was none - */ - public V putIfAbsent(ClassLoader cl, V v) { - ConcurrentHashMap<CLV, Object> map = map(cl); - @SuppressWarnings("unchecked") - CLV clv = (CLV) this; - while (true) { - try { - Object val = map.putIfAbsent(clv, v); - return extractValue(val); - } catch (Memoizer.RecursiveInvocationException e) { - // propagate RecursiveInvocationException for the same key that - // is just being calculated in computeIfAbsent - throw e; - } catch (Throwable t) { - // don't propagate exceptions thrown from foreign Memoizer - - // pretend that there was no entry and retry - // (foreign computeIfAbsent invocation will try to remove it anyway) - } - // TODO: - // Thread.onSpinLoop(); // when available - } - } - - /** - * Removes the value associated with this ClassLoaderValue and given - * ClassLoader if the associated value is equal to given value {@code v} and - * returns {@code true} or does nothing and returns {@code false} if there is - * no currently associated value or it is not equal to given value {@code v}. - * - * @param cl the ClassLoader for the associated value - * @param v the value to compare with currently associated value - * @return {@code true} if the association was removed or {@code false} if not - */ - public boolean remove(ClassLoader cl, Object v) { - return AbstractClassLoaderValue.<CLV>map(cl).remove(this, v); - } - - /** - * Returns the value associated with this ClassLoaderValue and given - * ClassLoader if there is one or computes the value by invoking given - * {@code mappingFunction}, associates it and returns it. - * <p> - * Computation and association of the computed value is performed atomically - * by the 1st thread that requests a particular association while holding a - * lock associated with this ClassLoaderValue and given ClassLoader. - * Nested calls from the {@code mappingFunction} to {@link #get}, - * {@link #putIfAbsent} or {@link #computeIfAbsent} for the same association - * are not allowed and throw {@link IllegalStateException}. Nested call to - * {@link #remove} for the same association is allowed but will always return - * {@code false} regardless of passed-in comparison value. Nested calls for - * other association(s) are allowed, but care should be taken to avoid - * deadlocks. When two threads perform nested computations of the overlapping - * set of associations they should always request them in the same order. - * - * @param cl the ClassLoader for the associated value - * @param mappingFunction the function to compute the value - * @return the value associated with this ClassLoaderValue and given - * ClassLoader. - * @throws IllegalStateException if a direct or indirect invocation from - * within given {@code mappingFunction} that - * computes the value of a particular association - * to {@link #get}, {@link #putIfAbsent} or - * {@link #computeIfAbsent} - * for the same association is attempted. - */ - public V computeIfAbsent(ClassLoader cl, - BiFunction< - ? super ClassLoader, - ? super CLV, - ? extends V - > mappingFunction) throws IllegalStateException { - ConcurrentHashMap<CLV, Object> map = map(cl); - @SuppressWarnings("unchecked") - CLV clv = (CLV) this; - Memoizer<CLV, V> mv = null; - while (true) { - Object val = (mv == null) ? map.get(clv) : map.putIfAbsent(clv, mv); - if (val == null) { - if (mv == null) { - // create Memoizer lazily when 1st needed and restart loop - mv = new Memoizer<>(cl, clv, mappingFunction); - continue; - } - // mv != null, therefore sv == null was a result of successful - // putIfAbsent - try { - // trigger Memoizer to compute the value - V v = mv.get(); - // attempt to replace our Memoizer with the value - map.replace(clv, mv, v); - // return computed value - return v; - } catch (Throwable t) { - // our Memoizer has thrown, attempt to remove it - map.remove(clv, mv); - // propagate exception because it's from our Memoizer - throw t; - } - } else { - try { - return extractValue(val); - } catch (Memoizer.RecursiveInvocationException e) { - // propagate recursive attempts to calculate the same - // value as being calculated at the moment - throw e; - } catch (Throwable t) { - // don't propagate exceptions thrown from foreign Memoizer - - // pretend that there was no entry and retry - // (foreign computeIfAbsent invocation will try to remove it anyway) - } - } - // TODO: - // Thread.onSpinLoop(); // when available - } - } - - /** - * Removes all values associated with given ClassLoader {@code cl} and - * {@link #isEqualOrDescendantOf(AbstractClassLoaderValue) this or descendants} - * of this ClassLoaderValue. - * This is not an atomic operation. Other threads may see some associations - * be already removed and others still present while this method is executing. - * <p> - * The sole intention of this method is to cleanup after a unit test that - * tests ClassLoaderValue directly. It is not intended for use in - * actual algorithms. - * - * @param cl the associated ClassLoader of the values to be removed - */ - public void removeAll(ClassLoader cl) { - ConcurrentHashMap<CLV, Object> map = map(cl); - for (Iterator<CLV> i = map.keySet().iterator(); i.hasNext(); ) { - if (i.next().isEqualOrDescendantOf(this)) { - i.remove(); - } - } - } - - private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); - - /** - * @return a ConcurrentHashMap for given ClassLoader - */ - @SuppressWarnings("unchecked") - private static <CLV extends AbstractClassLoaderValue<CLV, ?>> - ConcurrentHashMap<CLV, Object> map(ClassLoader cl) { - return (ConcurrentHashMap<CLV, Object>) - (cl == null ? BootLoader.getClassLoaderValueMap() - : JLA.createOrGetClassLoaderValueMap(cl)); - } - - /** - * @return value extracted from the {@link Memoizer} if given - * {@code memoizerOrValue} parameter is a {@code Memoizer} or - * just return given parameter. - */ - @SuppressWarnings("unchecked") - private V extractValue(Object memoizerOrValue) { - if (memoizerOrValue instanceof Memoizer) { - return ((Memoizer<?, V>) memoizerOrValue).get(); - } else { - return (V) memoizerOrValue; - } - } - - /** - * A memoized supplier that invokes given {@code mappingFunction} just once - * and remembers the result or thrown exception for subsequent calls. - * If given mappingFunction returns null, it is converted to NullPointerException, - * thrown from the Memoizer's {@link #get()} method and remembered. - * If the Memoizer is invoked recursively from the given {@code mappingFunction}, - * {@link RecursiveInvocationException} is thrown, but it is not remembered. - * The in-flight call to the {@link #get()} can still complete successfully if - * such exception is handled by the mappingFunction. - */ - private static final class Memoizer<CLV extends AbstractClassLoaderValue<CLV, V>, V> - implements Supplier<V> { - - private final ClassLoader cl; - private final CLV clv; - private final BiFunction<? super ClassLoader, ? super CLV, ? extends V> - mappingFunction; - - private volatile V v; - private volatile Throwable t; - private boolean inCall; - - Memoizer(ClassLoader cl, - CLV clv, - BiFunction<? super ClassLoader, ? super CLV, ? extends V> - mappingFunction - ) { - this.cl = cl; - this.clv = clv; - this.mappingFunction = mappingFunction; - } - - @Override - public V get() throws RecursiveInvocationException { - V v = this.v; - if (v != null) return v; - Throwable t = this.t; - if (t == null) { - synchronized (this) { - if ((v = this.v) == null && (t = this.t) == null) { - if (inCall) { - throw new RecursiveInvocationException(); - } - inCall = true; - try { - this.v = v = Objects.requireNonNull( - mappingFunction.apply(cl, clv)); - } catch (Throwable x) { - this.t = t = x; - } finally { - inCall = false; - } - } - } - } - if (v != null) return v; - if (t instanceof Error) { - throw (Error) t; - } else if (t instanceof RuntimeException) { - throw (RuntimeException) t; - } else { - throw new UndeclaredThrowableException(t); - } - } - - static class RecursiveInvocationException extends IllegalStateException { - private static final long serialVersionUID = 1L; - - RecursiveInvocationException() { - super("Recursive call"); - } - } - } - - /** - * sub-ClassLoaderValue is an inner class of {@link AbstractClassLoaderValue} - * and also a subclass of it. It can therefore be instantiated as an inner - * class of either an instance of root-{@link ClassLoaderValue} or another - * instance of itself. This enables composing type-safe compound keys of - * arbitrary length: - * <pre>{@code - * ClassLoaderValue<V> clv = new ClassLoaderValue<>(); - * ClassLoaderValue<V>.Sub<K1>.Sub<K2>.Sub<K3> clv_k123 = - * clv.sub(k1).sub(k2).sub(k3); - * }</pre> - * From which individual components are accessible in a type-safe way: - * <pre>{@code - * K1 k1 = clv_k123.parent().parent().key(); - * K2 k2 = clv_k123.parent().key(); - * K3 k3 = clv_k123.key(); - * }</pre> - * This allows specifying non-capturing lambdas for the mapping function of - * {@link #computeIfAbsent(ClassLoader, BiFunction)} operation that can - * access individual key components from passed-in - * sub-[sub-...]ClassLoaderValue instance in a type-safe way. - * - * @param <K> the type of {@link #key()} component contained in the - * sub-ClassLoaderValue. - */ - final class Sub<K> extends AbstractClassLoaderValue<Sub<K>, V> { - - private final K key; - - Sub(K key) { - this.key = key; - } - - /** - * @return the parent ClassLoaderValue this sub-ClassLoaderValue - * has been {@link #sub(Object) derived} from. - */ - public AbstractClassLoaderValue<CLV, V> parent() { - return AbstractClassLoaderValue.this; - } - - /** - * @return the key component of this sub-ClassLoaderValue. - */ - @Override - public K key() { - return key; - } - - /** - * sub-ClassLoaderValue is a descendant of given {@code clv} if it is - * either equal to it or if its {@link #parent() parent} is a - * descendant of given {@code clv}. - */ - @Override - public boolean isEqualOrDescendantOf(AbstractClassLoaderValue<?, V> clv) { - return equals(Objects.requireNonNull(clv)) || - parent().isEqualOrDescendantOf(clv); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Sub)) return false; - @SuppressWarnings("unchecked") - Sub<?> that = (Sub<?>) o; - return this.parent().equals(that.parent()) && - Objects.equals(this.key, that.key); - } - - @Override - public int hashCode() { - return 31 * parent().hashCode() + - Objects.hashCode(key); - } - } -}
--- a/jdk/src/java.base/share/classes/java/lang/reflect/ClassLoaderValue.java Mon Aug 22 18:19:31 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2016, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.lang.reflect; - -import java.util.Objects; -import java.util.function.BiFunction; - -/** - * root-ClassLoaderValue. Each instance defines a separate namespace for - * associated values. - * <p> - * ClassLoaderValue allows associating a - * {@link #computeIfAbsent(ClassLoader, BiFunction) computed} non-null value with - * a {@code (ClassLoader, keys...)} tuple. The associated value, as well as the - * keys are strongly reachable from the associated ClassLoader so care should be - * taken to use such keys and values that only reference types resolvable from - * the associated ClassLoader. Failing that, ClassLoader leaks are inevitable. - * <p> - * Example usage: - * <pre>{@code - * // create a root instance which represents a namespace and declares the type of - * // associated values (Class instances in this example) - * static final ClassLoaderValue<Class<?>> proxyClasses = new ClassLoaderValue<>(); - * - * // create a compound key composed of a Module and a list of interfaces - * Module module = ...; - * List<Class<?>> interfaces = ...; - * ClassLoaderValue<Class<?>>.Sub<Module>.Sub<List<Class<?>>> key = - * proxyClasses.sub(module).sub(interfaces); - * - * // use the compound key together with ClassLoader to lazily associate - * // the value with tuple (loader, module, interfaces) and return it - * ClassLoader loader = ...; - * Class<?> proxyClass = key.computeIfAbsent(loader, (ld, ky) -> { - * List<Class<?>> intfcs = ky.key(); - * Module m = ky.parent().key(); - * Class<?> clazz = defineProxyClass(ld, m, intfcs); - * return clazz; - * }); - * }</pre> - * <p> - * {@code classLoaderValue.<operation>(classLoader, ...)} represents an operation - * to {@link #get}, {@link #putIfAbsent}, {@link #computeIfAbsent} or {@link #remove} - * a value associated with a (classLoader, classLoaderValue) tuple. ClassLoader - * instances and root-{@link ClassLoaderValue} instances are compared using - * identity equality while {@link Sub sub}-ClassLoaderValue instances define - * {@link #equals(Object) equality} in terms of equality of its - * {@link Sub#parent() parent} ClassLoaderValue and its - * {@link #key() key} component. - * - * @param <V> the type of value(s) associated with the root-ClassLoaderValue and - * all its {@link #sub(Object) descendants}. - * @author Peter Levart - * @since 9 - */ -final class ClassLoaderValue<V> - extends AbstractClassLoaderValue<ClassLoaderValue<V>, V> { - - /** - * Constructs new root-ClassLoaderValue representing its own namespace. - */ - public ClassLoaderValue() {} - - /** - * @return the key component of this root-ClassLoaderValue (itself). - */ - @Override - public ClassLoaderValue<V> key() { - return this; - } - - /** - * root-ClassLoaderValue can only be equal to itself and has no predecessors. - */ - @Override - public boolean isEqualOrDescendantOf(AbstractClassLoaderValue<?, V> clv) { - return equals(Objects.requireNonNull(clv)); - } -}
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java Wed Jul 05 22:07:28 2017 +0200 @@ -29,11 +29,9 @@ import java.security.PrivilegedAction; import java.util.Arrays; import java.util.Collections; -import java.util.Deque; import java.util.HashMap; import java.util.HashSet; import java.util.IdentityHashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -49,6 +47,7 @@ import jdk.internal.misc.VM; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; +import jdk.internal.loader.ClassLoaderValue; import sun.reflect.misc.ReflectUtil; import sun.security.action.GetPropertyAction; import sun.security.util.SecurityConstants;
--- a/jdk/src/java.base/share/classes/java/security/AuthProvider.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/security/AuthProvider.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -50,9 +50,24 @@ * @param name the provider name. * @param version the provider version number. * @param info a description of the provider and its services. + * @deprecated use {@link #AuthProvider(String, String, String)} instead. */ + @Deprecated(since="9") protected AuthProvider(String name, double version, String info) { - super(name, version, info); + super(name, Double.toString(version), info); + } + + /** + * Constructs a provider with the specified name, version string, + * and information. + * + * @param name the provider name. + * @param versionStr the provider version string. + * @param info a description of the provider and its services. + * @since 9 + */ + protected AuthProvider(String name, String versionStr, String info) { + super(name, versionStr, info); } /**
--- a/jdk/src/java.base/share/classes/java/security/Provider.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/security/Provider.java Wed Jul 05 22:07:28 2017 +0200 @@ -67,14 +67,14 @@ * <tr><td>{@code Provider.id name}</td> * <td>{@code String.valueOf(provider.getName())}</td> * <tr><td>{@code Provider.id version}</td> - * <td>{@code String.valueOf(provider.getVersion())}</td> + * <td>{@code String.valueOf(provider.getVersionStr())}</td> * <tr><td>{@code Provider.id info}</td> <td>{@code String.valueOf(provider.getInfo())}</td> * <tr><td>{@code Provider.id className}</td> * <td>{@code provider.getClass().getName()}</td> * </table> * - * <p>Each provider has a name and a version number. A provider normally + * <p>Each provider has a name and a version string. A provider normally * identifies itself with a file named {@code java.security.Provider} * in the resource directory {@code META-INF/services}. * Security providers are looked up via the {@link ServiceLoader} mechanism @@ -102,11 +102,10 @@ public abstract class Provider extends Properties { // Declare serialVersionUID to be compatible with JDK1.1 - static final long serialVersionUID = -4298000515446427739L; + private static final long serialVersionUID = -4298000515446427739L; private static final sun.security.util.Debug debug = - sun.security.util.Debug.getInstance - ("provider", "Provider"); + sun.security.util.Debug.getInstance("provider", "Provider"); /** * The provider name. @@ -129,6 +128,12 @@ */ private double version; + /** + * The provider version string. + * + * @serial + */ + private String versionStr; private transient Set<Map.Entry<Object,Object>> entrySet = null; private transient int entrySetCallCount = 0; @@ -174,19 +179,83 @@ } } + private static double parseVersionStr(String s) { + try { + int firstDotIdx = s.indexOf('.'); + int nextDotIdx = s.indexOf('.', firstDotIdx + 1); + if (nextDotIdx != -1) { + s = s.substring(0, nextDotIdx); + } + int endIdx = s.indexOf('-'); + if (endIdx > 0) { + s = s.substring(0, endIdx); + } + endIdx = s.indexOf('+'); + if (endIdx > 0) { + s = s.substring(0, endIdx); + } + return Double.parseDouble(s); + } catch (NullPointerException | NumberFormatException e) { + return 0d; + } + } + /** * Constructs a provider with the specified name, version number, - * and information. + * and information. Calling this constructor is equivalent to call the + * {@link #Provider(String, String, String)} with {@code name} + * name, {@code Double.toString(version)}, and {@code info}. * * @param name the provider name. * * @param version the provider version number. * * @param info a description of the provider and its services. + * + * @deprecated use {@link #Provider(String, String, String)} instead. */ + @Deprecated(since="9") protected Provider(String name, double version, String info) { this.name = name; this.version = version; + this.versionStr = Double.toString(version); + this.info = info; + putId(); + initialized = true; + } + + /** + * Constructs a provider with the specified name, version string, + * and information. + * + * <p>The version string contains a version number optionally followed + * by other information separated by one of the characters of '+', '-'. + * + * The format for the version number is: + * + * <blockquote><pre> + * ^[0-9]+(\.[0-9]+)* + * </pre></blockquote> + * + * <p>In order to return the version number in a double, when there are + * more than two components (separated by '.' as defined above), only + * the first two components are retained. The resulting string is then + * passed to {@link Double#valueOf(String)} to generate version number, + * i.e. {@link #getVersion}. + * <p>If the conversion failed, value 0 will be used. + * + * @param name the provider name. + * + * @param versionStr the provider version string. + * + * @param info a description of the provider and its services. + * + * @since 9 + */ + protected Provider(String name, String versionStr, String info) { + this.name = name; + this.versionStr = versionStr; + this.version = parseVersionStr(versionStr); this.info = info; putId(); initialized = true; @@ -250,12 +319,26 @@ * Returns the version number for this provider. * * @return the version number for this provider. + * + * @deprecated use {@link #getVersionStr} instead. */ + @Deprecated(since="9") public double getVersion() { return version; } /** + * Returns the version string for this provider. + * + * @return the version string for this provider. + * + * @since 9 + */ + public String getVersionStr() { + return versionStr; + } + + /** * Returns a human-readable description of the provider and its * services. This may return an HTML page, with relevant links. * @@ -266,14 +349,14 @@ } /** - * Returns a string with the name and the version number + * Returns a string with the name and the version string * of this provider. * - * @return the string with the name and the version number + * @return the string with the name and the version string * for this provider. */ public String toString() { - return name + " version " + version; + return name + " version " + versionStr; } /* @@ -601,7 +684,7 @@ public synchronized Object compute(Object key, BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) { check("putProviderProperty." + name); - check("removeProviderProperty" + name); + check("removeProviderProperty." + name); if (debug != null) { debug.println("Compute " + name + " provider property " + key); @@ -632,7 +715,7 @@ public synchronized Object computeIfAbsent(Object key, Function<? super Object, ? extends Object> mappingFunction) { check("putProviderProperty." + name); - check("removeProviderProperty" + name); + check("removeProviderProperty." + name); if (debug != null) { debug.println("ComputeIfAbsent " + name + " provider property " + @@ -662,7 +745,7 @@ public synchronized Object computeIfPresent(Object key, BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) { check("putProviderProperty." + name); - check("removeProviderProperty" + name); + check("removeProviderProperty." + name); if (debug != null) { debug.println("ComputeIfPresent " + name + " provider property " + @@ -695,7 +778,7 @@ public synchronized Object merge(Object key, Object value, BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) { check("putProviderProperty." + name); - check("removeProviderProperty" + name); + check("removeProviderProperty." + name); if (debug != null) { debug.println("Merge " + name + " provider property " + key); @@ -787,11 +870,21 @@ private void putId() { // note: name and info may be null super.put("Provider.id name", String.valueOf(name)); - super.put("Provider.id version", String.valueOf(version)); + super.put("Provider.id version", String.valueOf(versionStr)); super.put("Provider.id info", String.valueOf(info)); super.put("Provider.id className", this.getClass().getName()); } + /** + * Reads the {@code ObjectInputStream} for the default serializable fields. + * If the serialized field {@code versionStr} is found in the STREAM FIELDS, + * its String value will be used to populate both the version string and + * version number. If {@code versionStr} is not found, but {@code version} + * is, then its double value will be used to populate both fields. + * + * @param in the {@code ObjectInputStream} to read + * @serial + */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { Map<Object,Object> copy = new HashMap<>(); @@ -800,6 +893,13 @@ } defaults = null; in.defaultReadObject(); + if (this.versionStr == null) { + // set versionStr based on version when not found in serialized bytes + this.versionStr = Double.toString(this.version); + } else { + // otherwise, set version based on versionStr + this.version = parseVersionStr(this.versionStr); + } implClear(); initialized = true; putAll(copy); @@ -904,8 +1004,8 @@ if (!checkLegacy(key)) { return null; } - legacyStrings.computeIfAbsent((String) key, - (Function<? super String, ? extends String>) remappingFunction); + legacyStrings.compute((String) key, + (BiFunction<? super String,? super String, ? extends String>) remappingFunction); } return super.compute(key, remappingFunction); } @@ -1913,7 +2013,5 @@ return provider.getName() + ": " + type + "." + algorithm + " -> " + className + aString + attrs + "\r\n"; } - } - }
--- a/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java Wed Jul 05 22:07:28 2017 +0200 @@ -399,7 +399,10 @@ * Calendar Elements in the Unicode Locale Data Markup Language * (LDML) specification</a> for more details. * - * @return the month strings. + * @return the month strings. Use + * {@link java.util.Calendar#JANUARY Calendar.JANUARY}, + * {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY}, + * etc. to index the result array. */ public String[] getMonths() { return Arrays.copyOf(months, months.length); @@ -407,7 +410,9 @@ /** * Sets month strings. For example: "January", "February", etc. - * @param newMonths the new month strings. + * @param newMonths the new month strings. The array should + * be indexed by {@link java.util.Calendar#JANUARY Calendar.JANUARY}, + * {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY}, etc. */ public void setMonths(String[] newMonths) { months = Arrays.copyOf(newMonths, newMonths.length); @@ -427,7 +432,10 @@ * Calendar Elements in the Unicode Locale Data Markup Language * (LDML) specification</a> for more details. * - * @return the short month strings. + * @return the short month strings. Use + * {@link java.util.Calendar#JANUARY Calendar.JANUARY}, + * {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY}, + * etc. to index the result array. */ public String[] getShortMonths() { return Arrays.copyOf(shortMonths, shortMonths.length); @@ -435,7 +443,9 @@ /** * Sets short month strings. For example: "Jan", "Feb", etc. - * @param newShortMonths the new short month strings. + * @param newShortMonths the new short month strings. The array should + * be indexed by {@link java.util.Calendar#JANUARY Calendar.JANUARY}, + * {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY}, etc. */ public void setShortMonths(String[] newShortMonths) { shortMonths = Arrays.copyOf(newShortMonths, newShortMonths.length); @@ -444,8 +454,10 @@ /** * Gets weekday strings. For example: "Sunday", "Monday", etc. - * @return the weekday strings. Use <code>Calendar.SUNDAY</code>, - * <code>Calendar.MONDAY</code>, etc. to index the result array. + * @return the weekday strings. Use + * {@link java.util.Calendar#SUNDAY Calendar.SUNDAY}, + * {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc. to index + * the result array. */ public String[] getWeekdays() { return Arrays.copyOf(weekdays, weekdays.length); @@ -454,8 +466,8 @@ /** * Sets weekday strings. For example: "Sunday", "Monday", etc. * @param newWeekdays the new weekday strings. The array should - * be indexed by <code>Calendar.SUNDAY</code>, - * <code>Calendar.MONDAY</code>, etc. + * be indexed by {@link java.util.Calendar#SUNDAY Calendar.SUNDAY}, + * {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc. */ public void setWeekdays(String[] newWeekdays) { weekdays = Arrays.copyOf(newWeekdays, newWeekdays.length); @@ -464,8 +476,10 @@ /** * Gets short weekday strings. For example: "Sun", "Mon", etc. - * @return the short weekday strings. Use <code>Calendar.SUNDAY</code>, - * <code>Calendar.MONDAY</code>, etc. to index the result array. + * @return the short weekday strings. Use + * {@link java.util.Calendar#SUNDAY Calendar.SUNDAY}, + * {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc. to index + * the result array. */ public String[] getShortWeekdays() { return Arrays.copyOf(shortWeekdays, shortWeekdays.length); @@ -474,8 +488,8 @@ /** * Sets short weekday strings. For example: "Sun", "Mon", etc. * @param newShortWeekdays the new short weekday strings. The array should - * be indexed by <code>Calendar.SUNDAY</code>, - * <code>Calendar.MONDAY</code>, etc. + * be indexed by {@link java.util.Calendar#SUNDAY Calendar.SUNDAY}, + * {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc. */ public void setShortWeekdays(String[] newShortWeekdays) { shortWeekdays = Arrays.copyOf(newShortWeekdays, newShortWeekdays.length);
--- a/jdk/src/java.base/share/classes/java/util/Date.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/util/Date.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2016, 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 @@ -952,6 +952,9 @@ * without affecting its internal state. */ static final long getMillisOf(Date date) { + if (date.getClass() != Date.class) { + return date.getTime(); + } if (date.cdate == null || date.cdate.isNormalized()) { return date.fastTime; }
--- a/jdk/src/java.base/share/classes/java/util/stream/Collectors.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/util/stream/Collectors.java Wed Jul 05 22:07:28 2017 +0200 @@ -295,7 +295,13 @@ public static <T> Collector<T, ?, Set<T>> toSet() { return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add, - (left, right) -> { left.addAll(right); return left; }, + (left, right) -> { + if (left.size() < right.size()) { + right.addAll(left); return right; + } else { + left.addAll(right); return left; + } + }, CH_UNORDERED_ID); }
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java Wed Jul 05 22:07:28 2017 +0200 @@ -861,6 +861,13 @@ * be enabled by default, since this list may include cipher suites which * do not meet quality of service requirements for those defaults. Such * cipher suites might be useful in specialized applications. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getEnabledCipherSuites() @@ -880,6 +887,13 @@ * or the requisite certificates (and private keys) for the suite are * not available, or an anonymous suite is enabled but authentication * is required. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getSupportedCipherSuites() @@ -896,6 +910,14 @@ * fail. Following a successful call to this method, only suites * listed in the {@code suites} parameter are enabled for use. * <P> + * Note that the standard list of cipher suite names may be found in the + * <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list or might not + * use the recommended name for a certain cipher suite. + * <P> * See {@link #getEnabledCipherSuites()} for more information * on why a specific cipher suite may never be used on a engine. *
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, 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 @@ -108,7 +108,12 @@ * <p> * Calling this constructor is equivalent to calling the no-args * constructor followed by - * {@code setCipherSuites(cipherSuites);}. + * {@code setCipherSuites(cipherSuites);}. Note that the + * standard list of cipher suite names may be found in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list. * * @param cipherSuites the array of ciphersuites (or null) */ @@ -123,6 +128,12 @@ * Calling this constructor is equivalent to calling the no-args * constructor followed by * {@code setCipherSuites(cipherSuites); setProtocols(protocols);}. + * Note that the standard list of cipher suite names may be found in the + * <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list. * * @param cipherSuites the array of ciphersuites (or null) * @param protocols the array of protocols (or null) @@ -139,6 +150,13 @@ /** * Returns a copy of the array of ciphersuites or null if none * have been set. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return a copy of the array of ciphersuites or null if none * have been set. @@ -150,7 +168,13 @@ /** * Sets the array of ciphersuites. * - * @param cipherSuites the array of ciphersuites (or null) + * @param cipherSuites the array of ciphersuites (or null). Note that the + * standard list of cipher suite names may be found in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list or might not + * use the recommended name for a certain cipher suite. */ public void setCipherSuites(String[] cipherSuites) { this.cipherSuites = clone(cipherSuites);
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java Wed Jul 05 22:07:28 2017 +0200 @@ -195,6 +195,13 @@ * or the requisite certificates (and private keys) for the suite are * not available, or an anonymous suite is enabled but authentication * is required. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suites enabled * @see #getSupportedCipherSuites() @@ -215,6 +222,14 @@ * in this ServerSocket's authentication context will not be used * in any case, even if they are enabled. * <P> + * Note that the standard list of cipher suite names may be found in the + * <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list or might not + * use the recommended name for a certain cipher suite. + * <P> * <code>SSLSocket</code>s returned from <code>accept()</code> * inherit this setting. * @@ -236,6 +251,13 @@ * be enabled by default, since this list may include cipher suites which * do not meet quality of service requirements for those defaults. Such * cipher suites are useful in specialized applications. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getEnabledCipherSuites()
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -123,6 +123,13 @@ * will use one of these cipher suites. The minimum quality of service * for these defaults requires confidentiality protection and server * authentication (that is, no anonymous cipher suites). + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @see #getSupportedCipherSuites() * @return array of the cipher suites enabled by default @@ -137,6 +144,13 @@ * be enabled by default, since this list may include cipher suites which * do not meet quality of service requirements for those defaults. Such * cipher suites are useful in specialized applications. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getDefaultCipherSuites()
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java Wed Jul 05 22:07:28 2017 +0200 @@ -265,6 +265,13 @@ * be enabled by default, since this list may include cipher suites which * do not meet quality of service requirements for those defaults. Such * cipher suites might be useful in specialized applications. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getEnabledCipherSuites() @@ -284,6 +291,13 @@ * or the requisite certificates (and private keys) for the suite are * not available, or an anonymous suite is enabled but authentication * is required. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getSupportedCipherSuites() @@ -300,6 +314,14 @@ * fail. Following a successful call to this method, only suites * listed in the <code>suites</code> parameter are enabled for use. * <P> + * Note that the standard list of cipher suite names may be found in the + * <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list or might not + * use the recommended name for a certain cipher suite. + * <P> * See {@link #getEnabledCipherSuites()} for more information * on why a specific ciphersuite may never be used on a connection. *
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -148,6 +148,13 @@ * will use one of these cipher suites. The minimum quality of service * for these defaults requires confidentiality protection and server * authentication (that is, no anonymous cipher suites). + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @see #getSupportedCipherSuites() * @return array of the cipher suites enabled by default @@ -160,6 +167,13 @@ * be enabled by default, since this list may include cipher suites which * do not meet quality of service requirements for those defaults. Such * cipher suites are useful in specialized applications. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @see #getDefaultCipherSuites() * @return an array of cipher suite names
--- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/jrtfsviewer.js Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/jrtfsviewer.js Wed Jul 05 22:07:28 2017 +0200 @@ -53,6 +53,7 @@ var Files = Java.type("java.nio.file.Files"); var System = Java.type("java.lang.System"); var URI = Java.type("java.net.URI"); +var Collections = Java.type("java.util.Collections"); // JavaFX classes used var StackPane = Java.type("javafx.scene.layout.StackPane"); @@ -100,7 +101,7 @@ print("did you miss specifying jrt-fs.jar with -cp option?"); usage(); } - return FileSystems.newFileSystem(uri, null, cls.classLoader); + return FileSystems.newFileSystem(uri, Collections.emptyMap(), cls.classLoader); } }
--- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/jrtls.js Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/jrtls.js Wed Jul 05 22:07:28 2017 +0200 @@ -34,7 +34,6 @@ * but also compiled and delivered as part of the jrtfs.jar to support access * to the jimage file provided by the shipped JDK by tools running on JDK 8. */ - */ // classes used var Files = Java.type("java.nio.file.Files");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/loader/AbstractClassLoaderValue.java Wed Jul 05 22:07:28 2017 +0200 @@ -0,0 +1,431 @@ +/* + * Copyright (c) 2016, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.loader; + +import jdk.internal.misc.JavaLangAccess; +import jdk.internal.misc.SharedSecrets; + +import java.lang.reflect.UndeclaredThrowableException; +import java.util.Iterator; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.BiFunction; +import java.util.function.Supplier; + +/** + * AbstractClassLoaderValue is a superclass of root-{@link ClassLoaderValue} + * and {@link Sub sub}-ClassLoaderValue. + * + * @param <CLV> the type of concrete ClassLoaderValue (this type) + * @param <V> the type of values associated with ClassLoaderValue + */ +public abstract class AbstractClassLoaderValue<CLV extends AbstractClassLoaderValue<CLV, V>, V> { + + /** + * Sole constructor. + */ + AbstractClassLoaderValue() {} + + /** + * Returns the key component of this ClassLoaderValue. The key component of + * the root-{@link ClassLoaderValue} is the ClassLoaderValue itself, + * while the key component of a {@link #sub(Object) sub}-ClassLoaderValue + * is what was given to construct it. + * + * @return the key component of this ClassLoaderValue. + */ + public abstract Object key(); + + /** + * Constructs new sub-ClassLoaderValue of this ClassLoaderValue with given + * key component. + * + * @param key the key component of the sub-ClassLoaderValue. + * @param <K> the type of the key component. + * @return a sub-ClassLoaderValue of this ClassLoaderValue for given key + */ + public <K> Sub<K> sub(K key) { + return new Sub<>(key); + } + + /** + * Returns {@code true} if this ClassLoaderValue is equal to given {@code clv} + * or if this ClassLoaderValue was derived from given {@code clv} by a chain + * of {@link #sub(Object)} invocations. + * + * @param clv the ClassLoaderValue to test this against + * @return if this ClassLoaderValue is equal to given {@code clv} or + * its descendant + */ + public abstract boolean isEqualOrDescendantOf(AbstractClassLoaderValue<?, V> clv); + + /** + * Returns the value associated with this ClassLoaderValue and given ClassLoader + * or {@code null} if there is none. + * + * @param cl the ClassLoader for the associated value + * @return the value associated with this ClassLoaderValue and given ClassLoader + * or {@code null} if there is none. + */ + public V get(ClassLoader cl) { + Object val = AbstractClassLoaderValue.<CLV>map(cl).get(this); + try { + return extractValue(val); + } catch (Memoizer.RecursiveInvocationException e) { + // propagate recursive get() for the same key that is just + // being calculated in computeIfAbsent() + throw e; + } catch (Throwable t) { + // don't propagate exceptions thrown from Memoizer - pretend + // that there was no entry + // (computeIfAbsent invocation will try to remove it anyway) + return null; + } + } + + /** + * Associates given value {@code v} with this ClassLoaderValue and given + * ClassLoader and returns {@code null} if there was no previously associated + * value or does nothing and returns previously associated value if there + * was one. + * + * @param cl the ClassLoader for the associated value + * @param v the value to associate + * @return previously associated value or null if there was none + */ + public V putIfAbsent(ClassLoader cl, V v) { + ConcurrentHashMap<CLV, Object> map = map(cl); + @SuppressWarnings("unchecked") + CLV clv = (CLV) this; + while (true) { + try { + Object val = map.putIfAbsent(clv, v); + return extractValue(val); + } catch (Memoizer.RecursiveInvocationException e) { + // propagate RecursiveInvocationException for the same key that + // is just being calculated in computeIfAbsent + throw e; + } catch (Throwable t) { + // don't propagate exceptions thrown from foreign Memoizer - + // pretend that there was no entry and retry + // (foreign computeIfAbsent invocation will try to remove it anyway) + } + // TODO: + // Thread.onSpinLoop(); // when available + } + } + + /** + * Removes the value associated with this ClassLoaderValue and given + * ClassLoader if the associated value is equal to given value {@code v} and + * returns {@code true} or does nothing and returns {@code false} if there is + * no currently associated value or it is not equal to given value {@code v}. + * + * @param cl the ClassLoader for the associated value + * @param v the value to compare with currently associated value + * @return {@code true} if the association was removed or {@code false} if not + */ + public boolean remove(ClassLoader cl, Object v) { + return AbstractClassLoaderValue.<CLV>map(cl).remove(this, v); + } + + /** + * Returns the value associated with this ClassLoaderValue and given + * ClassLoader if there is one or computes the value by invoking given + * {@code mappingFunction}, associates it and returns it. + * <p> + * Computation and association of the computed value is performed atomically + * by the 1st thread that requests a particular association while holding a + * lock associated with this ClassLoaderValue and given ClassLoader. + * Nested calls from the {@code mappingFunction} to {@link #get}, + * {@link #putIfAbsent} or {@link #computeIfAbsent} for the same association + * are not allowed and throw {@link IllegalStateException}. Nested call to + * {@link #remove} for the same association is allowed but will always return + * {@code false} regardless of passed-in comparison value. Nested calls for + * other association(s) are allowed, but care should be taken to avoid + * deadlocks. When two threads perform nested computations of the overlapping + * set of associations they should always request them in the same order. + * + * @param cl the ClassLoader for the associated value + * @param mappingFunction the function to compute the value + * @return the value associated with this ClassLoaderValue and given + * ClassLoader. + * @throws IllegalStateException if a direct or indirect invocation from + * within given {@code mappingFunction} that + * computes the value of a particular association + * to {@link #get}, {@link #putIfAbsent} or + * {@link #computeIfAbsent} + * for the same association is attempted. + */ + public V computeIfAbsent(ClassLoader cl, + BiFunction< + ? super ClassLoader, + ? super CLV, + ? extends V + > mappingFunction) throws IllegalStateException { + ConcurrentHashMap<CLV, Object> map = map(cl); + @SuppressWarnings("unchecked") + CLV clv = (CLV) this; + Memoizer<CLV, V> mv = null; + while (true) { + Object val = (mv == null) ? map.get(clv) : map.putIfAbsent(clv, mv); + if (val == null) { + if (mv == null) { + // create Memoizer lazily when 1st needed and restart loop + mv = new Memoizer<>(cl, clv, mappingFunction); + continue; + } + // mv != null, therefore sv == null was a result of successful + // putIfAbsent + try { + // trigger Memoizer to compute the value + V v = mv.get(); + // attempt to replace our Memoizer with the value + map.replace(clv, mv, v); + // return computed value + return v; + } catch (Throwable t) { + // our Memoizer has thrown, attempt to remove it + map.remove(clv, mv); + // propagate exception because it's from our Memoizer + throw t; + } + } else { + try { + return extractValue(val); + } catch (Memoizer.RecursiveInvocationException e) { + // propagate recursive attempts to calculate the same + // value as being calculated at the moment + throw e; + } catch (Throwable t) { + // don't propagate exceptions thrown from foreign Memoizer - + // pretend that there was no entry and retry + // (foreign computeIfAbsent invocation will try to remove it anyway) + } + } + // TODO: + // Thread.onSpinLoop(); // when available + } + } + + /** + * Removes all values associated with given ClassLoader {@code cl} and + * {@link #isEqualOrDescendantOf(AbstractClassLoaderValue) this or descendants} + * of this ClassLoaderValue. + * This is not an atomic operation. Other threads may see some associations + * be already removed and others still present while this method is executing. + * <p> + * The sole intention of this method is to cleanup after a unit test that + * tests ClassLoaderValue directly. It is not intended for use in + * actual algorithms. + * + * @param cl the associated ClassLoader of the values to be removed + */ + public void removeAll(ClassLoader cl) { + ConcurrentHashMap<CLV, Object> map = map(cl); + for (Iterator<CLV> i = map.keySet().iterator(); i.hasNext(); ) { + if (i.next().isEqualOrDescendantOf(this)) { + i.remove(); + } + } + } + + private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); + + /** + * @return a ConcurrentHashMap for given ClassLoader + */ + @SuppressWarnings("unchecked") + private static <CLV extends AbstractClassLoaderValue<CLV, ?>> + ConcurrentHashMap<CLV, Object> map(ClassLoader cl) { + return (ConcurrentHashMap<CLV, Object>) + (cl == null ? BootLoader.getClassLoaderValueMap() + : JLA.createOrGetClassLoaderValueMap(cl)); + } + + /** + * @return value extracted from the {@link Memoizer} if given + * {@code memoizerOrValue} parameter is a {@code Memoizer} or + * just return given parameter. + */ + @SuppressWarnings("unchecked") + private V extractValue(Object memoizerOrValue) { + if (memoizerOrValue instanceof Memoizer) { + return ((Memoizer<?, V>) memoizerOrValue).get(); + } else { + return (V) memoizerOrValue; + } + } + + /** + * A memoized supplier that invokes given {@code mappingFunction} just once + * and remembers the result or thrown exception for subsequent calls. + * If given mappingFunction returns null, it is converted to NullPointerException, + * thrown from the Memoizer's {@link #get()} method and remembered. + * If the Memoizer is invoked recursively from the given {@code mappingFunction}, + * {@link RecursiveInvocationException} is thrown, but it is not remembered. + * The in-flight call to the {@link #get()} can still complete successfully if + * such exception is handled by the mappingFunction. + */ + private static final class Memoizer<CLV extends AbstractClassLoaderValue<CLV, V>, V> + implements Supplier<V> { + + private final ClassLoader cl; + private final CLV clv; + private final BiFunction<? super ClassLoader, ? super CLV, ? extends V> + mappingFunction; + + private volatile V v; + private volatile Throwable t; + private boolean inCall; + + Memoizer(ClassLoader cl, + CLV clv, + BiFunction<? super ClassLoader, ? super CLV, ? extends V> + mappingFunction + ) { + this.cl = cl; + this.clv = clv; + this.mappingFunction = mappingFunction; + } + + @Override + public V get() throws RecursiveInvocationException { + V v = this.v; + if (v != null) return v; + Throwable t = this.t; + if (t == null) { + synchronized (this) { + if ((v = this.v) == null && (t = this.t) == null) { + if (inCall) { + throw new RecursiveInvocationException(); + } + inCall = true; + try { + this.v = v = Objects.requireNonNull( + mappingFunction.apply(cl, clv)); + } catch (Throwable x) { + this.t = t = x; + } finally { + inCall = false; + } + } + } + } + if (v != null) return v; + if (t instanceof Error) { + throw (Error) t; + } else if (t instanceof RuntimeException) { + throw (RuntimeException) t; + } else { + throw new UndeclaredThrowableException(t); + } + } + + static class RecursiveInvocationException extends IllegalStateException { + private static final long serialVersionUID = 1L; + + RecursiveInvocationException() { + super("Recursive call"); + } + } + } + + /** + * sub-ClassLoaderValue is an inner class of {@link AbstractClassLoaderValue} + * and also a subclass of it. It can therefore be instantiated as an inner + * class of either an instance of root-{@link ClassLoaderValue} or another + * instance of itself. This enables composing type-safe compound keys of + * arbitrary length: + * <pre>{@code + * ClassLoaderValue<V> clv = new ClassLoaderValue<>(); + * ClassLoaderValue<V>.Sub<K1>.Sub<K2>.Sub<K3> clv_k123 = + * clv.sub(k1).sub(k2).sub(k3); + * }</pre> + * From which individual components are accessible in a type-safe way: + * <pre>{@code + * K1 k1 = clv_k123.parent().parent().key(); + * K2 k2 = clv_k123.parent().key(); + * K3 k3 = clv_k123.key(); + * }</pre> + * This allows specifying non-capturing lambdas for the mapping function of + * {@link #computeIfAbsent(ClassLoader, BiFunction)} operation that can + * access individual key components from passed-in + * sub-[sub-...]ClassLoaderValue instance in a type-safe way. + * + * @param <K> the type of {@link #key()} component contained in the + * sub-ClassLoaderValue. + */ + public final class Sub<K> extends AbstractClassLoaderValue<Sub<K>, V> { + + private final K key; + + Sub(K key) { + this.key = key; + } + + /** + * @return the parent ClassLoaderValue this sub-ClassLoaderValue + * has been {@link #sub(Object) derived} from. + */ + public AbstractClassLoaderValue<CLV, V> parent() { + return AbstractClassLoaderValue.this; + } + + /** + * @return the key component of this sub-ClassLoaderValue. + */ + @Override + public K key() { + return key; + } + + /** + * sub-ClassLoaderValue is a descendant of given {@code clv} if it is + * either equal to it or if its {@link #parent() parent} is a + * descendant of given {@code clv}. + */ + @Override + public boolean isEqualOrDescendantOf(AbstractClassLoaderValue<?, V> clv) { + return equals(Objects.requireNonNull(clv)) || + parent().isEqualOrDescendantOf(clv); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Sub)) return false; + @SuppressWarnings("unchecked") + Sub<?> that = (Sub<?>) o; + return this.parent().equals(that.parent()) && + Objects.equals(this.key, that.key); + } + + @Override + public int hashCode() { + return 31 * parent().hashCode() + + Objects.hashCode(key); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/loader/ClassLoaderValue.java Wed Jul 05 22:07:28 2017 +0200 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2016, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.loader; + +import java.util.Objects; +import java.util.function.BiFunction; + +/** + * root-ClassLoaderValue. Each instance defines a separate namespace for + * associated values. + * <p> + * ClassLoaderValue allows associating a + * {@link #computeIfAbsent(ClassLoader, BiFunction) computed} non-null value with + * a {@code (ClassLoader, keys...)} tuple. The associated value, as well as the + * keys are strongly reachable from the associated ClassLoader so care should be + * taken to use such keys and values that only reference types resolvable from + * the associated ClassLoader. Failing that, ClassLoader leaks are inevitable. + * <p> + * Example usage: + * <pre>{@code + * // create a root instance which represents a namespace and declares the type of + * // associated values (Class instances in this example) + * static final ClassLoaderValue<Class<?>> proxyClasses = new ClassLoaderValue<>(); + * + * // create a compound key composed of a Module and a list of interfaces + * Module module = ...; + * List<Class<?>> interfaces = ...; + * ClassLoaderValue<Class<?>>.Sub<Module>.Sub<List<Class<?>>> key = + * proxyClasses.sub(module).sub(interfaces); + * + * // use the compound key together with ClassLoader to lazily associate + * // the value with tuple (loader, module, interfaces) and return it + * ClassLoader loader = ...; + * Class<?> proxyClass = key.computeIfAbsent(loader, (ld, ky) -> { + * List<Class<?>> intfcs = ky.key(); + * Module m = ky.parent().key(); + * Class<?> clazz = defineProxyClass(ld, m, intfcs); + * return clazz; + * }); + * }</pre> + * <p> + * {@code classLoaderValue.<operation>(classLoader, ...)} represents an operation + * to {@link #get}, {@link #putIfAbsent}, {@link #computeIfAbsent} or {@link #remove} + * a value associated with a (classLoader, classLoaderValue) tuple. ClassLoader + * instances and root-{@link ClassLoaderValue} instances are compared using + * identity equality while {@link Sub sub}-ClassLoaderValue instances define + * {@link #equals(Object) equality} in terms of equality of its + * {@link Sub#parent() parent} ClassLoaderValue and its + * {@link #key() key} component. + * + * @param <V> the type of value(s) associated with the root-ClassLoaderValue and + * all its {@link #sub(Object) descendants}. + * @author Peter Levart + * @since 9 + */ +public final class ClassLoaderValue<V> + extends AbstractClassLoaderValue<ClassLoaderValue<V>, V> { + + /** + * Constructs new root-ClassLoaderValue representing its own namespace. + */ + public ClassLoaderValue() {} + + /** + * @return the key component of this root-ClassLoaderValue (itself). + */ + @Override + public ClassLoaderValue<V> key() { + return this; + } + + /** + * root-ClassLoaderValue can only be equal to itself and has no predecessors. + */ + @Override + public boolean isEqualOrDescendantOf(AbstractClassLoaderValue<?, V> clv) { + return equals(Objects.requireNonNull(clv)); + } +}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java Wed Jul 05 22:07:28 2017 +0200 @@ -51,8 +51,17 @@ * an {@code int} representing method type. Used by * GenerateJLIClassesPlugin to generate such a class during the jlink phase. */ - byte[] generateDMHClassBytes(String className, MethodType[] methodTypes, - int[] types); + byte[] generateDirectMethodHandleHolderClassBytes(String className, + MethodType[] methodTypes, int[] types); + + /** + * Returns a {@code byte[]} containing the bytecode for a class implementing + * DelegatingMethodHandles of each {@code MethodType} kind in the + * {@code methodTypes} argument. Used by GenerateJLIClassesPlugin to + * generate such a class during the jlink phase. + */ + byte[] generateDelegatingMethodHandleHolderClassBytes(String className, + MethodType[] methodTypes); /** * Returns a {@code byte[]} containing the bytecode for a BoundMethodHandle @@ -63,4 +72,10 @@ */ Map.Entry<String, byte[]> generateConcreteBMHClassBytes( final String types); + + /** + * Returns a {@code byte[]} containing the bytecode for a class implementing + * the zero and identity forms of all {@code LambdaForm.BasicType}s. + */ + byte[] generateBasicFormsClassBytes(final String className); }
--- a/jdk/src/java.base/share/classes/module-info.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/module-info.java Wed Jul 05 22:07:28 2017 +0200 @@ -24,9 +24,8 @@ */ /** - * java.base defines and exports the core APIs of the Java SE platform. + * Defines the foundational APIs of the Java SE Platform. */ - module java.base { exports java.io;
--- a/jdk/src/java.base/share/classes/sun/security/jca/ProviderList.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/sun/security/jca/ProviderList.java Wed Jul 05 22:07:28 2017 +0200 @@ -76,7 +76,7 @@ // dummy provider object to use during initialization // used to avoid explicit null checks in various places private static final Provider EMPTY_PROVIDER = - new Provider("##Empty##", 1.0d, "initialization in progress") { + new Provider("##Empty##", "1.0", "initialization in progress") { private static final long serialVersionUID = 1151354171352296389L; // override getService() to return null slightly faster public Service getService(String type, String algorithm) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/MD4.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/sun/security/provider/MD4.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, 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 @@ -28,6 +28,7 @@ import java.security.*; import static sun.security.provider.ByteArrayAccess.*; +import static sun.security.util.SecurityConstants.PROVIDER_VER; /** * The MD4 class is used to compute an MD4 message digest over a given @@ -65,7 +66,8 @@ private static final Provider md4Provider; static { - md4Provider = new Provider("MD4Provider", 9.0d, "MD4 MessageDigest") { + md4Provider = new Provider("MD4Provider", PROVIDER_VER, + "MD4 MessageDigest") { private static final long serialVersionUID = -8850464997518327965L; }; AccessController.doPrivileged(new PrivilegedAction<Void>() {
--- a/jdk/src/java.base/share/classes/sun/security/provider/Sun.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/sun/security/provider/Sun.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -29,6 +29,8 @@ import java.security.*; import sun.security.action.PutAllAction; +import static sun.security.util.SecurityConstants.PROVIDER_VER; + /** * The SUN Security Provider. @@ -47,7 +49,7 @@ public Sun() { /* We are the SUN provider */ - super("SUN", 9.0d, INFO); + super("SUN", PROVIDER_VER, INFO); // if there is no security manager installed, put directly into // the provider. Otherwise, create a temporary map and use a
--- a/jdk/src/java.base/share/classes/sun/security/provider/VerificationProvider.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/sun/security/provider/VerificationProvider.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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,8 @@ import sun.security.action.PutAllAction; import sun.security.rsa.SunRsaSignEntries; +import static sun.security.util.SecurityConstants.PROVIDER_VER; + /** * Provider used for verification of signed JAR files *if* the Sun and @@ -61,7 +63,7 @@ } public VerificationProvider() { - super("SunJarVerification", 9.0d, "Jar Verification Provider"); + super("SunJarVerification", PROVIDER_VER, "Jar Verification Provider"); // register all algorithms normally registered by the Sun and SunRsaSign // providers, but only if they are missing if (ACTIVE == false) {
--- a/jdk/src/java.base/share/classes/sun/security/rsa/SunRsaSign.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/sun/security/rsa/SunRsaSign.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -30,6 +30,7 @@ import java.security.*; import sun.security.action.PutAllAction; +import static sun.security.util.SecurityConstants.PROVIDER_VER; /** * Provider class for the RSA signature provider. Supports RSA keyfactory, @@ -43,7 +44,7 @@ private static final long serialVersionUID = 866040293550393045L; public SunRsaSign() { - super("SunRsaSign", 9.0d, "Sun RSA signature provider"); + super("SunRsaSign", PROVIDER_VER, "Sun RSA signature provider"); // if there is no security manager installed, put directly into // the provider. Otherwise, create a temporary map and use a
--- a/jdk/src/java.base/share/classes/sun/security/ssl/JsseJce.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/JsseJce.java Wed Jul 05 22:07:28 2017 +0200 @@ -44,6 +44,7 @@ import sun.security.util.ECUtil; import static sun.security.ssl.SunJSSE.cryptoProvider; +import static sun.security.util.SecurityConstants.PROVIDER_VER; /** * This class contains a few static methods for interaction with the JCA/JCE @@ -90,7 +91,7 @@ private static final long serialVersionUID = -3284138292032213752L; SunCertificates(final Provider p) { - super("SunCertificates", 9.0d, "SunJSSE internal"); + super("SunCertificates", PROVIDER_VER, "SunJSSE internal"); AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() {
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SunJSSE.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/SunJSSE.java Wed Jul 05 22:07:28 2017 +0200 @@ -27,6 +27,7 @@ package sun.security.ssl; import java.security.*; +import static sun.security.util.SecurityConstants.PROVIDER_VER; /** * The JSSE provider. @@ -104,7 +105,7 @@ // standard constructor protected SunJSSE() { - super("SunJSSE", 9.0d, info); + super("SunJSSE", PROVIDER_VER, info); subclassCheck(); if (Boolean.TRUE.equals(fips)) { throw new ProviderException @@ -132,7 +133,7 @@ private SunJSSE(java.security.Provider cryptoProvider, String providerName) { - super("SunJSSE", 9.0d, fipsInfo + providerName + ")"); + super("SunJSSE", PROVIDER_VER, fipsInfo + providerName + ")"); subclassCheck(); if (cryptoProvider == null) { // Calling Security.getProvider() will cause other providers to be
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Wed Jul 05 22:07:28 2017 +0200 @@ -3631,8 +3631,8 @@ if (time != null) { if (time.matches("\\d\\d:\\d\\d:\\d\\d")) { c.set(Calendar.HOUR_OF_DAY, Integer.valueOf(time.substring(0, 2))); - c.set(Calendar.MINUTE, Integer.valueOf(time.substring(0, 2))); - c.set(Calendar.SECOND, Integer.valueOf(time.substring(0, 2))); + c.set(Calendar.MINUTE, Integer.valueOf(time.substring(3, 5))); + c.set(Calendar.SECOND, Integer.valueOf(time.substring(6, 8))); c.set(Calendar.MILLISECOND, 0); } else { throw ioe;
--- a/jdk/src/java.base/share/classes/sun/security/util/SecurityConstants.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/sun/security/util/SecurityConstants.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -33,6 +33,7 @@ import java.security.BasicPermission; import java.security.SecurityPermission; import java.security.AllPermission; +import sun.security.action.GetPropertyAction; /** * Permission constants and string constants used to create permissions @@ -145,4 +146,7 @@ // java.lang.SecurityManager public static final SocketPermission LOCAL_LISTEN_PERMISSION = new SocketPermission("localhost:0", SOCKET_LISTEN_ACTION); + + public static final String PROVIDER_VER = + GetPropertyAction.privilegedGetProperty("java.specification.version"); }
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java Wed Jul 05 22:07:28 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, 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 @@ -143,8 +143,8 @@ defaultLocaleProviderAdapter = Type.CLDR; if (!typeList.isEmpty()) { // bona fide preference exists - if (!typeList.contains(Type.CLDR)) { - // Append FALLBACK as the last resort. + if (!(typeList.contains(Type.CLDR) || (typeList.contains(Type.JRE)))) { + // Append FALLBACK as the last resort when no ResourceBundleBasedAdapter is available. typeList.add(Type.FALLBACK); defaultLocaleProviderAdapter = Type.FALLBACK; }
--- a/jdk/src/java.compact1/share/classes/module-info.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.compact1/share/classes/module-info.java Wed Jul 05 22:07:28 2017 +0200 @@ -23,6 +23,9 @@ * questions. */ +/** + * Aggregates {@code java.base}, {@code java.logging}, and {@code java.scripting}. + */ module java.compact1 { requires public java.logging; requires public java.scripting;
--- a/jdk/src/java.compact2/share/classes/module-info.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.compact2/share/classes/module-info.java Wed Jul 05 22:07:28 2017 +0200 @@ -23,6 +23,9 @@ * questions. */ +/** + * Supplements {@code java.compact1} with JDBC, JAXP, and RMI. + */ module java.compact2 { requires public java.compact1; requires public java.rmi;
--- a/jdk/src/java.compact3/share/classes/module-info.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.compact3/share/classes/module-info.java Wed Jul 05 22:07:28 2017 +0200 @@ -23,6 +23,10 @@ * questions. */ +/** + * Supplements {@code java.compact2} with JDBC RowSet, JMX, JNDI, Compiler, + * Instrumentation, Preferences, Security, and XML cryptography APIs. + */ module java.compact3 { requires public java.compact2; requires public java.compiler;
--- a/jdk/src/java.datatransfer/share/classes/module-info.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.datatransfer/share/classes/module-info.java Wed Jul 05 22:07:28 2017 +0200 @@ -24,10 +24,8 @@ */ /** - * Provides interfaces and classes for transferring data between and - * within applications. + * Defines an API for transferring data between and within applications. */ - module java.datatransfer { exports java.awt.datatransfer; exports sun.datatransfer to java.desktop;
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaProgressBarUI.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaProgressBarUI.java Wed Jul 05 22:07:28 2017 +0200 @@ -124,7 +124,9 @@ if (!progressBar.isIndeterminate()) return; stopAnimationTimer(); // start the animation thread - startAnimationTimer(); + if (progressBar.isDisplayable()) { + startAnimationTimer(); + } } if ("JProgressBar.style".equals(prop)) { @@ -141,7 +143,9 @@ public void ancestorAdded(final AncestorEvent e) { if (!progressBar.isIndeterminate()) return; - startAnimationTimer(); + if (progressBar.isDisplayable()) { + startAnimationTimer(); + } } public void ancestorMoved(final AncestorEvent e) { }
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m Wed Jul 05 22:07:28 2017 +0200 @@ -807,6 +807,18 @@ - (void)sendEvent:(NSEvent *)event { if ([event type] == NSLeftMouseDown || [event type] == NSRightMouseDown || [event type] == NSOtherMouseDown) { + // Move parent windows to front and make sure that a child window is displayed + // in front of its nearest parent. + if (self.ownerWindow != nil) { + JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; + jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env]; + if (platformWindow != NULL) { + static JNF_MEMBER_CACHE(jm_orderAboveSiblings, jc_CPlatformWindow, "orderAboveSiblings", "()V"); + JNFCallVoidMethod(env,platformWindow, jm_orderAboveSiblings); + (*env)->DeleteLocalRef(env, platformWindow); + } + } + [self orderChildWindows:YES]; NSPoint p = [NSEvent mouseLocation]; NSRect frame = [self.nsWindow frame]; @@ -1159,6 +1171,16 @@ NSWindow *nsWindow = OBJC(windowPtr); [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ [nsWindow orderBack:nil]; + // Order parent windows + AWTWindow *awtWindow = (AWTWindow*)[nsWindow delegate]; + while (awtWindow.ownerWindow != nil) { + awtWindow = awtWindow.ownerWindow; + if ([AWTWindow isJavaPlatformWindowVisible:awtWindow.nsWindow]) { + [awtWindow.nsWindow orderBack:nil]; + } + } + // Order child windows + [(AWTWindow*)[nsWindow delegate] orderChildWindows:NO]; }]; JNF_COCOA_EXIT(env);
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFColorConverter.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFColorConverter.java Wed Jul 05 22:07:28 2017 +0200 @@ -47,7 +47,7 @@ * @throws NullPointerException if {@code result} is * {@code null}. * @throws ArrayIndexOutOfBoundsException if - * {@code result.length < 3}. + * {@code result.length < 3}. */ public abstract void fromRGB(float r, float g, float b, float[] result); @@ -63,7 +63,7 @@ * @throws NullPointerException if {@code rgb} is * {@code null}. * @throws ArrayIndexOutOfBoundsException if - * {@code rgb.length < 3}. + * {@code rgb.length < 3}. */ public abstract void toRGB(float x0, float x1, float x2, float[] rgb); }
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFDecompressor.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFDecompressor.java Wed Jul 05 22:07:28 2017 +0200 @@ -353,7 +353,7 @@ * <p> The pixels in the source region to be copied are * those with X coordinates of the form {@code activeSrcMinX + * k*subsampleX}, where {@code k} is an integer such - * that {@code 0 ≤ k < dstWidth}. + * that {@code 0 <= k < dstWidth}. */ protected int activeSrcMinX; @@ -365,7 +365,7 @@ * <p> The pixels in the source region to be copied are * those with Y coordinates of the form {@code activeSrcMinY + * k*subsampleY}, where {@code k} is an integer such - * that {@code 0 ≤ k < dstHeight}. + * that {@code 0 <= k < dstHeight}. */ protected int activeSrcMinY;
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFIFD.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFIFD.java Wed Jul 05 22:07:28 2017 +0200 @@ -49,6 +49,45 @@ private long stripOrTileOffsetsPosition = -1; private long lastPosition = -1; + + /** + * Converts a {@code TIFFDirectory} to a {@code TIFFIFD}. + */ + public static TIFFIFD getDirectoryAsIFD(TIFFDirectory dir) { + if(dir instanceof TIFFIFD) { + return (TIFFIFD)dir; + } + + TIFFIFD ifd = new TIFFIFD(Arrays.asList(dir.getTagSets()), + dir.getParentTag()); + TIFFField[] fields = dir.getTIFFFields(); + int numFields = fields.length; + for(int i = 0; i < numFields; i++) { + TIFFField f = fields[i]; + TIFFTag tag = f.getTag(); + if(tag.isIFDPointer()) { + TIFFDirectory subDir = null; + if (f.hasDirectory()) { + subDir = f.getDirectory(); + } else if (f.getData() instanceof TIFFDirectory) { + subDir = (TIFFDirectory)f.getData(); + } + if (subDir != null) { + TIFFDirectory subIFD = getDirectoryAsIFD(subDir); + f = new TIFFField(tag, f.getType(), (long)f.getCount(), + subIFD); + } else { + f = null; + } + } + if (f != null) { + ifd.addTIFFField(f); + } + } + + return ifd; + } + public static TIFFTag getTag(int tagNumber, List<TIFFTagSet> tagSets) { Iterator<TIFFTagSet> iter = tagSets.iterator(); while (iter.hasNext()) { @@ -704,7 +743,7 @@ pos = nextSpace; if (tag.isIFDPointer() && f.hasDirectory()) { - TIFFIFD subIFD = (TIFFIFD)f.getDirectory(); + TIFFIFD subIFD = getDirectoryAsIFD(f.getDirectory()); subIFD.writeToStream(stream); nextSpace = subIFD.lastPosition; } else {
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageMetadata.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageMetadata.java Wed Jul 05 22:07:28 2017 +0200 @@ -132,7 +132,7 @@ if (tag == null) { node = f.getAsNativeNode(); } else if (tag.isIFDPointer() && f.hasDirectory()) { - TIFFIFD subIFD = (TIFFIFD)f.getDirectory(); + TIFFIFD subIFD = TIFFIFD.getDirectoryAsIFD(f.getDirectory()); // Recurse node = getIFDAsTree(subIFD, tag.getName(), tag.getNumber()); @@ -1465,8 +1465,14 @@ String className = st.nextToken(); Object o = null; + Class<?> setClass = null; try { - Class<?> setClass = Class.forName(className); + ClassLoader cl = TIFFImageMetadata.class.getClassLoader(); + setClass = Class.forName(className, false, cl); + if (!TIFFTagSet.class.isAssignableFrom(setClass)) { + fatal(node, "TagSets in IFD must be subset of" + + " TIFFTagSet class"); + } Method getInstanceMethod = setClass.getMethod("getInstance", (Class[])null); o = getInstanceMethod.invoke(null, (Object[])null);
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageReader.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageReader.java Wed Jul 05 22:07:28 2017 +0200 @@ -35,6 +35,7 @@ import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; +import java.io.EOFException; import java.io.IOException; import java.nio.ByteOrder; import java.util.ArrayList; @@ -189,8 +190,8 @@ // Seek to start of first IFD long offset = stream.readUnsignedInt(); + stream.seek(offset); imageStartPosition.add(Long.valueOf(offset)); - stream.seek(offset); } catch (IOException e) { throw new IIOException("I/O error reading header!", e); } @@ -201,10 +202,10 @@ private int locateImage(int imageIndex) throws IIOException { readHeader(); + // Find closest known index + int index = Math.min(imageIndex, imageStartPosition.size() - 1); + try { - // Find closest known index - int index = Math.min(imageIndex, imageStartPosition.size() - 1); - // Seek to that position Long l = imageStartPosition.get(index); stream.seek(l.longValue()); @@ -212,6 +213,11 @@ // Skip IFDs until at desired index or last image found while (index < imageIndex) { int count = stream.readUnsignedShort(); + // If zero-entry IFD, decrement the index and exit the loop + if (count == 0) { + imageIndex = index > 0 ? index - 1 : 0; + break; + } stream.skipBytes(12 * count); long offset = stream.readUnsignedInt(); @@ -219,12 +225,17 @@ return index; } + stream.seek(offset); imageStartPosition.add(Long.valueOf(offset)); - stream.seek(offset); ++index; } - } catch (IOException e) { - throw new IIOException("Couldn't seek!", e); + } catch (EOFException eofe) { + forwardWarningMessage("Ignored " + eofe); + + // Ran off the end of stream: decrement index + imageIndex = index > 0 ? index - 1 : 0; + } catch (IOException ioe) { + throw new IIOException("Couldn't seek!", ioe); } if (currIndex != imageIndex) {
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java Wed Jul 05 22:07:28 2017 +0200 @@ -1478,7 +1478,7 @@ (ExifParentTIFFTagSet.TAG_EXIF_IFD_POINTER); if(f != null && f.hasDirectory()) { // Retrieve the Exif IFD. - exifIFD = (TIFFIFD)f.getDirectory(); + exifIFD = TIFFIFD.getDirectoryAsIFD(f.getDirectory()); } else if(isPrimaryIFD) { // Create the Exif IFD. List<TIFFTagSet> exifTagSets = new ArrayList<TIFFTagSet>(1); @@ -3622,6 +3622,8 @@ streamMetadata = null; imageMetadata = null; + isRescaling = false; + isWritingSequence = false; isWritingEmpty = false; isInsertingEmpty = false;
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFMetadataFormat.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFMetadataFormat.java Wed Jul 05 22:07:28 2017 +0200 @@ -49,7 +49,8 @@ } try { ResourceBundle bundle = - ResourceBundle.getBundle(resourceBaseName, locale); + ResourceBundle.getBundle(resourceBaseName, locale, + this.getClass().getModule()); return bundle.getString(key); } catch (MissingResourceException e) { return null;
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/XPStyle.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/XPStyle.java Wed Jul 05 22:07:28 2017 +0200 @@ -657,7 +657,6 @@ protected void paintToImage(Component c, Image image, Graphics g, int w, int h, Object[] args) { - boolean accEnabled = false; Skin skin = (Skin)args[0]; Part part = skin.part; State state = (State)args[1]; @@ -668,6 +667,8 @@ c = skin.component; } BufferedImage bi = (BufferedImage)image; + w = bi.getWidth(); + h = bi.getHeight(); WritableRaster raster = bi.getRaster(); DataBufferInt dbi = (DataBufferInt)raster.getDataBuffer();
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractDataLine.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractDataLine.java Wed Jul 05 22:07:28 2017 +0200 @@ -32,7 +32,6 @@ import javax.sound.sampled.LineEvent; import javax.sound.sampled.LineUnavailableException; - /** * AbstractDataLine * @@ -147,36 +146,35 @@ } } - public final void open(AudioFormat format) throws LineUnavailableException { open(format, AudioSystem.NOT_SPECIFIED); } - /** * This implementation always returns 0. */ + @Override public int available() { return 0; } + /** + * This implementation does nothing. + */ + @Override + public void drain() { + if (Printer.trace) Printer.trace("AbstractDataLine: drain"); + } /** * This implementation does nothing. */ - public void drain() { - if (Printer.trace) Printer.trace("AbstractDataLine: drain"); - } - - - /** - * This implementation does nothing. - */ + @Override public void flush() { if (Printer.trace) Printer.trace("AbstractDataLine: flush"); } - + @Override public final void start() { //$$fb 2001-10-09: Bug #4517739: avoiding deadlock by synchronizing to mixer ! synchronized(mixer) { @@ -200,7 +198,7 @@ if (Printer.trace) Printer.trace("< "+getClass().getName()+".start() - AbstractDataLine"); } - + @Override public final void stop() { //$$fb 2001-10-09: Bug #4517739: avoiding deadlock by synchronizing to mixer ! @@ -245,15 +243,17 @@ // in MixerSourceLine and MixerClip, and I want to touch as little // code as possible to change isStarted() back to isRunning(). + @Override public final boolean isRunning() { return started; } + @Override public final boolean isActive() { return active; } - + @Override public final long getMicrosecondPosition() { long microseconds = getLongFramePosition(); @@ -263,12 +263,12 @@ return microseconds; } - + @Override public final AudioFormat getFormat() { return format; } - + @Override public final int getBufferSize() { return bufferSize; } @@ -283,11 +283,11 @@ /** * This implementation returns AudioSystem.NOT_SPECIFIED. */ + @Override public final float getLevel() { return (float)AudioSystem.NOT_SPECIFIED; } - // HELPER METHODS /** @@ -317,19 +317,12 @@ synchronized (this) { - //if (Printer.debug) Printer.debug(" AbstractDataLine: setActive: this.active: " + this.active); - //if (Printer.debug) Printer.debug(" active: " + active); - if (this.active != active) { this.active = active; //sendEvents = true; } } - //if (Printer.debug) Printer.debug(" this.active: " + this.active); - //if (Printer.debug) Printer.debug(" sendEvents: " + sendEvents); - - // $$kk: 11.19.99: take ACTIVE / INACTIVE / EOM events out; // putting them in is technically an API change. // do not generate ACTIVE / INACTIVE events for now @@ -356,18 +349,12 @@ synchronized (this) { - //if (Printer.debug) Printer.debug(" AbstractDataLine: setStarted: this.started: " + this.started); - //if (Printer.debug) Printer.debug(" started: " + started); - if (this.started != started) { this.started = started; sendEvents = true; } } - //if (Printer.debug) Printer.debug(" this.started: " + this.started); - //if (Printer.debug) Printer.debug(" sendEvents: " + sendEvents); - if (sendEvents) { if (started) { @@ -379,7 +366,6 @@ if (Printer.trace) Printer.trace("< AbstractDataLine: setStarted completed"); } - /** * This method generates a STOP event and sets the started state to false. * It is here for historic reasons when an EOM event existed. @@ -393,9 +379,6 @@ if (Printer.trace) Printer.trace("< AbstractDataLine: setEOM() completed"); } - - - // OVERRIDES OF ABSTRACT LINE METHODS /** @@ -404,6 +387,7 @@ * line is open, this should return quietly because the values * requested will match the current ones. */ + @Override public final void open() throws LineUnavailableException { if (Printer.trace) Printer.trace("> "+getClass().getName()+".open() - AbstractDataLine"); @@ -413,11 +397,11 @@ if (Printer.trace) Printer.trace("< "+getClass().getName()+".open() - AbstractDataLine"); } - /** * This should also stop the line. The closed line should not be running or active. * After we close the line, we reset the format and buffer size to the defaults. */ + @Override public final void close() { //$$fb 2001-10-09: Bug #4517739: avoiding deadlock by synchronizing to mixer ! synchronized (mixer) { @@ -445,12 +429,6 @@ if (Printer.trace) Printer.trace("< "+getClass().getName()+".close() - in AbstractDataLine"); } - - // IMPLEMENTATIONS OF ABSTRACT LINE ABSTRACE METHODS - - - // ABSTRACT METHODS - abstract void implOpen(AudioFormat format, int bufferSize) throws LineUnavailableException; abstract void implClose();
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractLine.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractLine.java Wed Jul 05 22:07:28 2017 +0200 @@ -36,7 +36,6 @@ import javax.sound.sampled.LineListener; import javax.sound.sampled.LineUnavailableException; - /** * AbstractLine * @@ -72,19 +71,19 @@ this.controls = controls; } - // LINE METHODS + @Override public final Line.Info getLineInfo() { return info; } - + @Override public final boolean isOpen() { return open; } - + @Override public final void addLineListener(LineListener listener) { synchronized(listeners) { if ( ! (listeners.contains(listener)) ) { @@ -93,22 +92,22 @@ } } - /** * Removes an audio listener. * @param listener listener to remove */ + @Override public final void removeLineListener(LineListener listener) { listeners.removeElement(listener); } - /** * Obtains the set of controls supported by the * line. If no controls are supported, returns an * array of length 0. * @return control set */ + @Override public final Control[] getControls() { Control[] returnedArray = new Control[controls.length]; @@ -119,7 +118,7 @@ return returnedArray; } - + @Override public final boolean isControlSupported(Control.Type controlType) { // protect against a NullPointerException if (controlType == null) { @@ -135,7 +134,7 @@ return false; } - + @Override public final Control getControl(Control.Type controlType) { // protect against a NullPointerException if (controlType != null) { @@ -150,10 +149,8 @@ throw new IllegalArgumentException("Unsupported control type: " + controlType); } - // HELPER METHODS - /** * This method sets the open state and generates * events if it changes. @@ -182,7 +179,6 @@ if (Printer.trace) Printer.trace("< "+getClass().getName()+" (AbstractLine): setOpen(" + open + ") this.open: " + this.open); } - /** * Send line events. */ @@ -190,7 +186,6 @@ getEventDispatcher().sendAudioEvents(event, listeners); } - /** * This is an error in the API: getFramePosition * should return a long value. At CD quality, @@ -200,7 +195,6 @@ return (int) getLongFramePosition(); } - /** * Return the frame position in a long value * This implementation returns AudioSystem.NOT_SPECIFIED. @@ -209,7 +203,6 @@ return AudioSystem.NOT_SPECIFIED; } - // $$kk: 06.03.99: returns the mixer used in construction. // this is a hold-over from when there was a public method like // this on line and should be fixed!! @@ -232,8 +225,8 @@ } } - // ABSTRACT METHODS - + @Override public abstract void open() throws LineUnavailableException; + @Override public abstract void close(); }
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDevice.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDevice.java Wed Jul 05 22:07:28 2017 +0200 @@ -26,10 +26,17 @@ package com.sun.media.sound; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.Collections; -import javax.sound.midi.*; +import javax.sound.midi.InvalidMidiDataException; +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiDeviceReceiver; +import javax.sound.midi.MidiDeviceTransmitter; +import javax.sound.midi.MidiMessage; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Receiver; +import javax.sound.midi.Transmitter; /** @@ -43,11 +50,8 @@ */ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice { - // STATIC VARIABLES private static final boolean TRACE_TRANSMITTER = false; - // INSTANCE VARIABLES - private ArrayList<Receiver> receiverList; private TransmitterList transmitterList; @@ -62,7 +66,6 @@ private final MidiDevice.Info info; - // DEVICE STATE private volatile boolean open; @@ -73,15 +76,10 @@ private List<Object> openKeepingObjects; /** - * This is the device handle returned from native code + * This is the device handle returned from native code. */ protected volatile long id; - - - // CONSTRUCTOR - - /** * Constructs an AbstractMidiDevice with the specified info object. * @param info the description of the device @@ -99,9 +97,9 @@ if(Printer.trace) Printer.trace("<< AbstractMidiDevice CONSTRUCTOR completed"); } - // MIDI DEVICE METHODS + @Override public final MidiDevice.Info getDeviceInfo() { return info; } @@ -111,6 +109,7 @@ * opened the device implicitly from closing it. The only way to close the device after * this call is a call to close(). */ + @Override public final void open() throws MidiUnavailableException { if (Printer.trace) Printer.trace("> AbstractMidiDevice: open()"); synchronized(this) { @@ -120,8 +119,6 @@ if (Printer.trace) Printer.trace("< AbstractMidiDevice: open() completed"); } - - /** Open the device implicitly. * This method is intended to be used by AbstractReceiver * and BasicTransmitter. Actually, it is called by getReceiverReferenceCounting() and @@ -146,7 +143,6 @@ if (Printer.trace) Printer.trace("< AbstractMidiDevice: openInternal() completed"); } - private void doOpen() throws MidiUnavailableException { if (Printer.trace) Printer.trace("> AbstractMidiDevice: doOpen()"); synchronized(this) { @@ -158,7 +154,7 @@ if (Printer.trace) Printer.trace("< AbstractMidiDevice: doOpen() completed"); } - + @Override public final void close() { if (Printer.trace) Printer.trace("> AbstractMidiDevice: close()"); synchronized (this) { @@ -168,7 +164,6 @@ if (Printer.trace) Printer.trace("< AbstractMidiDevice: close() completed"); } - /** Close the device for an object that implicitely opened it. * This method is intended to be used by Transmitter.close() and Receiver.close(). * Those methods should pass this for the object parameter. Since Transmitters or Receivers @@ -196,7 +191,6 @@ if (Printer.trace) Printer.trace("< AbstractMidiDevice: closeInternal() completed"); } - public final void doClose() { if (Printer.trace) Printer.trace("> AbstractMidiDevice: doClose()"); synchronized(this) { @@ -208,12 +202,11 @@ if (Printer.trace) Printer.trace("< AbstractMidiDevice: doClose() completed"); } - + @Override public final boolean isOpen() { return open; } - protected void implClose() { synchronized (traRecLock) { if (receiverList != null) { @@ -230,21 +223,21 @@ } } - /** * This implementation always returns -1. * Devices that actually provide this should over-ride * this method. */ + @Override public long getMicrosecondPosition() { return -1; } - /** Return the maximum number of Receivers supported by this device. Depending on the return value of hasReceivers(), this method returns either 0 or -1. Subclasses should rather override hasReceivers() than override this method. */ + @Override public final int getMaxReceivers() { if (hasReceivers()) { return -1; @@ -253,11 +246,11 @@ } } - /** Return the maximum number of Transmitters supported by this device. Depending on the return value of hasTransmitters(), this method returns either 0 or -1. Subclasses should override hasTransmitters(). */ + @Override public final int getMaxTransmitters() { if (hasTransmitters()) { return -1; @@ -266,7 +259,6 @@ } } - /** Retrieve a Receiver for this device. This method returns the value returned by createReceiver(), if it doesn't throw an exception. Subclasses should rather override createReceiver() than override @@ -274,6 +266,7 @@ If createReceiver returns a Receiver, it is added to the internal list of Receivers (see getReceiversList) */ + @Override public final Receiver getReceiver() throws MidiUnavailableException { Receiver receiver; synchronized (traRecLock) { @@ -283,7 +276,7 @@ return receiver; } - + @Override @SuppressWarnings("unchecked") // Cast of result of clone public final List<Receiver> getReceivers() { List<Receiver> recs; @@ -298,12 +291,12 @@ return recs; } - /** * This implementation uses createTransmitter, which may throw an exception. * If a transmitter is returned in createTransmitter, it is added to the internal * TransmitterList */ + @Override public final Transmitter getTransmitter() throws MidiUnavailableException { Transmitter transmitter; synchronized (traRecLock) { @@ -313,7 +306,7 @@ return transmitter; } - + @Override @SuppressWarnings("unchecked") // Cast of result of clone public final List<Transmitter> getTransmitters() { List<Transmitter> tras; @@ -328,19 +321,16 @@ return tras; } - - // HELPER METHODS - final long getId() { return id; } - // REFERENCE COUNTING /** Retrieve a Receiver and open the device implicitly. This method is called by MidiSystem.getReceiver(). */ + @Override public final Receiver getReceiverReferenceCounting() throws MidiUnavailableException { /* Keep this order of commands! If getReceiver() throws an exception, @@ -354,10 +344,10 @@ return receiver; } - /** Retrieve a Transmitter and open the device implicitly. This method is called by MidiSystem.getTransmitter(). */ + @Override public final Transmitter getTransmitterReferenceCounting() throws MidiUnavailableException { /* Keep this order of commands! If getTransmitter() throws an exception, @@ -371,7 +361,6 @@ return transmitter; } - /** Return the list of objects that have opened the device implicitely. */ private synchronized List<Object> getOpenKeepingObjects() { @@ -381,23 +370,19 @@ return openKeepingObjects; } - - // RECEIVER HANDLING METHODS - /** Return the internal list of Receivers, possibly creating it first. */ private List<Receiver> getReceiverList() { synchronized (traRecLock) { if (receiverList == null) { - receiverList = new ArrayList<Receiver>(); + receiverList = new ArrayList<>(); } } return receiverList; } - /** Returns if this device supports Receivers. Subclasses that use Receivers should override this method to return true. They also should override createReceiver(). @@ -408,7 +393,6 @@ return false; } - /** Create a Receiver object. throwing an exception here means that Receivers aren't enabled. Subclasses that use Receivers should override this method with @@ -420,8 +404,6 @@ throw new MidiUnavailableException("MIDI IN receiver not available"); } - - // TRANSMITTER HANDLING /** Return the internal list of Transmitters, possibly creating it first. @@ -435,7 +417,6 @@ return transmitterList; } - /** Returns if this device supports Transmitters. Subclasses that use Transmitters should override this method to return true. They also should override createTransmitter(). @@ -446,7 +427,6 @@ return false; } - /** Create a Transmitter object. throwing an exception here means that Transmitters aren't enabled. Subclasses that use Transmitters should override this method with @@ -458,20 +438,16 @@ throw new MidiUnavailableException("MIDI OUT transmitter not available"); } - // ABSTRACT METHODS - protected abstract void implOpen() throws MidiUnavailableException; - /** - * close this device if discarded by the garbage collector + * close this device if discarded by the garbage collector. */ + @Override protected final void finalize() { close(); } - // INNER CLASSES - /** Base class for Receivers. Subclasses that use Receivers must use this base class, since it contains magic necessary to manage implicit closing the device. @@ -550,6 +526,7 @@ this.tlist = tlist; } + @Override public final void setReceiver(Receiver receiver) { if (tlist != null && this.receiver != receiver) { if (Printer.debug) Printer.debug("Transmitter "+toString()+": set receiver "+receiver); @@ -558,16 +535,17 @@ } } + @Override public final Receiver getReceiver() { return receiver; } - /** Close the Transmitter. * Here, the call to the magic method closeInternal() takes place. * Therefore, subclasses that override this method must call * 'super.close()'. */ + @Override public final void close() { AbstractMidiDevice.this.closeInternal(this); if (tlist != null) { @@ -577,19 +555,19 @@ } } + @Override public final MidiDevice getMidiDevice() { return AbstractMidiDevice.this; } } // class BasicTransmitter - /** - * a class to manage a list of transmitters + * a class to manage a list of transmitters. */ final class TransmitterList { - private final ArrayList<Transmitter> transmitters = new ArrayList<Transmitter>(); + private final ArrayList<Transmitter> transmitters = new ArrayList<>(); private MidiOutDevice.MidiOutReceiver midiOutReceiver; // how many transmitters must be present for optimized @@ -712,9 +690,8 @@ } } - /** - * Send this message to all transmitters + * Send this message to all transmitters. */ void sendMessage(MidiMessage message, long timeStamp) { if (message instanceof FastShortMessage) { @@ -746,8 +723,5 @@ } } } - - } // TransmitterList - }
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDeviceProvider.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDeviceProvider.java Wed Jul 05 22:07:28 2017 +0200 @@ -52,7 +52,6 @@ // also for memory's sake, do not initialize the arrays here } - final synchronized void readDeviceInfos() { Info[] infos = getInfoCache(); MidiDevice[] devices = getDeviceCache(); @@ -148,10 +147,6 @@ throw MidiUtils.unsupportedDevice(info); } - - // INNER CLASSES - - /** * Info class for MidiDevices. Adds an index value for * making native references to a particular device. @@ -182,9 +177,6 @@ } // class Info - - // ABSTRACT METHODS - abstract int getNumDevices(); abstract MidiDevice[] getDeviceCache(); abstract void setDeviceCache(MidiDevice[] devices);
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMixer.java Mon Aug 22 18:19:31 2016 +0200 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMixer.java Wed Jul 05 22:07:28 2017 +0200 @@ -28,9 +28,9 @@ import java.util.Vector; import javax.sound.sampled.Control; -import javax.sound.sampled.Mixer; import javax.sound.sampled.Line; import javax.sound.sampled.LineUnavailableException;