From a354960abb8aa6cfa09bc372a2c97eb98107ac15 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov <kvn@openjdk.org> Date: Mon, 27 Jan 2014 10:20:51 -0800 Subject: [PATCH 001/157] 8032566: Crash in JIT when running Scala compiler (and compiling Scala std lib) Switch off EliminateAutoBox flag by default in jdk8 release. Reviewed-by: iveresov --- hotspot/src/share/vm/opto/c2_globals.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp index 4f45d28666b..093344bb32d 100644 --- a/hotspot/src/share/vm/opto/c2_globals.hpp +++ b/hotspot/src/share/vm/opto/c2_globals.hpp @@ -452,7 +452,7 @@ notproduct(bool, PrintEliminateLocks, false, \ "Print out when locks are eliminated") \ \ - product(bool, EliminateAutoBox, true, \ + product(bool, EliminateAutoBox, false, \ "Control optimizations for autobox elimination") \ \ diagnostic(bool, UseImplicitStableValues, true, \ From f5a766e0367c993c1afa67a648b8d614cafa27fe Mon Sep 17 00:00:00 2001 From: Staffan Larsen <sla@openjdk.org> Date: Sun, 25 May 2014 09:37:20 +0200 Subject: [PATCH 002/157] 8041923: Command line output is missing from jinfo Reviewed-by: dcubed, allwin, jbachorik --- jdk/src/share/classes/sun/tools/jinfo/JInfo.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/jdk/src/share/classes/sun/tools/jinfo/JInfo.java b/jdk/src/share/classes/sun/tools/jinfo/JInfo.java index 4911ef713d9..ce446378ffb 100644 --- a/jdk/src/share/classes/sun/tools/jinfo/JInfo.java +++ b/jdk/src/share/classes/sun/tools/jinfo/JInfo.java @@ -158,6 +158,8 @@ final public class JInfo { sysprops(pid); System.out.println(); flags(pid); + System.out.println(); + commandLine(pid); } else { usage(1); } @@ -248,6 +250,12 @@ final public class JInfo { drain(vm, in); } + private static void commandLine(String pid) throws IOException { + HotSpotVirtualMachine vm = (HotSpotVirtualMachine) attach(pid); + InputStream in = vm.executeJCmd("VM.command_line"); + drain(vm, in); + } + private static void sysprops(String pid) throws IOException { HotSpotVirtualMachine vm = (HotSpotVirtualMachine) attach(pid); InputStream in = vm.executeJCmd("VM.system_properties"); From 61db60f592f5bb4d3f16f97677c76827847071c0 Mon Sep 17 00:00:00 2001 From: Alan Bateman <alanb@openjdk.org> Date: Mon, 26 May 2014 15:52:40 +0100 Subject: [PATCH 003/157] 8043958: Remove unused com.sun.pept classes from jdk repository Reviewed-by: lancea --- jdk/make/CompileJavaClasses.gmk | 2 +- .../share/classes/com/sun/pept/Delegate.java | 67 ------ .../com/sun/pept/encoding/Decoder.java | 69 ------ .../com/sun/pept/encoding/Encoder.java | 70 ------ .../classes/com/sun/pept/ept/Acceptor.java | 54 ----- .../classes/com/sun/pept/ept/ContactInfo.java | 58 ----- .../com/sun/pept/ept/ContactInfoList.java | 55 ----- .../sun/pept/ept/ContactInfoListIterator.java | 64 ----- .../classes/com/sun/pept/ept/EPTFactory.java | 106 --------- .../classes/com/sun/pept/ept/MessageInfo.java | 151 ------------ .../sun/pept/presentation/MessageStruct.java | 223 ------------------ .../com/sun/pept/presentation/Stub.java | 67 ------ .../sun/pept/presentation/TargetFinder.java | 58 ----- .../com/sun/pept/presentation/Tie.java | 78 ------ .../com/sun/pept/protocol/Interceptors.java | 62 ----- .../sun/pept/protocol/MessageDispatcher.java | 73 ------ .../com/sun/pept/transport/Connection.java | 91 ------- 17 files changed, 1 insertion(+), 1347 deletions(-) delete mode 100644 jdk/src/share/classes/com/sun/pept/Delegate.java delete mode 100644 jdk/src/share/classes/com/sun/pept/encoding/Decoder.java delete mode 100644 jdk/src/share/classes/com/sun/pept/encoding/Encoder.java delete mode 100644 jdk/src/share/classes/com/sun/pept/ept/Acceptor.java delete mode 100644 jdk/src/share/classes/com/sun/pept/ept/ContactInfo.java delete mode 100644 jdk/src/share/classes/com/sun/pept/ept/ContactInfoList.java delete mode 100644 jdk/src/share/classes/com/sun/pept/ept/ContactInfoListIterator.java delete mode 100644 jdk/src/share/classes/com/sun/pept/ept/EPTFactory.java delete mode 100644 jdk/src/share/classes/com/sun/pept/ept/MessageInfo.java delete mode 100644 jdk/src/share/classes/com/sun/pept/presentation/MessageStruct.java delete mode 100644 jdk/src/share/classes/com/sun/pept/presentation/Stub.java delete mode 100644 jdk/src/share/classes/com/sun/pept/presentation/TargetFinder.java delete mode 100644 jdk/src/share/classes/com/sun/pept/presentation/Tie.java delete mode 100644 jdk/src/share/classes/com/sun/pept/protocol/Interceptors.java delete mode 100644 jdk/src/share/classes/com/sun/pept/protocol/MessageDispatcher.java delete mode 100644 jdk/src/share/classes/com/sun/pept/transport/Connection.java diff --git a/jdk/make/CompileJavaClasses.gmk b/jdk/make/CompileJavaClasses.gmk index f0ea1835967..6d2acb6708f 100644 --- a/jdk/make/CompileJavaClasses.gmk +++ b/jdk/make/CompileJavaClasses.gmk @@ -38,7 +38,7 @@ EXCLUDES := ########################################################################################## -EXCLUDES += com/sun/pept \ +EXCLUDES += \ com/sun/tools/example/trace \ com/sun/tools/example/debug/bdi \ com/sun/tools/example/debug/event \ diff --git a/jdk/src/share/classes/com/sun/pept/Delegate.java b/jdk/src/share/classes/com/sun/pept/Delegate.java deleted file mode 100644 index 7d29ce00c6b..00000000000 --- a/jdk/src/share/classes/com/sun/pept/Delegate.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "Delegate.java" generated from Poseidon for UML. - * Poseidon for UML is developed by <A HREF="http://www.gentleware.com">Gentleware</A>. - * Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine. - */ -package com.sun.pept; - -import com.sun.pept.presentation.MessageStruct; -import java.util.*; - -/** - * <p> - * - * @author Dr. Harold Carr - * </p> - */ -public interface Delegate { - - /////////////////////////////////////// - // operations - -/** - * <p> - * Does ... - * </p><p> - * - * @return a MessageStruct with ... - * </p> - */ - public MessageStruct getMessageStruct(); -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param message ... - * </p> - */ - public void send(MessageStruct message); - -} // end Delegate diff --git a/jdk/src/share/classes/com/sun/pept/encoding/Decoder.java b/jdk/src/share/classes/com/sun/pept/encoding/Decoder.java deleted file mode 100644 index 3af6e03bc84..00000000000 --- a/jdk/src/share/classes/com/sun/pept/encoding/Decoder.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "Decoder.java" generated from Poseidon for UML. - * Poseidon for UML is developed by <A HREF="http://www.gentleware.com">Gentleware</A>. - * Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine. - */ -package com.sun.pept.encoding; - -import com.sun.pept.ept.MessageInfo; -import java.util.*; - -/** - * <p> - * - * @author Dr. Harold Carr - * </p> - */ -public interface Decoder { - - /////////////////////////////////////// - // operations - -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param messageInfo ... - * </p> - */ - public void decode(MessageInfo messageInfo); -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param messageInfo ... - * </p> - */ - public void receiveAndDecode(MessageInfo messageInfo); - -} // end Decoder diff --git a/jdk/src/share/classes/com/sun/pept/encoding/Encoder.java b/jdk/src/share/classes/com/sun/pept/encoding/Encoder.java deleted file mode 100644 index 66a6d642931..00000000000 --- a/jdk/src/share/classes/com/sun/pept/encoding/Encoder.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "Encoder.java" generated from Poseidon for UML. - * Poseidon for UML is developed by <A HREF="http://www.gentleware.com">Gentleware</A>. - * Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine. - */ -package com.sun.pept.encoding; - -import com.sun.pept.ept.MessageInfo; -import java.nio.ByteBuffer; -import java.util.*; - -/** - * <p> - * - * @author Arun Gupta - * </p> - */ -public interface Encoder { - - /////////////////////////////////////// - // operations - -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param messageInfo ... - * </p> - */ - public void encodeAndSend(MessageInfo messageInfo); -/** - * <p> - * Does ... - * </p><p> - * - * @return a ByteBuffer with ... - * </p><p> - * @param messageInfo ... - * </p> - */ - public ByteBuffer encode(MessageInfo messageInfo); - -} // end Encoder diff --git a/jdk/src/share/classes/com/sun/pept/ept/Acceptor.java b/jdk/src/share/classes/com/sun/pept/ept/Acceptor.java deleted file mode 100644 index 82b59c1198b..00000000000 --- a/jdk/src/share/classes/com/sun/pept/ept/Acceptor.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "Acceptor.java" generated from Poseidon for UML. - * Poseidon for UML is developed by <A HREF="http://www.gentleware.com">Gentleware</A>. - * Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine. - */ -package com.sun.pept.ept; - -import java.util.*; - -/** - * <p> - * - * @author Dr. Harold Carr - * </p> - */ -public interface Acceptor extends EPTFactory { - - /////////////////////////////////////// - // operations - -/** - * <p> - * Does ... - * </p><p> - * - * </p> - */ - public void accept(); - -} // end Acceptor diff --git a/jdk/src/share/classes/com/sun/pept/ept/ContactInfo.java b/jdk/src/share/classes/com/sun/pept/ept/ContactInfo.java deleted file mode 100644 index 2981a5128b3..00000000000 --- a/jdk/src/share/classes/com/sun/pept/ept/ContactInfo.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "ContactInfo.java" generated from Poseidon for UML. - * Poseidon for UML is developed by <A HREF="http://www.gentleware.com">Gentleware</A>. - * Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine. - */ -package com.sun.pept.ept; - -import com.sun.pept.transport.Connection; -import java.util.*; - -/** - * <p> - * - * @author Dr. Harold Carr - * </p> - */ -public interface ContactInfo extends EPTFactory { - - /////////////////////////////////////// - // operations - -/** - * <p> - * Does ... - * </p><p> - * - * @return a Connection with ... - * </p><p> - * @param messageInfo ... - * </p> - */ - public Connection getConnection(MessageInfo messageInfo); - -} // end ContactInfo diff --git a/jdk/src/share/classes/com/sun/pept/ept/ContactInfoList.java b/jdk/src/share/classes/com/sun/pept/ept/ContactInfoList.java deleted file mode 100644 index b1ac49bbaaa..00000000000 --- a/jdk/src/share/classes/com/sun/pept/ept/ContactInfoList.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "ContactInfoList.java" generated from Poseidon for UML. - * Poseidon for UML is developed by <A HREF="http://www.gentleware.com">Gentleware</A>. - * Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine. - */ -package com.sun.pept.ept; - -import java.util.*; - -/** - * <p> - * - * @author Dr. Harold Carr - * </p> - */ -public interface ContactInfoList { - - /////////////////////////////////////// - // operations - -/** - * <p> - * Does ... - * </p><p> - * - * @return a ContactInfoListIterator with ... - * </p> - */ - public ContactInfoListIterator iterator(); - -} // end ContactInfoList diff --git a/jdk/src/share/classes/com/sun/pept/ept/ContactInfoListIterator.java b/jdk/src/share/classes/com/sun/pept/ept/ContactInfoListIterator.java deleted file mode 100644 index 16143ddcb6b..00000000000 --- a/jdk/src/share/classes/com/sun/pept/ept/ContactInfoListIterator.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "ContactInfoListIterator.java" generated from Poseidon for UML. - * Poseidon for UML is developed by <A HREF="http://www.gentleware.com">Gentleware</A>. - * Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine. - */ -package com.sun.pept.ept; - -import java.util.*; - -/** - * <p> - * - * @author Dr. Harold Carr - * </p> - */ -public interface ContactInfoListIterator { - - /////////////////////////////////////// - // operations - -/** - * <p> - * Does ... - * </p><p> - * - * @return a boolean with ... - * </p> - */ - public boolean hasNext(); -/** - * <p> - * Does ... - * </p><p> - * - * @return a ContactInfo with ... - * </p> - */ - public ContactInfo next(); - -} // end ContactInfoListIterator diff --git a/jdk/src/share/classes/com/sun/pept/ept/EPTFactory.java b/jdk/src/share/classes/com/sun/pept/ept/EPTFactory.java deleted file mode 100644 index 05595f09282..00000000000 --- a/jdk/src/share/classes/com/sun/pept/ept/EPTFactory.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "EPTFactory.java" generated from Poseidon for UML. - * Poseidon for UML is developed by <A HREF="http://www.gentleware.com">Gentleware</A>. - * Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine. - */ -package com.sun.pept.ept; - -import com.sun.pept.encoding.Decoder; -import com.sun.pept.encoding.Encoder; -import com.sun.pept.presentation.TargetFinder; -import com.sun.pept.protocol.Interceptors; -import com.sun.pept.protocol.MessageDispatcher; -import java.util.*; - -/** - * <p> - * - * @author Dr. Harold Carr - * </p> - */ -public interface EPTFactory { - - /////////////////////////////////////// - // operations - -/** - * <p> - * Does ... - * </p><p> - * - * @return a MessageDispatcher with ... - * </p><p> - * @param messageInfo ... - * </p> - */ - public MessageDispatcher getMessageDispatcher(MessageInfo messageInfo); -/** - * <p> - * Does ... - * </p><p> - * - * @return a Encoder with ... - * </p><p> - * @param messageInfo ... - * </p> - */ - public Encoder getEncoder(MessageInfo messageInfo); -/** - * <p> - * Does ... - * </p><p> - * - * @return a Decoder with ... - * </p><p> - * @param messageInfo ... - * </p> - */ - public Decoder getDecoder(MessageInfo messageInfo); -/** - * <p> - * Does ... - * </p><p> - * - * @return a Interceptors with ... - * </p><p> - * @param x ... - * </p> - */ - public Interceptors getInterceptors(MessageInfo x); -/** - * <p> - * Does ... - * </p><p> - * - * @return a TargetFinder with ... - * </p><p> - * @param x ... - * </p> - */ - public TargetFinder getTargetFinder(MessageInfo x); - -} // end EPTFactory diff --git a/jdk/src/share/classes/com/sun/pept/ept/MessageInfo.java b/jdk/src/share/classes/com/sun/pept/ept/MessageInfo.java deleted file mode 100644 index 9a4cd159a55..00000000000 --- a/jdk/src/share/classes/com/sun/pept/ept/MessageInfo.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "MessageInfo.java" generated from Poseidon for UML. - * Poseidon for UML is developed by <A HREF="http://www.gentleware.com">Gentleware</A>. - * Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine. - */ -package com.sun.pept.ept; - -import com.sun.pept.encoding.Decoder; -import com.sun.pept.encoding.Encoder; -import com.sun.pept.presentation.MessageStruct; -import com.sun.pept.protocol.MessageDispatcher; -import com.sun.pept.transport.Connection; -import java.util.*; - -/** - * <p> - * - * @author Dr. Harold Carr - * </p> - */ -public interface MessageInfo extends MessageStruct { - - /////////////////////////////////////// - // operations - -/** - * <p> - * Does ... - * </p><p> - * - * @return a EPTFactory with ... - * </p> - */ - public EPTFactory getEPTFactory(); -/** - * <p> - * Does ... - * </p><p> - * - * @return a MessageDispatcher with ... - * </p> - */ - public MessageDispatcher getMessageDispatcher(); -/** - * <p> - * Does ... - * </p><p> - * - * @return a Encoder with ... - * </p> - */ - public Encoder getEncoder(); -/** - * <p> - * Does ... - * </p><p> - * - * @return a Decoder with ... - * </p> - */ - public Decoder getDecoder(); -/** - * <p> - * Does ... - * </p><p> - * - * @return a Connection with ... - * </p> - */ - public Connection getConnection(); -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param eptFactory ... - * </p> - */ - public void setEPTFactory(EPTFactory eptFactory); -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param messageDispatcher ... - * </p> - */ - public void setMessageDispatcher(MessageDispatcher messageDispatcher); -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param encoder ... - * </p> - */ - public void setEncoder(Encoder encoder); -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param decoder ... - * </p> - */ - public void setDecoder(Decoder decoder); -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param connection ... - * </p> - */ - public void setConnection(Connection connection); - -} // end MessageInfo diff --git a/jdk/src/share/classes/com/sun/pept/presentation/MessageStruct.java b/jdk/src/share/classes/com/sun/pept/presentation/MessageStruct.java deleted file mode 100644 index 85f4fc7f889..00000000000 --- a/jdk/src/share/classes/com/sun/pept/presentation/MessageStruct.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "MessageStruct.java" generated from Poseidon for UML. - * Poseidon for UML is developed by <A HREF="http://www.gentleware.com">Gentleware</A>. - * Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine. - */ -package com.sun.pept.presentation; - -import java.util.*; -import java.lang.reflect.Method; -/** - * <p> - * - * @author Dr. Harold Carr - * </p> - */ -public interface MessageStruct { - - /////////////////////////////////////// - //attributes - - -/** - * <p> - * Represents ... - * </p> - */ - public static final int NORMAL_RESPONSE = 0; - -/** - * <p> - * Represents ... - * </p> - */ - public static final int CHECKED_EXCEPTION_RESPONSE = 1; - -/** - * <p> - * Represents ... - * </p> - */ - public static final int UNCHECKED_EXCEPTION_RESPONSE = 2; - -/** - * <p> - * Represents ... - * </p> - */ - public static final int REQUEST_RESPONSE_MEP = 1; - -/** - * <p> - * Represents ... - * </p> - */ - public static final int ONE_WAY_MEP = 2; - -/** - * <p> - * Represents ... - * </p> - */ - public static final int ASYNC_POLL_MEP = 3; - -/** - * <p> - * Represents ... - * </p> - */ - public static final int ASYNC_CALLBACK_MEP = 4; - - /////////////////////////////////////// - // operations - -/** - * <p> - * Does ... - * </p><p> - * - * @param data ... - * </p><p> - * - * </p> - */ - public void setData(Object[] data); -/** - * <p> - * Does ... - * </p><p> - * - * @return a Object[] with ... - * </p> - */ - public Object[] getData(); -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param name ... - * </p><p> - * @param value ... - * </p> - */ - public void setMetaData(Object name, Object value); -/** - * <p> - * Does ... - * </p><p> - * - * @return a Object with ... - * </p><p> - * @param name ... - * </p> - */ - public Object getMetaData(Object name); -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param messageExchangePattern ... - * </p> - */ - public void setMEP(int messageExchangePattern); -/** - * <p> - * Does ... - * </p><p> - * - * @return a int with ... - * </p> - */ - public int getMEP(); -/** - * <p> - * Does ... - * </p><p> - * - * @return a int with ... - * </p> - */ - public int getResponseType(); -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param responseType ... - * </p> - */ - public void setResponseType(int responseType); -/** - * <p> - * Does ... - * </p><p> - * - * @return a Object with ... - * </p> - */ - public Object getResponse(); -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param response ... - * </p> - */ - public void setResponse(Object response); -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param method ... - * </p> - */ - public void setMethod(Method method); -/** - * <p> - * Does ... - * </p><p> - * - * @return a Method with ... - * </p> - */ - public Method getMethod(); - -} // end MessageStruct diff --git a/jdk/src/share/classes/com/sun/pept/presentation/Stub.java b/jdk/src/share/classes/com/sun/pept/presentation/Stub.java deleted file mode 100644 index 4b44dd4e276..00000000000 --- a/jdk/src/share/classes/com/sun/pept/presentation/Stub.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "Stub.java" generated from Poseidon for UML. - * Poseidon for UML is developed by <A HREF="http://www.gentleware.com">Gentleware</A>. - * Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine. - */ -package com.sun.pept.presentation; - -import com.sun.pept.Delegate; -import java.util.*; - -/** - * <p> - * - * @author Dr. Harold Carr - * </p> - */ -public interface Stub { - - /////////////////////////////////////// - // operations - -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param delegate ... - * </p> - */ - public void _setDelegate(Delegate delegate); -/** - * <p> - * Does ... - * </p><p> - * - * @return a Delegate with ... - * </p> - */ - public Delegate _getDelegate(); - -} // end Stub diff --git a/jdk/src/share/classes/com/sun/pept/presentation/TargetFinder.java b/jdk/src/share/classes/com/sun/pept/presentation/TargetFinder.java deleted file mode 100644 index 6fabf9b9404..00000000000 --- a/jdk/src/share/classes/com/sun/pept/presentation/TargetFinder.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "TargetFinder.java" generated from Poseidon for UML. - * Poseidon for UML is developed by <A HREF="http://www.gentleware.com">Gentleware</A>. - * Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine. - */ -package com.sun.pept.presentation; - -import com.sun.pept.ept.MessageInfo; -import java.util.*; - -/** - * <p> - * - * @author Dr. Harold Carr - * </p> - */ -public interface TargetFinder { - - /////////////////////////////////////// - // operations - -/** - * <p> - * Does ... - * </p><p> - * - * @return a Tie with ... - * </p><p> - * @param x ... - * </p> - */ - public Tie findTarget(MessageInfo x); - -} // end TargetFinder diff --git a/jdk/src/share/classes/com/sun/pept/presentation/Tie.java b/jdk/src/share/classes/com/sun/pept/presentation/Tie.java deleted file mode 100644 index ed4dae25c33..00000000000 --- a/jdk/src/share/classes/com/sun/pept/presentation/Tie.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "Tie.java" generated from Poseidon for UML. - * Poseidon for UML is developed by <A HREF="http://www.gentleware.com">Gentleware</A>. - * Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine. - */ -package com.sun.pept.presentation; - -import com.sun.pept.ept.MessageInfo; -import java.util.*; - -/** - * <p> - * - * @author Dr. Harold Carr - * </p> - */ -public interface Tie { - - /////////////////////////////////////// - // operations - -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param servant ... - * </p> - */ - public void _setServant(Object servant); -/** - * <p> - * Does ... - * </p><p> - * - * @return a Object with ... - * </p> - */ - public Object _getServant(); -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param messageInfo ... - * </p> - */ - public void _invoke(MessageInfo messageInfo); - -} // end Tie diff --git a/jdk/src/share/classes/com/sun/pept/protocol/Interceptors.java b/jdk/src/share/classes/com/sun/pept/protocol/Interceptors.java deleted file mode 100644 index acfe1b927dd..00000000000 --- a/jdk/src/share/classes/com/sun/pept/protocol/Interceptors.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** - * $Id: Interceptors.java,v 1.1 2005/05/23 22:09:18 bbissett Exp $ - */ - -/** Java interface "Interceptors.java" generated from Poseidon for UML. - * Poseidon for UML is developed by <A HREF="http://www.gentleware.com">Gentleware</A>. - * Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine. - */ -package com.sun.pept.protocol; - -import com.sun.pept.ept.MessageInfo; -import java.util.*; - -/** - * <p> - * - * @author Dr. Harold Carr - * </p> - */ -public interface Interceptors { - - /////////////////////////////////////// - // operations - -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param messageInfo ... - * </p> - */ - public void interceptMessage(MessageInfo messageInfo); - -} // end Interceptors diff --git a/jdk/src/share/classes/com/sun/pept/protocol/MessageDispatcher.java b/jdk/src/share/classes/com/sun/pept/protocol/MessageDispatcher.java deleted file mode 100644 index 83b81f27236..00000000000 --- a/jdk/src/share/classes/com/sun/pept/protocol/MessageDispatcher.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** - * $Id: MessageDispatcher.java,v 1.1 2005/05/23 22:09:18 bbissett Exp $ - */ - -/** Java interface "MessageDispatcher.java" generated from Poseidon for UML. - * Poseidon for UML is developed by <A HREF="http://www.gentleware.com">Gentleware</A>. - * Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine. - */ -package com.sun.pept.protocol; - -import com.sun.pept.ept.MessageInfo; -import java.util.*; - -/** - * <p> - * - * @author Dr. Harold Carr - * </p> - */ -public interface MessageDispatcher { - - /////////////////////////////////////// - // operations - -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param messageInfo ... - * </p> - */ - public void send(MessageInfo messageInfo); -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param messageInfo ... - * </p> - */ - public void receive(MessageInfo messageInfo); - -} // end MessageDispatcher diff --git a/jdk/src/share/classes/com/sun/pept/transport/Connection.java b/jdk/src/share/classes/com/sun/pept/transport/Connection.java deleted file mode 100644 index 489827fbc59..00000000000 --- a/jdk/src/share/classes/com/sun/pept/transport/Connection.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** - * $Id: Connection.java,v 1.2 2005/07/23 04:09:58 kohlert Exp $ - */ - -/** Java interface "Connection.java" generated from Poseidon for UML. - * Poseidon for UML is developed by <A HREF="http://www.gentleware.com">Gentleware</A>. - * Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine. - */ -package com.sun.pept.transport; - -import com.sun.pept.ept.EPTFactory; -import java.nio.ByteBuffer; -import java.util.*; - -/** - * <p> - * - * @author Dr. Harold Carr - * </p> - */ -public interface Connection { - - /////////////////////////////////////// - // operations - -/** - * <p> - * Does ... - * </p><p> - * - * </p><p> - * - * @param byteBuffer ... - * </p> - */ - public void write(ByteBuffer byteBuffer); -/** - * <p> - * Does ... - * </p><p> - * - * @return a EPTFactory with ... - * </p> - */ - public EPTFactory getEPTFactory(); -/** - * <p> - * Does ... - * </p><p> - * - * @return a int with ... - * </p><p> - * @param byteBuffer ... - * </p> - */ - public int read(ByteBuffer byteBuffer); -/** - * <p> - * Does ... - * </p><p> - * - * </p> - */ - public ByteBuffer readUntilEnd(); - -} // end Connection From 73995e8591af009bedf84e9c1dfdf6ea93e16708 Mon Sep 17 00:00:00 2001 From: Ivan Gerasimov <igerasim@openjdk.org> Date: Mon, 26 May 2014 19:59:28 +0400 Subject: [PATCH 004/157] 8043476: java/util/BitSet/BSMethods.java failed with: java.lang.OutOfMemoryError: Java heap space Reviewed-by: alanb --- jdk/test/java/util/BitSet/BSMethods.java | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/jdk/test/java/util/BitSet/BSMethods.java b/jdk/test/java/util/BitSet/BSMethods.java index 9aa419ac9bf..86d7499a428 100644 --- a/jdk/test/java/util/BitSet/BSMethods.java +++ b/jdk/test/java/util/BitSet/BSMethods.java @@ -26,6 +26,7 @@ * 4979017 4979028 4979031 5030267 6222207 8040806 * @summary Test the operation of the methods of BitSet class * @author Mike McCloskey, Martin Buchholz + * @run main/othervm BSMethods */ import java.util.*; @@ -897,15 +898,20 @@ public class BSMethods { private static void testToString() { check(new BitSet().toString().equals("{}")); check(makeSet(2,3,42,43,234).toString().equals("{2, 3, 42, 43, 234}")); - try { - check(makeSet(Integer.MAX_VALUE-1).toString().equals( - "{" + (Integer.MAX_VALUE-1) + "}")); - check(makeSet(Integer.MAX_VALUE).toString().equals( - "{" + Integer.MAX_VALUE + "}")); - check(makeSet(0, 1, Integer.MAX_VALUE-1, Integer.MAX_VALUE).toString().equals( - "{0, 1, " + (Integer.MAX_VALUE-1) + ", " + Integer.MAX_VALUE + "}")); - } catch (IndexOutOfBoundsException exc) { - fail("toString() with indices near MAX_VALUE"); + + final long MB = 1024*1024; + if (Runtime.getRuntime().maxMemory() >= 512*MB) { + // only run it if we have enough memory + try { + check(makeSet(Integer.MAX_VALUE-1).toString().equals( + "{" + (Integer.MAX_VALUE-1) + "}")); + check(makeSet(Integer.MAX_VALUE).toString().equals( + "{" + Integer.MAX_VALUE + "}")); + check(makeSet(0, 1, Integer.MAX_VALUE-1, Integer.MAX_VALUE).toString().equals( + "{0, 1, " + (Integer.MAX_VALUE-1) + ", " + Integer.MAX_VALUE + "}")); + } catch (IndexOutOfBoundsException exc) { + fail("toString() with indices near MAX_VALUE"); + } } } From b47c2517adb6e45869e435a3a846ecb65f4ae583 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov <vlivanov@openjdk.org> Date: Mon, 24 Feb 2014 18:11:55 +0400 Subject: [PATCH 005/157] 8037210: Get rid of char-based descriptions 'J' of basic types Reviewed-by: jrose, psandoz, twisti --- .../java/lang/invoke/BoundMethodHandle.java | 468 ++++++++--------- .../java/lang/invoke/DirectMethodHandle.java | 12 +- .../lang/invoke/InvokerBytecodeGenerator.java | 277 +++++----- .../classes/java/lang/invoke/LambdaForm.java | 493 +++++++++++++----- .../java/lang/invoke/MethodHandle.java | 27 +- .../java/lang/invoke/MethodHandleImpl.java | 2 +- .../java/lang/invoke/MethodHandleNatives.java | 37 +- .../java/lang/invoke/MethodHandleStatics.java | 13 + .../java/lang/invoke/MethodHandles.java | 13 +- .../java/lang/invoke/SimpleMethodHandle.java | 10 +- jdk/test/java/lang/invoke/LambdaFormTest.java | 78 +++ 11 files changed, 831 insertions(+), 599 deletions(-) create mode 100644 jdk/test/java/lang/invoke/LambdaFormTest.java diff --git a/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java b/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java index ea75ddfef6f..f860c77e5e2 100644 --- a/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java +++ b/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java @@ -26,11 +26,10 @@ package java.lang.invoke; import static jdk.internal.org.objectweb.asm.Opcodes.*; -import static java.lang.invoke.LambdaForm.basicTypes; -import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic; +import static java.lang.invoke.LambdaForm.*; +import static java.lang.invoke.LambdaForm.BasicType.*; import static java.lang.invoke.MethodHandleStatics.*; -import java.lang.invoke.LambdaForm.Name; import java.lang.invoke.LambdaForm.NamedFunction; import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.Field; @@ -61,22 +60,22 @@ import jdk.internal.org.objectweb.asm.Type; // BMH API and internals // - static MethodHandle bindSingle(MethodType type, LambdaForm form, char xtype, Object x) { + static MethodHandle bindSingle(MethodType type, LambdaForm form, BasicType xtype, Object x) { // for some type signatures, there exist pre-defined concrete BMH classes try { switch (xtype) { - case 'L': + case L_TYPE: if (true) return bindSingle(type, form, x); // Use known fast path. - return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('L').constructor[0].invokeBasic(type, form, x); - case 'I': - return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('I').constructor[0].invokeBasic(type, form, ValueConversions.widenSubword(x)); - case 'J': - return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('J').constructor[0].invokeBasic(type, form, (long) x); - case 'F': - return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('F').constructor[0].invokeBasic(type, form, (float) x); - case 'D': - return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('D').constructor[0].invokeBasic(type, form, (double) x); - default : throw new InternalError("unexpected xtype: " + xtype); + return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(L_TYPE).constructor[0].invokeBasic(type, form, x); + case I_TYPE: + return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(I_TYPE).constructor[0].invokeBasic(type, form, ValueConversions.widenSubword(x)); + case J_TYPE: + return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(J_TYPE).constructor[0].invokeBasic(type, form, (long) x); + case F_TYPE: + return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(F_TYPE).constructor[0].invokeBasic(type, form, (float) x); + case D_TYPE: + return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(D_TYPE).constructor[0].invokeBasic(type, form, (double) x); + default : throw newInternalError("unexpected xtype: " + xtype); } } catch (Throwable t) { throw newInternalError(t); @@ -87,23 +86,23 @@ import jdk.internal.org.objectweb.asm.Type; return new Species_L(type, form, x); } - MethodHandle cloneExtend(MethodType type, LambdaForm form, char xtype, Object x) { + MethodHandle cloneExtend(MethodType type, LambdaForm form, BasicType xtype, Object x) { try { switch (xtype) { - case 'L': return cloneExtendL(type, form, x); - case 'I': return cloneExtendI(type, form, ValueConversions.widenSubword(x)); - case 'J': return cloneExtendJ(type, form, (long) x); - case 'F': return cloneExtendF(type, form, (float) x); - case 'D': return cloneExtendD(type, form, (double) x); + case L_TYPE: return copyWithExtendL(type, form, x); + case I_TYPE: return copyWithExtendI(type, form, ValueConversions.widenSubword(x)); + case J_TYPE: return copyWithExtendJ(type, form, (long) x); + case F_TYPE: return copyWithExtendF(type, form, (float) x); + case D_TYPE: return copyWithExtendD(type, form, (double) x); } } catch (Throwable t) { throw newInternalError(t); } - throw new InternalError("unexpected type: " + xtype); + throw newInternalError("unexpected type: " + xtype); } @Override - MethodHandle bindArgument(int pos, char basicType, Object value) { + MethodHandle bindArgument(int pos, BasicType basicType, Object value) { MethodType type = type().dropParameterTypes(pos, pos+1); LambdaForm form = internalForm().bind(1+pos, speciesData()); return cloneExtend(type, form, basicType, value); @@ -111,9 +110,9 @@ import jdk.internal.org.objectweb.asm.Type; @Override MethodHandle dropArguments(MethodType srcType, int pos, int drops) { - LambdaForm form = internalForm().addArguments(pos, srcType.parameterList().subList(pos, pos+drops)); + LambdaForm form = internalForm().addArguments(pos, srcType.parameterList().subList(pos, pos + drops)); try { - return clone(srcType, form); + return copyWith(srcType, form); } catch (Throwable t) { throw newInternalError(t); } @@ -122,26 +121,23 @@ import jdk.internal.org.objectweb.asm.Type; @Override MethodHandle permuteArguments(MethodType newType, int[] reorder) { try { - return clone(newType, form.permuteArguments(1, reorder, basicTypes(newType.parameterList()))); + return copyWith(newType, form.permuteArguments(1, reorder, basicTypes(newType.parameterList()))); } catch (Throwable t) { throw newInternalError(t); } } - static final String EXTENSION_TYPES = "LIJFD"; - static final byte INDEX_L = 0, INDEX_I = 1, INDEX_J = 2, INDEX_F = 3, INDEX_D = 4; - static byte extensionIndex(char type) { - int i = EXTENSION_TYPES.indexOf(type); - if (i < 0) throw new InternalError(); - return (byte) i; - } - /** * Return the {@link SpeciesData} instance representing this BMH species. All subclasses must provide a * static field containing this value, and they must accordingly implement this method. */ /*non-public*/ abstract SpeciesData speciesData(); + /** + * Return the number of fields in this BMH. Equivalent to speciesData().fieldCount(). + */ + /*non-public*/ abstract int fieldCount(); + @Override final Object internalProperties() { return "/BMH="+internalValues(); @@ -159,38 +155,33 @@ import jdk.internal.org.objectweb.asm.Type; /*non-public*/ final Object arg(int i) { try { switch (speciesData().fieldType(i)) { - case 'L': return argL(i); - case 'I': return argI(i); - case 'F': return argF(i); - case 'D': return argD(i); - case 'J': return argJ(i); + case L_TYPE: return speciesData().getters[i].invokeBasic(this); + case I_TYPE: return (int) speciesData().getters[i].invokeBasic(this); + case J_TYPE: return (long) speciesData().getters[i].invokeBasic(this); + case F_TYPE: return (float) speciesData().getters[i].invokeBasic(this); + case D_TYPE: return (double) speciesData().getters[i].invokeBasic(this); } } catch (Throwable ex) { throw newInternalError(ex); } - throw new InternalError("unexpected type: " + speciesData().types+"."+i); + throw new InternalError("unexpected type: " + speciesData().typeChars+"."+i); } - /*non-public*/ final Object argL(int i) throws Throwable { return speciesData().getters[i].invokeBasic(this); } - /*non-public*/ final int argI(int i) throws Throwable { return (int) speciesData().getters[i].invokeBasic(this); } - /*non-public*/ final float argF(int i) throws Throwable { return (float) speciesData().getters[i].invokeBasic(this); } - /*non-public*/ final double argD(int i) throws Throwable { return (double) speciesData().getters[i].invokeBasic(this); } - /*non-public*/ final long argJ(int i) throws Throwable { return (long) speciesData().getters[i].invokeBasic(this); } // // cloning API // - /*non-public*/ abstract BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable; - /*non-public*/ abstract BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable; - /*non-public*/ abstract BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable; - /*non-public*/ abstract BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable; - /*non-public*/ abstract BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable; - /*non-public*/ abstract BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable; + /*non-public*/ abstract BoundMethodHandle copyWith(MethodType mt, LambdaForm lf); + /*non-public*/ abstract BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg); + /*non-public*/ abstract BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg); + /*non-public*/ abstract BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg); + /*non-public*/ abstract BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg); + /*non-public*/ abstract BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg); // The following is a grossly irregular hack: @Override MethodHandle reinvokerTarget() { try { - return (MethodHandle) argL(0); + return (MethodHandle) arg(0); } catch (Throwable ex) { throw newInternalError(ex); } @@ -203,7 +194,7 @@ import jdk.internal.org.objectweb.asm.Type; private // make it private to force users to access the enclosing class first static final class Species_L extends BoundMethodHandle { final Object argL0; - /*non-public*/ Species_L(MethodType mt, LambdaForm lf, Object argL0) { + private Species_L(MethodType mt, LambdaForm lf, Object argL0) { super(mt, lf); this.argL0 = argL0; } @@ -213,140 +204,95 @@ import jdk.internal.org.objectweb.asm.Type; /*non-public*/ SpeciesData speciesData() { return SPECIES_DATA; } - /*non-public*/ static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class); @Override - /*non-public*/ final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable { + /*non-public*/ int fieldCount() { + return 1; + } + /*non-public*/ static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class); + /*non-public*/ static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0) { return new Species_L(mt, lf, argL0); } @Override - /*non-public*/ final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, narg); + /*non-public*/ final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) { + return new Species_L(mt, lf, argL0); } @Override - /*non-public*/ final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, narg); + /*non-public*/ final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) { + try { + return (BoundMethodHandle) SPECIES_DATA.extendWith(L_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg); + } catch (Throwable ex) { + throw uncaughtException(ex); + } } @Override - /*non-public*/ final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, narg); + /*non-public*/ final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) { + try { + return (BoundMethodHandle) SPECIES_DATA.extendWith(I_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg); + } catch (Throwable ex) { + throw uncaughtException(ex); + } } @Override - /*non-public*/ final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, narg); + /*non-public*/ final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) { + try { + return (BoundMethodHandle) SPECIES_DATA.extendWith(J_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg); + } catch (Throwable ex) { + throw uncaughtException(ex); + } } @Override - /*non-public*/ final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, narg); + /*non-public*/ final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) { + try { + return (BoundMethodHandle) SPECIES_DATA.extendWith(F_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg); + } catch (Throwable ex) { + throw uncaughtException(ex); + } + } + @Override + /*non-public*/ final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) { + try { + return (BoundMethodHandle) SPECIES_DATA.extendWith(D_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg); + } catch (Throwable ex) { + throw uncaughtException(ex); + } } } -/* - static final class Species_LL extends BoundMethodHandle { - final Object argL0; - final Object argL1; - public Species_LL(MethodType mt, LambdaForm lf, Object argL0, Object argL1) { - super(mt, lf); - this.argL0 = argL0; - this.argL1 = argL1; - } - @Override - public SpeciesData speciesData() { - return SPECIES_DATA; - } - public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LL", Species_LL.class); - @Override - public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable { - return new Species_LL(mt, lf, argL0, argL1); - } - @Override - public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg); - } - @Override - public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg); - } - @Override - public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg); - } - @Override - public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg); - } - @Override - public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg); - } - } - - static final class Species_JL extends BoundMethodHandle { - final long argJ0; - final Object argL1; - public Species_JL(MethodType mt, LambdaForm lf, long argJ0, Object argL1) { - super(mt, lf); - this.argJ0 = argJ0; - this.argL1 = argL1; - } - @Override - public SpeciesData speciesData() { - return SPECIES_DATA; - } - public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("JL", Species_JL.class); - @Override public final long argJ0() { return argJ0; } - @Override public final Object argL1() { return argL1; } - @Override - public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable { - return new Species_JL(mt, lf, argJ0, argL1); - } - @Override - public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg); - } - @Override - public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg); - } - @Override - public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg); - } - @Override - public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg); - } - @Override - public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg); - } - } -*/ - // // BMH species meta-data // /** - * Meta-data wrapper for concrete BMH classes. + * Meta-data wrapper for concrete BMH types. + * Each BMH type corresponds to a given sequence of basic field types (LIJFD). + * The fields are immutable; their values are fully specified at object construction. + * Each BMH type supplies an array of getter functions which may be used in lambda forms. + * A BMH is constructed by cloning a shorter BMH and adding one or more new field values. + * As a degenerate and common case, the "shorter BMH" can be missing, and contributes zero prior fields. */ static class SpeciesData { - final String types; + final String typeChars; + final BasicType[] typeCodes; final Class<? extends BoundMethodHandle> clazz; // Bootstrapping requires circular relations MH -> BMH -> SpeciesData -> MH // Therefore, we need a non-final link in the chain. Use array elements. final MethodHandle[] constructor; final MethodHandle[] getters; + final NamedFunction[] nominalGetters; final SpeciesData[] extensions; /*non-public*/ int fieldCount() { - return types.length(); + return typeCodes.length; } - /*non-public*/ char fieldType(int i) { - return types.charAt(i); + /*non-public*/ BasicType fieldType(int i) { + return typeCodes[i]; + } + /*non-public*/ char fieldTypeChar(int i) { + return typeChars.charAt(i); } public String toString() { - return "SpeciesData["+(isPlaceholder() ? "<placeholder>" : clazz.getSimpleName())+":"+types+"]"; + return "SpeciesData["+(isPlaceholder() ? "<placeholder>" : clazz.getSimpleName())+":"+typeChars+"]"; } /** @@ -354,45 +300,46 @@ import jdk.internal.org.objectweb.asm.Type; * represents a MH bound to a generic invoker, which in turn forwards to the corresponding * getter. */ - Name getterName(Name mhName, int i) { - MethodHandle mh = getters[i]; - assert(mh != null) : this+"."+i; - return new Name(mh, mhName); - } - NamedFunction getterFunction(int i) { - return new NamedFunction(getters[i]); + return nominalGetters[i]; } static final SpeciesData EMPTY = new SpeciesData("", BoundMethodHandle.class); private SpeciesData(String types, Class<? extends BoundMethodHandle> clazz) { - this.types = types; + this.typeChars = types; + this.typeCodes = basicTypes(types); this.clazz = clazz; if (!INIT_DONE) { - this.constructor = new MethodHandle[1]; + this.constructor = new MethodHandle[1]; // only one ctor this.getters = new MethodHandle[types.length()]; + this.nominalGetters = new NamedFunction[types.length()]; } else { this.constructor = Factory.makeCtors(clazz, types, null); this.getters = Factory.makeGetters(clazz, types, null); + this.nominalGetters = Factory.makeNominalGetters(types, null, this.getters); } - this.extensions = new SpeciesData[EXTENSION_TYPES.length()]; + this.extensions = new SpeciesData[ARG_TYPE_LIMIT]; } private void initForBootstrap() { assert(!INIT_DONE); if (constructor[0] == null) { + String types = typeChars; Factory.makeCtors(clazz, types, this.constructor); Factory.makeGetters(clazz, types, this.getters); + Factory.makeNominalGetters(types, this.nominalGetters, this.getters); } } - private SpeciesData(String types) { + private SpeciesData(String typeChars) { // Placeholder only. - this.types = types; + this.typeChars = typeChars; + this.typeCodes = basicTypes(typeChars); this.clazz = null; this.constructor = null; this.getters = null; + this.nominalGetters = null; this.extensions = null; } private boolean isPlaceholder() { return clazz == null; } @@ -401,18 +348,15 @@ import jdk.internal.org.objectweb.asm.Type; static { CACHE.put("", EMPTY); } // make bootstrap predictable private static final boolean INIT_DONE; // set after <clinit> finishes... - SpeciesData extendWithType(char type) { - int i = extensionIndex(type); - SpeciesData d = extensions[i]; - if (d != null) return d; - extensions[i] = d = get(types+type); - return d; + SpeciesData extendWith(byte type) { + return extendWith(BasicType.basicType(type)); } - SpeciesData extendWithIndex(byte index) { - SpeciesData d = extensions[index]; + SpeciesData extendWith(BasicType type) { + int ord = type.ordinal(); + SpeciesData d = extensions[ord]; if (d != null) return d; - extensions[index] = d = get(types+EXTENSION_TYPES.charAt(index)); + extensions[ord] = d = get(typeChars+type.basicTypeChar()); return d; } @@ -456,8 +400,6 @@ import jdk.internal.org.objectweb.asm.Type; static { // pre-fill the BMH speciesdata cache with BMH's inner classes final Class<BoundMethodHandle> rootCls = BoundMethodHandle.class; - SpeciesData d0 = BoundMethodHandle.SPECIES_DATA; // trigger class init - assert(d0 == null || d0 == lookupCache("")) : d0; try { for (Class<?> c : rootCls.getDeclaredClasses()) { if (rootCls.isAssignableFrom(c)) { @@ -465,7 +407,7 @@ import jdk.internal.org.objectweb.asm.Type; SpeciesData d = Factory.speciesDataFromConcreteBMHClass(cbmh); assert(d != null) : cbmh.getName(); assert(d.clazz == cbmh); - assert(d == lookupCache(d.types)); + assert(d == lookupCache(d.typeChars)); } } } catch (Throwable e) { @@ -516,11 +458,10 @@ import jdk.internal.org.objectweb.asm.Type; static final String BMHSPECIES_DATA_GFC_SIG = "(" + JLS_SIG + JLC_SIG + ")" + SPECIES_DATA_SIG; static final String MYSPECIES_DATA_SIG = "()" + SPECIES_DATA_SIG; static final String VOID_SIG = "()V"; + static final String INT_SIG = "()I"; static final String SIG_INCIPIT = "(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;"; - static final Class<?>[] TYPES = new Class<?>[] { Object.class, int.class, long.class, float.class, double.class }; - static final String[] E_THROWABLE = new String[] { "java/lang/Throwable" }; /** @@ -551,31 +492,35 @@ import jdk.internal.org.objectweb.asm.Type; * final Object argL0; * final Object argL1; * final int argI2; - * Species_LLI(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) { + * private Species_LLI(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) { * super(mt, lf); * this.argL0 = argL0; * this.argL1 = argL1; * this.argI2 = argI2; * } * final SpeciesData speciesData() { return SPECIES_DATA; } + * final int fieldCount() { return 3; } * static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LLI", Species_LLI.class); - * final BoundMethodHandle clone(MethodType mt, LambdaForm lf) { - * return SPECIES_DATA.constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2); + * static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) { + * return new Species_LLI(mt, lf, argL0, argL1, argI2); * } - * final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) { - * return SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); + * final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) { + * return new Species_LLI(mt, lf, argL0, argL1, argI2); * } - * final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) { - * return SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); + * final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) { + * return SPECIES_DATA.extendWith(L_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); * } - * final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) { - * return SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); + * final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) { + * return SPECIES_DATA.extendWith(I_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); * } - * final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) { - * return SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); + * final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) { + * return SPECIES_DATA.extendWith(J_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); * } - * final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) { - * return SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); + * final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) { + * return SPECIES_DATA.extendWith(F_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); + * } + * public final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) { + * return SPECIES_DATA.extendWith(D_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); * } * } * </pre> @@ -586,8 +531,9 @@ import jdk.internal.org.objectweb.asm.Type; static Class<? extends BoundMethodHandle> generateConcreteBMHClass(String types) { final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES); - final String className = SPECIES_PREFIX_PATH + types; - final String sourceFile = SPECIES_PREFIX_NAME + types; + String shortTypes = LambdaForm.shortenSignature(types); + final String className = SPECIES_PREFIX_PATH + shortTypes; + final String sourceFile = SPECIES_PREFIX_NAME + shortTypes; final int NOT_ACC_PUBLIC = 0; // not ACC_PUBLIC cw.visit(V1_6, NOT_ACC_PUBLIC + ACC_FINAL + ACC_SUPER, className, null, BMH, null); cw.visitSource(sourceFile, null); @@ -606,11 +552,11 @@ import jdk.internal.org.objectweb.asm.Type; MethodVisitor mv; // emit constructor - mv = cw.visitMethod(NOT_ACC_PUBLIC, "<init>", makeSignature(types, true), null, null); + mv = cw.visitMethod(ACC_PRIVATE, "<init>", makeSignature(types, true), null, null); mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 1); - mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ALOAD, 0); // this + mv.visitVarInsn(ALOAD, 1); // type + mv.visitVarInsn(ALOAD, 2); // form mv.visitMethodInsn(INVOKESPECIAL, BMH, "<init>", makeSignature("", true), false); @@ -647,39 +593,73 @@ import jdk.internal.org.objectweb.asm.Type; mv.visitMaxs(0, 0); mv.visitEnd(); - // emit clone() - mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "clone", makeSignature("", false), null, E_THROWABLE); + // emit implementation of fieldCount() + mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "fieldCount", INT_SIG, null, null); mv.visitCode(); - // return speciesData().constructor[0].invokeBasic(mt, lf, argL0, ...) - // obtain constructor - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG); - mv.visitFieldInsn(GETFIELD, SPECIES_DATA, "constructor", "[" + MH_SIG); - mv.visitInsn(ICONST_0); - mv.visitInsn(AALOAD); + int fc = types.length(); + if (fc <= (ICONST_5 - ICONST_0)) { + mv.visitInsn(ICONST_0 + fc); + } else { + mv.visitIntInsn(SIPUSH, fc); + } + mv.visitInsn(IRETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + // emit make() ...factory method wrapping constructor + mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_STATIC, "make", makeSignature(types, false), null, null); + mv.visitCode(); + // make instance + mv.visitTypeInsn(NEW, className); + mv.visitInsn(DUP); + // load mt, lf + mv.visitVarInsn(ALOAD, 0); // type + mv.visitVarInsn(ALOAD, 1); // form + // load factory method arguments + for (int i = 0, j = 0; i < types.length(); ++i, ++j) { + // i counts the arguments, j counts corresponding argument slots + char t = types.charAt(i); + mv.visitVarInsn(typeLoadOp(t), j + 2); // parameters start at 3 + if (t == 'J' || t == 'D') { + ++j; // adjust argument register access + } + } + + // finally, invoke the constructor and return + mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", makeSignature(types, true), false); + mv.visitInsn(ARETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + + // emit copyWith() + mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "copyWith", makeSignature("", false), null, null); + mv.visitCode(); + // make instance + mv.visitTypeInsn(NEW, className); + mv.visitInsn(DUP); // load mt, lf mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); // put fields on the stack emitPushFields(types, className, mv); // finally, invoke the constructor and return - mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types, false), false); + mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", makeSignature(types, true), false); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); - // for each type, emit cloneExtendT() - for (Class<?> c : TYPES) { - char t = Wrapper.basicTypeChar(c); - mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "cloneExtend" + t, makeSignature(String.valueOf(t), false), null, E_THROWABLE); + // for each type, emit copyWithExtendT() + for (BasicType type : BasicType.ARG_TYPES) { + int ord = type.ordinal(); + char btChar = type.basicTypeChar(); + mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "copyWithExtend" + btChar, makeSignature(String.valueOf(btChar), false), null, E_THROWABLE); mv.visitCode(); - // return SPECIES_DATA.extendWithIndex(extensionIndex(t)).constructor[0].invokeBasic(mt, lf, argL0, ..., narg) + // return SPECIES_DATA.extendWith(t).constructor[0].invokeBasic(mt, lf, argL0, ..., narg) // obtain constructor mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG); - int iconstInsn = ICONST_0 + extensionIndex(t); + int iconstInsn = ICONST_0 + ord; assert(iconstInsn <= ICONST_5); mv.visitInsn(iconstInsn); - mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "extendWithIndex", BMHSPECIES_DATA_EWI_SIG, false); + mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "extendWith", BMHSPECIES_DATA_EWI_SIG, false); mv.visitFieldInsn(GETFIELD, SPECIES_DATA, "constructor", "[" + MH_SIG); mv.visitInsn(ICONST_0); mv.visitInsn(AALOAD); @@ -689,9 +669,9 @@ import jdk.internal.org.objectweb.asm.Type; // put fields on the stack emitPushFields(types, className, mv); // put narg on stack - mv.visitVarInsn(typeLoadOp(t), 3); + mv.visitVarInsn(typeLoadOp(btChar), 3); // finally, invoke the constructor and return - mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types + t, false), false); + mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types + btChar, false), false); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); @@ -730,7 +710,7 @@ import jdk.internal.org.objectweb.asm.Type; case 'J': return LLOAD; case 'F': return FLOAD; case 'D': return DLOAD; - default : throw new InternalError("unrecognized type " + t); + default : throw newInternalError("unrecognized type " + t); } } @@ -771,10 +751,19 @@ import jdk.internal.org.objectweb.asm.Type; static MethodHandle[] makeCtors(Class<? extends BoundMethodHandle> cbmh, String types, MethodHandle mhs[]) { if (mhs == null) mhs = new MethodHandle[1]; + if (types.equals("")) return mhs; // hack for empty BMH species mhs[0] = makeCbmhCtor(cbmh, types); return mhs; } + static NamedFunction[] makeNominalGetters(String types, NamedFunction[] nfs, MethodHandle[] getters) { + if (nfs == null) nfs = new NamedFunction[types.length()]; + for (int i = 0; i < nfs.length; ++i) { + nfs[i] = new NamedFunction(getters[i]); + } + return nfs; + } + // // Auxiliary methods. // @@ -808,52 +797,11 @@ import jdk.internal.org.objectweb.asm.Type; static MethodHandle makeCbmhCtor(Class<? extends BoundMethodHandle> cbmh, String types) { try { - return linkConstructor(LOOKUP.findConstructor(cbmh, MethodType.fromMethodDescriptorString(makeSignature(types, true), null))); + return LOOKUP.findStatic(cbmh, "make", MethodType.fromMethodDescriptorString(makeSignature(types, false), null)); } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | TypeNotPresentException e) { throw newInternalError(e); } } - - /** - * Wrap a constructor call in a {@link LambdaForm}. - * - * If constructors ({@code <init>} methods) are called in LFs, problems might arise if the LFs - * are turned into bytecode, because the call to the allocator is routed through an MH, and the - * verifier cannot find a {@code NEW} instruction preceding the {@code INVOKESPECIAL} to - * {@code <init>}. To avoid this, we add an indirection by invoking {@code <init>} through - * {@link MethodHandle#linkToSpecial}. - * - * The last {@link LambdaForm.Name Name} in the argument's form is expected to be the {@code void} - * result of the {@code <init>} invocation. This entry is replaced. - */ - private static MethodHandle linkConstructor(MethodHandle cmh) { - final LambdaForm lf = cmh.form; - final int initNameIndex = lf.names.length - 1; - final Name initName = lf.names[initNameIndex]; - final MemberName ctorMN = initName.function.member; - final MethodType ctorMT = ctorMN.getInvocationType(); - - // obtain function member (call target) - // linker method type replaces initial parameter (BMH species) with BMH to avoid naming a species (anonymous class!) - final MethodType linkerMT = ctorMT.changeParameterType(0, BoundMethodHandle.class).appendParameterTypes(MemberName.class); - MemberName linkerMN = new MemberName(MethodHandle.class, "linkToSpecial", linkerMT, REF_invokeStatic); - try { - linkerMN = MemberName.getFactory().resolveOrFail(REF_invokeStatic, linkerMN, null, NoSuchMethodException.class); - assert(linkerMN.isStatic()); - } catch (ReflectiveOperationException ex) { - throw newInternalError(ex); - } - // extend arguments array - Object[] newArgs = Arrays.copyOf(initName.arguments, initName.arguments.length + 1); - newArgs[newArgs.length - 1] = ctorMN; - // replace function - final NamedFunction nf = new NamedFunction(linkerMN); - final Name linkedCtor = new Name(nf, newArgs); - linkedCtor.initIndex(initNameIndex); - lf.names[initNameIndex] = linkedCtor; - return cmh; - } - } private static final Lookup LOOKUP = Lookup.IMPL_LOOKUP; diff --git a/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java b/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java index 9c054519b43..0fbc4619e22 100644 --- a/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java +++ b/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java @@ -31,6 +31,7 @@ import java.util.Arrays; import sun.invoke.util.VerifyAccess; import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.LambdaForm.*; +import static java.lang.invoke.LambdaForm.BasicType.*; import static java.lang.invoke.MethodTypeForm.*; import static java.lang.invoke.MethodHandleStatics.*; import java.lang.ref.WeakReference; @@ -124,11 +125,6 @@ class DirectMethodHandle extends MethodHandle { return new Constructor(mtype, lform, ctor, init, instanceClass); } - @Override - MethodHandle copyWith(MethodType mt, LambdaForm lf) { - return new DirectMethodHandle(mt, lf, member); - } - @Override String internalProperties() { return "/DMH="+member.toString(); @@ -146,9 +142,9 @@ class DirectMethodHandle extends MethodHandle { } @Override - MethodHandle bindArgument(int pos, char basicType, Object value) { + MethodHandle bindArgument(int pos, BasicType basicType, Object value) { // If the member needs dispatching, do so. - if (pos == 0 && basicType == 'L') { + if (pos == 0 && basicType == L_TYPE) { DirectMethodHandle concrete = maybeRebind(value); if (concrete != null) return concrete.bindReceiver(value); @@ -274,7 +270,7 @@ class DirectMethodHandle extends MethodHandle { result = NEW_OBJ; } names[LINKER_CALL] = new Name(linker, outArgs); - lambdaName += "_" + LambdaForm.basicTypeSignature(mtype); + lambdaName += "_" + shortenSignature(basicTypeSignature(mtype)); LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result); // This is a tricky bit of code. Don't send it through the LF interpreter. lform.compileToBytecode(); diff --git a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java index 145203b0a07..7bcdfaf5e89 100644 --- a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java +++ b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java @@ -26,7 +26,7 @@ package java.lang.invoke; import sun.invoke.util.VerifyAccess; -import java.lang.invoke.LambdaForm.Name; +import static java.lang.invoke.LambdaForm.*; import sun.invoke.util.Wrapper; @@ -38,6 +38,7 @@ import jdk.internal.org.objectweb.asm.*; import java.lang.reflect.*; import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; +import static java.lang.invoke.LambdaForm.BasicType.*; import sun.invoke.util.VerifyType; /** @@ -115,7 +116,7 @@ class InvokerBytecodeGenerator { Name[] names = form.names; for (int i = 0, index = 0; i < localsMap.length; i++) { localsMap[i] = index; - index += Wrapper.forBasicType(names[i].type).stackSlots(); + index += names[i].type.basicTypeSlots(); } } @@ -358,47 +359,52 @@ class InvokerBytecodeGenerator { /* * NOTE: These load/store methods use the localsMap to find the correct index! */ - private void emitLoadInsn(char type, int index) { - int opcode; - switch (type) { - case 'I': opcode = Opcodes.ILOAD; break; - case 'J': opcode = Opcodes.LLOAD; break; - case 'F': opcode = Opcodes.FLOAD; break; - case 'D': opcode = Opcodes.DLOAD; break; - case 'L': opcode = Opcodes.ALOAD; break; - default: - throw new InternalError("unknown type: " + type); - } + private void emitLoadInsn(BasicType type, int index) { + int opcode = loadInsnOpcode(type); mv.visitVarInsn(opcode, localsMap[index]); } - private void emitAloadInsn(int index) { - emitLoadInsn('L', index); - } - private void emitStoreInsn(char type, int index) { - int opcode; + private int loadInsnOpcode(BasicType type) throws InternalError { switch (type) { - case 'I': opcode = Opcodes.ISTORE; break; - case 'J': opcode = Opcodes.LSTORE; break; - case 'F': opcode = Opcodes.FSTORE; break; - case 'D': opcode = Opcodes.DSTORE; break; - case 'L': opcode = Opcodes.ASTORE; break; - default: - throw new InternalError("unknown type: " + type); + case I_TYPE: return Opcodes.ILOAD; + case J_TYPE: return Opcodes.LLOAD; + case F_TYPE: return Opcodes.FLOAD; + case D_TYPE: return Opcodes.DLOAD; + case L_TYPE: return Opcodes.ALOAD; + default: + throw new InternalError("unknown type: " + type); } + } + private void emitAloadInsn(int index) { + emitLoadInsn(L_TYPE, index); + } + + private void emitStoreInsn(BasicType type, int index) { + int opcode = storeInsnOpcode(type); mv.visitVarInsn(opcode, localsMap[index]); } + + private int storeInsnOpcode(BasicType type) throws InternalError { + switch (type) { + case I_TYPE: return Opcodes.ISTORE; + case J_TYPE: return Opcodes.LSTORE; + case F_TYPE: return Opcodes.FSTORE; + case D_TYPE: return Opcodes.DSTORE; + case L_TYPE: return Opcodes.ASTORE; + default: + throw new InternalError("unknown type: " + type); + } + } private void emitAstoreInsn(int index) { - emitStoreInsn('L', index); + emitStoreInsn(L_TYPE, index); } /** * Emit a boxing call. * - * @param type primitive type class to box. + * @param wrapper primitive type class to box. */ - private void emitBoxing(Class<?> type) { - Wrapper wrapper = Wrapper.forPrimitiveType(type); + private void emitBoxing(Wrapper wrapper) { String owner = "java/lang/" + wrapper.wrapperType().getSimpleName(); String name = "valueOf"; String desc = "(" + wrapper.basicTypeChar() + ")L" + owner + ";"; @@ -408,10 +414,9 @@ class InvokerBytecodeGenerator { /** * Emit an unboxing call (plus preceding checkcast). * - * @param type wrapper type class to unbox. + * @param wrapper wrapper type class to unbox. */ - private void emitUnboxing(Class<?> type) { - Wrapper wrapper = Wrapper.forWrapperType(type); + private void emitUnboxing(Wrapper wrapper) { String owner = "java/lang/" + wrapper.wrapperType().getSimpleName(); String name = wrapper.primitiveSimpleName() + "Value"; String desc = "()" + wrapper.basicTypeChar(); @@ -425,9 +430,12 @@ class InvokerBytecodeGenerator { * @param ptype type of value present on stack * @param pclass type of value required on stack */ - private void emitImplicitConversion(char ptype, Class<?> pclass) { + private void emitImplicitConversion(BasicType ptype, Class<?> pclass) { + assert(basicType(pclass) == ptype); // boxing/unboxing handled by caller + if (pclass == ptype.basicTypeClass() && ptype != L_TYPE) + return; // nothing to do switch (ptype) { - case 'L': + case L_TYPE: if (VerifyType.isNullConversion(Object.class, pclass)) return; if (isStaticallyNameable(pclass)) { @@ -441,18 +449,9 @@ class InvokerBytecodeGenerator { mv.visitTypeInsn(Opcodes.CHECKCAST, OBJARY); } return; - case 'I': + case I_TYPE: if (!VerifyType.isNullConversion(int.class, pclass)) - emitPrimCast(ptype, Wrapper.basicTypeChar(pclass)); - return; - case 'J': - assert(pclass == long.class); - return; - case 'F': - assert(pclass == float.class); - return; - case 'D': - assert(pclass == double.class); + emitPrimCast(ptype.basicTypeWrapper(), Wrapper.forPrimitiveType(pclass)); return; } throw new InternalError("bad implicit conversion: tc="+ptype+": "+pclass); @@ -461,15 +460,15 @@ class InvokerBytecodeGenerator { /** * Emits an actual return instruction conforming to the given return type. */ - private void emitReturnInsn(Class<?> type) { + private void emitReturnInsn(BasicType type) { int opcode; - switch (Wrapper.basicTypeChar(type)) { - case 'I': opcode = Opcodes.IRETURN; break; - case 'J': opcode = Opcodes.LRETURN; break; - case 'F': opcode = Opcodes.FRETURN; break; - case 'D': opcode = Opcodes.DRETURN; break; - case 'L': opcode = Opcodes.ARETURN; break; - case 'V': opcode = Opcodes.RETURN; break; + switch (type) { + case I_TYPE: opcode = Opcodes.IRETURN; break; + case J_TYPE: opcode = Opcodes.LRETURN; break; + case F_TYPE: opcode = Opcodes.FRETURN; break; + case D_TYPE: opcode = Opcodes.DRETURN; break; + case L_TYPE: opcode = Opcodes.ARETURN; break; + case V_TYPE: opcode = Opcodes.RETURN; break; default: throw new InternalError("unknown return type: " + type); } @@ -531,7 +530,7 @@ class InvokerBytecodeGenerator { // avoid store/load/return and just return) if (i == lambdaForm.names.length - 1 && i == lambdaForm.result) { // return value - do nothing - } else if (name.type != 'V') { + } else if (name.type != V_TYPE) { // non-void: actually assign emitStoreInsn(name.type, name.index()); } @@ -865,20 +864,24 @@ class InvokerBytecodeGenerator { private void emitPushArgument(Name name, int paramIndex) { Object arg = name.arguments[paramIndex]; - char ptype = name.function.parameterType(paramIndex); - MethodType mtype = name.function.methodType(); + Class<?> ptype = name.function.methodType().parameterType(paramIndex); + emitPushArgument(ptype, arg); + } + + private void emitPushArgument(Class<?> ptype, Object arg) { + BasicType bptype = basicType(ptype); if (arg instanceof Name) { Name n = (Name) arg; emitLoadInsn(n.type, n.index()); - emitImplicitConversion(n.type, mtype.parameterType(paramIndex)); - } else if ((arg == null || arg instanceof String) && ptype == 'L') { + emitImplicitConversion(n.type, ptype); + } else if ((arg == null || arg instanceof String) && bptype == L_TYPE) { emitConst(arg); } else { - if (Wrapper.isWrapperType(arg.getClass()) && ptype != 'L') { + if (Wrapper.isWrapperType(arg.getClass()) && bptype != L_TYPE) { emitConst(arg); } else { mv.visitLdcInsn(constantPlaceholder(arg)); - emitImplicitConversion('L', mtype.parameterType(paramIndex)); + emitImplicitConversion(L_TYPE, ptype); } } } @@ -888,52 +891,33 @@ class InvokerBytecodeGenerator { */ private void emitReturn() { // return statement - if (lambdaForm.result == -1) { + Class<?> rclass = invokerType.returnType(); + BasicType rtype = lambdaForm.returnType(); + assert(rtype == basicType(rclass)); // must agree + if (rtype == V_TYPE) { // void mv.visitInsn(Opcodes.RETURN); + // it doesn't matter what rclass is; the JVM will discard any value } else { LambdaForm.Name rn = lambdaForm.names[lambdaForm.result]; - char rtype = Wrapper.basicTypeChar(invokerType.returnType()); // put return value on the stack if it is not already there - if (lambdaForm.result != lambdaForm.names.length - 1) { + if (lambdaForm.result != lambdaForm.names.length - 1 || + lambdaForm.result < lambdaForm.arity) { emitLoadInsn(rn.type, lambdaForm.result); } - // potentially generate cast - // rtype is the return type of the invoker - generated code must conform to this - // rn.type is the type of the result Name in the LF - if (rtype != rn.type) { - // need cast - if (rtype == 'L') { - // possibly cast the primitive to the correct type for boxing - char boxedType = Wrapper.forWrapperType(invokerType.returnType()).basicTypeChar(); - if (boxedType != rn.type) { - emitPrimCast(rn.type, boxedType); - } - // cast primitive to reference ("boxing") - emitBoxing(invokerType.returnType()); - } else { - // to-primitive cast - if (rn.type != 'L') { - // prim-to-prim cast - emitPrimCast(rn.type, rtype); - } else { - // ref-to-prim cast ("unboxing") - throw new InternalError("no ref-to-prim (unboxing) casts supported right now"); - } - } - } + emitImplicitConversion(rtype, rclass); // generate actual return statement - emitReturnInsn(invokerType.returnType()); + emitReturnInsn(rtype); } } /** * Emit a type conversion bytecode casting from "from" to "to". */ - private void emitPrimCast(char from, char to) { + private void emitPrimCast(Wrapper from, Wrapper to) { // Here's how. // - indicates forbidden // <-> indicates implicit @@ -950,17 +934,15 @@ class InvokerBytecodeGenerator { // no cast required, should be dead code anyway return; } - Wrapper wfrom = Wrapper.forBasicType(from); - Wrapper wto = Wrapper.forBasicType(to); - if (wfrom.isSubwordOrInt()) { + if (from.isSubwordOrInt()) { // cast from {byte,short,char,int} to anything emitI2X(to); } else { // cast from {long,float,double} to anything - if (wto.isSubwordOrInt()) { + if (to.isSubwordOrInt()) { // cast to {byte,short,char,int} emitX2I(from); - if (wto.bitWidth() < 32) { + if (to.bitWidth() < 32) { // targets other than int require another conversion emitI2X(to); } @@ -968,20 +950,26 @@ class InvokerBytecodeGenerator { // cast to {long,float,double} - this is verbose boolean error = false; switch (from) { - case 'J': - if (to == 'F') { mv.visitInsn(Opcodes.L2F); } - else if (to == 'D') { mv.visitInsn(Opcodes.L2D); } - else error = true; + case LONG: + switch (to) { + case FLOAT: mv.visitInsn(Opcodes.L2F); break; + case DOUBLE: mv.visitInsn(Opcodes.L2D); break; + default: error = true; break; + } break; - case 'F': - if (to == 'J') { mv.visitInsn(Opcodes.F2L); } - else if (to == 'D') { mv.visitInsn(Opcodes.F2D); } - else error = true; + case FLOAT: + switch (to) { + case LONG : mv.visitInsn(Opcodes.F2L); break; + case DOUBLE: mv.visitInsn(Opcodes.F2D); break; + default: error = true; break; + } break; - case 'D': - if (to == 'J') { mv.visitInsn(Opcodes.D2L); } - else if (to == 'F') { mv.visitInsn(Opcodes.D2F); } - else error = true; + case DOUBLE: + switch (to) { + case LONG : mv.visitInsn(Opcodes.D2L); break; + case FLOAT: mv.visitInsn(Opcodes.D2F); break; + default: error = true; break; + } break; default: error = true; @@ -994,16 +982,16 @@ class InvokerBytecodeGenerator { } } - private void emitI2X(char type) { + private void emitI2X(Wrapper type) { switch (type) { - case 'B': mv.visitInsn(Opcodes.I2B); break; - case 'S': mv.visitInsn(Opcodes.I2S); break; - case 'C': mv.visitInsn(Opcodes.I2C); break; - case 'I': /* naught */ break; - case 'J': mv.visitInsn(Opcodes.I2L); break; - case 'F': mv.visitInsn(Opcodes.I2F); break; - case 'D': mv.visitInsn(Opcodes.I2D); break; - case 'Z': + case BYTE: mv.visitInsn(Opcodes.I2B); break; + case SHORT: mv.visitInsn(Opcodes.I2S); break; + case CHAR: mv.visitInsn(Opcodes.I2C); break; + case INT: /* naught */ break; + case LONG: mv.visitInsn(Opcodes.I2L); break; + case FLOAT: mv.visitInsn(Opcodes.I2F); break; + case DOUBLE: mv.visitInsn(Opcodes.I2D); break; + case BOOLEAN: // For compatibility with ValueConversions and explicitCastArguments: mv.visitInsn(Opcodes.ICONST_1); mv.visitInsn(Opcodes.IAND); @@ -1012,39 +1000,24 @@ class InvokerBytecodeGenerator { } } - private void emitX2I(char type) { + private void emitX2I(Wrapper type) { switch (type) { - case 'J': mv.visitInsn(Opcodes.L2I); break; - case 'F': mv.visitInsn(Opcodes.F2I); break; - case 'D': mv.visitInsn(Opcodes.D2I); break; - default: throw new InternalError("unknown type: " + type); + case LONG: mv.visitInsn(Opcodes.L2I); break; + case FLOAT: mv.visitInsn(Opcodes.F2I); break; + case DOUBLE: mv.visitInsn(Opcodes.D2I); break; + default: throw new InternalError("unknown type: " + type); } } - private static String basicTypeCharSignature(String prefix, MethodType type) { - StringBuilder buf = new StringBuilder(prefix); - for (Class<?> ptype : type.parameterList()) - buf.append(Wrapper.forBasicType(ptype).basicTypeChar()); - buf.append('_').append(Wrapper.forBasicType(type.returnType()).basicTypeChar()); - return buf.toString(); - } - /** * Generate bytecode for a LambdaForm.vmentry which calls interpretWithArguments. */ static MemberName generateLambdaFormInterpreterEntryPoint(String sig) { - assert(LambdaForm.isValidSignature(sig)); - //System.out.println("generateExactInvoker "+sig); - // compute method type - // first parameter and return type - char tret = LambdaForm.signatureReturn(sig); - MethodType type = MethodType.methodType(LambdaForm.typeClass(tret), MethodHandle.class); - // other parameter types - int arity = LambdaForm.signatureArity(sig); - for (int i = 1; i < arity; i++) { - type = type.appendParameterTypes(LambdaForm.typeClass(sig.charAt(i))); - } - InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("LFI", "interpret_"+tret, type); + assert(isValidSignature(sig)); + String name = "interpret_"+signatureReturn(sig).basicTypeChar(); + MethodType type = signatureType(sig); // sig includes leading argument + type = type.changeParameterType(0, MethodHandle.class); + InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("LFI", name, type); return g.loadMethod(g.generateLambdaFormInterpreterEntryPointBytes()); } @@ -1066,10 +1039,10 @@ class InvokerBytecodeGenerator { Class<?> ptype = invokerType.parameterType(i); mv.visitInsn(Opcodes.DUP); emitIconstInsn(i); - emitLoadInsn(Wrapper.basicTypeChar(ptype), i); + emitLoadInsn(basicType(ptype), i); // box if primitive type if (ptype.isPrimitive()) { - emitBoxing(ptype); + emitBoxing(Wrapper.forPrimitiveType(ptype)); } mv.visitInsn(Opcodes.AASTORE); } @@ -1082,11 +1055,11 @@ class InvokerBytecodeGenerator { // maybe unbox Class<?> rtype = invokerType.returnType(); if (rtype.isPrimitive() && rtype != void.class) { - emitUnboxing(Wrapper.asWrapperType(rtype)); + emitUnboxing(Wrapper.forPrimitiveType(rtype)); } // return statement - emitReturnInsn(rtype); + emitReturnInsn(basicType(rtype)); classFileEpilogue(); bogusMethod(invokerType); @@ -1100,14 +1073,12 @@ class InvokerBytecodeGenerator { * Generate bytecode for a NamedFunction invoker. */ static MemberName generateNamedFunctionInvoker(MethodTypeForm typeForm) { - MethodType invokerType = LambdaForm.NamedFunction.INVOKER_METHOD_TYPE; - String invokerName = basicTypeCharSignature("invoke_", typeForm.erasedType()); + MethodType invokerType = NamedFunction.INVOKER_METHOD_TYPE; + String invokerName = "invoke_" + shortenSignature(basicTypeSignature(typeForm.erasedType())); InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("NFI", invokerName, invokerType); return g.loadMethod(g.generateNamedFunctionInvokerImpl(typeForm)); } - static int nfi = 0; - private byte[] generateNamedFunctionInvokerImpl(MethodTypeForm typeForm) { MethodType dstType = typeForm.erasedType(); classFilePrologue(); @@ -1133,8 +1104,8 @@ class InvokerBytecodeGenerator { Class<?> sptype = dstType.basicType().wrap().parameterType(i); Wrapper dstWrapper = Wrapper.forBasicType(dptype); Wrapper srcWrapper = dstWrapper.isSubwordOrInt() ? Wrapper.INT : dstWrapper; // narrow subword from int - emitUnboxing(srcWrapper.wrapperType()); - emitPrimCast(srcWrapper.basicTypeChar(), dstWrapper.basicTypeChar()); + emitUnboxing(srcWrapper); + emitPrimCast(srcWrapper, dstWrapper); } } @@ -1148,15 +1119,15 @@ class InvokerBytecodeGenerator { Wrapper srcWrapper = Wrapper.forBasicType(rtype); Wrapper dstWrapper = srcWrapper.isSubwordOrInt() ? Wrapper.INT : srcWrapper; // widen subword to int // boolean casts not allowed - emitPrimCast(srcWrapper.basicTypeChar(), dstWrapper.basicTypeChar()); - emitBoxing(dstWrapper.primitiveType()); + emitPrimCast(srcWrapper, dstWrapper); + emitBoxing(dstWrapper); } // If the return type is void we return a null reference. if (rtype == void.class) { mv.visitInsn(Opcodes.ACONST_NULL); } - emitReturnInsn(Object.class); // NOTE: NamedFunction invokers always return a reference value. + emitReturnInsn(L_TYPE); // NOTE: NamedFunction invokers always return a reference value. classFileEpilogue(); bogusMethod(dstType); diff --git a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java index a5e40ed5211..36630459b88 100644 --- a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java +++ b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java @@ -30,14 +30,14 @@ import java.lang.reflect.Method; import java.util.Map; import java.util.List; import java.util.Arrays; -import java.util.ArrayList; import java.util.HashMap; import java.util.concurrent.ConcurrentHashMap; import sun.invoke.util.Wrapper; +import java.lang.reflect.Field; + +import static java.lang.invoke.LambdaForm.BasicType.*; import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; -import java.lang.reflect.Field; -import java.util.Objects; /** * The symbolic, non-executable form of a method handle's invocation semantics. @@ -130,13 +130,119 @@ class LambdaForm { public static final int VOID_RESULT = -1, LAST_RESULT = -2; + enum BasicType { + L_TYPE('L', Object.class, Wrapper.OBJECT), // all reference types + I_TYPE('I', int.class, Wrapper.INT), + J_TYPE('J', long.class, Wrapper.LONG), + F_TYPE('F', float.class, Wrapper.FLOAT), + D_TYPE('D', double.class, Wrapper.DOUBLE), // all primitive types + V_TYPE('V', void.class, Wrapper.VOID); // not valid in all contexts + + static final BasicType[] ALL_TYPES = BasicType.values(); + static final BasicType[] ARG_TYPES = Arrays.copyOf(ALL_TYPES, ALL_TYPES.length-1); + + static final int ARG_TYPE_LIMIT = ARG_TYPES.length; + static final int TYPE_LIMIT = ALL_TYPES.length; + + private final char btChar; + private final Class<?> btClass; + private final Wrapper btWrapper; + + private BasicType(char btChar, Class<?> btClass, Wrapper wrapper) { + this.btChar = btChar; + this.btClass = btClass; + this.btWrapper = wrapper; + } + + char basicTypeChar() { + return btChar; + } + Class<?> basicTypeClass() { + return btClass; + } + Wrapper basicTypeWrapper() { + return btWrapper; + } + int basicTypeSlots() { + return btWrapper.stackSlots(); + } + + static BasicType basicType(byte type) { + return ALL_TYPES[type]; + } + static BasicType basicType(char type) { + switch (type) { + case 'L': return L_TYPE; + case 'I': return I_TYPE; + case 'J': return J_TYPE; + case 'F': return F_TYPE; + case 'D': return D_TYPE; + case 'V': return V_TYPE; + // all subword types are represented as ints + case 'Z': + case 'B': + case 'S': + case 'C': + return I_TYPE; + default: + throw newInternalError("Unknown type char: '"+type+"'"); + } + } + static BasicType basicType(Wrapper type) { + char c = type.basicTypeChar(); + return basicType(c); + } + static BasicType basicType(Class<?> type) { + if (!type.isPrimitive()) return L_TYPE; + return basicType(Wrapper.forPrimitiveType(type)); + } + + static char basicTypeChar(Class<?> type) { + return basicType(type).btChar; + } + static BasicType[] basicTypes(List<Class<?>> types) { + BasicType[] btypes = new BasicType[types.size()]; + for (int i = 0; i < btypes.length; i++) { + btypes[i] = basicType(types.get(i)); + } + return btypes; + } + static BasicType[] basicTypes(String types) { + BasicType[] btypes = new BasicType[types.length()]; + for (int i = 0; i < btypes.length; i++) { + btypes[i] = basicType(types.charAt(i)); + } + return btypes; + } + static boolean isBasicTypeChar(char c) { + return "LIJFDV".indexOf(c) >= 0; + } + static boolean isArgBasicTypeChar(char c) { + return "LIJFD".indexOf(c) >= 0; + } + + static { assert(checkBasicType()); } + private static boolean checkBasicType() { + for (int i = 0; i < ARG_TYPE_LIMIT; i++) { + assert ARG_TYPES[i].ordinal() == i; + assert ARG_TYPES[i] == ALL_TYPES[i]; + } + for (int i = 0; i < TYPE_LIMIT; i++) { + assert ALL_TYPES[i].ordinal() == i; + } + assert ALL_TYPES[TYPE_LIMIT - 1] == V_TYPE; + assert !Arrays.asList(ARG_TYPES).contains(V_TYPE); + return true; + } + } + LambdaForm(String debugName, int arity, Name[] names, int result) { assert(namesOK(arity, names)); this.arity = arity; this.result = fixResult(result, names); this.names = names.clone(); - this.debugName = debugName; + this.debugName = fixDebugName(debugName); normalize(); } @@ -168,12 +274,12 @@ class LambdaForm { // Called only from getPreparedForm. assert(isValidSignature(sig)); this.arity = signatureArity(sig); - this.result = (signatureReturn(sig) == 'V' ? -1 : arity); + this.result = (signatureReturn(sig) == V_TYPE ? -1 : arity); this.names = buildEmptyNames(arity, sig); this.debugName = "LF.zero"; assert(nameRefsAreLegal()); assert(isEmpty()); - assert(sig.equals(basicTypeSignature())); + assert(sig.equals(basicTypeSignature())) : sig + " != " + basicTypeSignature(); } private static Name[] buildEmptyNames(int arity, String basicTypeSignature) { @@ -181,24 +287,55 @@ class LambdaForm { int resultPos = arity + 1; // skip '_' if (arity < 0 || basicTypeSignature.length() != resultPos+1) throw new IllegalArgumentException("bad arity for "+basicTypeSignature); - int numRes = (basicTypeSignature.charAt(resultPos) == 'V' ? 0 : 1); + int numRes = (basicType(basicTypeSignature.charAt(resultPos)) == V_TYPE ? 0 : 1); Name[] names = arguments(numRes, basicTypeSignature.substring(0, arity)); for (int i = 0; i < numRes; i++) { - names[arity + i] = constantZero(arity + i, basicTypeSignature.charAt(resultPos + i)); + Name zero = new Name(constantZero(basicType(basicTypeSignature.charAt(resultPos + i)))); + names[arity + i] = zero.newIndex(arity + i); } return names; } private static int fixResult(int result, Name[] names) { - if (result >= 0) { - if (names[result].type == 'V') - return -1; - } else if (result == LAST_RESULT) { - return names.length - 1; - } + if (result == LAST_RESULT) + result = names.length - 1; // might still be void + if (result >= 0 && names[result].type == V_TYPE) + result = VOID_RESULT; return result; } + private static String fixDebugName(String debugName) { + if (DEBUG_NAME_COUNTERS != null) { + int under = debugName.indexOf('_'); + int length = debugName.length(); + if (under < 0) under = length; + String debugNameStem = debugName.substring(0, under); + Integer ctr; + synchronized (DEBUG_NAME_COUNTERS) { + ctr = DEBUG_NAME_COUNTERS.get(debugNameStem); + if (ctr == null) ctr = 0; + DEBUG_NAME_COUNTERS.put(debugNameStem, ctr+1); + } + StringBuilder buf = new StringBuilder(debugNameStem); + buf.append('_'); + int leadingZero = buf.length(); + buf.append((int) ctr); + for (int i = buf.length() - leadingZero; i < 3; i++) + buf.insert(leadingZero, '0'); + if (under < length) { + ++under; // skip "_" + while (under < length && Character.isDigit(debugName.charAt(under))) { + ++under; + } + if (under < length && debugName.charAt(under) == '_') ++under; + if (under < length) + buf.append('_').append(debugName, under, length); + } + return buf.toString(); + } + return debugName; + } + private static boolean namesOK(int arity, Name[] names) { for (int i = 0; i < names.length; i++) { Name n = names[i]; @@ -294,14 +431,14 @@ class LambdaForm { // } /** Report the return type. */ - char returnType() { - if (result < 0) return 'V'; + BasicType returnType() { + if (result < 0) return V_TYPE; Name n = names[result]; return n.type; } /** Report the N-th argument type. */ - char parameterType(int n) { + BasicType parameterType(int n) { assert(n < arity); return names[n].type; } @@ -319,15 +456,15 @@ class LambdaForm { final String basicTypeSignature() { StringBuilder buf = new StringBuilder(arity() + 3); for (int i = 0, a = arity(); i < a; i++) - buf.append(parameterType(i)); - return buf.append('_').append(returnType()).toString(); + buf.append(parameterType(i).basicTypeChar()); + return buf.append('_').append(returnType().basicTypeChar()).toString(); } static int signatureArity(String sig) { assert(isValidSignature(sig)); return sig.indexOf('_'); } - static char signatureReturn(String sig) { - return sig.charAt(signatureArity(sig)+1); + static BasicType signatureReturn(String sig) { + return basicType(sig.charAt(signatureArity(sig)+1)); } static boolean isValidSignature(String sig) { int arity = sig.indexOf('_'); @@ -339,27 +476,15 @@ class LambdaForm { char c = sig.charAt(i); if (c == 'V') return (i == siglen - 1 && arity == siglen - 2); - if (ALL_TYPES.indexOf(c) < 0) return false; // must be [LIJFD] + if (!isArgBasicTypeChar(c)) return false; // must be [LIJFD] } return true; // [LIJFD]*_[LIJFDV] } - static Class<?> typeClass(char t) { - switch (t) { - case 'I': return int.class; - case 'J': return long.class; - case 'F': return float.class; - case 'D': return double.class; - case 'L': return Object.class; - case 'V': return void.class; - default: assert false; - } - return null; - } static MethodType signatureType(String sig) { Class<?>[] ptypes = new Class<?>[signatureArity(sig)]; for (int i = 0; i < ptypes.length; i++) - ptypes[i] = typeClass(sig.charAt(i)); - Class<?> rtype = typeClass(signatureReturn(sig)); + ptypes[i] = basicType(sig.charAt(i)).btClass; + Class<?> rtype = signatureReturn(sig).btClass; return MethodType.methodType(rtype, ptypes); } @@ -543,21 +668,21 @@ class LambdaForm { assert(mt.parameterCount() == arity-1); for (int i = 0; i < av.length; i++) { Class<?> pt = (i == 0 ? MethodHandle.class : mt.parameterType(i-1)); - assert(valueMatches(sig.charAt(i), pt, av[i])); + assert(valueMatches(basicType(sig.charAt(i)), pt, av[i])); } return true; } - private static boolean valueMatches(char tc, Class<?> type, Object x) { + private static boolean valueMatches(BasicType tc, Class<?> type, Object x) { // The following line is needed because (...)void method handles can use non-void invokers - if (type == void.class) tc = 'V'; // can drop any kind of value + if (type == void.class) tc = V_TYPE; // can drop any kind of value assert tc == basicType(type) : tc + " == basicType(" + type + ")=" + basicType(type); switch (tc) { - case 'I': assert checkInt(type, x) : "checkInt(" + type + "," + x +")"; break; - case 'J': assert x instanceof Long : "instanceof Long: " + x; break; - case 'F': assert x instanceof Float : "instanceof Float: " + x; break; - case 'D': assert x instanceof Double : "instanceof Double: " + x; break; - case 'L': assert checkRef(type, x) : "checkRef(" + type + "," + x + ")"; break; - case 'V': break; // allow anything here; will be dropped + case I_TYPE: assert checkInt(type, x) : "checkInt(" + type + "," + x +")"; break; + case J_TYPE: assert x instanceof Long : "instanceof Long: " + x; break; + case F_TYPE: assert x instanceof Float : "instanceof Float: " + x; break; + case D_TYPE: assert x instanceof Double : "instanceof Double: " + x; break; + case L_TYPE: assert checkRef(type, x) : "checkRef(" + type + "," + x + ")"; break; + case V_TYPE: break; // allow anything here; will be dropped default: assert(false); } return true; @@ -736,7 +861,7 @@ class LambdaForm { * The first parameter to a LambdaForm, a0:L, always represents the form's method handle, so 0 is not * accepted as valid. */ - LambdaForm bindImmediate(int pos, char basicType, Object value) { + LambdaForm bindImmediate(int pos, BasicType basicType, Object value) { // must be an argument, and the types must match assert pos > 0 && pos < arity && names[pos].type == basicType && Name.typesMatch(basicType, value); @@ -782,8 +907,8 @@ class LambdaForm { LambdaForm bind(int namePos, BoundMethodHandle.SpeciesData oldData) { Name name = names[namePos]; - BoundMethodHandle.SpeciesData newData = oldData.extendWithType(name.type); - return bind(name, newData.getterName(names[0], oldData.fieldCount()), oldData, newData); + BoundMethodHandle.SpeciesData newData = oldData.extendWith(name.type); + return bind(name, new Name(newData.getterFunction(oldData.fieldCount()), names[0]), oldData, newData); } LambdaForm bind(Name name, Name binding, BoundMethodHandle.SpeciesData oldData, @@ -874,7 +999,7 @@ class LambdaForm { return false; } - LambdaForm addArguments(int pos, char... types) { + LambdaForm addArguments(int pos, BasicType... types) { assert(pos <= arity); int length = names.length; int inTypes = types.length; @@ -895,13 +1020,10 @@ class LambdaForm { } LambdaForm addArguments(int pos, List<Class<?>> types) { - char[] basicTypes = new char[types.size()]; - for (int i = 0; i < basicTypes.length; i++) - basicTypes[i] = basicType(types.get(i)); - return addArguments(pos, basicTypes); + return addArguments(pos, basicTypes(types)); } - LambdaForm permuteArguments(int skip, int[] reorder, char[] types) { + LambdaForm permuteArguments(int skip, int[] reorder, BasicType[] types) { // Note: When inArg = reorder[outArg], outArg is fed by a copy of inArg. // The types are the types of the new (incoming) arguments. int length = names.length; @@ -960,7 +1082,7 @@ class LambdaForm { return new LambdaForm(debugName, arity2, names2, result2); } - static boolean permutedTypesMatch(int[] reorder, char[] types, Name[] names, int skip) { + static boolean permutedTypesMatch(int[] reorder, BasicType[] types, Name[] names, int skip) { int inTypes = types.length; int outArgs = reorder.length; for (int i = 0; i < outArgs; i++) { @@ -1044,7 +1166,7 @@ class LambdaForm { String sig = m.getName().substring("invoke_".length()); int arity = LambdaForm.signatureArity(sig); MethodType srcType = MethodType.genericMethodType(arity); - if (LambdaForm.signatureReturn(sig) == 'V') + if (LambdaForm.signatureReturn(sig) == V_TYPE) srcType = srcType.changeReturnType(void.class); MethodTypeForm typeForm = srcType.form(); typeForm.namedFunctionInvoker = DirectMethodHandle.make(m); @@ -1134,7 +1256,7 @@ class LambdaForm { MethodHandle mh2 = typeForm.namedFunctionInvoker; if (mh2 != null) return mh2; // benign race if (!mh.type().equals(INVOKER_METHOD_TYPE)) - throw new InternalError(mh.debugString()); + throw newInternalError(mh.debugString()); return typeForm.namedFunctionInvoker = mh; } @@ -1193,11 +1315,6 @@ class LambdaForm { return true; } - String basicTypeSignature() { - //return LambdaForm.basicTypeSignature(resolvedHandle.type()); - return LambdaForm.basicTypeSignature(methodType()); - } - MethodType methodType() { if (resolvedHandle != null) return resolvedHandle.type(); @@ -1224,18 +1341,15 @@ class LambdaForm { return (member == null) ? null : member.getDeclaringClass(); } - char returnType() { + BasicType returnType() { return basicType(methodType().returnType()); } - char parameterType(int n) { + BasicType parameterType(int n) { return basicType(methodType().parameterType(n)); } int arity() { - //int siglen = member.getMethodType().parameterCount(); - //if (!member.isStatic()) siglen += 1; - //return siglen; return methodType().parameterCount(); } @@ -1243,44 +1357,63 @@ class LambdaForm { if (member == null) return String.valueOf(resolvedHandle); return member.getDeclaringClass().getSimpleName()+"."+member.getName(); } - } - void resolve() { - for (Name n : names) n.resolve(); - } - - public static char basicType(Class<?> type) { - char c = Wrapper.basicTypeChar(type); - if ("ZBSC".indexOf(c) >= 0) c = 'I'; - assert("LIJFDV".indexOf(c) >= 0); - return c; - } - public static char[] basicTypes(List<Class<?>> types) { - char[] btypes = new char[types.size()]; - for (int i = 0; i < btypes.length; i++) { - btypes[i] = basicType(types.get(i)); + public boolean isIdentity() { + return this.equals(identity(returnType())); + } + + public boolean isConstantZero() { + return this.equals(constantZero(returnType())); } - return btypes; } + public static String basicTypeSignature(MethodType type) { char[] sig = new char[type.parameterCount() + 2]; int sigp = 0; for (Class<?> pt : type.parameterList()) { - sig[sigp++] = basicType(pt); + sig[sigp++] = basicTypeChar(pt); } sig[sigp++] = '_'; - sig[sigp++] = basicType(type.returnType()); + sig[sigp++] = basicTypeChar(type.returnType()); assert(sigp == sig.length); return String.valueOf(sig); } + public static String shortenSignature(String signature) { + // Hack to make signatures more readable when they show up in method names. + final int NO_CHAR = -1, MIN_RUN = 3; + int c0, c1 = NO_CHAR, c1reps = 0; + StringBuilder buf = null; + int len = signature.length(); + if (len < MIN_RUN) return signature; + for (int i = 0; i <= len; i++) { + // shift in the next char: + c0 = c1; c1 = (i == len ? NO_CHAR : signature.charAt(i)); + if (c1 == c0) { ++c1reps; continue; } + // shift in the next count: + int c0reps = c1reps; c1reps = 1; + // end of a character run + if (c0reps < MIN_RUN) { + if (buf != null) { + while (--c0reps >= 0) + buf.append((char)c0); + } + continue; + } + // found three or more in a row + if (buf == null) + buf = new StringBuilder().append(signature, 0, i - c0reps); + buf.append((char)c0).append(c0reps); + } + return (buf == null) ? signature : buf.toString(); + } static final class Name { - final char type; + final BasicType type; private short index; final NamedFunction function; @Stable final Object[] arguments; - private Name(int index, char type, NamedFunction function, Object[] arguments) { + private Name(int index, BasicType type, NamedFunction function, Object[] arguments) { this.index = (short)index; this.type = type; this.function = function; @@ -1292,7 +1425,7 @@ class LambdaForm { } Name(MethodType functionType, Object... arguments) { this(new NamedFunction(functionType), arguments); - assert(arguments[0] instanceof Name && ((Name)arguments[0]).type == 'L'); + assert(arguments[0] instanceof Name && ((Name)arguments[0]).type == L_TYPE); } Name(MemberName function, Object... arguments) { this(new NamedFunction(function), arguments); @@ -1303,14 +1436,14 @@ class LambdaForm { for (int i = 0; i < arguments.length; i++) assert(typesMatch(function.parameterType(i), arguments[i])) : "types don't match: function.parameterType(" + i + ")=" + function.parameterType(i) + ", arguments[" + i + "]=" + arguments[i] + " in " + debugString(); } - Name(int index, char type) { + /** Create a raw parameter of the given type, with an expected index. */ + Name(int index, BasicType type) { this(index, type, null, null); } - Name(char type) { - this(-1, type); - } + /** Create a raw parameter of the given type. */ + Name(BasicType type) { this(-1, type); } - char type() { return type; } + BasicType type() { return type; } int index() { return index; } boolean initIndex(int i) { if (index != i) { @@ -1319,7 +1452,9 @@ class LambdaForm { } return true; } - + char typeChar() { + return type.btChar; + } void resolve() { if (function != null) @@ -1397,18 +1532,18 @@ class LambdaForm { return function == null; } boolean isConstantZero() { - return !isParam() && arguments.length == 0 && function.equals(constantZero(0, type).function); + return !isParam() && arguments.length == 0 && function.isConstantZero(); } public String toString() { - return (isParam()?"a":"t")+(index >= 0 ? index : System.identityHashCode(this))+":"+type; + return (isParam()?"a":"t")+(index >= 0 ? index : System.identityHashCode(this))+":"+typeChar(); } public String debugString() { String s = toString(); return (function == null) ? s : s + "=" + exprString(); } public String exprString() { - if (function == null) return "null"; + if (function == null) return toString(); StringBuilder buf = new StringBuilder(function.toString()); buf.append("("); String cma = ""; @@ -1423,17 +1558,17 @@ class LambdaForm { return buf.toString(); } - private static boolean typesMatch(char parameterType, Object object) { + static boolean typesMatch(BasicType parameterType, Object object) { if (object instanceof Name) { return ((Name)object).type == parameterType; } switch (parameterType) { - case 'I': return object instanceof Integer; - case 'J': return object instanceof Long; - case 'F': return object instanceof Float; - case 'D': return object instanceof Double; + case I_TYPE: return object instanceof Integer; + case J_TYPE: return object instanceof Long; + case F_TYPE: return object instanceof Float; + case D_TYPE: return object instanceof Double; } - assert(parameterType == 'L'); + assert(parameterType == L_TYPE); return true; } @@ -1510,7 +1645,7 @@ class LambdaForm { @Override public int hashCode() { if (isParam()) - return index | (type << 8); + return index | (type.ordinal() << 8); return function.hashCode() ^ Arrays.hashCode(arguments); } } @@ -1545,10 +1680,12 @@ class LambdaForm { } static Name argument(int which, char type) { - int tn = ALL_TYPES.indexOf(type); - if (tn < 0 || which >= INTERNED_ARGUMENT_LIMIT) + return argument(which, basicType(type)); + } + static Name argument(int which, BasicType type) { + if (which >= INTERNED_ARGUMENT_LIMIT) return new Name(which, type); - return INTERNED_ARGUMENTS[tn][which]; + return INTERNED_ARGUMENTS[type.ordinal()][which]; } static Name internArgument(Name n) { assert(n.isParam()) : "not param: " + n; @@ -1590,56 +1727,118 @@ class LambdaForm { names[i] = argument(i, basicType(types.parameterType(i))); return names; } - static final String ALL_TYPES = "LIJFD"; // omit V, not an argument type static final int INTERNED_ARGUMENT_LIMIT = 10; private static final Name[][] INTERNED_ARGUMENTS - = new Name[ALL_TYPES.length()][INTERNED_ARGUMENT_LIMIT]; + = new Name[ARG_TYPE_LIMIT][INTERNED_ARGUMENT_LIMIT]; static { - for (int tn = 0; tn < ALL_TYPES.length(); tn++) { - for (int i = 0; i < INTERNED_ARGUMENTS[tn].length; i++) { - char type = ALL_TYPES.charAt(tn); - INTERNED_ARGUMENTS[tn][i] = new Name(i, type); + for (BasicType type : BasicType.ARG_TYPES) { + int ord = type.ordinal(); + for (int i = 0; i < INTERNED_ARGUMENTS[ord].length; i++) { + INTERNED_ARGUMENTS[ord][i] = new Name(i, type); } } } private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory(); - static Name constantZero(int which, char type) { - return CONSTANT_ZERO[ALL_TYPES.indexOf(type)].newIndex(which); + static LambdaForm identityForm(BasicType type) { + return LF_identityForm[type.ordinal()]; } - private static final Name[] CONSTANT_ZERO - = new Name[ALL_TYPES.length()]; - static { - for (int tn = 0; tn < ALL_TYPES.length(); tn++) { - char bt = ALL_TYPES.charAt(tn); - Wrapper wrap = Wrapper.forBasicType(bt); - MemberName zmem = new MemberName(LambdaForm.class, "zero"+bt, MethodType.methodType(wrap.primitiveType()), REF_invokeStatic); + static LambdaForm zeroForm(BasicType type) { + return LF_zeroForm[type.ordinal()]; + } + static NamedFunction identity(BasicType type) { + return NF_identity[type.ordinal()]; + } + static NamedFunction constantZero(BasicType type) { + return NF_zero[type.ordinal()]; + } + private static final LambdaForm[] LF_identityForm = new LambdaForm[TYPE_LIMIT]; + private static final LambdaForm[] LF_zeroForm = new LambdaForm[TYPE_LIMIT]; + private static final NamedFunction[] NF_identity = new NamedFunction[TYPE_LIMIT]; + private static final NamedFunction[] NF_zero = new NamedFunction[TYPE_LIMIT]; + private static void createIdentityForms() { + for (BasicType type : BasicType.ALL_TYPES) { + int ord = type.ordinal(); + char btChar = type.basicTypeChar(); + boolean isVoid = (type == V_TYPE); + Class<?> btClass = type.btClass; + MethodType zeType = MethodType.methodType(btClass); + MethodType idType = isVoid ? zeType : zeType.appendParameterTypes(btClass); + + // Look up some symbolic names. It might not be necessary to have these, + // but if we need to emit direct references to bytecodes, it helps. + // Zero is built from a call to an identity function with a constant zero input. + MemberName idMem = new MemberName(LambdaForm.class, "identity_"+btChar, idType, REF_invokeStatic); + MemberName zeMem = new MemberName(LambdaForm.class, "zero_"+btChar, zeType, REF_invokeStatic); try { - zmem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, zmem, null, NoSuchMethodException.class); + zeMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, zeMem, null, NoSuchMethodException.class); + idMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, idMem, null, NoSuchMethodException.class); } catch (IllegalAccessException|NoSuchMethodException ex) { throw newInternalError(ex); } - NamedFunction zcon = new NamedFunction(zmem); - Name n = new Name(zcon).newIndex(0); - assert(n.type == ALL_TYPES.charAt(tn)); - CONSTANT_ZERO[tn] = n; - assert(n.isConstantZero()); + + NamedFunction idFun = new NamedFunction(idMem); + LambdaForm idForm; + if (isVoid) { + Name[] idNames = new Name[] { argument(0, L_TYPE) }; + idForm = new LambdaForm(idMem.getName(), 1, idNames, VOID_RESULT); + } else { + Name[] idNames = new Name[] { argument(0, L_TYPE), argument(1, type) }; + idForm = new LambdaForm(idMem.getName(), 2, idNames, 1); + } + LF_identityForm[ord] = idForm; + NF_identity[ord] = idFun; + + NamedFunction zeFun = new NamedFunction(zeMem); + LambdaForm zeForm; + if (isVoid) { + zeForm = idForm; + } else { + 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); + } + LF_zeroForm[ord] = zeForm; + NF_zero[ord] = zeFun; + + assert(idFun.isIdentity()); + assert(zeFun.isConstantZero()); + assert(new Name(zeFun).isConstantZero()); + } + + // Do this in a separate pass, so that SimpleMethodHandle.make can see the tables. + for (BasicType type : BasicType.ALL_TYPES) { + int ord = type.ordinal(); + NamedFunction idFun = NF_identity[ord]; + LambdaForm idForm = LF_identityForm[ord]; + MemberName idMem = idFun.member; + idFun.resolvedHandle = SimpleMethodHandle.make(idMem.getInvocationType(), idForm); + + NamedFunction zeFun = NF_zero[ord]; + LambdaForm zeForm = LF_zeroForm[ord]; + MemberName zeMem = zeFun.member; + zeFun.resolvedHandle = SimpleMethodHandle.make(zeMem.getInvocationType(), zeForm); + + assert(idFun.isIdentity()); + assert(zeFun.isConstantZero()); + assert(new Name(zeFun).isConstantZero()); } } // Avoid appealing to ValueConversions at bootstrap time: - private static int zeroI() { return 0; } - private static long zeroJ() { return 0; } - private static float zeroF() { return 0; } - private static double zeroD() { return 0; } - private static Object zeroL() { return null; } - - // Put this last, so that previous static inits can run before. - static { - if (USE_PREDEFINED_INTERPRET_METHODS) - PREPARED_FORMS.putAll(computeInitialPreparedForms()); - } + private static int identity_I(int x) { return x; } + private static long identity_J(long x) { return x; } + private static float identity_F(float x) { return x; } + private static double identity_D(double x) { return x; } + private static Object identity_L(Object x) { return x; } + private static void identity_V() { return; } // same as zeroV, but that's OK + private static int zero_I() { return 0; } + private static long zero_J() { return 0; } + private static float zero_F() { return 0; } + private static double zero_D() { return 0; } + private static Object zero_L() { return null; } + private static void zero_V() { return; } /** * Internal marker for byte-compiled LambdaForms. @@ -1690,7 +1889,21 @@ class LambdaForm { static final native Object linkToInterface(Object x1, MemberName mn) throws Throwable; */ - static { NamedFunction.initializeInvokers(); } + private static final HashMap<String,Integer> DEBUG_NAME_COUNTERS; + static { + if (debugEnabled()) + DEBUG_NAME_COUNTERS = new HashMap<>(); + else + DEBUG_NAME_COUNTERS = null; + } + + // Put this last, so that previous static inits can run before. + static { + createIdentityForms(); + if (USE_PREDEFINED_INTERPRET_METHODS) + PREPARED_FORMS.putAll(computeInitialPreparedForms()); + NamedFunction.initializeInvokers(); + } // The following hack is necessary in order to suppress TRACE_INTERPRETER // during execution of the static initializes of this class. diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java index f142076f528..19664528f26 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java @@ -27,10 +27,12 @@ package java.lang.invoke; import java.util.*; +import java.lang.invoke.LambdaForm.BasicType; import sun.invoke.util.*; import sun.misc.Unsafe; import static java.lang.invoke.MethodHandleStatics.*; +import static java.lang.invoke.LambdaForm.BasicType.*; /** * A method handle is a typed, directly executable reference to an underlying method, @@ -729,7 +731,7 @@ public abstract class MethodHandle { * <li>If the return type <em>T0</em> is void and <em>T1</em> a primitive, * a zero value is introduced. * </ul> - * (<em>Note:</em> Both <em>T0</em> and <em>T1</em> may be regarded as static types, + * (<em>Note:</em> Both <em>T0</em> and <em>T1</em> may be regarded as static types, * because neither corresponds specifically to the <em>dynamic type</em> of any * actual argument or return value.) * <p> @@ -1374,7 +1376,7 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString()); } /*non-public*/ - MethodHandle bindArgument(int pos, char basicType, Object value) { + MethodHandle bindArgument(int pos, BasicType basicType, Object value) { // Override this if it can be improved. return rebind().bindArgument(pos, basicType, value); } @@ -1382,26 +1384,7 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString()); /*non-public*/ MethodHandle bindReceiver(Object receiver) { // Override this if it can be improved. - return bindArgument(0, 'L', receiver); - } - - /*non-public*/ - MethodHandle bindImmediate(int pos, char basicType, Object value) { - // Bind an immediate value to a position in the arguments. - // This means, elide the respective argument, - // and replace all references to it in NamedFunction args with the specified value. - - // CURRENT RESTRICTIONS - // * only for pos 0 and UNSAFE (position is adjusted in MHImpl to make API usable for others) - assert pos == 0 && basicType == 'L' && value instanceof Unsafe; - MethodType type2 = type.dropParameterTypes(pos, pos + 1); // adjustment: ignore receiver! - LambdaForm form2 = form.bindImmediate(pos + 1, basicType, value); // adjust pos to form-relative pos - return copyWith(type2, form2); - } - - /*non-public*/ - MethodHandle copyWith(MethodType mt, LambdaForm lf) { - throw new InternalError("copyWith: " + this.getClass()); + return bindArgument(0, L_TYPE, receiver); } /*non-public*/ diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java index cdf6e5a75ce..6abceb5ad19 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -412,7 +412,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; @Override - MethodHandle bindArgument(int pos, char basicType, Object value) { + MethodHandle bindArgument(int pos, BasicType basicType, Object value) { return asFixedArity().bindArgument(pos, basicType, value); } diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java index fd5cac8cd7b..0f5169e95e2 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java @@ -78,7 +78,7 @@ class MethodHandleNatives { // The JVM calls MethodHandleNatives.<clinit>. Cascade the <clinit> calls as needed: MethodHandleImpl.initStatics(); -} + } // All compile-time constants go here. // There is an opportunity to check them against the JVM's idea of them. @@ -293,6 +293,17 @@ class MethodHandleNatives { Class<?> caller = (Class<?>)callerObj; String name = nameObj.toString().intern(); MethodType type = (MethodType)typeObj; + if (!TRACE_METHOD_LINKAGE) + return linkCallSiteImpl(caller, bootstrapMethod, name, type, + staticArguments, appendixResult); + return linkCallSiteTracing(caller, bootstrapMethod, name, type, + staticArguments, appendixResult); + } + static MemberName linkCallSiteImpl(Class<?> caller, + MethodHandle bootstrapMethod, + String name, MethodType type, + Object staticArguments, + Object[] appendixResult) { CallSite callSite = CallSite.makeSite(bootstrapMethod, name, type, @@ -306,6 +317,30 @@ class MethodHandleNatives { return Invokers.linkToCallSiteMethod(type); } } + // Tracing logic: + static MemberName linkCallSiteTracing(Class<?> caller, + MethodHandle bootstrapMethod, + String name, MethodType type, + Object staticArguments, + Object[] appendixResult) { + Object bsmReference = bootstrapMethod.internalMemberName(); + if (bsmReference == null) bsmReference = bootstrapMethod; + Object staticArglist = (staticArguments instanceof Object[] ? + java.util.Arrays.asList((Object[]) staticArguments) : + staticArguments); + System.out.println("linkCallSite "+caller.getName()+" "+ + bsmReference+" "+ + name+type+"/"+staticArglist); + try { + MemberName res = linkCallSiteImpl(caller, bootstrapMethod, name, type, + staticArguments, appendixResult); + System.out.println("linkCallSite => "+res+" + "+appendixResult[0]); + return res; + } catch (Throwable ex) { + System.out.println("linkCallSite => throw "+ex); + throw ex; + } + } /** * The JVM wants a pointer to a MethodType. Oblige it by finding or creating one. diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java index 8a8eedfe1bf..50a14b35d52 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java @@ -65,6 +65,16 @@ import sun.misc.Unsafe; COMPILE_THRESHOLD = (Integer) values[4]; } + /** Tell if any of the debugging switches are turned on. + * If this is the case, it is reasonable to perform extra checks or save extra information. + */ + /*non-public*/ static boolean debugEnabled() { + return (DEBUG_METHOD_HANDLE_NAMES | + DUMP_CLASS_FILES | + TRACE_INTERPRETER | + TRACE_METHOD_LINKAGE); + } + /*non-public*/ static String getNameString(MethodHandle target, MethodType type) { if (type == null) type = target.type(); @@ -93,6 +103,9 @@ import sun.misc.Unsafe; } // handy shared exception makers (they simplify the common case code) + /*non-public*/ static InternalError newInternalError(String message) { + return new InternalError(message); + } /*non-public*/ static InternalError newInternalError(String message, Throwable cause) { return new InternalError(message, cause); } diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java index 834650c84fa..48a937c1998 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java @@ -37,10 +37,11 @@ import sun.reflect.CallerSensitive; import sun.reflect.Reflection; import sun.reflect.misc.ReflectUtil; import sun.security.util.SecurityConstants; +import java.lang.invoke.LambdaForm.BasicType; +import static java.lang.invoke.LambdaForm.BasicType.*; import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; import java.util.concurrent.ConcurrentHashMap; -import sun.security.util.SecurityConstants; /** * This class consists exclusively of static methods that operate on or return @@ -2189,12 +2190,12 @@ assert((int)twice.invokeExact(21) == 42); Object value = values[i]; Class<?> ptype = oldType.parameterType(pos+i); if (ptype.isPrimitive()) { - char btype = 'I'; + BasicType btype = I_TYPE; Wrapper w = Wrapper.forPrimitiveType(ptype); switch (w) { - case LONG: btype = 'J'; break; - case FLOAT: btype = 'F'; break; - case DOUBLE: btype = 'D'; break; + case LONG: btype = J_TYPE; break; + case FLOAT: btype = F_TYPE; break; + case DOUBLE: btype = D_TYPE; break; } // perform unboxing and/or primitive conversion value = w.convert(value, ptype); @@ -2205,7 +2206,7 @@ assert((int)twice.invokeExact(21) == 42); if (pos == 0) { result = result.bindReceiver(value); } else { - result = result.bindArgument(pos, 'L', value); + result = result.bindArgument(pos, L_TYPE, value); } } return result; diff --git a/jdk/src/share/classes/java/lang/invoke/SimpleMethodHandle.java b/jdk/src/share/classes/java/lang/invoke/SimpleMethodHandle.java index 07f08dd6962..752505ee68e 100644 --- a/jdk/src/share/classes/java/lang/invoke/SimpleMethodHandle.java +++ b/jdk/src/share/classes/java/lang/invoke/SimpleMethodHandle.java @@ -26,7 +26,7 @@ package java.lang.invoke; import static java.lang.invoke.LambdaForm.*; -import static java.lang.invoke.MethodHandleNatives.Constants.*; +import static java.lang.invoke.LambdaForm.BasicType.*; /** * A method handle whose behavior is determined only by its LambdaForm. @@ -42,7 +42,7 @@ final class SimpleMethodHandle extends MethodHandle { } @Override - MethodHandle bindArgument(int pos, char basicType, Object value) { + MethodHandle bindArgument(int pos, BasicType basicType, Object value) { MethodType type2 = type().dropParameterTypes(pos, pos+1); LambdaForm form2 = internalForm().bind(1+pos, BoundMethodHandle.SpeciesData.EMPTY); return BoundMethodHandle.bindSingle(type2, form2, basicType, value); @@ -59,10 +59,4 @@ final class SimpleMethodHandle extends MethodHandle { LambdaForm form2 = internalForm().permuteArguments(1, reorder, basicTypes(newType.parameterList())); return new SimpleMethodHandle(newType, form2); } - - @Override - MethodHandle copyWith(MethodType mt, LambdaForm lf) { - return new SimpleMethodHandle(mt, lf); - } - } diff --git a/jdk/test/java/lang/invoke/LambdaFormTest.java b/jdk/test/java/lang/invoke/LambdaFormTest.java new file mode 100644 index 00000000000..f078189c5c0 --- /dev/null +++ b/jdk/test/java/lang/invoke/LambdaFormTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 unit tests for java.lang.invoke.LambdaForm + * @run junit/othervm test.java.lang.invoke.LambdaFormTest + */ +package test.java.lang.invoke; + +import org.junit.Test; +import java.lang.reflect.Method; +import static org.junit.Assert.*; + +public class LambdaFormTest { + static final Method M_shortenSignature; + static { + try { + Class<?> impl = Class.forName("java.lang.invoke.LambdaForm", false, null); + Method m = impl.getDeclaredMethod("shortenSignature", String.class); + m.setAccessible(true); + M_shortenSignature = m; + } catch(Exception e) { + throw new AssertionError(e); + } + } + + public static String shortenSignature(String signature) throws ReflectiveOperationException { + return (String)M_shortenSignature.invoke(null, signature); + } + + @Test + public void testShortenSignature() throws ReflectiveOperationException { + for (String s : new String[] { + // invariant strings: + "L", "LL", "ILL", "LIL", "LLI", "IILL", "ILIL", "ILLI", + // a few mappings: + "LLL=L3", "LLLL=L4", "LLLLLLLLLL=L10", + "IIIDDD=I3D3", "IDDD=ID3", "IIDDD=IID3", "IIID=I3D", "IIIDD=I3DD" + }) { + String s2 = s.substring(s.indexOf('=')+1); + String s1 = s.equals(s2) ? s : s.substring(0, s.length() - s2.length() - 1); + // mix the above cases with before and after reps of Z* + for (int k = -3; k <= 3; k++) { + String beg = (k < 0 ? "ZZZZ".substring(-k) : ""); + String end = (k > 0 ? "ZZZZ".substring(+k) : ""); + String ks1 = beg+s1+end; + String ks2 = shortenSignature(beg)+s2+shortenSignature(end); + String ks3 = shortenSignature(ks1); + assertEquals(ks2, ks3); + } + } + } + + public static void main(String[] args) throws ReflectiveOperationException { + LambdaFormTest test = new LambdaFormTest(); + test.testShortenSignature(); + } +} From ae28b717f4a216c9db76ba3df1404d5896b58bc3 Mon Sep 17 00:00:00 2001 From: Albert Noll <anoll@openjdk.org> Date: Thu, 8 May 2014 12:49:21 +0200 Subject: [PATCH 006/157] 8042431: compiler/7200264/TestIntVect.java fails with: Test Failed: AddVI 0 < 4 Define a new function that determines the minimum number of compiler threads for a particular platform/configuration. Reviewed-by: kvn --- hotspot/src/share/vm/runtime/arguments.cpp | 34 ++++++++++++++++++++-- hotspot/src/share/vm/runtime/arguments.hpp | 1 + 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index d146785b53b..9fb4c5ba34b 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1151,6 +1151,32 @@ void Arguments::set_tiered_flags() { } } +/** + * Returns the minimum number of compiler threads needed to run the JVM. The following + * configurations are possible. + * + * 1) The JVM is build using an interpreter only. As a result, the minimum number of + * compiler threads is 0. + * 2) The JVM is build using the compiler(s) and tiered compilation is disabled. As + * a result, either C1 or C2 is used, so the minimum number of compiler threads is 1. + * 3) The JVM is build using the compiler(s) and tiered compilation is enabled. However, + * the option "TieredStopAtLevel < CompLevel_full_optimization". As a result, only + * C1 can be used, so the minimum number of compiler threads is 1. + * 4) The JVM is build using the compilers and tiered compilation is enabled. The option + * 'TieredStopAtLevel = CompLevel_full_optimization' (the default value). As a result, + * the minimum number of compiler threads is 2. + */ +int Arguments::get_min_number_of_compiler_threads() { +#if !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK) + return 0; // case 1 +#else + if (!TieredCompilation || (TieredStopAtLevel < CompLevel_full_optimization)) { + return 1; // case 2 or case 3 + } + return 2; // case 4 (tiered) +#endif +} + #if INCLUDE_ALL_GCS static void disable_adaptive_size_policy(const char* collector_name) { if (UseAdaptiveSizePolicy) { @@ -2398,9 +2424,11 @@ bool Arguments::check_vm_args_consistency() { status &= verify_interval(CodeCacheMinBlockLength, 1, 100, "CodeCacheMinBlockLength"); status &= verify_interval(CodeCacheSegmentSize, 1, 1024, "CodeCacheSegmentSize"); - // TieredCompilation needs at least 2 compiler threads. - const int num_min_compiler_threads = (TieredCompilation && (TieredStopAtLevel >= CompLevel_full_optimization)) ? 2 : CI_COMPILER_COUNT; - status &=verify_min_value(CICompilerCount, num_min_compiler_threads, "CICompilerCount"); + int min_number_of_compiler_threads = get_min_number_of_compiler_threads(); + // The default CICompilerCount's value is CI_COMPILER_COUNT. + assert(min_number_of_compiler_threads <= CI_COMPILER_COUNT, "minimum should be less or equal default number"); + // Check the minimum number of compiler threads + status &=verify_min_value(CICompilerCount, min_number_of_compiler_threads, "CICompilerCount"); if (!FLAG_IS_DEFAULT(CICompilerCount) && !FLAG_IS_DEFAULT(CICompilerCountPerCPU) && CICompilerCountPerCPU) { warning("The VM option CICompilerCountPerCPU overrides CICompilerCount."); diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp index f898c24b22d..903fcd5db85 100644 --- a/hotspot/src/share/vm/runtime/arguments.hpp +++ b/hotspot/src/share/vm/runtime/arguments.hpp @@ -323,6 +323,7 @@ class Arguments : AllStatic { // Tiered static void set_tiered_flags(); + static int get_min_number_of_compiler_threads(); // CMS/ParNew garbage collectors static void set_parnew_gc_flags(); static void set_cms_and_parnew_gc_flags(); From d2af4e35ec7bc7439942a1218ad68c012b335673 Mon Sep 17 00:00:00 2001 From: Tobias Hartmann <tobias.hartmann@oracle.com> Date: Fri, 9 May 2014 09:12:39 +0200 Subject: [PATCH 007/157] 8029343: CodeCache::allocate increments '_number_of_blobs' even if allocation fails Incrementing the number of code blobs in CodeCache::allocate(...) is now only performed if allocation succeeds. The guarantee is fixed. Reviewed-by: kvn, iveresov --- hotspot/src/share/vm/code/codeCache.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/code/codeCache.cpp b/hotspot/src/share/vm/code/codeCache.cpp index b3a857c2062..a2e8f0e0f15 100644 --- a/hotspot/src/share/vm/code/codeCache.cpp +++ b/hotspot/src/share/vm/code/codeCache.cpp @@ -178,10 +178,12 @@ CodeBlob* CodeCache::allocate(int size, bool is_critical) { // cache will contain a garbage CodeBlob until the caller can // run the constructor for the CodeBlob subclass he is busy // instantiating. - guarantee(size >= 0, "allocation request must be reasonable"); assert_locked_or_safepoint(CodeCache_lock); + assert(size > 0, "allocation request must be reasonable"); + if (size <= 0) { + return NULL; + } CodeBlob* cb = NULL; - _number_of_blobs++; while (true) { cb = (CodeBlob*)_heap->allocate(size, is_critical); if (cb != NULL) break; @@ -199,6 +201,7 @@ CodeBlob* CodeCache::allocate(int size, bool is_critical) { maxCodeCacheUsed = MAX2(maxCodeCacheUsed, ((address)_heap->high_boundary() - (address)_heap->low_boundary()) - unallocated_capacity()); print_trace("allocation", cb, size); + _number_of_blobs++; return cb; } From 5938d3d5b90eac7a257d638c3f91c33244500d3f Mon Sep 17 00:00:00 2001 From: Tobias Hartmann <tobias.hartmann@oracle.com> Date: Tue, 13 May 2014 11:25:17 +0200 Subject: [PATCH 008/157] 8021770: BackEdgeThreshold option is no longer used and should be removed The BackEdgeThreshold option is removed because it is no longer used. Reviewed-by: twisti, kvn, cjplummer --- hotspot/src/cpu/ppc/vm/c2_globals_ppc.hpp | 1 - hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp | 1 - hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp | 1 - hotspot/src/cpu/x86/vm/c1_globals_x86.hpp | 1 - hotspot/src/cpu/x86/vm/c2_globals_x86.hpp | 1 - hotspot/src/cpu/zero/vm/shark_globals_zero.hpp | 1 - hotspot/src/share/vm/runtime/arguments.cpp | 1 + hotspot/src/share/vm/runtime/globals.hpp | 5 ----- 8 files changed, 1 insertion(+), 11 deletions(-) diff --git a/hotspot/src/cpu/ppc/vm/c2_globals_ppc.hpp b/hotspot/src/cpu/ppc/vm/c2_globals_ppc.hpp index 58e4f3887cb..cfa7559c42a 100644 --- a/hotspot/src/cpu/ppc/vm/c2_globals_ppc.hpp +++ b/hotspot/src/cpu/ppc/vm/c2_globals_ppc.hpp @@ -41,7 +41,6 @@ define_pd_global(bool, UseOnStackReplacement, true); define_pd_global(bool, ProfileInterpreter, true); define_pd_global(bool, TieredCompilation, false); define_pd_global(intx, CompileThreshold, 10000); -define_pd_global(intx, BackEdgeThreshold, 140000); define_pd_global(intx, OnStackReplacePercentage, 140); define_pd_global(intx, ConditionalMoveLimit, 3); diff --git a/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp b/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp index 111f22730d3..54e35cb94d9 100644 --- a/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp +++ b/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp @@ -40,7 +40,6 @@ define_pd_global(bool, ProfileTraps, false); define_pd_global(bool, UseOnStackReplacement, true ); define_pd_global(bool, TieredCompilation, false); define_pd_global(intx, CompileThreshold, 1000 ); // Design center runs on 1.3.1 -define_pd_global(intx, BackEdgeThreshold, 100000); define_pd_global(intx, OnStackReplacePercentage, 1400 ); define_pd_global(bool, UseTLAB, true ); diff --git a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp index 10005a76b89..3969f39ecf8 100644 --- a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp +++ b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp @@ -44,7 +44,6 @@ define_pd_global(bool, ProfileInterpreter, true); #endif // CC_INTERP define_pd_global(bool, TieredCompilation, trueInTiered); define_pd_global(intx, CompileThreshold, 10000); -define_pd_global(intx, BackEdgeThreshold, 140000); define_pd_global(intx, OnStackReplacePercentage, 140); define_pd_global(intx, ConditionalMoveLimit, 4); diff --git a/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp b/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp index 742a5d8601d..fb7cb2889be 100644 --- a/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp @@ -41,7 +41,6 @@ define_pd_global(bool, ProfileTraps, false); define_pd_global(bool, UseOnStackReplacement, true ); define_pd_global(bool, TieredCompilation, false); define_pd_global(intx, CompileThreshold, 1500 ); -define_pd_global(intx, BackEdgeThreshold, 100000); define_pd_global(intx, OnStackReplacePercentage, 933 ); define_pd_global(intx, FreqInlineSize, 325 ); diff --git a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp index 880d9439462..0366d8fcf49 100644 --- a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp @@ -45,7 +45,6 @@ define_pd_global(bool, ProfileInterpreter, true); #endif // CC_INTERP define_pd_global(bool, TieredCompilation, trueInTiered); define_pd_global(intx, CompileThreshold, 10000); -define_pd_global(intx, BackEdgeThreshold, 100000); define_pd_global(intx, OnStackReplacePercentage, 140); define_pd_global(intx, ConditionalMoveLimit, 3); diff --git a/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp b/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp index edb7364c80f..b86cb79dd86 100644 --- a/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp +++ b/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp @@ -43,7 +43,6 @@ define_pd_global(intx, Tier2CompileThreshold, 1500); define_pd_global(intx, Tier3CompileThreshold, 2500); define_pd_global(intx, Tier4CompileThreshold, 4500); -define_pd_global(intx, BackEdgeThreshold, 100000); define_pd_global(intx, Tier2BackEdgeThreshold, 100000); define_pd_global(intx, Tier3BackEdgeThreshold, 100000); define_pd_global(intx, Tier4BackEdgeThreshold, 100000); diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index da1ed40c534..8960f7e63ef 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -310,6 +310,7 @@ static ObsoleteFlag obsolete_jvm_flags[] = { { "UseBoundThreads", JDK_Version::jdk(9), JDK_Version::jdk(10) }, { "DefaultThreadPriority", JDK_Version::jdk(9), JDK_Version::jdk(10) }, { "NoYieldsInMicrolock", JDK_Version::jdk(9), JDK_Version::jdk(10) }, + { "BackEdgeThreshold", JDK_Version::jdk(9), JDK_Version::jdk(10) }, { NULL, JDK_Version(0), JDK_Version(0) } }; diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index b2f622e3c91..df3d941ec0d 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -177,7 +177,6 @@ define_pd_global(bool, ProfileTraps, false); define_pd_global(bool, TieredCompilation, false); define_pd_global(intx, CompileThreshold, 0); -define_pd_global(intx, BackEdgeThreshold, 0); define_pd_global(intx, OnStackReplacePercentage, 0); define_pd_global(bool, ResizeTLAB, false); @@ -3525,10 +3524,6 @@ class CommandLineFlags { product_pd(intx, CompileThreshold, \ "number of interpreted method invocations before (re-)compiling") \ \ - product_pd(intx, BackEdgeThreshold, \ - "Interpreter Back edge threshold at which an OSR compilation is " \ - "invoked") \ - \ product(intx, Tier0InvokeNotifyFreqLog, 7, \ "Interpreter (tier 0) invocation notification frequency") \ \ From 54db2c2d612c573f91f69b7b387b43a8e1c9d563 Mon Sep 17 00:00:00 2001 From: Igor Veresov <iveresov@openjdk.org> Date: Tue, 13 May 2014 11:32:10 -0700 Subject: [PATCH 009/157] 8032463: VirtualDispatch test timeout with DeoptimizeALot Introduce code aging for warm method detection Reviewed-by: kvn, twisti --- .../src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp | 1 + .../src/cpu/sparc/vm/c1_Runtime1_sparc.cpp | 2 +- hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp | 1 + hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp | 5 +- hotspot/src/share/vm/c1/c1_CodeStubs.hpp | 4 +- hotspot/src/share/vm/c1/c1_Compilation.hpp | 4 + hotspot/src/share/vm/c1/c1_LIRGenerator.cpp | 26 +++- hotspot/src/share/vm/c1/c1_LIRGenerator.hpp | 2 +- hotspot/src/share/vm/c1/c1_Runtime1.cpp | 23 +++- hotspot/src/share/vm/c1/c1_Runtime1.hpp | 2 +- hotspot/src/share/vm/ci/ciMethod.cpp | 9 ++ hotspot/src/share/vm/ci/ciMethod.hpp | 5 + hotspot/src/share/vm/oops/method.hpp | 7 ++ hotspot/src/share/vm/oops/methodCounters.cpp | 1 + hotspot/src/share/vm/oops/methodCounters.hpp | 34 +++++- hotspot/src/share/vm/oops/methodData.cpp | 1 + hotspot/src/share/vm/oops/methodData.hpp | 7 ++ hotspot/src/share/vm/opto/compile.cpp | 1 + hotspot/src/share/vm/opto/compile.hpp | 5 +- hotspot/src/share/vm/opto/parse.hpp | 1 + hotspot/src/share/vm/opto/parse1.cpp | 28 +++++ .../src/share/vm/runtime/deoptimization.cpp | 49 ++++---- .../src/share/vm/runtime/deoptimization.hpp | 3 +- hotspot/src/share/vm/runtime/globals.hpp | 14 +++ hotspot/src/share/vm/runtime/sweeper.cpp | 114 +++++++++++++----- hotspot/src/share/vm/runtime/sweeper.hpp | 1 + hotspot/src/share/vm/runtime/vmStructs.cpp | 2 + 27 files changed, 283 insertions(+), 69 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp index 8584037f1ca..f3709eb8d05 100644 --- a/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp @@ -414,6 +414,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { void DeoptimizeStub::emit_code(LIR_Assembler* ce) { __ bind(_entry); + __ set(_trap_request, G4); __ call(Runtime1::entry_for(Runtime1::deoptimize_id), relocInfo::runtime_call_type); __ delayed()->nop(); ce->add_call_info_here(_info); diff --git a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp index 0b065201261..1eeca870804 100644 --- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp @@ -781,7 +781,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { { __ set_info("deoptimize", dont_gc_arguments); OopMap* oop_map = save_live_registers(sasm); - int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize)); + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize), G4); oop_maps = new OopMapSet(); oop_maps->add_gc_map(call_offset, oop_map); restore_live_registers(sasm); diff --git a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp index a6e7731bdd5..718c82904f0 100644 --- a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp @@ -430,6 +430,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { void DeoptimizeStub::emit_code(LIR_Assembler* ce) { __ bind(_entry); + ce->store_parameter(_trap_request, 0); __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::deoptimize_id))); ce->add_call_info_here(_info); DEBUG_ONLY(__ should_not_reach_here()); diff --git a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp index fd6302d21be..580964a7cd9 100644 --- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp @@ -1468,9 +1468,10 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { case deoptimize_id: { StubFrame f(sasm, "deoptimize", dont_gc_arguments); - const int num_rt_args = 1; // thread + const int num_rt_args = 2; // thread, trap_request OopMap* oop_map = save_live_registers(sasm, num_rt_args); - int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize)); + f.load_argument(0, rax); + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize), rax); oop_maps = new OopMapSet(); oop_maps->add_gc_map(call_offset, oop_map); restore_live_registers(sasm); diff --git a/hotspot/src/share/vm/c1/c1_CodeStubs.hpp b/hotspot/src/share/vm/c1/c1_CodeStubs.hpp index d3c5a0d8bbb..2d0c31e2afe 100644 --- a/hotspot/src/share/vm/c1/c1_CodeStubs.hpp +++ b/hotspot/src/share/vm/c1/c1_CodeStubs.hpp @@ -450,9 +450,11 @@ class PatchingStub: public CodeStub { class DeoptimizeStub : public CodeStub { private: CodeEmitInfo* _info; + jint _trap_request; public: - DeoptimizeStub(CodeEmitInfo* info) : _info(new CodeEmitInfo(info)) {} + DeoptimizeStub(CodeEmitInfo* info, Deoptimization::DeoptReason reason, Deoptimization::DeoptAction action) : + _info(new CodeEmitInfo(info)), _trap_request(Deoptimization::make_trap_request(reason, action)) {} virtual void emit_code(LIR_Assembler* e); virtual CodeEmitInfo* info() const { return _info; } diff --git a/hotspot/src/share/vm/c1/c1_Compilation.hpp b/hotspot/src/share/vm/c1/c1_Compilation.hpp index 8ff7f3e50c3..6ecd26477e0 100644 --- a/hotspot/src/share/vm/c1/c1_Compilation.hpp +++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp @@ -251,6 +251,10 @@ class Compilation: public StackObj { return env()->comp_level() == CompLevel_full_profile && C1UpdateMethodData && MethodData::profile_return(); } + bool age_code() const { + return _method->profile_aging(); + } + // will compilation make optimistic assumptions that might lead to // deoptimization and that the runtime will account for? bool is_optimistic() const { diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp index 14bc1993ff6..4e4caaa26cb 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp @@ -2782,7 +2782,10 @@ void LIRGenerator::do_Base(Base* x) { __ lock_object(syncTempOpr(), obj, lock, new_register(T_OBJECT), slow_path, NULL); } } - + if (compilation()->age_code()) { + CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, 0), NULL, false); + decrement_age(info); + } // increment invocation counters if needed if (!method()->is_accessor()) { // Accessors do not have MDOs, so no counting. profile_parameters(x); @@ -3328,6 +3331,27 @@ void LIRGenerator::increment_event_counter(CodeEmitInfo* info, int bci, bool bac increment_event_counter_impl(info, info->scope()->method(), (1 << freq_log) - 1, bci, backedge, true); } +void LIRGenerator::decrement_age(CodeEmitInfo* info) { + ciMethod* method = info->scope()->method(); + MethodCounters* mc_adr = method->ensure_method_counters(); + if (mc_adr != NULL) { + LIR_Opr mc = new_pointer_register(); + __ move(LIR_OprFact::intptrConst(mc_adr), mc); + int offset = in_bytes(MethodCounters::nmethod_age_offset()); + LIR_Address* counter = new LIR_Address(mc, offset, T_INT); + LIR_Opr result = new_register(T_INT); + __ load(counter, result); + __ sub(result, LIR_OprFact::intConst(1), result); + __ store(result, counter); + // DeoptimizeStub will reexecute from the current state in code info. + CodeStub* deopt = new DeoptimizeStub(info, Deoptimization::Reason_tenured, + Deoptimization::Action_make_not_entrant); + __ cmp(lir_cond_lessEqual, result, LIR_OprFact::intConst(0)); + __ branch(lir_cond_lessEqual, T_INT, deopt); + } +} + + void LIRGenerator::increment_event_counter_impl(CodeEmitInfo* info, ciMethod *method, int frequency, int bci, bool backedge, bool notify) { diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp index 90b278f4356..13446a9ebe9 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp @@ -372,7 +372,7 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure { increment_event_counter(info, bci, true); } } - + void decrement_age(CodeEmitInfo* info); CodeEmitInfo* state_for(Instruction* x, ValueStack* state, bool ignore_xhandler = false); CodeEmitInfo* state_for(Instruction* x); diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp index 9942e44b842..1bafb67f69c 100644 --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp @@ -685,19 +685,32 @@ JRT_LEAF(void, Runtime1::monitorexit(JavaThread* thread, BasicObjectLock* lock)) JRT_END // Cf. OptoRuntime::deoptimize_caller_frame -JRT_ENTRY(void, Runtime1::deoptimize(JavaThread* thread)) +JRT_ENTRY(void, Runtime1::deoptimize(JavaThread* thread, jint trap_request)) // Called from within the owner thread, so no need for safepoint RegisterMap reg_map(thread, false); frame stub_frame = thread->last_frame(); - assert(stub_frame.is_runtime_frame(), "sanity check"); + assert(stub_frame.is_runtime_frame(), "Sanity check"); frame caller_frame = stub_frame.sender(®_map); + nmethod* nm = caller_frame.cb()->as_nmethod_or_null(); + assert(nm != NULL, "Sanity check"); + methodHandle method(thread, nm->method()); + assert(nm == CodeCache::find_nmethod(caller_frame.pc()), "Should be the same"); + Deoptimization::DeoptAction action = Deoptimization::trap_request_action(trap_request); + Deoptimization::DeoptReason reason = Deoptimization::trap_request_reason(trap_request); - // We are coming from a compiled method; check this is true. - assert(CodeCache::find_nmethod(caller_frame.pc()) != NULL, "sanity"); + if (action == Deoptimization::Action_make_not_entrant) { + if (nm->make_not_entrant()) { + if (reason == Deoptimization::Reason_tenured) { + MethodData* trap_mdo = Deoptimization::get_method_data(thread, method, true /*create_if_missing*/); + if (trap_mdo != NULL) { + trap_mdo->inc_tenure_traps(); + } + } + } + } // Deoptimize the caller frame. Deoptimization::deoptimize_frame(thread, caller_frame.id()); - // Return to the now deoptimized frame. JRT_END diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.hpp b/hotspot/src/share/vm/c1/c1_Runtime1.hpp index 276ca44ffbe..9d72a45c891 100644 --- a/hotspot/src/share/vm/c1/c1_Runtime1.hpp +++ b/hotspot/src/share/vm/c1/c1_Runtime1.hpp @@ -156,7 +156,7 @@ class Runtime1: public AllStatic { static void monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock); static void monitorexit (JavaThread* thread, BasicObjectLock* lock); - static void deoptimize(JavaThread* thread); + static void deoptimize(JavaThread* thread, jint trap_request); static int access_field_patching(JavaThread* thread); static int move_klass_patching(JavaThread* thread); diff --git a/hotspot/src/share/vm/ci/ciMethod.cpp b/hotspot/src/share/vm/ci/ciMethod.cpp index dbbbb7fabc8..2e4ef93a946 100644 --- a/hotspot/src/share/vm/ci/ciMethod.cpp +++ b/hotspot/src/share/vm/ci/ciMethod.cpp @@ -129,6 +129,7 @@ ciMethod::ciMethod(methodHandle h_m) : ciMetadata(h_m()) { constantPoolHandle cpool = h_m()->constants(); _signature = new (env->arena()) ciSignature(_holder, cpool, sig_symbol); _method_data = NULL; + _nmethod_age = h_m()->nmethod_age(); // Take a snapshot of these values, so they will be commensurate with the MDO. if (ProfileInterpreter || TieredCompilation) { int invcnt = h_m()->interpreter_invocation_count(); @@ -1275,6 +1276,14 @@ bool ciMethod::check_call(int refinfo_index, bool is_static) const { return false; } +// ------------------------------------------------------------------ +// ciMethod::profile_aging +// +// Should the method be compiled with an age counter? +bool ciMethod::profile_aging() const { + return UseCodeAging && (!MethodCounters::is_nmethod_hot(nmethod_age()) && + !MethodCounters::is_nmethod_age_unset(nmethod_age())); +} // ------------------------------------------------------------------ // ciMethod::print_codes // diff --git a/hotspot/src/share/vm/ci/ciMethod.hpp b/hotspot/src/share/vm/ci/ciMethod.hpp index e061ea463e5..2b9cf376991 100644 --- a/hotspot/src/share/vm/ci/ciMethod.hpp +++ b/hotspot/src/share/vm/ci/ciMethod.hpp @@ -68,6 +68,7 @@ class ciMethod : public ciMetadata { int _max_locals; vmIntrinsics::ID _intrinsic_id; int _handler_count; + int _nmethod_age; int _interpreter_invocation_count; int _interpreter_throwout_count; int _instructions_size; @@ -168,6 +169,10 @@ class ciMethod : public ciMetadata { int interpreter_invocation_count() const { check_is_loaded(); return _interpreter_invocation_count; } int interpreter_throwout_count() const { check_is_loaded(); return _interpreter_throwout_count; } int size_of_parameters() const { check_is_loaded(); return _size_of_parameters; } + int nmethod_age() const { check_is_loaded(); return _nmethod_age; } + + // Should the method be compiled with an age counter? + bool profile_aging() const; // Code size for inlining decisions. int code_size_for_inlining(); diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp index 7d5afaec0b8..3bae50ce712 100644 --- a/hotspot/src/share/vm/oops/method.hpp +++ b/hotspot/src/share/vm/oops/method.hpp @@ -371,6 +371,13 @@ class Method : public Metadata { } } #endif + int nmethod_age() const { + if (method_counters() == NULL) { + return INT_MAX; + } else { + return method_counters()->nmethod_age(); + } + } int invocation_count(); int backedge_count(); diff --git a/hotspot/src/share/vm/oops/methodCounters.cpp b/hotspot/src/share/vm/oops/methodCounters.cpp index 1ee8eb17001..91b05a7bcc8 100644 --- a/hotspot/src/share/vm/oops/methodCounters.cpp +++ b/hotspot/src/share/vm/oops/methodCounters.cpp @@ -34,4 +34,5 @@ void MethodCounters::clear_counters() { backedge_counter()->reset(); set_interpreter_throwout_count(0); set_interpreter_invocation_count(0); + set_nmethod_age(INT_MAX); } diff --git a/hotspot/src/share/vm/oops/methodCounters.hpp b/hotspot/src/share/vm/oops/methodCounters.hpp index 0a6c895b328..75b8c9e6e16 100644 --- a/hotspot/src/share/vm/oops/methodCounters.hpp +++ b/hotspot/src/share/vm/oops/methodCounters.hpp @@ -36,6 +36,15 @@ class MethodCounters: public MetaspaceObj { u2 _number_of_breakpoints; // fullspeed debugging support InvocationCounter _invocation_counter; // Incremented before each activation of the method - used to trigger frequency-based optimizations InvocationCounter _backedge_counter; // Incremented before each backedge taken - used to trigger frequencey-based optimizations + // NMethod age is a counter for warm methods detection in the code cache sweeper. + // The counter is reset by the sweeper and is decremented by some of the compiled + // code. The counter values are interpreted as follows: + // 1. (HotMethodDetection..INT_MAX] - initial value, no counters inserted + // 2. (1..HotMethodDetectionLimit) - the method is warm, the counter is used + // to figure out which methods can be flushed. + // 3. (INT_MIN..0] - method is hot and will deopt and get + // recompiled without the counters + int _nmethod_age; #ifdef TIERED float _rate; // Events (invocation and backedge counter increments) per millisecond @@ -44,7 +53,8 @@ class MethodCounters: public MetaspaceObj { MethodCounters() : _interpreter_invocation_count(0), _interpreter_throwout_count(0), - _number_of_breakpoints(0) + _number_of_breakpoints(0), + _nmethod_age(INT_MAX) #ifdef TIERED , _rate(0), _prev_time(0) @@ -52,6 +62,10 @@ class MethodCounters: public MetaspaceObj { { invocation_counter()->init(); backedge_counter()->init(); + + if (StressCodeAging) { + set_nmethod_age(HotMethodDetectionLimit); + } } public: @@ -104,6 +118,24 @@ class MethodCounters: public MetaspaceObj { InvocationCounter* invocation_counter() { return &_invocation_counter; } InvocationCounter* backedge_counter() { return &_backedge_counter; } + int nmethod_age() { + return _nmethod_age; + } + void set_nmethod_age(int age) { + _nmethod_age = age; + } + void reset_nmethod_age() { + set_nmethod_age(HotMethodDetectionLimit); + } + + static bool is_nmethod_hot(int age) { return age <= 0; } + static bool is_nmethod_warm(int age) { return age < HotMethodDetectionLimit; } + static bool is_nmethod_age_unset(int age) { return age > HotMethodDetectionLimit; } + + static ByteSize nmethod_age_offset() { + return byte_offset_of(MethodCounters, _nmethod_age); + } + static ByteSize interpreter_invocation_counter_offset() { return byte_offset_of(MethodCounters, _interpreter_invocation_count); } diff --git a/hotspot/src/share/vm/oops/methodData.cpp b/hotspot/src/share/vm/oops/methodData.cpp index 4bbdc992d86..2975462fbbf 100644 --- a/hotspot/src/share/vm/oops/methodData.cpp +++ b/hotspot/src/share/vm/oops/methodData.cpp @@ -1130,6 +1130,7 @@ void MethodData::init() { _backedge_counter.init(); _invocation_counter_start = 0; _backedge_counter_start = 0; + _tenure_traps = 0; _num_loops = 0; _num_blocks = 0; _highest_comp_level = 0; diff --git a/hotspot/src/share/vm/oops/methodData.hpp b/hotspot/src/share/vm/oops/methodData.hpp index efd05cb5ade..32a48a97a5a 100644 --- a/hotspot/src/share/vm/oops/methodData.hpp +++ b/hotspot/src/share/vm/oops/methodData.hpp @@ -2059,6 +2059,7 @@ private: // Counter values at the time profiling started. int _invocation_counter_start; int _backedge_counter_start; + uint _tenure_traps; #if INCLUDE_RTM_OPT // State of RTM code generation during compilation of the method @@ -2398,6 +2399,12 @@ public: method()->set_not_compilable(CompLevel_full_optimization, true, "decompile_count > PerMethodRecompilationCutoff"); } } + uint tenure_traps() const { + return _tenure_traps; + } + void inc_tenure_traps() { + _tenure_traps += 1; + } // Return pointer to area dedicated to parameters in MDO ParametersTypeData* parameters_type_data() const { diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index 738644001b1..3a00ae2f829 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -1089,6 +1089,7 @@ void Compile::Init(int aliaslevel) { set_do_scheduling(OptoScheduling); set_do_count_invocations(false); set_do_method_data_update(false); + set_age_code(has_method() && method()->profile_aging()); set_rtm_state(NoRTM); // No RTM lock eliding by default #if INCLUDE_RTM_OPT if (UseRTMLocking && has_method() && (method()->method_data_or_null() != NULL)) { diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp index aa4a5720502..a875259b823 100644 --- a/hotspot/src/share/vm/opto/compile.hpp +++ b/hotspot/src/share/vm/opto/compile.hpp @@ -311,6 +311,7 @@ class Compile : public Phase { bool _do_freq_based_layout; // True if we intend to do frequency based block layout bool _do_count_invocations; // True if we generate code to count invocations bool _do_method_data_update; // True if we generate code to update MethodData*s + bool _age_code; // True if we need to profile code age (decrement the aging counter) int _AliasLevel; // Locally-adjusted version of AliasLevel flag. bool _print_assembly; // True if we should dump assembly code for this compilation bool _print_inlining; // True if we should print inlining for this compilation @@ -584,7 +585,9 @@ class Compile : public Phase { void set_do_count_invocations(bool z){ _do_count_invocations = z; } bool do_method_data_update() const { return _do_method_data_update; } void set_do_method_data_update(bool z) { _do_method_data_update = z; } - int AliasLevel() const { return _AliasLevel; } + bool age_code() const { return _age_code; } + void set_age_code(bool z) { _age_code = z; } + int AliasLevel() const { return _AliasLevel; } bool print_assembly() const { return _print_assembly; } void set_print_assembly(bool z) { _print_assembly = z; } bool print_inlining() const { return _print_inlining; } diff --git a/hotspot/src/share/vm/opto/parse.hpp b/hotspot/src/share/vm/opto/parse.hpp index aae634a9563..e810c9d4d58 100644 --- a/hotspot/src/share/vm/opto/parse.hpp +++ b/hotspot/src/share/vm/opto/parse.hpp @@ -581,6 +581,7 @@ class Parse : public GraphKit { void jump_switch_ranges(Node* a, SwitchRange* lo, SwitchRange* hi, int depth = 0); bool create_jump_tables(Node* a, SwitchRange* lo, SwitchRange* hi); + void decrement_age(); // helper functions for methodData style profiling void test_counter_against_threshold(Node* cnt, int limit); void increment_and_test_invocation_counter(int limit); diff --git a/hotspot/src/share/vm/opto/parse1.cpp b/hotspot/src/share/vm/opto/parse1.cpp index d7c7a40bc50..6fea7130786 100644 --- a/hotspot/src/share/vm/opto/parse1.cpp +++ b/hotspot/src/share/vm/opto/parse1.cpp @@ -568,6 +568,9 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses, Pars } else { set_map(entry_map); do_method_entry(); + if (depth() == 1 && C->age_code()) { + decrement_age(); + } } if (depth() == 1) { // Add check to deoptimize the nmethod if RTM state was changed @@ -2048,6 +2051,31 @@ void Parse::rtm_deopt() { #endif } +void Parse::decrement_age() { + MethodCounters* mc = method()->ensure_method_counters(); + if (mc == NULL) { + C->record_failure("Must have MCs"); + return; + } + assert(!is_osr_parse(), "Not doing this for OSRs"); + + // Set starting bci for uncommon trap. + set_parse_bci(0); + + const TypePtr* adr_type = TypeRawPtr::make((address)mc); + Node* mc_adr = makecon(adr_type); + Node* cnt_adr = basic_plus_adr(mc_adr, mc_adr, in_bytes(MethodCounters::nmethod_age_offset())); + Node* cnt = make_load(control(), cnt_adr, TypeInt::INT, T_INT, adr_type, MemNode::unordered); + Node* decr = _gvn.transform(new (C) SubINode(cnt, makecon(TypeInt::ONE))); + store_to_memory(control(), cnt_adr, decr, T_INT, adr_type, MemNode::unordered); + Node *chk = _gvn.transform(new (C) CmpINode(decr, makecon(TypeInt::ZERO))); + Node* tst = _gvn.transform(new (C) BoolNode(chk, BoolTest::gt)); + { BuildCutout unless(this, tst, PROB_ALWAYS); + uncommon_trap(Deoptimization::Reason_tenured, + Deoptimization::Action_make_not_entrant); + } +} + //------------------------------return_current--------------------------------- // Append current _map to _exit_return void Parse::return_current(Node* value) { diff --git a/hotspot/src/share/vm/runtime/deoptimization.cpp b/hotspot/src/share/vm/runtime/deoptimization.cpp index 1ec4e3b12f8..eec441873c3 100644 --- a/hotspot/src/share/vm/runtime/deoptimization.cpp +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp @@ -744,6 +744,8 @@ int Deoptimization::deoptimize_dependents() { return 0; } +Deoptimization::DeoptAction Deoptimization::_unloaded_action + = Deoptimization::Action_reinterpret; #ifdef COMPILER2 bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS) { @@ -1185,6 +1187,23 @@ JRT_LEAF(void, Deoptimization::popframe_preserve_args(JavaThread* thread, int by } JRT_END +MethodData* +Deoptimization::get_method_data(JavaThread* thread, methodHandle m, + bool create_if_missing) { + Thread* THREAD = thread; + MethodData* mdo = m()->method_data(); + if (mdo == NULL && create_if_missing && !HAS_PENDING_EXCEPTION) { + // Build an MDO. Ignore errors like OutOfMemory; + // that simply means we won't have an MDO to update. + Method::build_interpreter_method_data(m, THREAD); + if (HAS_PENDING_EXCEPTION) { + assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here"); + CLEAR_PENDING_EXCEPTION; + } + mdo = m()->method_data(); + } + return mdo; +} #if defined(COMPILER2) || defined(SHARK) void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) { @@ -1285,7 +1304,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra // Ensure that we can record deopt. history: // Need MDO to record RTM code generation state. - bool create_if_missing = ProfileTraps RTM_OPT_ONLY( || UseRTMLocking ); + bool create_if_missing = ProfileTraps || UseCodeAging RTM_OPT_ONLY( || UseRTMLocking ); MethodData* trap_mdo = get_method_data(thread, trap_method, create_if_missing); @@ -1421,7 +1440,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra // // The other actions cause immediate removal of the present code. - bool update_trap_state = true; + bool update_trap_state = (reason != Reason_tenured); bool make_not_entrant = false; bool make_not_compilable = false; bool reprofile = false; @@ -1548,7 +1567,6 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra if (make_not_entrant && maybe_prior_recompile && maybe_prior_trap) { reprofile = true; } - } // Take requested actions on the method: @@ -1577,6 +1595,11 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra trap_mdo->atomic_set_rtm_state(ProfileRTM); } #endif + // For code aging we count traps separately here, using make_not_entrant() + // as a guard against simultaneous deopts in multiple threads. + if (reason == Reason_tenured && trap_mdo != NULL) { + trap_mdo->inc_tenure_traps(); + } } if (inc_recompile_count) { @@ -1609,24 +1632,6 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra } JRT_END -MethodData* -Deoptimization::get_method_data(JavaThread* thread, methodHandle m, - bool create_if_missing) { - Thread* THREAD = thread; - MethodData* mdo = m()->method_data(); - if (mdo == NULL && create_if_missing && !HAS_PENDING_EXCEPTION) { - // Build an MDO. Ignore errors like OutOfMemory; - // that simply means we won't have an MDO to update. - Method::build_interpreter_method_data(m, THREAD); - if (HAS_PENDING_EXCEPTION) { - assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here"); - CLEAR_PENDING_EXCEPTION; - } - mdo = m()->method_data(); - } - return mdo; -} - ProfileData* Deoptimization::query_update_method_data(MethodData* trap_mdo, int trap_bci, @@ -1813,8 +1818,6 @@ const char* Deoptimization::format_trap_state(char* buf, size_t buflen, //--------------------------------statics-------------------------------------- -Deoptimization::DeoptAction Deoptimization::_unloaded_action - = Deoptimization::Action_reinterpret; const char* Deoptimization::_trap_reason_name[Reason_LIMIT] = { // Note: Keep this in sync. with enum DeoptReason. "none", diff --git a/hotspot/src/share/vm/runtime/deoptimization.hpp b/hotspot/src/share/vm/runtime/deoptimization.hpp index eb8e2cbdede..d0af1823248 100644 --- a/hotspot/src/share/vm/runtime/deoptimization.hpp +++ b/hotspot/src/share/vm/runtime/deoptimization.hpp @@ -62,6 +62,7 @@ class Deoptimization : AllStatic { Reason_speculate_class_check, // saw unexpected object class from type speculation Reason_speculate_null_check, // saw unexpected null from type speculation Reason_rtm_state_change, // rtm state change detected + Reason_tenured, // age of the code has reached the limit Reason_LIMIT, // Note: Keep this enum in sync. with _trap_reason_name. Reason_RECORDED_LIMIT = Reason_bimorphic // some are not recorded per bc @@ -357,8 +358,8 @@ class Deoptimization : AllStatic { // returning to a deoptimized caller static void popframe_preserve_args(JavaThread* thread, int bytes_to_save, void* start_address); - private: static MethodData* get_method_data(JavaThread* thread, methodHandle m, bool create_if_missing); + private: // Update the mdo's count and per-BCI reason bits, returning previous state: static ProfileData* query_update_method_data(MethodData* trap_mdo, int trap_bci, diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index df3d941ec0d..aab516a55d9 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -2561,6 +2561,20 @@ class CommandLineFlags { diagnostic(bool, PrintMethodFlushingStatistics, false, \ "print statistics about method flushing") \ \ + diagnostic(intx, HotMethodDetectionLimit, 100000, \ + "Number of compiled code invocations after which " \ + "the method is considered as hot by the flusher") \ + \ + diagnostic(intx, MinPassesBeforeFlush, 10, \ + "Minimum number of sweeper passes before an nmethod " \ + "can be flushed") \ + \ + product(bool, UseCodeAging, true, \ + "Insert counter to detect warm methods") \ + \ + diagnostic(bool, StressCodeAging, false, \ + "Start with counters compiled in") \ + \ develop(bool, UseRelocIndex, false, \ "Use an index to speed random access to relocations") \ \ diff --git a/hotspot/src/share/vm/runtime/sweeper.cpp b/hotspot/src/share/vm/runtime/sweeper.cpp index 4eba81debe6..99047609fdc 100644 --- a/hotspot/src/share/vm/runtime/sweeper.cpp +++ b/hotspot/src/share/vm/runtime/sweeper.cpp @@ -573,37 +573,7 @@ int NMethodSweeper::process_nmethod(nmethod *nm) { SWEEP(nm); } } else { - if (UseCodeCacheFlushing) { - if (!nm->is_locked_by_vm() && !nm->is_osr_method() && !nm->is_native_method()) { - // Do not make native methods and OSR-methods not-entrant - nm->dec_hotness_counter(); - // Get the initial value of the hotness counter. This value depends on the - // ReservedCodeCacheSize - int reset_val = hotness_counter_reset_val(); - int time_since_reset = reset_val - nm->hotness_counter(); - double threshold = -reset_val + (CodeCache::reverse_free_ratio() * NmethodSweepActivity); - // The less free space in the code cache we have - the bigger reverse_free_ratio() is. - // I.e., 'threshold' increases with lower available space in the code cache and a higher - // NmethodSweepActivity. If the current hotness counter - which decreases from its initial - // value until it is reset by stack walking - is smaller than the computed threshold, the - // corresponding nmethod is considered for removal. - if ((NmethodSweepActivity > 0) && (nm->hotness_counter() < threshold) && (time_since_reset > 10)) { - // A method is marked as not-entrant if the method is - // 1) 'old enough': nm->hotness_counter() < threshold - // 2) The method was in_use for a minimum amount of time: (time_since_reset > 10) - // The second condition is necessary if we are dealing with very small code cache - // sizes (e.g., <10m) and the code cache size is too small to hold all hot methods. - // The second condition ensures that methods are not immediately made not-entrant - // after compilation. - nm->make_not_entrant(); - // Code cache state change is tracked in make_not_entrant() - if (PrintMethodFlushing && Verbose) { - tty->print_cr("### Nmethod %d/" PTR_FORMAT "made not-entrant: hotness counter %d/%d threshold %f", - nm->compile_id(), nm, nm->hotness_counter(), reset_val, threshold); - } - } - } - } + possibly_flush(nm); // Clean-up all inline caches that point to zombie/non-reentrant methods MutexLocker cl(CompiledIC_lock); nm->cleanup_inline_caches(); @@ -612,6 +582,88 @@ int NMethodSweeper::process_nmethod(nmethod *nm) { return freed_memory; } + +void NMethodSweeper::possibly_flush(nmethod* nm) { + if (UseCodeCacheFlushing) { + if (!nm->is_locked_by_vm() && !nm->is_osr_method() && !nm->is_native_method()) { + bool make_not_entrant = false; + + // Do not make native methods and OSR-methods not-entrant + nm->dec_hotness_counter(); + // Get the initial value of the hotness counter. This value depends on the + // ReservedCodeCacheSize + int reset_val = hotness_counter_reset_val(); + int time_since_reset = reset_val - nm->hotness_counter(); + double threshold = -reset_val + (CodeCache::reverse_free_ratio() * NmethodSweepActivity); + // The less free space in the code cache we have - the bigger reverse_free_ratio() is. + // I.e., 'threshold' increases with lower available space in the code cache and a higher + // NmethodSweepActivity. If the current hotness counter - which decreases from its initial + // value until it is reset by stack walking - is smaller than the computed threshold, the + // corresponding nmethod is considered for removal. + if ((NmethodSweepActivity > 0) && (nm->hotness_counter() < threshold) && (time_since_reset > MinPassesBeforeFlush)) { + // A method is marked as not-entrant if the method is + // 1) 'old enough': nm->hotness_counter() < threshold + // 2) The method was in_use for a minimum amount of time: (time_since_reset > MinPassesBeforeFlush) + // The second condition is necessary if we are dealing with very small code cache + // sizes (e.g., <10m) and the code cache size is too small to hold all hot methods. + // The second condition ensures that methods are not immediately made not-entrant + // after compilation. + make_not_entrant = true; + } + + // The stack-scanning low-cost detection may not see the method was used (which can happen for + // flat profiles). Check the age counter for possible data. + if (UseCodeAging && make_not_entrant && (nm->is_compiled_by_c2() || nm->is_compiled_by_c1())) { + MethodCounters* mc = nm->method()->method_counters(); + if (mc != NULL) { + // Snapshot the value as it's changed concurrently + int age = mc->nmethod_age(); + if (MethodCounters::is_nmethod_hot(age)) { + // The method has gone through flushing, and it became relatively hot that it deopted + // before we could take a look at it. Give it more time to appear in the stack traces, + // proportional to the number of deopts. + MethodData* md = nm->method()->method_data(); + if (md != NULL && time_since_reset > (int)(MinPassesBeforeFlush * (md->tenure_traps() + 1))) { + // It's been long enough, we still haven't seen it on stack. + // Try to flush it, but enable counters the next time. + mc->reset_nmethod_age(); + } else { + make_not_entrant = false; + } + } else if (MethodCounters::is_nmethod_warm(age)) { + // Method has counters enabled, and the method was used within + // previous MinPassesBeforeFlush sweeps. Reset the counter. Stay in the existing + // compiled state. + mc->reset_nmethod_age(); + // delay the next check + nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val()); + make_not_entrant = false; + } else if (MethodCounters::is_nmethod_age_unset(age)) { + // No counters were used before. Set the counters to the detection + // limit value. If the method is going to be used again it will be compiled + // with counters that we're going to use for analysis the the next time. + mc->reset_nmethod_age(); + } else { + // Method was totally idle for 10 sweeps + // The counter already has the initial value, flush it and may be recompile + // later with counters + } + } + } + + if (make_not_entrant) { + nm->make_not_entrant(); + + // Code cache state change is tracked in make_not_entrant() + if (PrintMethodFlushing && Verbose) { + tty->print_cr("### Nmethod %d/" PTR_FORMAT "made not-entrant: hotness counter %d/%d threshold %f", + nm->compile_id(), nm, nm->hotness_counter(), reset_val, threshold); + } + } + } + } +} + // Print out some state information about the current sweep and the // state of the code cache if it's requested. void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { diff --git a/hotspot/src/share/vm/runtime/sweeper.hpp b/hotspot/src/share/vm/runtime/sweeper.hpp index f7482d8194d..d9630b2e5c4 100644 --- a/hotspot/src/share/vm/runtime/sweeper.hpp +++ b/hotspot/src/share/vm/runtime/sweeper.hpp @@ -111,6 +111,7 @@ class NMethodSweeper : public AllStatic { static int hotness_counter_reset_val(); static void report_state_change(nmethod* nm); static void possibly_enable_sweeper(); + static void possibly_flush(nmethod* nm); static void print(); // Printing/debugging }; diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 67bf7b1033d..f169c3b2ef0 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -361,10 +361,12 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable; nonstatic_field(MethodData, _arg_local, intx) \ nonstatic_field(MethodData, _arg_stack, intx) \ nonstatic_field(MethodData, _arg_returned, intx) \ + nonstatic_field(MethodData, _tenure_traps, uint) \ nonstatic_field(DataLayout, _header._struct._tag, u1) \ nonstatic_field(DataLayout, _header._struct._flags, u1) \ nonstatic_field(DataLayout, _header._struct._bci, u2) \ nonstatic_field(DataLayout, _cells[0], intptr_t) \ + nonstatic_field(MethodCounters, _nmethod_age, int) \ nonstatic_field(MethodCounters, _interpreter_invocation_count, int) \ nonstatic_field(MethodCounters, _interpreter_throwout_count, u2) \ nonstatic_field(MethodCounters, _number_of_breakpoints, u2) \ From 38d80b03c4c0b7b7cadf05059b16e109421d0670 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov <vlivanov@openjdk.org> Date: Tue, 11 Mar 2014 15:06:34 +0400 Subject: [PATCH 010/157] 8023461: Thread holding lock at safepoint that vm can block on: MethodCompileQueue_lock Reviewed-by: kvn, iveresov --- .../src/share/vm/compiler/compileBroker.cpp | 44 +++++++++++++++++-- .../src/share/vm/compiler/compileBroker.hpp | 7 +++ hotspot/src/share/vm/oops/method.hpp | 42 +++++++++++------- hotspot/src/share/vm/prims/whitebox.cpp | 4 +- .../vm/runtime/advancedThresholdPolicy.cpp | 22 +++++----- 5 files changed, 86 insertions(+), 33 deletions(-) diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp index b2320eac8bd..ff292fbd747 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.cpp +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp @@ -704,13 +704,39 @@ CompileTask* CompileQueue::get() { return NULL; } - CompileTask* task = CompilationPolicy::policy()->select_task(this); + CompileTask* task; + { + No_Safepoint_Verifier nsv; + task = CompilationPolicy::policy()->select_task(this); + } remove(task); + purge_stale_tasks(); // may temporarily release MCQ lock return task; } -void CompileQueue::remove(CompileTask* task) -{ +// Clean & deallocate stale compile tasks. +// Temporarily releases MethodCompileQueue lock. +void CompileQueue::purge_stale_tasks() { + assert(lock()->owned_by_self(), "must own lock"); + if (_first_stale != NULL) { + // Stale tasks are purged when MCQ lock is released, + // but _first_stale updates are protected by MCQ lock. + // Once task processing starts and MCQ lock is released, + // other compiler threads can reuse _first_stale. + CompileTask* head = _first_stale; + _first_stale = NULL; + { + MutexUnlocker ul(lock()); + for (CompileTask* task = head; task != NULL; ) { + CompileTask* next_task = task->next(); + CompileTaskWrapper ctw(task); // Frees the task + task = next_task; + } + } + } +} + +void CompileQueue::remove(CompileTask* task) { assert(lock()->owned_by_self(), "must own lock"); if (task->prev() != NULL) { task->prev()->set_next(task->next()); @@ -730,6 +756,16 @@ void CompileQueue::remove(CompileTask* task) --_size; } +void CompileQueue::remove_and_mark_stale(CompileTask* task) { + assert(lock()->owned_by_self(), "must own lock"); + remove(task); + + // Enqueue the task for reclamation (should be done outside MCQ lock) + task->set_next(_first_stale); + task->set_prev(NULL); + _first_stale = task; +} + // methods in the compile queue need to be marked as used on the stack // so that they don't get reclaimed by Redefine Classes void CompileQueue::mark_on_stack() { @@ -2006,7 +2042,7 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) { // Note that the queued_for_compilation bits are cleared without // protection of a mutex. [They were set by the requester thread, - // when adding the task to the complie queue -- at which time the + // when adding the task to the compile queue -- at which time the // compile queue lock was held. Subsequently, we acquired the compile // queue lock to get this task off the compile queue; thus (to belabour // the point somewhat) our clearing of the bits must be occurring diff --git a/hotspot/src/share/vm/compiler/compileBroker.hpp b/hotspot/src/share/vm/compiler/compileBroker.hpp index dc0b0ba854f..d3a25dddcc4 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.hpp +++ b/hotspot/src/share/vm/compiler/compileBroker.hpp @@ -196,7 +196,11 @@ class CompileQueue : public CHeapObj<mtCompiler> { CompileTask* _first; CompileTask* _last; + CompileTask* _first_stale; + int _size; + + void purge_stale_tasks(); public: CompileQueue(const char* name, Monitor* lock) { _name = name; @@ -204,6 +208,7 @@ class CompileQueue : public CHeapObj<mtCompiler> { _first = NULL; _last = NULL; _size = 0; + _first_stale = NULL; } const char* name() const { return _name; } @@ -211,6 +216,7 @@ class CompileQueue : public CHeapObj<mtCompiler> { void add(CompileTask* task); void remove(CompileTask* task); + void remove_and_mark_stale(CompileTask* task); CompileTask* first() { return _first; } CompileTask* last() { return _last; } @@ -219,6 +225,7 @@ class CompileQueue : public CHeapObj<mtCompiler> { bool is_empty() const { return _first == NULL; } int size() const { return _size; } + // Redefine Classes support void mark_on_stack(); void free_all(); diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp index 3bae50ce712..315746c501f 100644 --- a/hotspot/src/share/vm/oops/method.hpp +++ b/hotspot/src/share/vm/oops/method.hpp @@ -200,10 +200,11 @@ class Method : public Metadata { // Tracking number of breakpoints, for fullspeed debugging. // Only mutated by VM thread. u2 number_of_breakpoints() const { - if (method_counters() == NULL) { + MethodCounters* mcs = method_counters(); + if (mcs == NULL) { return 0; } else { - return method_counters()->number_of_breakpoints(); + return mcs->number_of_breakpoints(); } } void incr_number_of_breakpoints(TRAPS) { @@ -220,8 +221,9 @@ class Method : public Metadata { } // Initialization only void clear_number_of_breakpoints() { - if (method_counters() != NULL) { - method_counters()->clear_number_of_breakpoints(); + MethodCounters* mcs = method_counters(); + if (mcs != NULL) { + mcs->clear_number_of_breakpoints(); } } @@ -268,10 +270,11 @@ class Method : public Metadata { } int interpreter_throwout_count() const { - if (method_counters() == NULL) { + MethodCounters* mcs = method_counters(); + if (mcs == NULL) { return 0; } else { - return method_counters()->interpreter_throwout_count(); + return mcs->interpreter_throwout_count(); } } @@ -346,26 +349,28 @@ class Method : public Metadata { return method_counters()->interpreter_invocation_count(); } } - void set_prev_event_count(int count, TRAPS) { - MethodCounters* mcs = get_method_counters(CHECK); + void set_prev_event_count(int count) { + MethodCounters* mcs = method_counters(); if (mcs != NULL) { mcs->set_interpreter_invocation_count(count); } } jlong prev_time() const { - return method_counters() == NULL ? 0 : method_counters()->prev_time(); + MethodCounters* mcs = method_counters(); + return mcs == NULL ? 0 : mcs->prev_time(); } - void set_prev_time(jlong time, TRAPS) { - MethodCounters* mcs = get_method_counters(CHECK); + void set_prev_time(jlong time) { + MethodCounters* mcs = method_counters(); if (mcs != NULL) { mcs->set_prev_time(time); } } float rate() const { - return method_counters() == NULL ? 0 : method_counters()->rate(); + MethodCounters* mcs = method_counters(); + return mcs == NULL ? 0 : mcs->rate(); } - void set_rate(float rate, TRAPS) { - MethodCounters* mcs = get_method_counters(CHECK); + void set_rate(float rate) { + MethodCounters* mcs = method_counters(); if (mcs != NULL) { mcs->set_rate(rate); } @@ -390,9 +395,12 @@ class Method : public Metadata { static MethodCounters* build_method_counters(Method* m, TRAPS); int interpreter_invocation_count() { - if (TieredCompilation) return invocation_count(); - else return (method_counters() == NULL) ? 0 : - method_counters()->interpreter_invocation_count(); + if (TieredCompilation) { + return invocation_count(); + } else { + MethodCounters* mcs = method_counters(); + return (mcs == NULL) ? 0 : mcs->interpreter_invocation_count(); + } } int increment_interpreter_invocation_count(TRAPS) { if (TieredCompilation) ShouldNotReachHere(); diff --git a/hotspot/src/share/vm/prims/whitebox.cpp b/hotspot/src/share/vm/prims/whitebox.cpp index 2e6b9952b8b..5e2fbed5ced 100644 --- a/hotspot/src/share/vm/prims/whitebox.cpp +++ b/hotspot/src/share/vm/prims/whitebox.cpp @@ -495,8 +495,8 @@ WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method)) #ifdef TIERED mcs->set_rate(0.0F); - mh->set_prev_event_count(0, THREAD); - mh->set_prev_time(0, THREAD); + mh->set_prev_event_count(0); + mh->set_prev_time(0); #endif } WB_END diff --git a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp index a92c36c3e62..1b97c18b7f7 100644 --- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp +++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp @@ -75,11 +75,14 @@ void AdvancedThresholdPolicy::initialize() { // update_rate() is called from select_task() while holding a compile queue lock. void AdvancedThresholdPolicy::update_rate(jlong t, Method* m) { - JavaThread* THREAD = JavaThread::current(); + // Skip update if counters are absent. + // Can't allocate them since we are holding compile queue lock. + if (m->method_counters() == NULL) return; + if (is_old(m)) { // We don't remove old methods from the queue, // so we can just zero the rate. - m->set_rate(0, THREAD); + m->set_rate(0); return; } @@ -95,14 +98,15 @@ void AdvancedThresholdPolicy::update_rate(jlong t, Method* m) { if (delta_s >= TieredRateUpdateMinTime) { // And we must've taken the previous point at least 1ms before. if (delta_t >= TieredRateUpdateMinTime && delta_e > 0) { - m->set_prev_time(t, THREAD); - m->set_prev_event_count(event_count, THREAD); - m->set_rate((float)delta_e / (float)delta_t, THREAD); // Rate is events per millisecond - } else + m->set_prev_time(t); + m->set_prev_event_count(event_count); + m->set_rate((float)delta_e / (float)delta_t); // Rate is events per millisecond + } else { if (delta_t > TieredRateUpdateMaxTime && delta_e == 0) { // If nothing happened for 25ms, zero the rate. Don't modify prev values. - m->set_rate(0, THREAD); + m->set_rate(0); } + } } } @@ -164,7 +168,6 @@ CompileTask* AdvancedThresholdPolicy::select_task(CompileQueue* compile_queue) { for (CompileTask* task = compile_queue->first(); task != NULL;) { CompileTask* next_task = task->next(); Method* method = task->method(); - MethodData* mdo = method->method_data(); update_rate(t, method); if (max_task == NULL) { max_task = task; @@ -175,8 +178,7 @@ CompileTask* AdvancedThresholdPolicy::select_task(CompileQueue* compile_queue) { if (PrintTieredEvents) { print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level()); } - CompileTaskWrapper ctw(task); // Frees the task - compile_queue->remove(task); + compile_queue->remove_and_mark_stale(task); method->clear_queued_for_compilation(); task = next_task; continue; From d9bd02ffc269240b77c01153f6f48c643e1991ce Mon Sep 17 00:00:00 2001 From: Petr Pchelko <pchelko@openjdk.org> Date: Fri, 18 Apr 2014 10:47:23 +0400 Subject: [PATCH 011/157] 8035169: Move ThreadGroupUtils from the sun.misc package Reviewed-by: anthony, serb, azvegint --- jdk/src/macosx/classes/sun/font/CFontManager.java | 2 +- jdk/src/macosx/classes/sun/lwawt/LWToolkit.java | 2 +- jdk/src/macosx/native/sun/awt/awt.m | 2 +- jdk/src/share/classes/sun/awt/AWTAutoShutdown.java | 2 +- .../classes/sun/{misc => awt/util}/ThreadGroupUtils.java | 4 ++-- jdk/src/share/classes/sun/font/CreatedFontTracker.java | 2 +- jdk/src/share/classes/sun/font/SunFontManager.java | 2 +- jdk/src/share/classes/sun/java2d/Disposer.java | 2 +- jdk/src/share/classes/sun/java2d/opengl/OGLRenderQueue.java | 2 +- jdk/src/solaris/classes/sun/awt/X11/XToolkit.java | 2 +- jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java | 2 +- .../classes/sun/awt/shell/Win32ShellFolderManager2.java | 2 +- jdk/src/windows/classes/sun/awt/windows/WToolkit.java | 2 +- .../classes/sun/java2d/d3d/D3DScreenUpdateManager.java | 2 +- 14 files changed, 15 insertions(+), 15 deletions(-) rename jdk/src/share/classes/sun/{misc => awt/util}/ThreadGroupUtils.java (95%) diff --git a/jdk/src/macosx/classes/sun/font/CFontManager.java b/jdk/src/macosx/classes/sun/font/CFontManager.java index ad2bfab62ba..8e1cead53c2 100644 --- a/jdk/src/macosx/classes/sun/font/CFontManager.java +++ b/jdk/src/macosx/classes/sun/font/CFontManager.java @@ -40,7 +40,7 @@ import javax.swing.plaf.FontUIResource; import sun.awt.FontConfiguration; import sun.awt.HeadlessToolkit; -import sun.misc.ThreadGroupUtils; +import sun.awt.util.ThreadGroupUtils; import sun.lwawt.macosx.*; public class CFontManager extends SunFontManager { diff --git a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java index 8dd9467eed6..b18fdb004f1 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java @@ -35,7 +35,7 @@ import java.util.*; import sun.awt.*; import sun.print.*; -import sun.misc.ThreadGroupUtils; +import sun.awt.util.ThreadGroupUtils; import static sun.lwawt.LWWindowPeer.PeerType; diff --git a/jdk/src/macosx/native/sun/awt/awt.m b/jdk/src/macosx/native/sun/awt/awt.m index 0f553d0e69f..f5fe3ea9eba 100644 --- a/jdk/src/macosx/native/sun/awt/awt.m +++ b/jdk/src/macosx/native/sun/awt/awt.m @@ -435,7 +435,7 @@ JNF_COCOA_ENTER(env); forceEmbeddedMode = YES; } JNIEnv* env = [ThreadUtilities getJNIEnvUncached]; - jclass jc_ThreadGroupUtils = (*env)->FindClass(env, "sun/misc/ThreadGroupUtils"); + jclass jc_ThreadGroupUtils = (*env)->FindClass(env, "sun/awt/util/ThreadGroupUtils"); jmethodID sjm_getRootThreadGroup = (*env)->GetStaticMethodID(env, jc_ThreadGroupUtils, "getRootThreadGroup", "()Ljava/lang/ThreadGroup;"); jobject rootThreadGroup = (*env)->CallStaticObjectMethod(env, jc_ThreadGroupUtils, sjm_getRootThreadGroup); [ThreadUtilities setAppkitThreadGroup:(*env)->NewGlobalRef(env, rootThreadGroup)]; diff --git a/jdk/src/share/classes/sun/awt/AWTAutoShutdown.java b/jdk/src/share/classes/sun/awt/AWTAutoShutdown.java index f03cd50988d..d5b7633f224 100644 --- a/jdk/src/share/classes/sun/awt/AWTAutoShutdown.java +++ b/jdk/src/share/classes/sun/awt/AWTAutoShutdown.java @@ -35,7 +35,7 @@ import java.util.Map; import java.util.Set; import sun.util.logging.PlatformLogger; -import sun.misc.ThreadGroupUtils; +import sun.awt.util.ThreadGroupUtils; /** * This class is to let AWT shutdown automatically when a user is done diff --git a/jdk/src/share/classes/sun/misc/ThreadGroupUtils.java b/jdk/src/share/classes/sun/awt/util/ThreadGroupUtils.java similarity index 95% rename from jdk/src/share/classes/sun/misc/ThreadGroupUtils.java rename to jdk/src/share/classes/sun/awt/util/ThreadGroupUtils.java index 066a8002f72..5d58a1c29d4 100644 --- a/jdk/src/share/classes/sun/misc/ThreadGroupUtils.java +++ b/jdk/src/share/classes/sun/awt/util/ThreadGroupUtils.java @@ -23,13 +23,13 @@ * questions. */ -package sun.misc; +package sun.awt.util; /** * A utility class needed to access the root {@code ThreadGroup} * * The class should not depend on any others, because it' called from JNI_OnLoad of the AWT - * native library. Triggering class loading could could lead to a deadlock. + * native library. Triggering class loading could lead to a deadlock. */ public final class ThreadGroupUtils { diff --git a/jdk/src/share/classes/sun/font/CreatedFontTracker.java b/jdk/src/share/classes/sun/font/CreatedFontTracker.java index 02b264db785..43f8b098658 100644 --- a/jdk/src/share/classes/sun/font/CreatedFontTracker.java +++ b/jdk/src/share/classes/sun/font/CreatedFontTracker.java @@ -35,7 +35,7 @@ import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import sun.awt.AppContext; -import sun.misc.ThreadGroupUtils; +import sun.awt.util.ThreadGroupUtils; public class CreatedFontTracker { diff --git a/jdk/src/share/classes/sun/font/SunFontManager.java b/jdk/src/share/classes/sun/font/SunFontManager.java index 8487b9632a1..04df414365c 100644 --- a/jdk/src/share/classes/sun/font/SunFontManager.java +++ b/jdk/src/share/classes/sun/font/SunFontManager.java @@ -52,7 +52,7 @@ import javax.swing.plaf.FontUIResource; import sun.awt.AppContext; import sun.awt.FontConfiguration; import sun.awt.SunToolkit; -import sun.misc.ThreadGroupUtils; +import sun.awt.util.ThreadGroupUtils; import sun.java2d.FontSupport; import sun.util.logging.PlatformLogger; diff --git a/jdk/src/share/classes/sun/java2d/Disposer.java b/jdk/src/share/classes/sun/java2d/Disposer.java index 1acf1447cdc..ba69ce763dd 100644 --- a/jdk/src/share/classes/sun/java2d/Disposer.java +++ b/jdk/src/share/classes/sun/java2d/Disposer.java @@ -25,7 +25,7 @@ package sun.java2d; -import sun.misc.ThreadGroupUtils; +import sun.awt.util.ThreadGroupUtils; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; diff --git a/jdk/src/share/classes/sun/java2d/opengl/OGLRenderQueue.java b/jdk/src/share/classes/sun/java2d/opengl/OGLRenderQueue.java index a73a883d16f..ecf1ed3467b 100644 --- a/jdk/src/share/classes/sun/java2d/opengl/OGLRenderQueue.java +++ b/jdk/src/share/classes/sun/java2d/opengl/OGLRenderQueue.java @@ -25,7 +25,7 @@ package sun.java2d.opengl; -import sun.misc.ThreadGroupUtils; +import sun.awt.util.ThreadGroupUtils; import sun.java2d.pipe.RenderBuffer; import sun.java2d.pipe.RenderQueue; import static sun.java2d.pipe.BufferedOpCodes.*; diff --git a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java index c10a1d9522c..3648e874b6a 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java @@ -51,7 +51,7 @@ import sun.awt.datatransfer.DataTransferer; import sun.font.FontConfigManager; import sun.java2d.SunGraphicsEnvironment; import sun.misc.*; -import sun.misc.ThreadGroupUtils; +import sun.awt.util.ThreadGroupUtils; import sun.print.PrintJob2D; import sun.security.action.GetPropertyAction; import sun.security.action.GetBooleanAction; diff --git a/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java b/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java index d69a4a0bce0..10365f9a647 100644 --- a/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java +++ b/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java @@ -42,7 +42,7 @@ import sun.java2d.opengl.GLXGraphicsConfig; import sun.java2d.xr.XRGraphicsConfig; import sun.java2d.loops.SurfaceType; -import sun.misc.ThreadGroupUtils; +import sun.awt.util.ThreadGroupUtils; /** * This is an implementation of a GraphicsDevice object for a single diff --git a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java index c6b7351699e..269eff2e421 100644 --- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java +++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java @@ -39,7 +39,7 @@ import java.util.concurrent.*; import static sun.awt.shell.Win32ShellFolder2.*; import sun.awt.OSInfo; -import sun.misc.ThreadGroupUtils; +import sun.awt.util.ThreadGroupUtils; // NOTE: This class supersedes Win32ShellFolderManager, which was removed // from distribution after version 1.4.2. diff --git a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java index 71af30e5190..2a27c2df9cc 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java +++ b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java @@ -40,7 +40,7 @@ import sun.awt.AWTAutoShutdown; import sun.awt.AWTPermissions; import sun.awt.LightweightFrame; import sun.awt.SunToolkit; -import sun.misc.ThreadGroupUtils; +import sun.awt.util.ThreadGroupUtils; import sun.awt.Win32GraphicsDevice; import sun.awt.Win32GraphicsEnvironment; import sun.awt.datatransfer.DataTransferer; diff --git a/jdk/src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java b/jdk/src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java index bc9e98eb85c..bd210e92765 100644 --- a/jdk/src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java +++ b/jdk/src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java @@ -38,7 +38,7 @@ import java.util.ArrayList; import java.util.HashMap; import sun.awt.AWTAccessor; -import sun.misc.ThreadGroupUtils; +import sun.awt.util.ThreadGroupUtils; import sun.awt.Win32GraphicsConfig; import sun.awt.windows.WComponentPeer; import sun.java2d.InvalidPipeException; From 0a31e5f2467b81735348e7b555ee106d11330f37 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov <serb@openjdk.org> Date: Fri, 18 Apr 2014 20:10:39 +0400 Subject: [PATCH 012/157] 8026252: [macosx] Change AWT_DEBUG_BUG_REPORT_MESSAGE for macosx platform Reviewed-by: azvegint, pchelko --- jdk/src/macosx/native/sun/osxapp/AWT_debug.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jdk/src/macosx/native/sun/osxapp/AWT_debug.h b/jdk/src/macosx/native/sun/osxapp/AWT_debug.h index 1d02a824f3a..46f57cc6d73 100644 --- a/jdk/src/macosx/native/sun/osxapp/AWT_debug.h +++ b/jdk/src/macosx/native/sun/osxapp/AWT_debug.h @@ -32,9 +32,10 @@ #define kInternalError "java/lang/InternalError" #define AWT_DEBUG_LOG(str) \ - NSLog(@"Cocoa AWT: %@ %@", str, [NSThread callStackSymbols]) + NSLog(@"\tCocoa AWT: %@ %@", str, [NSThread callStackSymbols]) #define AWT_DEBUG_BUG_REPORT_MESSAGE \ - NSLog(@"\tPlease file a bug report at http://java.net/jira/browse/MACOSX_PORT with this message and a reproducible test case.") + NSLog(@"\tPlease file a bug report at http://bugreport.java.com/bugreport \ +with this message and a reproducible test case.") #endif From 81ae76b8dd94c3d1cdbcdcd3cc8c6ad568646ab6 Mon Sep 17 00:00:00 2001 From: Henry Jen <henryjen@openjdk.org> Date: Fri, 18 Apr 2014 09:56:34 -0700 Subject: [PATCH 013/157] 8038644: Fix raw and unchecked warnings in sun.java2d.* Reviewed-by: darcy, prr --- jdk/src/share/classes/sun/java2d/Spans.java | 23 ++++++++----------- .../classes/sun/java2d/SunGraphics2D.java | 7 ++++-- .../sun/java2d/SunGraphicsEnvironment.java | 2 +- .../classes/sun/java2d/cmm/lcms/LCMS.java | 4 ++-- .../share/classes/sun/java2d/loops/Blit.java | 12 +++++----- .../sun/java2d/loops/CustomComponent.java | 2 +- .../sun/java2d/loops/GeneralRenderer.java | 2 +- .../sun/java2d/loops/GraphicsPrimitive.java | 15 ++++++------ .../java2d/loops/GraphicsPrimitiveMgr.java | 21 +++++++++-------- .../java2d/loops/GraphicsPrimitiveProxy.java | 6 ++--- .../classes/sun/java2d/loops/MaskBlit.java | 12 +++++----- .../sun/java2d/opengl/OGLBlitLoops.java | 8 +++---- .../sun/java2d/pipe/AlphaPaintPipe.java | 20 ++++++++-------- .../classes/sun/java2d/pipe/RenderQueue.java | 4 ++-- .../sun/java2d/pipe/SpanClipRenderer.java | 6 ++--- .../sun/java2d/x11/X11SurfaceData.java | 2 +- 16 files changed, 74 insertions(+), 72 deletions(-) diff --git a/jdk/src/share/classes/sun/java2d/Spans.java b/jdk/src/share/classes/sun/java2d/Spans.java index ae708f1f161..abd1eda118f 100644 --- a/jdk/src/share/classes/sun/java2d/Spans.java +++ b/jdk/src/share/classes/sun/java2d/Spans.java @@ -49,7 +49,7 @@ public class Spans { * Holds a list of individual * Span instances. */ - private List mSpans = new Vector(kMaxAddsSinceSort); + private List<Span> mSpans = new Vector<>(kMaxAddsSinceSort); /** * The number of <code>Span</code> @@ -144,7 +144,7 @@ public class Spans { Collections.sort(mSpans); mAddsSinceSort = 0; - Iterator iter = mSpans.iterator(); + Iterator<Span> iter = mSpans.iterator(); /* Have 'span' start at the first span in * the collection. The collection may be empty @@ -152,7 +152,7 @@ public class Spans { */ Span span = null; if (iter.hasNext()) { - span = (Span) iter.next(); + span = iter.next(); } /* Loop over the spans collapsing those that intersect @@ -160,7 +160,7 @@ public class Spans { */ while (iter.hasNext()) { - Span nextSpan = (Span) iter.next(); + Span nextSpan = iter.next(); /* The spans are in ascending start position * order and so the next span's starting point @@ -202,9 +202,9 @@ public class Spans { private void printSpans() { System.out.println("----------"); if (mSpans != null) { - Iterator iter = mSpans.iterator(); + Iterator<Span> iter = mSpans.iterator(); while (iter.hasNext()) { - Span span = (Span) iter.next(); + Span span = iter.next(); System.out.println(span); } } @@ -216,7 +216,7 @@ public class Spans { /** * Holds a single half-open interval. */ - static class Span implements Comparable { + static class Span implements Comparable<Span> { /** * The span includes the starting point. @@ -315,8 +315,7 @@ public class Spans { * position. The end position is ignored * in this ranking. */ - public int compareTo(Object o) { - Span otherSpan = (Span) o; + public int compareTo(Span otherSpan) { float otherStart = otherSpan.getStart(); int result; @@ -345,7 +344,7 @@ public class Spans { * <code>SpanIntersection.instance</code> to * get the single instance of this class. */ - static class SpanIntersection implements Comparator { + static class SpanIntersection implements Comparator<Span> { /** * This class is a Singleton and the following @@ -361,10 +360,8 @@ public class Spans { } - public int compare(Object o1, Object o2) { + public int compare(Span span1, Span span2) { int result; - Span span1 = (Span) o1; - Span span2 = (Span) o2; /* Span 1 is entirely to the left of span2. * span1: <-----< diff --git a/jdk/src/share/classes/sun/java2d/SunGraphics2D.java b/jdk/src/share/classes/sun/java2d/SunGraphics2D.java index 287549c2062..58f90c36b11 100644 --- a/jdk/src/share/classes/sun/java2d/SunGraphics2D.java +++ b/jdk/src/share/classes/sun/java2d/SunGraphics2D.java @@ -1430,8 +1430,11 @@ public final class SunGraphics2D } } - RenderingHints makeHints(Map hints) { - RenderingHints model = new RenderingHints(hints); + RenderingHints makeHints(Map<?,?> hints) { + RenderingHints model = new RenderingHints(null); + if (hints != null) { + model.putAll(hints); + } model.put(SunHints.KEY_RENDERING, SunHints.Value.get(SunHints.INTKEY_RENDERING, renderHint)); diff --git a/jdk/src/share/classes/sun/java2d/SunGraphicsEnvironment.java b/jdk/src/share/classes/sun/java2d/SunGraphicsEnvironment.java index c4e0be79f1c..cc2d113e064 100644 --- a/jdk/src/share/classes/sun/java2d/SunGraphicsEnvironment.java +++ b/jdk/src/share/classes/sun/java2d/SunGraphicsEnvironment.java @@ -82,7 +82,7 @@ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment public SunGraphicsEnvironment() { java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction<Object>() { public Object run() { String version = System.getProperty("os.version", "0.0"); try { diff --git a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java index d01dff66c45..c9333616065 100644 --- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java +++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java @@ -189,7 +189,7 @@ public class LCMS implements PCMM { LCMSImageLayout dest); public static native void freeTransform(long ID); - public static native void initLCMS(Class Trans, Class IL, Class Pf); + public static native void initLCMS(Class<?> Trans, Class<?> IL, Class<?> Pf); private LCMS() {}; @@ -201,7 +201,7 @@ public class LCMS implements PCMM { } java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction<Object>() { public Object run() { /* We need to load awt here because of usage trace and * disposer frameworks diff --git a/jdk/src/share/classes/sun/java2d/loops/Blit.java b/jdk/src/share/classes/sun/java2d/loops/Blit.java index 7a337e15214..802385279a2 100644 --- a/jdk/src/share/classes/sun/java2d/loops/Blit.java +++ b/jdk/src/share/classes/sun/java2d/loops/Blit.java @@ -217,8 +217,8 @@ public class Blit extends GraphicsPrimitive Blit performop; Blit convertresult; - WeakReference srcTmp; - WeakReference dstTmp; + WeakReference<SurfaceData> srcTmp; + WeakReference<SurfaceData> dstTmp; public GeneralXorBlit(SurfaceType srctype, CompositeType comptype, @@ -257,14 +257,14 @@ public class Blit extends GraphicsPrimitive } else { SurfaceData cachedSrc = null; if (srcTmp != null) { - cachedSrc = (SurfaceData) srcTmp.get(); + cachedSrc = srcTmp.get(); } src = convertFrom(convertsrc, srcData, srcx, srcy, width, height, cachedSrc); sx = 0; sy = 0; if (src != cachedSrc) { - srcTmp = new WeakReference(src); + srcTmp = new WeakReference<>(src); } } @@ -277,7 +277,7 @@ public class Blit extends GraphicsPrimitive // assert: convertresult != null SurfaceData cachedDst = null; if (dstTmp != null) { - cachedDst = (SurfaceData) dstTmp.get(); + cachedDst = dstTmp.get(); } dst = convertFrom(convertdst, dstData, dstx, dsty, width, height, cachedDst); @@ -285,7 +285,7 @@ public class Blit extends GraphicsPrimitive dy = 0; opclip = null; if (dst != cachedDst) { - dstTmp = new WeakReference(dst); + dstTmp = new WeakReference<>(dst); } } diff --git a/jdk/src/share/classes/sun/java2d/loops/CustomComponent.java b/jdk/src/share/classes/sun/java2d/loops/CustomComponent.java index 55a921aeb1d..ff346172387 100644 --- a/jdk/src/share/classes/sun/java2d/loops/CustomComponent.java +++ b/jdk/src/share/classes/sun/java2d/loops/CustomComponent.java @@ -50,7 +50,7 @@ public final class CustomComponent { public static void register() { // REMIND: This does not work for all destinations yet since // the screen SurfaceData objects do not implement getRaster - Class owner = CustomComponent.class; + Class<?> owner = CustomComponent.class; GraphicsPrimitive[] primitives = { new GraphicsPrimitiveProxy(owner, "OpaqueCopyAnyToArgb", Blit.methodSignature, diff --git a/jdk/src/share/classes/sun/java2d/loops/GeneralRenderer.java b/jdk/src/share/classes/sun/java2d/loops/GeneralRenderer.java index ac01d5324c3..af0fa2ece8b 100644 --- a/jdk/src/share/classes/sun/java2d/loops/GeneralRenderer.java +++ b/jdk/src/share/classes/sun/java2d/loops/GeneralRenderer.java @@ -50,7 +50,7 @@ import sun.font.GlyphList; public final class GeneralRenderer { public static void register() { - Class owner = GeneralRenderer.class; + Class<?> owner = GeneralRenderer.class; GraphicsPrimitive[] primitives = { new GraphicsPrimitiveProxy(owner, "SetFillRectANY", FillRect.methodSignature, diff --git a/jdk/src/share/classes/sun/java2d/loops/GraphicsPrimitive.java b/jdk/src/share/classes/sun/java2d/loops/GraphicsPrimitive.java index 47db650374a..ca23fe72aec 100644 --- a/jdk/src/share/classes/sun/java2d/loops/GraphicsPrimitive.java +++ b/jdk/src/share/classes/sun/java2d/loops/GraphicsPrimitive.java @@ -316,7 +316,7 @@ public abstract class GraphicsPrimitive { public abstract GraphicsPrimitive traceWrap(); - static HashMap traceMap; + static HashMap<Object, int[]> traceMap; public static int traceflags; public static String tracefile; @@ -427,13 +427,14 @@ public abstract class GraphicsPrimitive { public void run() { PrintStream ps = getTraceOutputFile(); - Iterator iterator = traceMap.entrySet().iterator(); + Iterator<Map.Entry<Object, int[]>> iterator = + traceMap.entrySet().iterator(); long total = 0; int numprims = 0; while (iterator.hasNext()) { - Map.Entry me = (Map.Entry) iterator.next(); + Map.Entry<Object, int[]> me = iterator.next(); Object prim = me.getKey(); - int[] count = (int[]) me.getValue(); + int[] count = me.getValue(); if (count[0] == 1) { ps.print("1 call to "); } else { @@ -455,15 +456,15 @@ public abstract class GraphicsPrimitive { public synchronized static void tracePrimitive(Object prim) { if ((traceflags & TRACECOUNTS) != 0) { if (traceMap == null) { - traceMap = new HashMap(); + traceMap = new HashMap<>(); TraceReporter.setShutdownHook(); } - Object o = traceMap.get(prim); + int[] o = traceMap.get(prim); if (o == null) { o = new int[1]; traceMap.put(prim, o); } - ((int[]) o)[0]++; + o[0]++; } if ((traceflags & TRACELOG) != 0) { PrintStream ps = getTraceOutputFile(); diff --git a/jdk/src/share/classes/sun/java2d/loops/GraphicsPrimitiveMgr.java b/jdk/src/share/classes/sun/java2d/loops/GraphicsPrimitiveMgr.java index 6f76f544bec..177aa2148aa 100644 --- a/jdk/src/share/classes/sun/java2d/loops/GraphicsPrimitiveMgr.java +++ b/jdk/src/share/classes/sun/java2d/loops/GraphicsPrimitiveMgr.java @@ -45,11 +45,11 @@ public final class GraphicsPrimitiveMgr { private static GraphicsPrimitive generalPrimitives[]; private static boolean needssort = true; - private static native void initIDs(Class GP, Class ST, Class CT, - Class SG2D, Class Color, Class AT, - Class XORComp, Class AlphaComp, - Class Path2D, Class Path2DFloat, - Class SHints); + private static native void initIDs(Class<?> GP, Class<?> ST, Class<?> CT, + Class<?> SG2D, Class<?> Color, Class<?> AT, + Class<?> XORComp, Class<?> AlphaComp, + Class<?> Path2D, Class<?> Path2DFloat, + Class<?> SHints); private static native void registerNativeLoops(); static { @@ -73,16 +73,17 @@ public final class GraphicsPrimitiveMgr { public int uniqueID; } - private static Comparator primSorter = new Comparator() { - public int compare(Object o1, Object o2) { - int id1 = ((GraphicsPrimitive) o1).getUniqueID(); - int id2 = ((GraphicsPrimitive) o2).getUniqueID(); + private static Comparator<GraphicsPrimitive> primSorter = + new Comparator<GraphicsPrimitive>() { + public int compare(GraphicsPrimitive o1, GraphicsPrimitive o2) { + int id1 = o1.getUniqueID(); + int id2 = o2.getUniqueID(); return (id1 == id2 ? 0 : (id1 < id2 ? -1 : 1)); } }; - private static Comparator primFinder = new Comparator() { + private static Comparator<Object> primFinder = new Comparator<Object>() { public int compare(Object o1, Object o2) { int id1 = ((GraphicsPrimitive) o1).getUniqueID(); int id2 = ((PrimitiveSpec) o2).uniqueID; diff --git a/jdk/src/share/classes/sun/java2d/loops/GraphicsPrimitiveProxy.java b/jdk/src/share/classes/sun/java2d/loops/GraphicsPrimitiveProxy.java index 15c93111d69..73f18a60946 100644 --- a/jdk/src/share/classes/sun/java2d/loops/GraphicsPrimitiveProxy.java +++ b/jdk/src/share/classes/sun/java2d/loops/GraphicsPrimitiveProxy.java @@ -41,7 +41,7 @@ package sun.java2d.loops; */ public class GraphicsPrimitiveProxy extends GraphicsPrimitive { - private Class owner; + private Class<?> owner; private String relativeClassName; /** @@ -53,7 +53,7 @@ public class GraphicsPrimitiveProxy extends GraphicsPrimitive { * @param relativeClassName The name of the class this is a proxy for. * This should not include the package. */ - public GraphicsPrimitiveProxy(Class owner, String relativeClassName, + public GraphicsPrimitiveProxy(Class<?> owner, String relativeClassName, String methodSignature, int primID, SurfaceType srctype, @@ -80,7 +80,7 @@ public class GraphicsPrimitiveProxy extends GraphicsPrimitive { String name = getPackageName(owner.getName()) + "." + relativeClassName; try { - Class clazz = Class.forName(name); + Class<?> clazz = Class.forName(name); GraphicsPrimitive p = (GraphicsPrimitive) clazz.newInstance(); if (!satisfiesSameAs(p)) { throw new RuntimeException("Primitive " + p diff --git a/jdk/src/share/classes/sun/java2d/loops/MaskBlit.java b/jdk/src/share/classes/sun/java2d/loops/MaskBlit.java index 39a047d19ff..1572d05e0b6 100644 --- a/jdk/src/share/classes/sun/java2d/loops/MaskBlit.java +++ b/jdk/src/share/classes/sun/java2d/loops/MaskBlit.java @@ -143,8 +143,8 @@ public class MaskBlit extends GraphicsPrimitive MaskBlit performop; Blit convertresult; - WeakReference srcTmp; - WeakReference dstTmp; + WeakReference<SurfaceData> srcTmp; + WeakReference<SurfaceData> dstTmp; public General(SurfaceType srctype, CompositeType comptype, @@ -184,14 +184,14 @@ public class MaskBlit extends GraphicsPrimitive } else { SurfaceData cachedSrc = null; if (srcTmp != null) { - cachedSrc = (SurfaceData) srcTmp.get(); + cachedSrc = srcTmp.get(); } src = convertFrom(convertsrc, srcData, srcx, srcy, width, height, cachedSrc); sx = 0; sy = 0; if (src != cachedSrc) { - srcTmp = new WeakReference(src); + srcTmp = new WeakReference<>(src); } } @@ -204,7 +204,7 @@ public class MaskBlit extends GraphicsPrimitive // assert: convertresult != null SurfaceData cachedDst = null; if (dstTmp != null) { - cachedDst = (SurfaceData) dstTmp.get(); + cachedDst = dstTmp.get(); } dst = convertFrom(convertdst, dstData, dstx, dsty, width, height, cachedDst); @@ -212,7 +212,7 @@ public class MaskBlit extends GraphicsPrimitive dy = 0; opclip = null; if (dst != cachedDst) { - dstTmp = new WeakReference(dst); + dstTmp = new WeakReference<>(dst); } } diff --git a/jdk/src/share/classes/sun/java2d/opengl/OGLBlitLoops.java b/jdk/src/share/classes/sun/java2d/opengl/OGLBlitLoops.java index a613daf4808..64459c1145e 100644 --- a/jdk/src/share/classes/sun/java2d/opengl/OGLBlitLoops.java +++ b/jdk/src/share/classes/sun/java2d/opengl/OGLBlitLoops.java @@ -728,7 +728,7 @@ class OGLTextureToSurfaceTransform extends TransformBlit { class OGLGeneralBlit extends Blit { private Blit performop; - private WeakReference srcTmp; + private WeakReference<SurfaceData> srcTmp; OGLGeneralBlit(SurfaceType dstType, CompositeType compType, @@ -750,7 +750,7 @@ class OGLGeneralBlit extends Blit { SurfaceData cachedSrc = null; if (srcTmp != null) { // use cached intermediate surface, if available - cachedSrc = (SurfaceData)srcTmp.get(); + cachedSrc = srcTmp.get(); } // convert source to IntArgbPre @@ -763,7 +763,7 @@ class OGLGeneralBlit extends Blit { if (src != cachedSrc) { // cache the intermediate surface - srcTmp = new WeakReference(src); + srcTmp = new WeakReference<>(src); } } } @@ -802,7 +802,7 @@ class OGLAnyCompositeBlit extends Blit { if (dstBuffer != cachedDst) { // cache the intermediate surface - dstTmp = new WeakReference(dstBuffer); + dstTmp = new WeakReference<>(dstBuffer); } // now blit the buffer back to the destination diff --git a/jdk/src/share/classes/sun/java2d/pipe/AlphaPaintPipe.java b/jdk/src/share/classes/sun/java2d/pipe/AlphaPaintPipe.java index 547211cf1e5..70cb1c18efe 100644 --- a/jdk/src/share/classes/sun/java2d/pipe/AlphaPaintPipe.java +++ b/jdk/src/share/classes/sun/java2d/pipe/AlphaPaintPipe.java @@ -48,16 +48,16 @@ import sun.java2d.loops.GraphicsPrimitiveMgr; * SunGraphics2D. */ public class AlphaPaintPipe implements CompositePipe { - static WeakReference cachedLastRaster; - static WeakReference cachedLastColorModel; - static WeakReference cachedLastData; + static WeakReference<Raster> cachedLastRaster; + static WeakReference<ColorModel> cachedLastColorModel; + static WeakReference<SurfaceData> cachedLastData; static class TileContext { SunGraphics2D sunG2D; PaintContext paintCtxt; ColorModel paintModel; - WeakReference lastRaster; - WeakReference lastData; + WeakReference<Raster> lastRaster; + WeakReference<SurfaceData> lastData; MaskBlit lastMask; Blit lastBlit; SurfaceData dstData; @@ -105,8 +105,8 @@ public class AlphaPaintPipe implements CompositePipe { SurfaceData srcData = null; Raster lastRas = null; if (context.lastData != null && context.lastRaster != null) { - srcData = (SurfaceData) context.lastData.get(); - lastRas = (Raster) context.lastRaster.get(); + srcData = context.lastData.get(); + lastRas = context.lastRaster.get(); if (srcData == null || lastRas == null) { srcData = null; lastRas = null; @@ -127,7 +127,7 @@ public class AlphaPaintPipe implements CompositePipe { } if (lastRas != srcRaster) { lastRas = srcRaster; - context.lastRaster = new WeakReference(lastRas); + context.lastRaster = new WeakReference<>(lastRas); // REMIND: This will fail for a non-Writable raster! BufferedImage bImg = new BufferedImage(paintModel, @@ -135,7 +135,7 @@ public class AlphaPaintPipe implements CompositePipe { paintModel.isAlphaPremultiplied(), null); srcData = BufImgSurfaceData.createData(bImg); - context.lastData = new WeakReference(srcData); + context.lastData = new WeakReference<>(srcData); context.lastMask = null; context.lastBlit = null; } @@ -197,7 +197,7 @@ public class AlphaPaintPipe implements CompositePipe { { // Avoid creating new WeakReference if possible cachedLastColorModel = - new WeakReference(context.paintModel); + new WeakReference<>(context.paintModel); } cachedLastData = context.lastData; } diff --git a/jdk/src/share/classes/sun/java2d/pipe/RenderQueue.java b/jdk/src/share/classes/sun/java2d/pipe/RenderQueue.java index 6f65c05349c..f9dc262f17c 100644 --- a/jdk/src/share/classes/sun/java2d/pipe/RenderQueue.java +++ b/jdk/src/share/classes/sun/java2d/pipe/RenderQueue.java @@ -81,10 +81,10 @@ public abstract class RenderQueue { * A Set containing hard references to Objects that must stay alive until * the queue has been completely flushed. */ - protected Set refSet; + protected Set<Object> refSet; protected RenderQueue() { - refSet = new HashSet(); + refSet = new HashSet<>(); buf = RenderBuffer.allocate(BUFFER_SIZE); } diff --git a/jdk/src/share/classes/sun/java2d/pipe/SpanClipRenderer.java b/jdk/src/share/classes/sun/java2d/pipe/SpanClipRenderer.java index bba66f65907..0e18b92a7d7 100644 --- a/jdk/src/share/classes/sun/java2d/pipe/SpanClipRenderer.java +++ b/jdk/src/share/classes/sun/java2d/pipe/SpanClipRenderer.java @@ -39,14 +39,14 @@ public class SpanClipRenderer implements CompositePipe { CompositePipe outpipe; - static Class RegionClass = Region.class; - static Class RegionIteratorClass = RegionIterator.class; + static Class<?> RegionClass = Region.class; + static Class<?> RegionIteratorClass = RegionIterator.class; static { initIDs(RegionClass, RegionIteratorClass); } - static native void initIDs(Class rc, Class ric); + static native void initIDs(Class<?> rc, Class<?> ric); public SpanClipRenderer(CompositePipe pipe) { outpipe = pipe; diff --git a/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java b/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java index af65891495f..4e6c24f2e23 100644 --- a/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java +++ b/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java @@ -72,7 +72,7 @@ public abstract class X11SurfaceData extends XSurfaceData { protected int depth; - private static native void initIDs(Class xorComp, boolean tryDGA); + private static native void initIDs(Class<?> xorComp, boolean tryDGA); protected native void initSurface(int depth, int width, int height, long drawable); From a2651f668e20d651428158c7cc56bfb6590246e5 Mon Sep 17 00:00:00 2001 From: Petr Pchelko <pchelko@openjdk.org> Date: Mon, 21 Apr 2014 11:00:46 +0400 Subject: [PATCH 014/157] 8037477: Reproducible hang of JAWS and webstart application with JAB 2.0.4 Reviewed-by: anthony, serb --- .../accessibility/AccessibleContext.java | 23 ++++++++++++++++ .../share/classes/sun/awt/AWTAccessor.java | 27 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/jdk/src/share/classes/javax/accessibility/AccessibleContext.java b/jdk/src/share/classes/javax/accessibility/AccessibleContext.java index 15f0f7f3983..b7f584b95db 100644 --- a/jdk/src/share/classes/javax/accessibility/AccessibleContext.java +++ b/jdk/src/share/classes/javax/accessibility/AccessibleContext.java @@ -25,6 +25,9 @@ package javax.accessibility; +import sun.awt.AWTAccessor; +import sun.awt.AppContext; + import java.util.Locale; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; @@ -79,6 +82,26 @@ import java.awt.IllegalComponentStateException; */ public abstract class AccessibleContext { + /** + * The AppContext that should be used to dispatch events for this + * AccessibleContext + */ + private volatile AppContext targetAppContext; + + static { + AWTAccessor.setAccessibleContextAccessor(new AWTAccessor.AccessibleContextAccessor() { + @Override + public void setAppContext(AccessibleContext accessibleContext, AppContext appContext) { + accessibleContext.targetAppContext = appContext; + } + + @Override + public AppContext getAppContext(AccessibleContext accessibleContext) { + return accessibleContext.targetAppContext; + } + }); + } + /** * Constant used to determine when the accessibleName property has * changed. The old value in the PropertyChangeEvent will be the old diff --git a/jdk/src/share/classes/sun/awt/AWTAccessor.java b/jdk/src/share/classes/sun/awt/AWTAccessor.java index 9e41cd4dfaa..b99ccdfe2ee 100644 --- a/jdk/src/share/classes/sun/awt/AWTAccessor.java +++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java @@ -27,6 +27,7 @@ package sun.awt; import sun.misc.Unsafe; +import javax.accessibility.AccessibleContext; import java.awt.*; import java.awt.KeyboardFocusManager; import java.awt.DefaultKeyboardFocusManager; @@ -761,6 +762,14 @@ public final class AWTAccessor { void updateSystemColors(); } + /* + * An accessor object for the AccessibleContext class + */ + public interface AccessibleContextAccessor { + void setAppContext(AccessibleContext accessibleContext, AppContext appContext); + AppContext getAppContext(AccessibleContext accessibleContext); + } + /* * Accessor instances are initialized in the static initializers of * corresponding AWT classes by using setters defined below. @@ -791,6 +800,7 @@ public final class AWTAccessor { private static ToolkitAccessor toolkitAccessor; private static InvocationEventAccessor invocationEventAccessor; private static SystemColorAccessor systemColorAccessor; + private static AccessibleContextAccessor accessibleContextAccessor; /* * Set an accessor object for the java.awt.Component class. @@ -1234,4 +1244,21 @@ public final class AWTAccessor { public static void setSystemColorAccessor(SystemColorAccessor systemColorAccessor) { AWTAccessor.systemColorAccessor = systemColorAccessor; } + + /* + * Get the accessor object for the javax.accessibility.AccessibleContext class. + */ + public static AccessibleContextAccessor getAccessibleContextAccessor() { + if (accessibleContextAccessor == null) { + unsafe.ensureClassInitialized(AccessibleContext.class); + } + return accessibleContextAccessor; + } + + /* + * Set the accessor object for the javax.accessibility.AccessibleContext class. + */ + public static void setAccessibleContextAccessor(AccessibleContextAccessor accessor) { + AWTAccessor.accessibleContextAccessor = accessor; + } } From 704f4dc11341abce912047621f389f50b2f5930f Mon Sep 17 00:00:00 2001 From: Dmitriy Ermashov <dmitriy.ermashov@oracle.com> Date: Mon, 21 Apr 2014 14:35:14 +0400 Subject: [PATCH 015/157] 8039279: Move awt tests to openjdk repository Reviewed-by: pchelko, alexsch --- .../SetMaximizedBounds.java | 88 +++++++ .../ChangeGridSize/ChangeGridSize.java | 189 ++++++++++++++ .../ComponentPreferredSize.java | 181 ++++++++++++++ .../ModifierRobotKeyTest.java | 230 ++++++++++++++++++ .../LockingKeyStateTest.java | 126 ++++++++++ 5 files changed, 814 insertions(+) create mode 100644 jdk/test/java/awt/Frame/SetMaximizedBounds/SetMaximizedBounds.java create mode 100644 jdk/test/java/awt/GridLayout/ChangeGridSize/ChangeGridSize.java create mode 100644 jdk/test/java/awt/GridLayout/ComponentPreferredSize/ComponentPreferredSize.java create mode 100644 jdk/test/java/awt/Robot/ModifierRobotKey/ModifierRobotKeyTest.java create mode 100644 jdk/test/java/awt/Toolkit/LockingKeyStateTest/LockingKeyStateTest.java diff --git a/jdk/test/java/awt/Frame/SetMaximizedBounds/SetMaximizedBounds.java b/jdk/test/java/awt/Frame/SetMaximizedBounds/SetMaximizedBounds.java new file mode 100644 index 00000000000..da5b3800eae --- /dev/null +++ b/jdk/test/java/awt/Frame/SetMaximizedBounds/SetMaximizedBounds.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.*; + +/* + * @test + * @summary When Frame.setExtendedState(Frame.MAXIMIZED_BOTH) + * is called for a Frame after been called setMaximizedBounds() with + * certain value, Frame bounds must equal to this value. + * + * @library ../../../../lib/testlibrary + * @build ExtendedRobot + * @run main SetMaximizedBounds + */ + +public class SetMaximizedBounds { + + Frame frame; + Rectangle bound; + boolean supported; + ExtendedRobot robot; + static Rectangle max = new Rectangle(100,100,400,400); + + public void doTest() throws Exception { + robot = new ExtendedRobot(); + + EventQueue.invokeAndWait( () -> { + frame = new Frame( "TestFrame "); + frame.setLayout(new FlowLayout()); + + if (Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH)) { + supported = true; + frame.setMaximizedBounds(max); + } else { + supported = false; + } + + frame.setSize(200, 200); + frame.setVisible(true); + }); + + robot.waitForIdle(2000); + if (supported) { + EventQueue.invokeAndWait( () -> { + frame.setExtendedState(Frame.MAXIMIZED_BOTH); + }); + robot.waitForIdle(2000); + bound = frame.getBounds(); + if(!bound.equals(max)) + throw new RuntimeException("The bounds of the Frame do not equal to what" + + " is specified when the frame is in Frame.MAXIMIZED_BOTH state"); + } else { + System.out.println("Frame.MAXIMIZED_BOTH not supported"); + } + + frame.dispose(); + } + + public static void main(String[] args) throws Exception { + String os = System.getProperty("os.name").toLowerCase(); + System.out.println(os); + if (os.contains("windows") || os.contains("os x")) + new SetMaximizedBounds().doTest(); + else + System.out.println("Platform "+os+" is not supported. Supported platforms are Windows and OS X."); + } +} diff --git a/jdk/test/java/awt/GridLayout/ChangeGridSize/ChangeGridSize.java b/jdk/test/java/awt/GridLayout/ChangeGridSize/ChangeGridSize.java new file mode 100644 index 00000000000..86f7a7a8b3a --- /dev/null +++ b/jdk/test/java/awt/GridLayout/ChangeGridSize/ChangeGridSize.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.*; +import java.awt.event.*; + +/* + * @test + * @summary Have different components having different preferred sizes + * added to a grid layout. Change the rows and columns of the + * grid layout and check the components are re-laid out. + * The strategy followed is to calculate the component location + * depending on the preferred sizes and gaps and click the cornors + * of the components to check if events are triggered + * @library ../../../../lib/testlibrary/ + * @build ExtendedRobot + * @run main ChangeGridSize + * @run main ChangeGridSize -hg 20 -vg 20 + */ + +public class ChangeGridSize { + + private int width = 200; + private int height = 200; + private final int hGap, vGap; + private final int rows = 3; + private final int columns = 2; + private final int componentCount = 6; + + private Button[] buttons; + private Frame frame; + + private ExtendedRobot robot; + private GridLayout layout; + + private volatile boolean actionPerformed = false; + + public ChangeGridSize(int hGap, int vGap) throws Exception { + this.hGap = hGap; + this.vGap = vGap; + robot = new ExtendedRobot(); + EventQueue.invokeAndWait( () -> { + frame = new Frame("Test frame"); + frame.setSize(width, height); + layout = new GridLayout(rows + 3, columns - 1, hGap, vGap); + frame.setLayout(layout); + + buttons = new Button[componentCount]; + for (int i = 0; i < componentCount; i++) { + buttons[i] = new Button("Button" + i); + frame.add(buttons[i]); + buttons[i].addActionListener( (event) -> { actionPerformed = true; }); + } + frame.setVisible(true); + }); + } + + public static void main(String[] args) throws Exception { + int hGap = 0; + int vGap = 0; + for (int i = 0; i < args.length; i++) { + switch (args[i]) { + case "-hg": + hGap = Integer.parseInt(args[++i]); + break; + case "-vg": + vGap = Integer.parseInt(args[++i]); + break; + } + } + new ChangeGridSize(hGap, vGap).doTest(); + } + + private void resizeFrame() throws Exception { + EventQueue.invokeAndWait(() -> { + Insets insets = frame.getInsets(); + double dH = (height-insets.top-insets.bottom - vGap*(rows-1)) % rows; + double dW = (width-insets.left-insets.right - hGap*(columns-1)) % columns; + height -= dH; + width -= dW; + frame.setSize(width, height); + frame.revalidate(); + }); + robot.waitForIdle(); + } + + private void changeGridSize() throws Exception { + EventQueue.invokeAndWait(() -> { + layout.setRows(rows); + layout.setColumns(columns); + + frame.revalidate(); + }); + robot.waitForIdle(); + } + + public void testBoundaries(int topLeftX, int topLeftY, int bottomRightX, int bottomRightY) throws Exception { + + actionPerformed = false; + robot.mouseMove(topLeftX, topLeftY); + robot.delay(500); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(500); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(3000); + + if(!actionPerformed) + throw new RuntimeException("Clicking on the left top of button did not trigger action event"); + + actionPerformed = false; + robot.mouseMove(bottomRightX, bottomRightY); + robot.delay(500); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(500); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(3000); + + if(!actionPerformed) + throw new RuntimeException("Clicking on the bottom right of button did not trigger action event"); + } + + private void doTest() throws Exception { + robot.waitForIdle(); + changeGridSize(); + resizeFrame(); + + int availableWidth = width - frame.getInsets().left - + frame.getInsets().right; + int componentWidth = (availableWidth + hGap) / columns - hGap; + int availableHeight = height - frame.getInsets().top - + frame.getInsets().bottom; + int componentHeight = (availableHeight + vGap) / rows - vGap; + + for (int i = 0; i < buttons.length; i++) { + if (buttons[i].getSize().width != componentWidth || + buttons[i].getSize().height != componentHeight) { + throw new RuntimeException( + "FAIL: Button " + i + " not of proper size" + + "Expected: " + componentWidth + "*" + componentHeight + + "Actual: " + buttons[i].getSize().width + "*" + buttons[i].getSize().height); + } + } + + // Components are visible. They should trigger events. + // Now you can check for the actual size shown. + int currentRow = 1; + int currentColumn = 0; + for (int i = 0; i < buttons.length; i++) { + currentColumn++; + if (currentColumn > columns) { + currentColumn = 1; + currentRow++; + } + + int topPosX = frame.getLocationOnScreen().x + + frame.getInsets().left + + (currentColumn - 1) * (componentWidth + hGap); + int topPosY = frame.getLocationOnScreen().y + + frame.getInsets().top + + (currentRow - 1) * (componentHeight + vGap); + + int bottomPosX = topPosX + componentWidth - 1; + int bottomPosY = topPosY + componentHeight - 1; + testBoundaries(topPosX, topPosY, bottomPosX, bottomPosY); + } + + frame.dispose(); + } +} diff --git a/jdk/test/java/awt/GridLayout/ComponentPreferredSize/ComponentPreferredSize.java b/jdk/test/java/awt/GridLayout/ComponentPreferredSize/ComponentPreferredSize.java new file mode 100644 index 00000000000..d8ceac748c8 --- /dev/null +++ b/jdk/test/java/awt/GridLayout/ComponentPreferredSize/ComponentPreferredSize.java @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.*; +import java.awt.event.InputEvent; + +/* + * @test + * @summary Have different components having different preferred sizes + * added to a grid layout having various values of row/columns. + * Check if the compnents are correctly laid out. + * The strategy followed is to calculate the component location + * depending on the preferred sizes and gaps and click the cornors + * of the components to check if events are triggered + * @library ../../../../lib/testlibrary/ + * @build ExtendedRobot + * @run main ComponentPreferredSize + * @run main ComponentPreferredSize -hg 20 -vg 20 + */ + +public class ComponentPreferredSize { + + private int width = 200; + private int height = 200; + private final int hGap, vGap; + private final int rows = 3; + private final int columns = 2; + private final int componentCount = 6; + + private Button[] buttons; + private Frame frame; + + private ExtendedRobot robot; + private GridLayout layout; + + private volatile boolean actionPerformed = false; + + public ComponentPreferredSize(int hGap, int vGap) throws Exception { + this.hGap = hGap; + this.vGap = vGap; + robot = new ExtendedRobot(); + EventQueue.invokeAndWait( () -> { + frame = new Frame("Test frame"); + frame.setSize(width, height); + layout = new GridLayout(rows, columns, hGap, vGap); + frame.setLayout(layout); + + buttons = new Button[componentCount]; + for (int i = 0; i < componentCount; i++) { + buttons[i] = new Button("Button" + i); + buttons[i].setPreferredSize(new Dimension((int) Math.random() * 100, + (int) Math.random() * 100)); + frame.add(buttons[i]); + buttons[i].addActionListener((event) -> {actionPerformed = true;}); + } + + frame.setVisible(true); + }); + } + + public static void main(String[] args) throws Exception { + int hGap = 0; + int vGap = 0; + for (int i = 0; i < args.length; i++) { + switch (args[i]) { + case "-hg": + hGap = Integer.parseInt(args[++i]); + break; + case "-vg": + vGap = Integer.parseInt(args[++i]); + break; + } + } + new ComponentPreferredSize(hGap, vGap).doTest(); + } + + private void resizeFrame() throws Exception { + EventQueue.invokeAndWait(() -> { + Insets insets = frame.getInsets(); + double dH = (height-insets.top-insets.bottom - vGap*(rows-1)) % rows; + double dW = (width-insets.left-insets.right - hGap*(columns-1)) % columns; + height -= dH; + width -= dW; + frame.setSize(width, height); + frame.revalidate(); + }); + robot.waitForIdle(); + } + + public void testBoundaries(int topLeftX, int topLeftY, int bottomRightX, int bottomRightY) throws Exception { + + actionPerformed = false; + robot.mouseMove(topLeftX, topLeftY); + robot.delay(500); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(500); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(3000); + + if(!actionPerformed) + throw new RuntimeException("Clicking on the left top of button did not trigger action event"); + + actionPerformed = false; + robot.mouseMove(bottomRightX, bottomRightY); + robot.delay(500); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(500); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(3000); + + if(!actionPerformed) + throw new RuntimeException("Clicking on the bottom right of button did not trigger action event"); + } + + private void doTest() throws Exception { + robot.waitForIdle(); + resizeFrame(); + + int availableWidth = width - frame.getInsets().left - + frame.getInsets().right; + int componentWidth = (availableWidth + hGap) / columns - hGap; + int availableHeight = height - frame.getInsets().top - + frame.getInsets().bottom; + int componentHeight = (availableHeight + vGap) / rows - vGap; + + for (int i = 0; i < buttons.length; i++) { + if (buttons[i].getSize().width != componentWidth || + buttons[i].getSize().height != componentHeight) { + throw new RuntimeException( + "FAIL: Button " + i + " not of proper size" + + "Expected: " + componentWidth + "*" + componentHeight + + "Actual: " + buttons[i].getSize().width + "*" + buttons[i].getSize().height); + } + } + + // Components are visible. They should trigger events. + // Now you can check for the actual size shown. + int currentRow = 1; + int currentColumn = 0; + for (int i = 0; i < buttons.length; i++) { + currentColumn++; + if (currentColumn > columns) { + currentColumn = 1; + currentRow++; + } + + int topPosX = frame.getLocationOnScreen().x + + frame.getInsets().left + + (currentColumn - 1) * (componentWidth + hGap); + int topPosY = frame.getLocationOnScreen().y + + frame.getInsets().top + + (currentRow - 1) * (componentHeight + vGap); + + int bottomPosX = topPosX + componentWidth - 1; + int bottomPosY = topPosY + componentHeight - 1; + testBoundaries(topPosX, topPosY, bottomPosX, bottomPosY); + } + + frame.dispose(); + } +} diff --git a/jdk/test/java/awt/Robot/ModifierRobotKey/ModifierRobotKeyTest.java b/jdk/test/java/awt/Robot/ModifierRobotKey/ModifierRobotKeyTest.java new file mode 100644 index 00000000000..5cdc8085255 --- /dev/null +++ b/jdk/test/java/awt/Robot/ModifierRobotKey/ModifierRobotKeyTest.java @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.*; +import java.awt.event.*; + +import static jdk.testlibrary.Asserts.assertTrue; + +/* + * @test + * @summary Make sure that modifier key mask is set when robot press + * some key with one or more modifiers. + * + * @library ../../../../lib/testlibrary/ + * @build ExtendedRobot + * @run main ModifierRobotKeyTest + */ + +public class ModifierRobotKeyTest extends KeyAdapter { + + private boolean focusGained = false; + private boolean startTest = false; + private ExtendedRobot robot; + private Frame frame; + private Canvas canvas; + + private volatile boolean tempPress = false; + + private int[] textKeys, modifierKeys, inputMasks; + private boolean[] modifierStatus, textStatus; + + private final static int waitDelay = 5000; + private Object tempLock = new Object(); + private Object keyLock = new Object(); + + public static void main(String[] args) throws Exception { + ModifierRobotKeyTest test = new ModifierRobotKeyTest(); + test.doTest(); + } + + public ModifierRobotKeyTest() throws Exception { + modifierKeys = new int[3]; + modifierKeys[0] = KeyEvent.VK_SHIFT; + modifierKeys[1] = KeyEvent.VK_CONTROL; + modifierKeys[2] = KeyEvent.VK_ALT; + + inputMasks = new int[3]; + inputMasks[0] = InputEvent.SHIFT_MASK; + inputMasks[1] = InputEvent.CTRL_MASK; + inputMasks[2] = InputEvent.ALT_MASK; + + modifierStatus = new boolean[modifierKeys.length]; + + textKeys = new int[2]; + textKeys[0] = KeyEvent.VK_A; + + String os = System.getProperty("os.name").toLowerCase(); + + if (os.contains("solaris") || os.contains("sunos")) + textKeys[1] = KeyEvent.VK_S; + else if (os.contains("os x")) + textKeys[1] = KeyEvent.VK_K; + else + textKeys[1] = KeyEvent.VK_I; + + textStatus = new boolean[textKeys.length]; + + EventQueue.invokeAndWait( () -> { initializeGUI(); }); + } + + public void keyPressed(KeyEvent event) { + + tempPress = true; + synchronized (tempLock) { tempLock.notifyAll(); } + + if (! startTest) { + return; + } + for (int x = 0; x < inputMasks.length; x++) { + if ((event.getModifiers() & inputMasks[x]) != 0) { + System.out.println("Modifier set: " + event.getKeyModifiersText(inputMasks[x])); + modifierStatus[x] = true; + } + } + for (int x = 0; x < textKeys.length; x++) { + if (event.getKeyCode() == textKeys[x]) { + System.out.println("Text set: " + event.getKeyText(textKeys[x])); + textStatus[x] = true; + } + } + + synchronized (keyLock) { keyLock.notifyAll(); } + } + + private void initializeGUI() { + frame = new Frame("Test frame"); + canvas = new Canvas(); + canvas.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent event) { focusGained = true; } + }); + canvas.addKeyListener(this); + frame.setLayout(new BorderLayout()); + frame.add(canvas); + frame.setSize(200, 200); + frame.setVisible(true); + } + + public void doTest() throws Exception { + robot = new ExtendedRobot(); + + robot.mouseMove((int) frame.getLocationOnScreen().getX() + frame.getSize().width / 2, + (int) frame.getLocationOnScreen().getY() + frame.getSize().height / 2); + robot.click(MouseEvent.BUTTON1_MASK); + robot.waitForIdle(); + + assertTrue(focusGained, "FAIL: Canvas gained focus!"); + + for (int i = 0; i < modifierKeys.length; i++) { + for (int j = 0; j < textKeys.length; j++) { + tempPress = false; + robot.keyPress(modifierKeys[i]); + robot.waitForIdle(); + if (! tempPress) { + synchronized (tempLock) { tempLock.wait(waitDelay); } + } + assertTrue(tempPress, "FAIL: keyPressed triggered for i=" + i); + + resetStatus(); + startTest = true; + robot.keyPress(textKeys[j]); + robot.waitForIdle(); + if (! modifierStatus[i] || ! textStatus[j]) { + synchronized (keyLock) { keyLock.wait(waitDelay); } + } + + + assertTrue(modifierStatus[i] && textStatus[j], + "FAIL: KeyEvent not proper!"+ + "Key checked: i=" + i + "; j=" + j+ + "ModifierStatus = " + modifierStatus[i]+ + "TextStatus = " + textStatus[j]); + startTest = false; + robot.keyRelease(textKeys[j]); + robot.waitForIdle(); + robot.keyRelease(modifierKeys[i]); + robot.waitForIdle(); + } + } + + for (int i = 0; i < modifierKeys.length; i++) { + for (int j = i + 1; j < modifierKeys.length; j++) { + for (int k = 0; k < textKeys.length; k++) { + tempPress = false; + robot.keyPress(modifierKeys[i]); + robot.waitForIdle(); + if (! tempPress) { + synchronized (tempLock) { tempLock.wait(waitDelay); } + } + + assertTrue(tempPress, "FAIL: MultiKeyTest: keyPressed triggered for i=" + i); + + tempPress = false; + robot.keyPress(modifierKeys[j]); + robot.waitForIdle(); + if (! tempPress) { + synchronized (tempLock) { tempLock.wait(waitDelay); } + } + assertTrue(tempPress, "FAIL: MultiKeyTest keyPressed triggered for j=" + j); + + resetStatus(); + startTest = true; + robot.keyPress(textKeys[k]); + robot.waitForIdle(); + if (! modifierStatus[i] || ! modifierStatus[j] || ! textStatus[k]) { + synchronized (keyLock) { + keyLock.wait(waitDelay); + } + } + assertTrue(modifierStatus[i] && modifierStatus[j] && textStatus[k], + "FAIL: KeyEvent not proper!"+ + "Key checked: i=" + i + "; j=" + j + "; k=" + k+ + "Modifier1Status = " + modifierStatus[i]+ + "Modifier2Status = " + modifierStatus[j]+ + "TextStatus = " + textStatus[k]); + + startTest = false; + robot.keyRelease(textKeys[k]); + robot.waitForIdle(); + robot.keyRelease(modifierKeys[j]); + robot.waitForIdle(); + robot.keyRelease(modifierKeys[i]); + robot.waitForIdle(); + } + } + } + + frame.dispose(); + } + + private void resetStatus() { + for (int i = 0; i < modifierStatus.length; i++) { + modifierStatus[i] = false; + } + for (int i = 0; i < textStatus.length; i++) { + textStatus[i] = false; + } + } + +} diff --git a/jdk/test/java/awt/Toolkit/LockingKeyStateTest/LockingKeyStateTest.java b/jdk/test/java/awt/Toolkit/LockingKeyStateTest/LockingKeyStateTest.java new file mode 100644 index 00000000000..37aef352a15 --- /dev/null +++ b/jdk/test/java/awt/Toolkit/LockingKeyStateTest/LockingKeyStateTest.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.*; +import java.awt.event.KeyEvent; + +/* + @test + @summary verify LOCK buttons toogle + @author Yuri.Nesterenko, Dmitriy.Ermashov + @library ../../../../lib/testlibrary + @build ExtendedRobot + @run main LockingKeyStateTest +*/ + +public class LockingKeyStateTest { + + Frame frame; + ExtendedRobot robot; + + // Note that Kana lock you may actually toggle only if you have one. + static int[] lockingKeys = { KeyEvent.VK_CAPS_LOCK, KeyEvent.VK_NUM_LOCK, + KeyEvent.VK_SCROLL_LOCK, KeyEvent.VK_KANA_LOCK }; + boolean[] getSupported = new boolean[lockingKeys.length]; + boolean[] setSupported = new boolean[lockingKeys.length]; + boolean[] state0 = new boolean[lockingKeys.length]; + + Toolkit toolkit = Toolkit.getDefaultToolkit(); + + LockingKeyStateTest() throws Exception { + robot = new ExtendedRobot(); + EventQueue.invokeAndWait( this::createGui ); + } + + void toggleAllTrue(){toggleAll(true);} + void toggleAllFalse(){toggleAll(false);} + void toggleAll(boolean b) { + for(int i = 0; i < lockingKeys.length; i++) { + if(setSupported[i]) { + toolkit.setLockingKeyState(lockingKeys[i], b); + } + } + } + + void checkAllTrue(){checkAll(true);} + void checkAllFalse(){checkAll(false);} + void checkAll(boolean b) { + for(int i = 0; i < lockingKeys.length; i++) { + if(getSupported[i] && setSupported[i]) { + if (!(toolkit.getLockingKeyState(lockingKeys[i]) == b)) + throw new RuntimeException("State of "+KeyEvent.getKeyText(lockingKeys[i])+" is not "+b); + System.out.println("OK, state of "+KeyEvent.getKeyText(lockingKeys[i])+" is "+b); + } + } + } + + void restoreAll() { + for(int i = 0; i < lockingKeys.length; i++) { + if(setSupported[i] && getSupported[i]) { + toolkit.setLockingKeyState(lockingKeys[i], state0[i]); + } + } + } + + public void createGui() { + for(int i = 0; i < lockingKeys.length; i++) { + getSupported[i] = false; + setSupported[i] = false; + try { + state0[i] = toolkit.getLockingKeyState(lockingKeys[i]); + getSupported[i] = true; + toolkit.setLockingKeyState(lockingKeys[i], state0[i]); + setSupported[i] = true; + } catch (UnsupportedOperationException uoe) { + } + System.out.println(" State get/set of "+KeyEvent.getKeyText(lockingKeys[i])+" is supported? "+ + getSupported[i]+", "+setSupported[i]); + } + frame = new Frame("LockingKeyStateTest Title"); + frame.setSize(200,200); + frame.setVisible(true); + } + + void doTest() throws Exception{ + robot.waitForIdle(); + robot.mouseMove(frame.getLocationOnScreen().x + frame.getWidth() / 2, + frame.getLocationOnScreen().y + frame.getHeight() / 2); + robot.click(); + + EventQueue.invokeAndWait( this::toggleAllTrue ); + robot.waitForIdle(2000); + EventQueue.invokeAndWait( this::checkAllTrue ); + EventQueue.invokeAndWait( this::toggleAllFalse ); + robot.waitForIdle(2000); + EventQueue.invokeAndWait( this::checkAllFalse ); + EventQueue.invokeAndWait( this::restoreAll ); + robot.waitForIdle(); + + frame.dispose(); + } + + public static void main(String argv[]) throws Exception { + LockingKeyStateTest af = new LockingKeyStateTest(); + af.doTest(); + } +} From c6886100bee271e778ac99813d655e76b96e2e2d Mon Sep 17 00:00:00 2001 From: Alexey Ivanov <alexey.ivanov@oracle.com> Date: Mon, 21 Apr 2014 16:32:41 +0400 Subject: [PATCH 016/157] 8024061: Exception thrown when drag and drop between two components is executed quickly Reviewed-by: pchelko, serb --- .../sun/awt/dnd/SunDropTargetContextPeer.java | 9 +- jdk/test/sun/awt/dnd/8024061/bug8024061.java | 357 ++++++++++++++++++ 2 files changed, 365 insertions(+), 1 deletion(-) create mode 100644 jdk/test/sun/awt/dnd/8024061/bug8024061.java diff --git a/jdk/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java b/jdk/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java index 2efea8da2de..842b387f6f4 100644 --- a/jdk/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java +++ b/jdk/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -239,6 +239,13 @@ public abstract class SunDropTargetContextPeer implements DropTargetContextPeer, if (localTransferable != null) { return localTransferable.getTransferData(df); + } else if (df.isMimeTypeEqual(DataFlavor.javaJVMLocalObjectMimeType)) { + // Workaround to JDK-8024061: Exception thrown when drag and drop + // between two components is executed quickly. + // It is expected localTransferable is not null if javaJVMLocalObjectMimeType + // is used. Executing further results in ClassCastException, so null is + // returned here as no transfer data is available in this case. + return null; } if (dropStatus != STATUS_ACCEPT || dropComplete) { diff --git a/jdk/test/sun/awt/dnd/8024061/bug8024061.java b/jdk/test/sun/awt/dnd/8024061/bug8024061.java new file mode 100644 index 00000000000..07165c09a61 --- /dev/null +++ b/jdk/test/sun/awt/dnd/8024061/bug8024061.java @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @bug 8024061 + * @summary Checks that no exception is thrown if dragGestureRecognized + * takes a while to complete. + */ +import sun.awt.OSInfo; +import sun.awt.OSInfo.OSType; +import sun.awt.SunToolkit; + +import java.awt.*; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.InputEvent; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import javax.swing.*; + +/** + * If dragGestureRecognized() takes a while to complete and if user performs a drag quickly, + * an exception is thrown from DropTargetListener.dragEnter when it calls + * DropTargetDragEvent.getTransferable(). + * <p> + * This class introduces a delay in dragGestureRecognized() to cause the exception. + */ +public class bug8024061 { + private static final DataFlavor DropObjectFlavor; + private static final int DELAY = 1000; + + private final DnDPanel panel1 = new DnDPanel(Color.yellow); + private final DnDPanel panel2 = new DnDPanel(Color.pink); + private final JFrame frame; + + private static final CountDownLatch lock = new CountDownLatch(1); + private static volatile Exception dragEnterException = null; + + static { + DataFlavor flavor = null; + try { + flavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + DropObjectFlavor = flavor; + } + + bug8024061() { + frame = new JFrame("DnDWithRobot"); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + + Dimension d = new Dimension(100, 100); + + panel1.setPreferredSize(d); + panel2.setPreferredSize(d); + + Container content = frame.getContentPane(); + content.setLayout(new GridLayout(1, 2, 5, 5)); + content.add(panel1); + content.add(panel2); + + frame.pack(); + + DropObject drop = new DropObject(); + drop.place(panel1, new Point(10, 10)); + frame.setVisible(true); + } + + public static void main(String[] args) throws AWTException, InvocationTargetException, InterruptedException { + OSType type = OSInfo.getOSType(); + if (type != OSType.LINUX && type != OSType.SOLARIS) { + System.out.println("This test is for Linux and Solaris only... " + + "skipping!"); + return; + } + + final bug8024061[] dnd = {null}; + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + dnd[0] = new bug8024061(); + } + }); + final Robot robot = new Robot(); + robot.setAutoDelay(10); + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + toolkit.realSync(); + + JFrame frame = dnd[0].frame; + Point point = frame.getLocationOnScreen(); + Point here = new Point(point.x + 35, point.y + 45); + Point there = new Point(point.x + 120, point.y + 45); + here.x += 25; + robot.mouseMove(here.x, here.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + while (here.x < there.x) { + here.x += 20; + robot.mouseMove(here.x, here.y); + System.out.println("x = " + here.x); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + System.out.println("finished"); + + try { + if (lock.await(5, TimeUnit.SECONDS)) { + if (dragEnterException == null) { + System.out.println("Test passed."); + } else { + System.out.println("Test failed."); + dragEnterException.printStackTrace(); + throw new RuntimeException(dragEnterException); + } + } else { + System.out.println("Test failed. Timeout reached"); + throw new RuntimeException("Timed out waiting for dragEnter()"); + } + } finally { + frame.dispose(); + } + } + + class DropObject implements Transferable { + DnDPanel panel; + Color color = Color.CYAN; + int width = 50; + int height = 50; + int x; + int y; + + void draw(Graphics2D g) { + Color savedColor = g.getColor(); + g.setColor(color); + g.fillRect(x, y, width, height); + g.setColor(Color.lightGray); + g.drawRect(x, y, width, height); + g.setColor(savedColor); + } + + boolean contains(int x, int y) { + return (x > this.x && x < this.x + width) + && (y > this.y && y < this.y + height); + } + + @Override + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[]{DropObjectFlavor}; + } + + void place(DnDPanel panel, Point location) { + if (panel != this.panel) { + x = location.x; + y = location.y; + if (this.panel != null) { + this.panel.setDropObject(null); + this.panel.repaint(); + } + this.panel = panel; + this.panel.setDropObject(this); + this.panel.repaint(); + } + } + + @Override + public boolean isDataFlavorSupported(DataFlavor flavor) { + return DropObjectFlavor.equals(flavor); + } + + @Override + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException, IOException { + if (isDataFlavorSupported(flavor)) { + return this; + } else { + throw new UnsupportedFlavorException(flavor); + } + } + } + + class DnDPanel extends JPanel { + DropObject dropObject; + final DragSource dragSource; + final DropTarget dropTarget; + final Color color; + final DragGestureListener dgListener; + final DragSourceListener dsListener; + final DropTargetListener dtListener; + + DnDPanel(Color color) { + this.color = color; + this.dragSource = DragSource.getDefaultDragSource(); + dgListener = new DragGestureListener() { + @Override + public void dragGestureRecognized(DragGestureEvent dge) { + Point location = dge.getDragOrigin(); + if (dropObject != null && dropObject.contains(location.x, location.y)) { + dragSource.startDrag(dge, DragSource.DefaultCopyNoDrop, dropObject, dsListener); + try { + Thread.sleep(DELAY); + } catch (InterruptedException e) { + } + } + } + }; + + dsListener = new DragSourceListener() { + @Override + public void dragEnter(DragSourceDragEvent dsde) { + } + + @Override + public void dragOver(DragSourceDragEvent dsde) { + } + + @Override + public void dropActionChanged(DragSourceDragEvent dsde) { + } + + @Override + public void dragExit(DragSourceEvent dse) { + } + + @Override + public void dragDropEnd(DragSourceDropEvent dsde) { + } + }; + + dtListener = new DropTargetListener() { + @Override + public void dragEnter(DropTargetDragEvent dtde) { + if (dropObject != null) { + dtde.rejectDrag(); + return; + } + dtde.acceptDrag(DnDConstants.ACTION_MOVE); + try { + Transferable t = dtde.getTransferable(); + Object data = t.getTransferData(DropObjectFlavor); + if (data != null) { + throw new Exception("getTransferData returned non-null"); + } + } catch (Exception e) { + dragEnterException = e; + e.printStackTrace(); + } finally { + lock.countDown(); + } + } + + @Override + public void dragOver(DropTargetDragEvent dtde) { + if (dropObject != null) { + dtde.rejectDrag(); + return; + } + dtde.acceptDrag(DnDConstants.ACTION_MOVE); + } + + @Override + public void dropActionChanged(DropTargetDragEvent dtde) { + } + + @Override + public void dragExit(DropTargetEvent dte) { + } + + @Override + public void drop(DropTargetDropEvent dtde) { + if (dropObject != null) { + dtde.rejectDrop(); + return; + } + try { + dtde.acceptDrop(DnDConstants.ACTION_MOVE); + Transferable t = dtde.getTransferable(); + DropObject dropObject = (DropObject) t.getTransferData(DropObjectFlavor); + Point location = dtde.getLocation(); + dropObject.place(DnDPanel.this, location); + dtde.dropComplete(true); + } catch (Exception e) { + e.printStackTrace(); + } + + } + }; + + dragSource.createDefaultDragGestureRecognizer(this, + DnDConstants.ACTION_MOVE, dgListener); + + dropTarget = new DropTarget(this, DnDConstants.ACTION_MOVE, dtListener, true); + + } + + public void paintComponent(Graphics g) { + super.paintComponent(g); + Color savedColor = g.getColor(); + g.setColor(color); + g.fillRect(0, 0, getWidth(), getHeight()); + g.setColor(savedColor); + if (dropObject != null) { + dropObject.draw((Graphics2D) g); + } + } + + void setDropObject(DropObject dropObject) { + this.dropObject = dropObject; + } + + DropObject findDropObject(int x, int y) { + if (dropObject != null && dropObject.contains(x, y)) { + return dropObject; + } + return null; + } + } +} From 1d1194721bbf7749899315b2316a31ad143f083a Mon Sep 17 00:00:00 2001 From: Sergey Malenkov <malenkov@openjdk.org> Date: Mon, 21 Apr 2014 20:59:59 +0400 Subject: [PATCH 017/157] 8040656: Classes with overriden methods with covariant returns return random read methods Reviewed-by: alexsch, serb --- .../classes/java/beans/MethodDescriptor.java | 13 +- .../java/beans/Introspector/Test8040656.java | 311 ++++++++++++++++++ 2 files changed, 322 insertions(+), 2 deletions(-) create mode 100644 jdk/test/java/beans/Introspector/Test8040656.java diff --git a/jdk/src/share/classes/java/beans/MethodDescriptor.java b/jdk/src/share/classes/java/beans/MethodDescriptor.java index da2f754c97e..1e169046746 100644 --- a/jdk/src/share/classes/java/beans/MethodDescriptor.java +++ b/jdk/src/share/classes/java/beans/MethodDescriptor.java @@ -162,6 +162,16 @@ public class MethodDescriptor extends FeatureDescriptor { : null; } + private static Method resolve(Method oldMethod, Method newMethod) { + if (oldMethod == null) { + return newMethod; + } + if (newMethod == null) { + return oldMethod; + } + return !oldMethod.isSynthetic() && newMethod.isSynthetic() ? oldMethod : newMethod; + } + /* * Package-private constructor * Merge two method descriptors. Where they conflict, give the @@ -173,8 +183,7 @@ public class MethodDescriptor extends FeatureDescriptor { MethodDescriptor(MethodDescriptor x, MethodDescriptor y) { super(x, y); - Method method = y.methodRef.get(); - this.methodRef.set(null != method ? method : x.methodRef.get()); + this.methodRef.set(resolve(x.methodRef.get(), y.methodRef.get())); params = x.params; if (y.params != null) { params = y.params; diff --git a/jdk/test/java/beans/Introspector/Test8040656.java b/jdk/test/java/beans/Introspector/Test8040656.java new file mode 100644 index 00000000000..73e80ac377f --- /dev/null +++ b/jdk/test/java/beans/Introspector/Test8040656.java @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.beans.Introspector; +import java.beans.MethodDescriptor; + +/* + * @test + * @bug 8040656 + * @summary Tests that a normal method is preferred to a synthetic one + * @author Sergey Malenkov + */ + +public class Test8040656 { + public static void main(String[] args) throws Exception { + test(String.class, C.class); + test(String.class, C1.class); + test(String.class, C2.class); + test(String.class, C3.class); + test(String.class, C4.class); + test(String.class, C5.class); + test(String.class, C6.class); + test(String.class, C7.class); + test(String.class, C8.class); + test(String.class, C9.class); + } + + private static void test(Class<?> type, Class<?> bean) throws Exception { + for (MethodDescriptor md : Introspector.getBeanInfo(bean).getMethodDescriptors()) { + if (md.getName().equals("getFoo")) { + if (type != md.getMethod().getReturnType()) { + throw new Error("unexpected type"); + } + } + } + } + + public interface A { + public Object getFoo(); + } + + public class C implements A { + @Override + public String getFoo() { + return null; + } + } + + public class C1 implements A { + @Override + public String getFoo() { + return null; + } + + public String getFoo1() { + return null; + } + } + + public class C2 implements A { + @Override + public String getFoo() { + return null; + } + + public String getFoo1() { + return null; + } + + public String getFoo2() { + return null; + } + } + + public class C3 implements A { + @Override + public String getFoo() { + return null; + } + + public String getFoo1() { + return null; + } + + public String getFoo2() { + return null; + } + + public String getFoo3() { + return null; + } + } + + public class C4 implements A { + @Override + public String getFoo() { + return null; + } + + public String getFoo1() { + return null; + } + + public String getFoo2() { + return null; + } + + public String getFoo3() { + return null; + } + + public String getFoo4() { + return null; + } + } + + public class C5 implements A { + @Override + public String getFoo() { + return null; + } + + public String getFoo1() { + return null; + } + + public String getFoo2() { + return null; + } + + public String getFoo3() { + return null; + } + + public String getFoo4() { + return null; + } + + public String getFoo5() { + return null; + } + } + + public class C6 implements A { + @Override + public String getFoo() { + return null; + } + + public String getFoo1() { + return null; + } + + public String getFoo2() { + return null; + } + + public String getFoo3() { + return null; + } + + public String getFoo4() { + return null; + } + + public String getFoo5() { + return null; + } + + public String getFoo6() { + return null; + } + } + + public class C7 implements A { + @Override + public String getFoo() { + return null; + } + + public String getFoo1() { + return null; + } + + public String getFoo2() { + return null; + } + + public String getFoo3() { + return null; + } + + public String getFoo4() { + return null; + } + + public String getFoo5() { + return null; + } + + public String getFoo6() { + return null; + } + + public String getFoo7() { + return null; + } + } + + public class C8 implements A { + @Override + public String getFoo() { + return null; + } + + public String getFoo1() { + return null; + } + + public String getFoo2() { + return null; + } + + public String getFoo3() { + return null; + } + + public String getFoo4() { + return null; + } + + public String getFoo5() { + return null; + } + + public String getFoo6() { + return null; + } + + public String getFoo7() { + return null; + } + + public String getFoo8() { + return null; + } + } + + public class C9 implements A { + @Override + public String getFoo() { + return null; + } + + public String getFoo1() { + return null; + } + + public String getFoo2() { + return null; + } + + public String getFoo3() { + return null; + } + + public String getFoo4() { + return null; + } + + public String getFoo5() { + return null; + } + + public String getFoo6() { + return null; + } + + public String getFoo7() { + return null; + } + + public String getFoo8() { + return null; + } + + public String getFoo9() { + return null; + } + } +} From 7025bc84e60aab89f5ce8b435273c4f763c90d95 Mon Sep 17 00:00:00 2001 From: Joe Darcy <darcy@openjdk.org> Date: Mon, 21 Apr 2014 23:39:30 -0700 Subject: [PATCH 018/157] 8039862: Fix fallthrough lint warnings in 2d Reviewed-by: flar --- jdk/src/share/classes/sun/font/SunFontManager.java | 1 + jdk/src/share/classes/sun/font/TrueTypeGlyphMapper.java | 2 ++ jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java | 1 + 3 files changed, 4 insertions(+) diff --git a/jdk/src/share/classes/sun/font/SunFontManager.java b/jdk/src/share/classes/sun/font/SunFontManager.java index 04df414365c..998713b4494 100644 --- a/jdk/src/share/classes/sun/font/SunFontManager.java +++ b/jdk/src/share/classes/sun/font/SunFontManager.java @@ -1161,6 +1161,7 @@ public abstract class SunFontManager implements FontSupport, FontManagerForSGE { case FONTFORMAT_NATIVE: NativeFont nf = new NativeFont(fileName, false); physicalFont = addToFontList(nf, fontRank); + break; default: } diff --git a/jdk/src/share/classes/sun/font/TrueTypeGlyphMapper.java b/jdk/src/share/classes/sun/font/TrueTypeGlyphMapper.java index febaf6a5eb7..4ebee6cd280 100644 --- a/jdk/src/share/classes/sun/font/TrueTypeGlyphMapper.java +++ b/jdk/src/share/classes/sun/font/TrueTypeGlyphMapper.java @@ -109,6 +109,7 @@ public class TrueTypeGlyphMapper extends CharToGlyphMapper { cmap = CMap.theNullCmap; } + @SuppressWarnings("fallthrough") private final char remapJAChar(char unicode) { switch (unicode) { case REVERSE_SOLIDUS: @@ -123,6 +124,7 @@ public class TrueTypeGlyphMapper extends CharToGlyphMapper { default: return unicode; } } + @SuppressWarnings("fallthrough") private final int remapJAIntChar(int unicode) { switch (unicode) { case REVERSE_SOLIDUS: diff --git a/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java b/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java index 4e6c24f2e23..1d83b65a876 100644 --- a/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java +++ b/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java @@ -515,6 +515,7 @@ public abstract class X11SurfaceData extends XSurfaceData { return getSurfaceType(gc, transparency, false); } + @SuppressWarnings("fallthrough") public static SurfaceType getSurfaceType(X11GraphicsConfig gc, int transparency, boolean pixmapSurface) From f341bacaf3da00f13c04a1bd03480ae1266eb05c Mon Sep 17 00:00:00 2001 From: Joe Darcy <darcy@openjdk.org> Date: Tue, 22 Apr 2014 17:55:25 -0700 Subject: [PATCH 019/157] 8039860: Fix fallthrough lint warnings in swing Reviewed-by: malenkov --- .../com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java | 1 + .../java/swing/plaf/windows/WindowsLookAndFeel.java | 1 + .../java/swing/plaf/windows/WindowsTableHeaderUI.java | 2 +- .../javax/swing/plaf/metal/MetalLookAndFeel.java | 3 ++- .../share/classes/javax/swing/text/JTextComponent.java | 1 + .../classes/javax/swing/text/html/StyleSheet.java | 1 + .../swing/text/html/parser/ContentModelState.java | 4 +++- .../classes/javax/swing/text/html/parser/Parser.java | 10 ++++++++++ .../classes/javax/swing/text/rtf/RTFGenerator.java | 3 ++- .../share/classes/javax/swing/text/rtf/RTFParser.java | 3 ++- 10 files changed, 24 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java index d86b4ec92ac..b35e60d7ec6 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java @@ -1683,6 +1683,7 @@ public class GTKLookAndFeel extends SynthLookAndFeel { * adjustments that windows/metal do. This is because gtk doesn't * provide margins/insets for checkbox/radiobuttons. */ + @SuppressWarnings("fallthrough") private static class GnomeLayoutStyle extends DefaultLayoutStyle { private static GnomeLayoutStyle INSTANCE = new GnomeLayoutStyle(); diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java index 00530fa19ea..a6c1c895757 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java @@ -2409,6 +2409,7 @@ public class WindowsLookAndFeel extends BasicLookAndFeel // Windows LayoutStyle. From: // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwue/html/ch14e.asp + @SuppressWarnings("fallthrough") private class WindowsLayoutStyle extends DefaultLayoutStyle { @Override public int getPreferredGap(JComponent component1, diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java index c5101177f40..117e9d7b7b1 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java @@ -182,7 +182,6 @@ public class WindowsTableHeaderUI extends BasicTableHeaderUI { if (sortOrder != null) { switch(sortOrder) { case ASCENDING: - /* falls through */ case DESCENDING: switch (state) { case NORMAL: @@ -197,6 +196,7 @@ public class WindowsTableHeaderUI extends BasicTableHeaderUI { default: /* do nothing */ } + break; default : /* do nothing */ } diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java index 6a64676673b..b1aea28c79f 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java @@ -2271,6 +2271,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel // From the JLF Design Guidelines: // http://www.oracle.com/technetwork/java/jlf-135985.html + @SuppressWarnings("fallthrough") private static class MetalLayoutStyle extends DefaultLayoutStyle { private static MetalLayoutStyle INSTANCE = new MetalLayoutStyle(); @@ -2407,4 +2408,4 @@ public class MetalLookAndFeel extends BasicLookAndFeel return 0; } } -} \ No newline at end of file +} diff --git a/jdk/src/share/classes/javax/swing/text/JTextComponent.java b/jdk/src/share/classes/javax/swing/text/JTextComponent.java index 94f950eb88b..ca3c9ebef1a 100644 --- a/jdk/src/share/classes/javax/swing/text/JTextComponent.java +++ b/jdk/src/share/classes/javax/swing/text/JTextComponent.java @@ -4473,6 +4473,7 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A // composed(uncommitted) text is done here after all input // method listeners get called for stealing the events. // + @SuppressWarnings("fallthrough") protected void processInputMethodEvent(InputMethodEvent e) { // let listeners handle the events super.processInputMethodEvent(e); diff --git a/jdk/src/share/classes/javax/swing/text/html/StyleSheet.java b/jdk/src/share/classes/javax/swing/text/html/StyleSheet.java index de0f2b91fe5..4c5d8d95ce5 100644 --- a/jdk/src/share/classes/javax/swing/text/html/StyleSheet.java +++ b/jdk/src/share/classes/javax/swing/text/html/StyleSheet.java @@ -2324,6 +2324,7 @@ public class StyleSheet extends StyleContext { * @param itemNum number to format * @param type type of ordered list */ + @SuppressWarnings("fallthrough") String formatItemNum(int itemNum, char type) { String numStyle = "1"; diff --git a/jdk/src/share/classes/javax/swing/text/html/parser/ContentModelState.java b/jdk/src/share/classes/javax/swing/text/html/parser/ContentModelState.java index fb623981fcc..3bc9825d9c0 100644 --- a/jdk/src/share/classes/javax/swing/text/html/parser/ContentModelState.java +++ b/jdk/src/share/classes/javax/swing/text/html/parser/ContentModelState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2000, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,12 +92,14 @@ class ContentModelState { * tokens required in the input stream. * @return true if the model can terminate without further input */ + @SuppressWarnings("fallthrough") public boolean terminate() { switch (model.type) { case '+': if ((value == 0) && !(model).empty()) { return false; } + // Fall through case '*': case '?': return (next == null) || next.terminate(); diff --git a/jdk/src/share/classes/javax/swing/text/html/parser/Parser.java b/jdk/src/share/classes/javax/swing/text/html/parser/Parser.java index 79124461f9c..0963b4b6dc9 100644 --- a/jdk/src/share/classes/javax/swing/text/html/parser/Parser.java +++ b/jdk/src/share/classes/javax/swing/text/html/parser/Parser.java @@ -852,6 +852,7 @@ class Parser implements DTDConstants { if (lower) { ch = 'a' + (ch - 'A'); } + break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': @@ -876,6 +877,7 @@ class Parser implements DTDConstants { if (lower) { ch = 'a' + (ch - 'A'); } + break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': @@ -1214,6 +1216,7 @@ class Parser implements DTDConstants { /** * Parse attribute value. [33] 331:1 */ + @SuppressWarnings("fallthrough") String parseAttributeValue(boolean lower) throws IOException { int delim = -1; @@ -1258,6 +1261,7 @@ class Parser implements DTDConstants { case '\t': if (delim < 0) c = ' '; + // Fall through case ' ': ch = readCh(); if (delim < 0) { @@ -1559,6 +1563,7 @@ class Parser implements DTDConstants { /** * Parse a start or end tag. */ + @SuppressWarnings("fallthrough") void parseTag() throws IOException { Element elem; boolean net = false; @@ -1602,6 +1607,7 @@ class Parser implements DTDConstants { continue; case '>': ch = readCh(); + return; case -1: return; default: @@ -1626,6 +1632,7 @@ class Parser implements DTDConstants { switch(ch) { case '>': ch = readCh(); + // Fall through case -1: error("invalid.markup"); return; @@ -1657,6 +1664,7 @@ class Parser implements DTDConstants { switch (ch = readCh()) { case '>': ch = readCh(); + // Fall through case '<': // empty end tag. either </> or </< if (recent == null) { @@ -1675,6 +1683,7 @@ class Parser implements DTDConstants { switch (ch) { case '>': ch = readCh(); + break; case '<': break; @@ -1875,6 +1884,7 @@ class Parser implements DTDConstants { switch (ch) { case '/': net = true; + // Fall through case '>': ch = readCh(); if (ch == '>' && net) { diff --git a/jdk/src/share/classes/javax/swing/text/rtf/RTFGenerator.java b/jdk/src/share/classes/javax/swing/text/rtf/RTFGenerator.java index 38b2b7ad864..7aba1408039 100644 --- a/jdk/src/share/classes/javax/swing/text/rtf/RTFGenerator.java +++ b/jdk/src/share/classes/javax/swing/text/rtf/RTFGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -868,6 +868,7 @@ public void writeEndgroup() afterKeyword = false; } +@SuppressWarnings("fallthrough") public void writeCharacter(char ch) throws IOException { diff --git a/jdk/src/share/classes/javax/swing/text/rtf/RTFParser.java b/jdk/src/share/classes/javax/swing/text/rtf/RTFParser.java index a251552d76c..2b4969dda1e 100644 --- a/jdk/src/share/classes/javax/swing/text/rtf/RTFParser.java +++ b/jdk/src/share/classes/javax/swing/text/rtf/RTFParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -148,6 +148,7 @@ abstract class RTFParser extends AbstractFilter handleText(s); } + @SuppressWarnings("fallthrough") public void write(char ch) throws IOException { From 1b4d763c777d1ba965d002892051b9a249055b2d Mon Sep 17 00:00:00 2001 From: Petr Pchelko <pchelko@openjdk.org> Date: Wed, 23 Apr 2014 17:56:05 +0400 Subject: [PATCH 020/157] 8027148: SystemFlavorMap.getNativesForFlavor returns list of native formats in incorrect order Reviewed-by: anthony, serb --- .../awt/datatransfer/SystemFlavorMap.java | 359 ++++++++---------- .../sun/awt/datatransfer/DataTransferer.java | 25 +- .../classes/sun/awt/X11/XDataTransferer.java | 9 +- .../MappingGenerationTest.java | 183 +++++++++ 4 files changed, 344 insertions(+), 232 deletions(-) create mode 100644 jdk/test/java/awt/datatransfer/MappingGenerationTest/MappingGenerationTest.java diff --git a/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java b/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java index bc6e1642001..fd54c9414a0 100644 --- a/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java +++ b/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java @@ -38,13 +38,14 @@ import java.net.URL; import java.net.MalformedURLException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; -import java.util.WeakHashMap; import sun.awt.AppContext; import sun.awt.datatransfer.DataTransferer; @@ -101,20 +102,12 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { */ private static final String HTML_TEXT_BASE_TYPE = "text/html"; - /** - * This constant is passed to flavorToNativeLookup() to indicate that a - * a native should be synthesized, stored, and returned by encoding the - * DataFlavor's MIME type in case if the DataFlavor is not found in - * 'flavorToNative' map. - */ - private static final boolean SYNTHESIZE_IF_NOT_FOUND = true; - /** * Maps native Strings to Lists of DataFlavors (or base type Strings for * text DataFlavors). * Do not use the field directly, use getNativeToFlavor() instead. */ - private final Map<String, List<DataFlavor>> nativeToFlavor = new HashMap<>(); + private final Map<String, LinkedHashSet<DataFlavor>> nativeToFlavor = new HashMap<>(); /** * Accessor to nativeToFlavor map. Since we use lazy initialization we must @@ -123,7 +116,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * * @return nativeToFlavor */ - private Map<String, List<DataFlavor>> getNativeToFlavor() { + private Map<String, LinkedHashSet<DataFlavor>> getNativeToFlavor() { if (!isMapInitialized) { initSystemFlavorMap(); } @@ -135,7 +128,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * native Strings. * Do not use the field directly, use getFlavorToNative() instead. */ - private final Map<DataFlavor, List<String>> flavorToNative = new HashMap<>(); + private final Map<DataFlavor, LinkedHashSet<String>> flavorToNative = new HashMap<>(); /** * Accessor to flavorToNative map. Since we use lazy initialization we must @@ -144,29 +137,52 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * * @return flavorToNative */ - private synchronized Map<DataFlavor, List<String>> getFlavorToNative() { + private synchronized Map<DataFlavor, LinkedHashSet<String>> getFlavorToNative() { if (!isMapInitialized) { initSystemFlavorMap(); } return flavorToNative; } + /** + * Maps a text DataFlavor primary mime-type to the native. Used only to store + * standard mappings registered in the flavormap.properties + * Do not use this field directly, use getTextTypeToNative() instead. + */ + private Map<String, LinkedHashSet<String>> textTypeToNative = new HashMap<>(); + /** * Shows if the object has been initialized. */ private boolean isMapInitialized = false; /** - * Caches the result of getNativesForFlavor(). Maps DataFlavors to - * SoftReferences which reference Lists of String natives. + * An accessor to textTypeToNative map. Since we use lazy initialization we + * must use this accessor instead of direct access to the field which may not + * be initialized yet. This method will initialize the field if needed. + * + * @return textTypeToNative */ - private Map<DataFlavor, SoftReference<List<String>>> getNativesForFlavorCache = new HashMap<>(); + private synchronized Map<String, LinkedHashSet<String>> getTextTypeToNative() { + if (!isMapInitialized) { + initSystemFlavorMap(); + // From this point the map should not be modified + textTypeToNative = Collections.unmodifiableMap(textTypeToNative); + } + return textTypeToNative; + } + + /** + * Caches the result of getNativesForFlavor(). Maps DataFlavors to + * SoftReferences which reference LinkedHashSet of String natives. + */ + private final SoftCache<DataFlavor, String> nativesForFlavorCache = new SoftCache<>(); /** * Caches the result getFlavorsForNative(). Maps String natives to - * SoftReferences which reference Lists of DataFlavors. + * SoftReferences which reference LinkedHashSet of DataFlavors. */ - private Map<String, SoftReference<List<DataFlavor>>> getFlavorsForNativeCache = new HashMap<>(); + private final SoftCache<String, DataFlavor> flavorsForNativeCache = new SoftCache<>(); /** * Dynamic mapping generation used for text mappings should not be applied @@ -174,7 +190,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * explicitly specified with setFlavorsForNative() or * setNativesForFlavor(). This keeps all such keys. */ - private Set disabledMappingGenerationKeys = new HashSet(); + private Set<Object> disabledMappingGenerationKeys = new HashSet<>(); /** * Returns the default FlavorMap for this thread's ClassLoader. @@ -404,7 +420,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { flavor = new DataFlavor(value); } catch (Exception e) { try { - flavor = new DataFlavor(value, (String)null); + flavor = new DataFlavor(value, null); } catch (Exception ee) { ee.printStackTrace(); continue; @@ -412,11 +428,11 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } final LinkedHashSet<DataFlavor> dfs = new LinkedHashSet<>(); - dfs.add(flavor); if ("text".equals(flavor.getPrimaryType())) { dfs.addAll(convertMimeTypeToDataFlavors(value)); + store(flavor.mimeType.getBaseType(), key, getTextTypeToNative()); } for (DataFlavor df : dfs) { @@ -505,10 +521,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * the appropriate Map location, but rather will be appended to a List * stored in that location. */ - private <H, L> void store(H hashed, L listed, Map<H, List<L>> map) { - List<L> list = map.get(hashed); + private <H, L> void store(H hashed, L listed, Map<H, LinkedHashSet<L>> map) { + LinkedHashSet<L> list = map.get(hashed); if (list == null) { - list = new ArrayList<>(1); + list = new LinkedHashSet<>(1); map.put(hashed, list); } if (!list.contains(listed)) { @@ -522,17 +538,16 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * case, a new DataFlavor is synthesized, stored, and returned, if and * only if the specified native is encoded as a Java MIME type. */ - private List<DataFlavor> nativeToFlavorLookup(String nat) { - List<DataFlavor> flavors = getNativeToFlavor().get(nat); + private LinkedHashSet<DataFlavor> nativeToFlavorLookup(String nat) { + LinkedHashSet<DataFlavor> flavors = getNativeToFlavor().get(nat); if (nat != null && !disabledMappingGenerationKeys.contains(nat)) { DataTransferer transferer = DataTransferer.getInstance(); if (transferer != null) { - List<DataFlavor> platformFlavors = + LinkedHashSet<DataFlavor> platformFlavors = transferer.getPlatformMappingsForNative(nat); if (!platformFlavors.isEmpty()) { if (flavors != null) { - platformFlavors.removeAll(new HashSet<>(flavors)); // Prepending the platform-specific mappings ensures // that the flavors added with // addFlavorForUnencodedNative() are at the end of @@ -558,24 +573,22 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } if (flavor != null) { - flavors = new ArrayList<>(1); + flavors = new LinkedHashSet<>(1); getNativeToFlavor().put(nat, flavors); flavors.add(flavor); - getFlavorsForNativeCache.remove(nat); - getFlavorsForNativeCache.remove(null); + flavorsForNativeCache.remove(nat); - List<String> natives = getFlavorToNative().get(flavor); + LinkedHashSet<String> natives = getFlavorToNative().get(flavor); if (natives == null) { - natives = new ArrayList<>(1); + natives = new LinkedHashSet<>(1); getFlavorToNative().put(flavor, natives); } natives.add(nat); - getNativesForFlavorCache.remove(flavor); - getNativesForFlavorCache.remove(null); + nativesForFlavorCache.remove(flavor); } } - return (flavors != null) ? flavors : new ArrayList<>(0); + return (flavors != null) ? flavors : new LinkedHashSet<>(0); } /** @@ -586,18 +599,18 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * encoding the DataFlavor's MIME type. Otherwise an empty List is returned * and 'flavorToNative' remains unaffected. */ - private List<String> flavorToNativeLookup(final DataFlavor flav, - final boolean synthesize) { - List<String> natives = getFlavorToNative().get(flav); + private LinkedHashSet<String> flavorToNativeLookup(final DataFlavor flav, + final boolean synthesize) { + + LinkedHashSet<String> natives = getFlavorToNative().get(flav); if (flav != null && !disabledMappingGenerationKeys.contains(flav)) { DataTransferer transferer = DataTransferer.getInstance(); if (transferer != null) { - List<String> platformNatives = + LinkedHashSet<String> platformNatives = transferer.getPlatformMappingsForFlavor(flav); if (!platformNatives.isEmpty()) { if (natives != null) { - platformNatives.removeAll(new HashSet<>(natives)); // Prepend the platform-specific mappings to ensure // that the natives added with // addUnencodedNativeForFlavor() are at the end of @@ -612,26 +625,25 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { if (natives == null) { if (synthesize) { String encoded = encodeDataFlavor(flav); - natives = new ArrayList<>(1); + natives = new LinkedHashSet<>(1); getFlavorToNative().put(flav, natives); natives.add(encoded); - getNativesForFlavorCache.remove(flav); - getNativesForFlavorCache.remove(null); - List<DataFlavor> flavors = getNativeToFlavor().get(encoded); + LinkedHashSet<DataFlavor> flavors = getNativeToFlavor().get(encoded); if (flavors == null) { - flavors = new ArrayList<>(1); + flavors = new LinkedHashSet<>(1); getNativeToFlavor().put(encoded, flavors); } flavors.add(flav); - getFlavorsForNativeCache.remove(encoded); - getFlavorsForNativeCache.remove(null); + + nativesForFlavorCache.remove(flav); + flavorsForNativeCache.remove(encoded); } else { - natives = new ArrayList<>(0); + natives = new LinkedHashSet<>(0); } } - return natives; + return new LinkedHashSet<>(natives); } /** @@ -659,103 +671,63 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * @see #encodeDataFlavor * @since 1.4 */ + @Override public synchronized List<String> getNativesForFlavor(DataFlavor flav) { - List<String> retval = null; - - // Check cache, even for null flav - SoftReference<List<String>> ref = getNativesForFlavorCache.get(flav); - if (ref != null) { - retval = ref.get(); - if (retval != null) { - // Create a copy, because client code can modify the returned - // list. - return new ArrayList<>(retval); - } + LinkedHashSet<String> retval = nativesForFlavorCache.check(flav); + if (retval != null) { + return new ArrayList<>(retval); } if (flav == null) { - retval = new ArrayList<>(getNativeToFlavor().keySet()); + retval = new LinkedHashSet<>(getNativeToFlavor().keySet()); } else if (disabledMappingGenerationKeys.contains(flav)) { // In this case we shouldn't synthesize a native for this flavor, // since its mappings were explicitly specified. - retval = flavorToNativeLookup(flav, !SYNTHESIZE_IF_NOT_FOUND); + retval = flavorToNativeLookup(flav, false); } else if (DataTransferer.isFlavorCharsetTextType(flav)) { + retval = new LinkedHashSet<>(0); // For text/* flavors, flavor-to-native mappings specified in // flavormap.properties are stored per flavor's base type. if ("text".equals(flav.getPrimaryType())) { - retval = getAllNativesForType(flav.mimeType.getBaseType()); - if (retval != null) { - // To prevent the List stored in the map from modification. - retval = new ArrayList(retval); + LinkedHashSet<String> textTypeNatives = + getTextTypeToNative().get(flav.mimeType.getBaseType()); + if (textTypeNatives != null) { + retval.addAll(textTypeNatives); } } // Also include text/plain natives, but don't duplicate Strings - List<String> textPlainList = getAllNativesForType(TEXT_PLAIN_BASE_TYPE); - - if (textPlainList != null && !textPlainList.isEmpty()) { - // To prevent the List stored in the map from modification. - // This also guarantees that removeAll() is supported. - textPlainList = new ArrayList<>(textPlainList); - if (retval != null && !retval.isEmpty()) { - // Use HashSet to get constant-time performance for search. - textPlainList.removeAll(new HashSet<>(retval)); - retval.addAll(textPlainList); - } else { - retval = textPlainList; - } + LinkedHashSet<String> textTypeNatives = + getTextTypeToNative().get(TEXT_PLAIN_BASE_TYPE); + if (textTypeNatives != null) { + retval.addAll(textTypeNatives); } - if (retval == null || retval.isEmpty()) { - retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND); + if (retval.isEmpty()) { + retval = flavorToNativeLookup(flav, true); } else { // In this branch it is guaranteed that natives explicitly // listed for flav's MIME type were added with // addUnencodedNativeForFlavor(), so they have lower priority. - List<String> explicitList = - flavorToNativeLookup(flav, !SYNTHESIZE_IF_NOT_FOUND); - - // flavorToNativeLookup() never returns null. - // It can return an empty List, however. - if (!explicitList.isEmpty()) { - // To prevent the List stored in the map from modification. - // This also guarantees that removeAll() is supported. - explicitList = new ArrayList<>(explicitList); - // Use HashSet to get constant-time performance for search. - explicitList.removeAll(new HashSet<>(retval)); - retval.addAll(explicitList); - } + retval.addAll(flavorToNativeLookup(flav, false)); } } else if (DataTransferer.isFlavorNoncharsetTextType(flav)) { - retval = getAllNativesForType(flav.mimeType.getBaseType()); + retval = getTextTypeToNative().get(flav.mimeType.getBaseType()); if (retval == null || retval.isEmpty()) { - retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND); + retval = flavorToNativeLookup(flav, true); } else { // In this branch it is guaranteed that natives explicitly // listed for flav's MIME type were added with // addUnencodedNativeForFlavor(), so they have lower priority. - List<String> explicitList = - flavorToNativeLookup(flav, !SYNTHESIZE_IF_NOT_FOUND); - - // flavorToNativeLookup() never returns null. - // It can return an empty List, however. - if (!explicitList.isEmpty()) { - // To prevent the List stored in the map from modification. - // This also guarantees that add/removeAll() are supported. - retval = new ArrayList<>(retval); - explicitList = new ArrayList<>(explicitList); - // Use HashSet to get constant-time performance for search. - explicitList.removeAll(new HashSet<>(retval)); - retval.addAll(explicitList); - } + retval.addAll(flavorToNativeLookup(flav, false)); } } else { - retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND); + retval = flavorToNativeLookup(flav, true); } - getNativesForFlavorCache.put(flav, new SoftReference<>(retval)); + nativesForFlavorCache.put(flav, retval); // Create a copy, because client code can modify the returned list. return new ArrayList<>(retval); } @@ -791,62 +763,38 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * @see #encodeJavaMIMEType * @since 1.4 */ + @Override public synchronized List<DataFlavor> getFlavorsForNative(String nat) { - - // Check cache, even for null nat - SoftReference<List<DataFlavor>> ref = getFlavorsForNativeCache.get(nat); - if (ref != null) { - List<DataFlavor> retval = ref.get(); - if (retval != null) { - return new ArrayList<>(retval); - } + LinkedHashSet<DataFlavor> returnValue = flavorsForNativeCache.check(nat); + if (returnValue != null) { + return new ArrayList<>(returnValue); + } else { + returnValue = new LinkedHashSet<>(); } - final LinkedHashSet <DataFlavor> returnValue = - new LinkedHashSet<>(); - if (nat == null) { - final List<String> natives = getNativesForFlavor(null); - - for (String n : natives) - { - final List<DataFlavor> flavors = getFlavorsForNative(n); - - for (DataFlavor df : flavors) - { - returnValue.add(df); - } + for (String n : getNativesForFlavor(null)) { + returnValue.addAll(getFlavorsForNative(n)); } } else { - - final List<DataFlavor> flavors = nativeToFlavorLookup(nat); - + final LinkedHashSet<DataFlavor> flavors = nativeToFlavorLookup(nat); if (disabledMappingGenerationKeys.contains(nat)) { - return flavors; + return new ArrayList<>(flavors); } - final List<DataFlavor> flavorsAndBaseTypes = - nativeToFlavorLookup(nat); + final LinkedHashSet<DataFlavor> flavorsWithSynthesized = + nativeToFlavorLookup(nat); - for (DataFlavor df : flavorsAndBaseTypes) { + for (DataFlavor df : flavorsWithSynthesized) { returnValue.add(df); if ("text".equals(df.getPrimaryType())) { - try { - returnValue.addAll( - convertMimeTypeToDataFlavors( - new MimeType(df.getMimeType() - ).getBaseType())); - } catch (MimeTypeParseException e) { - e.printStackTrace(); - } + String baseType = df.mimeType.getBaseType(); + returnValue.addAll(convertMimeTypeToDataFlavors(baseType)); } } - } - - final List<DataFlavor> arrayList = new ArrayList<>(returnValue); - getFlavorsForNativeCache.put(nat, new SoftReference<>(arrayList)); - return new ArrayList<>(arrayList); + flavorsForNativeCache.put(nat, returnValue); + return new ArrayList<>(returnValue); } private static Set<DataFlavor> convertMimeTypeToDataFlavors( @@ -862,7 +810,6 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } catch (MimeTypeParseException mtpe) { // Cannot happen, since we checked all mappings // on load from flavormap.properties. - assert(false); } if (DataTransferer.doesSubtypeSupportCharset(subType, null)) { @@ -941,10 +888,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } private static final String [] htmlDocumntTypes = - new String [] {"all", "selection", "fragment"}; + new String [] {"all", "selection", "fragment"}; - private static LinkedHashSet<String> handleHtmlMimeTypes( - String baseType, String mimeType) { + private static LinkedHashSet<String> handleHtmlMimeTypes(String baseType, + String mimeType) { LinkedHashSet<String> returnValues = new LinkedHashSet<>(); @@ -981,14 +928,14 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * @see #getNativesForFlavor * @see #encodeDataFlavor */ - public synchronized Map<DataFlavor,String> - getNativesForFlavors(DataFlavor[] flavors) + @Override + public synchronized Map<DataFlavor,String> getNativesForFlavors(DataFlavor[] flavors) { // Use getNativesForFlavor to generate extra natives for text flavors // and stringFlavor if (flavors == null) { - List flavor_list = getFlavorsForNative(null); + List<DataFlavor> flavor_list = getFlavorsForNative(null); flavors = new DataFlavor[flavor_list.size()]; flavor_list.toArray(flavors); } @@ -1027,15 +974,14 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * @see #getFlavorsForNative * @see #encodeJavaMIMEType */ - public synchronized Map<String,DataFlavor> - getFlavorsForNatives(String[] natives) + @Override + public synchronized Map<String,DataFlavor> getFlavorsForNatives(String[] natives) { // Use getFlavorsForNative to generate extra flavors for text natives - if (natives == null) { - List native_list = getNativesForFlavor(null); - natives = new String[native_list.size()]; - native_list.toArray(natives); + List<String> nativesList = getNativesForFlavor(null); + natives = new String[nativesList.size()]; + nativesList.toArray(natives); } Map<String, DataFlavor> retval = new HashMap<>(natives.length, 1.0f); @@ -1044,7 +990,6 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { DataFlavor flav = (flavors.isEmpty())? null : flavors.get(0); retval.put(aNative, flav); } - return retval; } @@ -1070,20 +1015,16 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { */ public synchronized void addUnencodedNativeForFlavor(DataFlavor flav, String nat) { - if (flav == null || nat == null) { - throw new NullPointerException("null arguments not permitted"); - } + Objects.requireNonNull(nat, "Null native not permitted"); + Objects.requireNonNull(flav, "Null flavor not permitted"); - List<String> natives = getFlavorToNative().get(flav); + LinkedHashSet<String> natives = getFlavorToNative().get(flav); if (natives == null) { - natives = new ArrayList<>(1); + natives = new LinkedHashSet<>(1); getFlavorToNative().put(flav, natives); - } else if (natives.contains(nat)) { - return; } natives.add(nat); - getNativesForFlavorCache.remove(flav); - getNativesForFlavorCache.remove(null); + nativesForFlavorCache.remove(flav); } /** @@ -1116,18 +1057,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { */ public synchronized void setNativesForFlavor(DataFlavor flav, String[] natives) { - if (flav == null || natives == null) { - throw new NullPointerException("null arguments not permitted"); - } + Objects.requireNonNull(natives, "Null natives not permitted"); + Objects.requireNonNull(flav, "Null flavors not permitted"); getFlavorToNative().remove(flav); for (String aNative : natives) { addUnencodedNativeForFlavor(flav, aNative); } disabledMappingGenerationKeys.add(flav); - // Clear the cache to handle the case of empty natives. - getNativesForFlavorCache.remove(flav); - getNativesForFlavorCache.remove(null); + nativesForFlavorCache.remove(flav); } /** @@ -1150,20 +1088,16 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { */ public synchronized void addFlavorForUnencodedNative(String nat, DataFlavor flav) { - if (nat == null || flav == null) { - throw new NullPointerException("null arguments not permitted"); - } + Objects.requireNonNull(nat, "Null native not permitted"); + Objects.requireNonNull(flav, "Null flavor not permitted"); - List<DataFlavor> flavors = getNativeToFlavor().get(nat); + LinkedHashSet<DataFlavor> flavors = getNativeToFlavor().get(nat); if (flavors == null) { - flavors = new ArrayList<>(1); + flavors = new LinkedHashSet<>(1); getNativeToFlavor().put(nat, flavors); - } else if (flavors.contains(flav)) { - return; } flavors.add(flav); - getFlavorsForNativeCache.remove(nat); - getFlavorsForNativeCache.remove(null); + flavorsForNativeCache.remove(nat); } /** @@ -1195,18 +1129,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { */ public synchronized void setFlavorsForNative(String nat, DataFlavor[] flavors) { - if (nat == null || flavors == null) { - throw new NullPointerException("null arguments not permitted"); - } + Objects.requireNonNull(nat, "Null native not permitted"); + Objects.requireNonNull(flavors, "Null flavors not permitted"); getNativeToFlavor().remove(nat); for (DataFlavor flavor : flavors) { addFlavorForUnencodedNative(nat, flavor); } disabledMappingGenerationKeys.add(nat); - // Clear the cache to handle the case of empty flavors. - getFlavorsForNativeCache.remove(nat); - getFlavorsForNativeCache.remove(null); + flavorsForNativeCache.remove(nat); } /** @@ -1307,17 +1238,29 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { : null; } - private List<String> getAllNativesForType(String type) { - Set<String> retval = null; - for (DataFlavor dataFlavor : convertMimeTypeToDataFlavors(type)) { - List<String> natives = getFlavorToNative().get(dataFlavor); - if (natives != null && !natives.isEmpty()) { - if (retval == null) { - retval = new LinkedHashSet<>(); - } - retval.addAll(natives); + private static final class SoftCache<K, V> { + Map<K, SoftReference<LinkedHashSet<V>>> cache; + + public void put(K key, LinkedHashSet<V> value) { + if (cache == null) { + cache = new HashMap<>(1); } + cache.put(key, new SoftReference<>(value)); + } + + public void remove(K key) { + if (cache == null) return; + cache.remove(null); + cache.remove(key); + } + + public LinkedHashSet<V> check(K key) { + if (cache == null) return null; + SoftReference<LinkedHashSet<V>> ref = cache.get(key); + if (ref != null) { + return ref.get(); + } + return null; } - return retval == null ? null : new ArrayList<>(retval); } } diff --git a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java index b4b658a6166..3f22bd86fe9 100644 --- a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java +++ b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java @@ -70,22 +70,7 @@ import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.security.ProtectionDomain; -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.SortedMap; -import java.util.SortedSet; -import java.util.Set; -import java.util.Stack; -import java.util.TreeMap; -import java.util.TreeSet; +import java.util.*; import sun.util.logging.PlatformLogger; @@ -2267,8 +2252,8 @@ search: * If there are no platform-specific mappings for this native, the method * returns an empty <code>List</code>. */ - public List<DataFlavor> getPlatformMappingsForNative(String nat) { - return new ArrayList<>(); + public LinkedHashSet<DataFlavor> getPlatformMappingsForNative(String nat) { + return new LinkedHashSet<>(); } /** @@ -2276,8 +2261,8 @@ search: * If there are no platform-specific mappings for this flavor, the method * returns an empty <code>List</code>. */ - public List<String> getPlatformMappingsForFlavor(DataFlavor df) { - return new ArrayList<>(); + public LinkedHashSet<String> getPlatformMappingsForFlavor(DataFlavor df) { + return new LinkedHashSet<>(); } /** diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java b/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java index f54bc87c337..554e19507dc 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java @@ -45,6 +45,7 @@ import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import javax.imageio.ImageIO; @@ -330,8 +331,8 @@ public class XDataTransferer extends DataTransferer { * type can be translated by the Data Transfer subsystem. */ @Override - public List<DataFlavor> getPlatformMappingsForNative(String nat) { - List<DataFlavor> flavors = new ArrayList<>(); + public LinkedHashSet<DataFlavor> getPlatformMappingsForNative(String nat) { + LinkedHashSet<DataFlavor> flavors = new LinkedHashSet<>(); if (nat == null) { return flavors; @@ -392,8 +393,8 @@ public class XDataTransferer extends DataTransferer { * Transfer subsystem. */ @Override - public List<String> getPlatformMappingsForFlavor(DataFlavor df) { - List<String> natives = new ArrayList<>(1); + public LinkedHashSet<String> getPlatformMappingsForFlavor(DataFlavor df) { + LinkedHashSet<String> natives = new LinkedHashSet<>(1); if (df == null) { return natives; diff --git a/jdk/test/java/awt/datatransfer/MappingGenerationTest/MappingGenerationTest.java b/jdk/test/java/awt/datatransfer/MappingGenerationTest/MappingGenerationTest.java new file mode 100644 index 00000000000..b0d8587afa3 --- /dev/null +++ b/jdk/test/java/awt/datatransfer/MappingGenerationTest/MappingGenerationTest.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.SystemFlavorMap; +import java.util.List; + +/* + @test + @bug 4512530 8027148 + @summary tests that mappings for text flavors are generated properly + @author das@sparc.spb.su area=datatransfer +*/ + +public class MappingGenerationTest { + + private static final SystemFlavorMap fm = + (SystemFlavorMap)SystemFlavorMap.getDefaultFlavorMap(); + + public static void main(String[] args) { + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + } + + /** + * Verifies that Lists returned from getNativesForFlavor() and + * getFlavorsForNative() are not modified with a subsequent call + * to addUnencodedNativeForFlavor() and addFlavorForUnencodedNative() + * respectively. + */ + public static void test1() { + DataFlavor df = new DataFlavor("text/plain-test1", null); + String nat = "native1"; + + List<String> natives = fm.getNativesForFlavor(df); + fm.addUnencodedNativeForFlavor(df, nat); + List<String> nativesNew = fm.getNativesForFlavor(df); + if (natives.equals(nativesNew)) { + System.err.println("orig=" + natives); + System.err.println("new=" + nativesNew); + throw new RuntimeException("Test failed"); + } + + List<DataFlavor> flavors = fm.getFlavorsForNative(nat); + fm.addFlavorForUnencodedNative(nat, df); + List<DataFlavor> flavorsNew = fm.getFlavorsForNative(nat); + if (flavors.equals(flavorsNew)) { + System.err.println("orig=" + flavors); + System.err.println("new=" + flavorsNew); + throw new RuntimeException("Test failed"); + } + } + + /** + * Verifies that SystemFlavorMap is not affected by modification of + * the Lists returned from getNativesForFlavor() and + * getFlavorsForNative(). + */ + public static void test2() { + DataFlavor df = new DataFlavor("text/plain-test2", null); + String nat = "native2"; + DataFlavor extraDf = new DataFlavor("text/test", null); + + List<String> natives = fm.getNativesForFlavor(df); + natives.add("Should not be here"); + java.util.List nativesNew = fm.getNativesForFlavor(df); + if (natives.equals(nativesNew)) { + System.err.println("orig=" + natives); + System.err.println("new=" + nativesNew); + throw new RuntimeException("Test failed"); + } + + List<DataFlavor> flavors = fm.getFlavorsForNative(nat); + flavors.add(extraDf); + java.util.List flavorsNew = fm.getFlavorsForNative(nat); + if (flavors.equals(flavorsNew)) { + System.err.println("orig=" + flavors); + System.err.println("new=" + flavorsNew); + throw new RuntimeException("Test failed"); + } + } + + /** + * Verifies that addUnencodedNativeForFlavor() for a particular text flavor + * doesn't affect mappings for other flavors. + */ + public static void test3() { + DataFlavor df1 = new DataFlavor("text/plain-test3", null); + DataFlavor df2 = new DataFlavor("text/plain-test3; charset=Unicode; class=java.io.Reader", null); + String nat = "native3"; + List<String> natives = fm.getNativesForFlavor(df2); + fm.addUnencodedNativeForFlavor(df1, nat); + List<String> nativesNew = fm.getNativesForFlavor(df2); + if (!natives.equals(nativesNew)) { + System.err.println("orig=" + natives); + System.err.println("new=" + nativesNew); + throw new RuntimeException("Test failed"); + } + } + + /** + * Verifies that addUnencodedNativeForFlavor() really adds the specified + * flavor-to-native mapping to the existing mappings. + */ + public static void test4() { + DataFlavor df = new DataFlavor("text/plain-test4; charset=Unicode; class=java.io.Reader", null); + String nat = "native4"; + List<String> natives = fm.getNativesForFlavor(df); + if (!natives.contains(nat)) { + fm.addUnencodedNativeForFlavor(df, nat); + List<String> nativesNew = fm.getNativesForFlavor(df); + natives.add(nat); + if (!natives.equals(nativesNew)) { + System.err.println("orig=" + natives); + System.err.println("new=" + nativesNew); + throw new RuntimeException("Test failed"); + } + } + } + + /** + * Verifies that a flavor doesn't have any flavor-to-native mappings after + * a call to setNativesForFlavor() with this flavor and an empty native + * array as arguments. + */ + public static void test5() { + final DataFlavor flavor = + new DataFlavor("text/plain-TEST5; charset=Unicode", null); + + fm.getNativesForFlavor(flavor); + + fm.setNativesForFlavor(flavor, new String[0]); + + List<String> natives = fm.getNativesForFlavor(flavor); + + if (!natives.isEmpty()) { + System.err.println("natives=" + natives); + throw new RuntimeException("Test failed"); + } + } + + /** + * Verifies that a native doesn't have any native-to-flavor mappings after + * a call to setFlavorsForNative() with this native and an empty flavor + * array as arguments. + */ + public static void test6() { + final String nat = "STRING"; + fm.getFlavorsForNative(nat); + fm.setFlavorsForNative(nat, new DataFlavor[0]); + + List<DataFlavor> flavors = fm.getFlavorsForNative(nat); + + if (!flavors.isEmpty()) { + System.err.println("flavors=" + flavors); + throw new RuntimeException("Test failed"); + } + } +} From 39ba3c9ea6f296f0dd966bf69808e3a7c9c68bbc Mon Sep 17 00:00:00 2001 From: Petr Pchelko <pchelko@openjdk.org> Date: Wed, 23 Apr 2014 18:07:12 +0400 Subject: [PATCH 021/157] 8039567: Duplicated code in DataTransferer Reviewed-by: serb, azvegint --- .../sun/lwawt/macosx/CDataTransferer.java | 3 +- .../sun/awt/datatransfer/DataTransferer.java | 65 ++++--------------- .../classes/sun/awt/X11/XDataTransferer.java | 28 +------- .../sun/awt/windows/WDataTransferer.java | 7 +- 4 files changed, 22 insertions(+), 81 deletions(-) diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CDataTransferer.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CDataTransferer.java index 26d2347ff15..c07356057ee 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CDataTransferer.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CDataTransferer.java @@ -31,6 +31,7 @@ import sun.awt.image.ImageRepresentation; import java.io.*; import java.net.URL; +import java.nio.charset.Charset; import java.text.Normalizer; import java.text.Normalizer.Form; import java.util.*; @@ -126,7 +127,7 @@ public class CDataTransferer extends DataTransferer { if (format == CF_URL && URL.class.equals(flavor.getRepresentationClass())) { - String charset = getDefaultTextCharset(); + String charset = Charset.defaultCharset().name(); if (transferable != null && transferable.isDataFlavorSupported(javaTextEncodingFlavor)) { try { charset = new String((byte[])transferable.getTransferData(javaTextEncodingFlavor), "UTF-8"); diff --git a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java index 3f22bd86fe9..d9c8334df8a 100644 --- a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java +++ b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java @@ -57,6 +57,7 @@ import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.StandardCharsets; import java.nio.charset.UnsupportedCharsetException; import java.lang.reflect.Constructor; @@ -149,7 +150,7 @@ public abstract class DataTransferer { tempSet.add("UTF-16BE"); tempSet.add("UTF-16LE"); tempSet.add("UTF-16"); - tempSet.add(getDefaultTextCharset()); + tempSet.add(Charset.defaultCharset().name()); return Collections.unmodifiableSortedSet(tempSet); } } @@ -162,12 +163,6 @@ public abstract class DataTransferer { */ private static final Map<String, Boolean> textMIMESubtypeCharsetSupport; - /** - * Cache of the platform default encoding as specified in the - * "file.encoding" system property. - */ - private static String defaultEncoding; - /** * A collection of all natives listed in flavormap.properties with * a primary MIME type of "text". @@ -266,17 +261,7 @@ public abstract class DataTransferer { String encoding = flavor.getParameter("charset"); - return (encoding != null) ? encoding : getDefaultTextCharset(); - } - - /** - * Returns the platform's default character encoding. - */ - public static String getDefaultTextCharset() { - if (defaultEncoding != null) { - return defaultEncoding; - } - return defaultEncoding = Charset.defaultCharset().name(); + return (encoding != null) ? encoding : Charset.defaultCharset().name(); } /** @@ -470,7 +455,7 @@ public abstract class DataTransferer { textNatives.add(format); nativeCharsets.put(format, (charset != null && charset.length() != 0) - ? charset : getDefaultTextCharset()); + ? charset : Charset.defaultCharset().name()); if (eoln != null && eoln.length() != 0 && !eoln.equals("\n")) { nativeEOLNs.put(format, eoln); } @@ -771,19 +756,17 @@ public abstract class DataTransferer { * clipboard string encoding/decoding, basing on clipboard * format and localeTransferable(on decoding, if available) */ - private String getBestCharsetForTextFormat(Long lFormat, + protected String getBestCharsetForTextFormat(Long lFormat, Transferable localeTransferable) throws IOException { String charset = null; if (localeTransferable != null && isLocaleDependentTextFormat(lFormat) && - localeTransferable.isDataFlavorSupported(javaTextEncodingFlavor)) - { + localeTransferable.isDataFlavorSupported(javaTextEncodingFlavor)) { try { - charset = new String( - (byte[])localeTransferable.getTransferData(javaTextEncodingFlavor), - "UTF-8" - ); + byte[] charsetNameBytes = (byte[])localeTransferable + .getTransferData(javaTextEncodingFlavor); + charset = new String(charsetNameBytes, StandardCharsets.UTF_8); } catch (UnsupportedFlavorException cannotHappen) { } } else { @@ -791,7 +774,7 @@ public abstract class DataTransferer { } if (charset == null) { // Only happens when we have a custom text type. - charset = getDefaultTextCharset(); + charset = Charset.defaultCharset().name(); } return charset; } @@ -1716,28 +1699,8 @@ search: { Long lFormat = format; - String sourceEncoding = null; - if (isLocaleDependentTextFormat(format) && - localeTransferable != null && - localeTransferable. - isDataFlavorSupported(javaTextEncodingFlavor)) - { - try { - sourceEncoding = new String((byte[])localeTransferable. - getTransferData(javaTextEncodingFlavor), - "UTF-8"); - } catch (UnsupportedFlavorException cannotHappen) { - } - } else { - sourceEncoding = getCharsetForTextFormat(lFormat); - } - - if (sourceEncoding == null) { - // Only happens when we have a custom text type. - sourceEncoding = getDefaultTextCharset(); - } - wrapped = new BufferedReader - (new InputStreamReader(bytestream, sourceEncoding)); + String sourceEncoding = getBestCharsetForTextFormat(format, localeTransferable); + wrapped = new BufferedReader(new InputStreamReader(bytestream, sourceEncoding)); if (targetEncoding == null) { // Throw NullPointerException for compatibility with the former @@ -2318,7 +2281,6 @@ search: */ public static class CharsetComparator extends IndexedComparator<String> { private static final Map<String, Integer> charsets; - private static final String defaultEncoding; private static final Integer DEFAULT_CHARSET_INDEX = 2; private static final Integer OTHER_CHARSET_INDEX = 1; @@ -2339,8 +2301,7 @@ search: // US-ASCII is the worst charset supported charsetsMap.put(canonicalName("US-ASCII"), WORST_CHARSET_INDEX); - defaultEncoding = DataTransferer.canonicalName(DataTransferer.getDefaultTextCharset()); - charsetsMap.putIfAbsent(defaultEncoding, DEFAULT_CHARSET_INDEX); + charsetsMap.putIfAbsent(Charset.defaultCharset().name(), DEFAULT_CHARSET_INDEX); charsetsMap.put(UNSUPPORTED_CHARSET, UNSUPPORTED_CHARSET_INDEX); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java b/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java index 554e19507dc..fd9cbb8f13c 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java @@ -259,28 +259,9 @@ public class XDataTransferer extends DataTransferer { Transferable localeTransferable) throws IOException { - String charset = null; - if (localeTransferable != null && - isLocaleDependentTextFormat(format) && - localeTransferable.isDataFlavorSupported(javaTextEncodingFlavor)) { - try { - charset = new String( - (byte[])localeTransferable.getTransferData(javaTextEncodingFlavor), - "UTF-8" - ); - } catch (UnsupportedFlavorException cannotHappen) { - } - } else { - charset = getCharsetForTextFormat(format); - } - if (charset == null) { - // Only happens when we have a custom text type. - charset = getDefaultTextCharset(); - } - - BufferedReader reader = null; - try { - reader = new BufferedReader(new InputStreamReader(stream, charset)); + String charset = getBestCharsetForTextFormat(format, localeTransferable); + try (InputStreamReader isr = new InputStreamReader(stream, charset); + BufferedReader reader = new BufferedReader(isr)) { String line; ArrayList<URI> uriList = new ArrayList<>(); URI uri; @@ -293,9 +274,6 @@ public class XDataTransferer extends DataTransferer { uriList.add(uri); } return uriList.toArray(new URI[uriList.size()]); - } finally { - if (reader != null) - reader.close(); } } diff --git a/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java b/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java index 4b16e214052..2ccb76462aa 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java @@ -59,6 +59,7 @@ import java.io.File; import java.net.URL; +import java.nio.charset.Charset; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -268,9 +269,9 @@ final class WDataTransferer extends DataTransferer { if (format == CFSTR_INETURL && URL.class.equals(flavor.getRepresentationClass())) { - String charset = getDefaultTextCharset(); - if (localeTransferable != null && localeTransferable. - isDataFlavorSupported(javaTextEncodingFlavor)) + String charset = Charset.defaultCharset().name(); + if (localeTransferable != null + && localeTransferable.isDataFlavorSupported(javaTextEncodingFlavor)) { try { charset = new String((byte[])localeTransferable. From 781d6564c91d1a182473da2c9f99c744beadbab6 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov <malenkov@openjdk.org> Date: Wed, 23 Apr 2014 21:11:25 +0400 Subject: [PATCH 022/157] 8039464: The scrollbar in JScrollPane has no right border if used WindowsLookAndFeel Reviewed-by: alexsch, serb --- .../plaf/windows/WindowsScrollBarUI.java | 25 ++++- .../swing/JScrollBar/8039464/Test8039464.html | 32 +++++++ .../swing/JScrollBar/8039464/Test8039464.java | 92 +++++++++++++++++++ 3 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 jdk/test/javax/swing/JScrollBar/8039464/Test8039464.html create mode 100644 jdk/test/javax/swing/JScrollBar/8039464/Test8039464.java diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsScrollBarUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsScrollBarUI.java index 279bdb72b79..418f326165f 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsScrollBarUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsScrollBarUI.java @@ -51,6 +51,8 @@ import static com.sun.java.swing.plaf.windows.XPStyle.Skin; public class WindowsScrollBarUI extends BasicScrollBarUI { private Grid thumbGrid; private Grid highlightGrid; + private Dimension horizontalThumbSize; + private Dimension verticalThumbSize; /** * Creates a UI for a JScrollBar. @@ -65,11 +67,32 @@ public class WindowsScrollBarUI extends BasicScrollBarUI { protected void installDefaults() { super.installDefaults(); - if (XPStyle.getXP() != null) { + XPStyle xp = XPStyle.getXP(); + if (xp != null) { scrollbar.setBorder(null); + horizontalThumbSize = getSize(scrollbar, xp, Part.SBP_THUMBBTNHORZ); + verticalThumbSize = getSize(scrollbar, xp, Part.SBP_THUMBBTNVERT); + } else { + horizontalThumbSize = null; + verticalThumbSize = null; } } + private static Dimension getSize(Component component, XPStyle xp, Part part) { + Skin skin = xp.getSkin(component, part); + return new Dimension(skin.getWidth(), skin.getHeight()); + } + + @Override + protected Dimension getMinimumThumbSize() { + if ((horizontalThumbSize == null) || (verticalThumbSize == null)) { + return super.getMinimumThumbSize(); + } + return JScrollBar.HORIZONTAL == scrollbar.getOrientation() + ? horizontalThumbSize + : verticalThumbSize; + } + public void uninstallUI(JComponent c) { super.uninstallUI(c); thumbGrid = highlightGrid = null; diff --git a/jdk/test/javax/swing/JScrollBar/8039464/Test8039464.html b/jdk/test/javax/swing/JScrollBar/8039464/Test8039464.html new file mode 100644 index 00000000000..a473b819d1c --- /dev/null +++ b/jdk/test/javax/swing/JScrollBar/8039464/Test8039464.html @@ -0,0 +1,32 @@ +<!-- + Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + This code is free software; you can redistribute it and/or modify it + 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. +--> + +<html> +<body> +Choose the variable applet size and try to resize the applet. +The test passes the thumb is painted correctly. + +<applet width="400" height="200" code="Test8039464"> +</applet> +</body> +</html> diff --git a/jdk/test/javax/swing/JScrollBar/8039464/Test8039464.java b/jdk/test/javax/swing/JScrollBar/8039464/Test8039464.java new file mode 100644 index 00000000000..44bb33abd94 --- /dev/null +++ b/jdk/test/javax/swing/JScrollBar/8039464/Test8039464.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.Container; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; + +import javax.swing.JApplet; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JScrollBar; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +/* + * @test + * @bug 8039464 + * @summary Tests enabling/disabling of titled border's caption + * @author Sergey Malenkov + * @run applet/manual=yesno Test8039464.html + */ + +public class Test8039464 extends JApplet { + static { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception exception) { + throw new Error("unexpected", exception); + } + } + + @Override + public void init() { + init(this); + } + + private static void init(Container container) { + container.setLayout(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.fill = GridBagConstraints.BOTH; + gbc.gridx = 0; + gbc.gridy = 1; + JLabel label = new JLabel(); + Dimension size = new Dimension(111, 0); + label.setPreferredSize(size); + label.setMinimumSize(size); + container.add(label, gbc); + gbc.gridx = 1; + gbc.weightx = 1; + container.add(new JScrollBar(JScrollBar.HORIZONTAL, 1, 111, 1, 1111), gbc); + gbc.gridx = 2; + gbc.gridy = 0; + gbc.weightx = 0; + gbc.weighty = 1; + container.add(new JScrollBar(JScrollBar.VERTICAL, 1, 111, 1, 1111), gbc); + } + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + JFrame frame = new JFrame("8039464"); + init(frame); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + }); + } +} From 6b14d69b604651b081196ddc015311be01bf6bb1 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy <alexsch@openjdk.org> Date: Thu, 24 Apr 2014 16:15:08 +0400 Subject: [PATCH 023/157] 8040279: [macosx] Do not use the base image in the MultiResolutionBufferedImage Reviewed-by: serb, pchelko --- .../com/apple/laf/AquaImageFactory.java | 24 +--- .../classes/com/apple/laf/AquaPainter.java | 6 +- .../classes/com/apple/laf/AquaUtils.java | 6 +- .../classes/sun/lwawt/macosx/CImage.java | 36 ++--- .../image/AbstractMultiResolutionImage.java | 123 ++++++++++++++++++ ...e.java => MultiResolutionCachedImage.java} | 56 ++++---- .../swing/JMenuItem/8031573/bug8031573.java | 2 +- .../swing/JOptionPane/8024926/bug8024926.java | 2 +- 8 files changed, 177 insertions(+), 78 deletions(-) create mode 100644 jdk/src/share/classes/sun/awt/image/AbstractMultiResolutionImage.java rename jdk/src/share/classes/sun/awt/image/{MultiResolutionBufferedImage.java => MultiResolutionCachedImage.java} (80%) diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaImageFactory.java b/jdk/src/macosx/classes/com/apple/laf/AquaImageFactory.java index be6a787a45b..9e0f34f7a4c 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaImageFactory.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaImageFactory.java @@ -46,10 +46,8 @@ import com.apple.laf.AquaIcon.JRSUIControlSpec; import com.apple.laf.AquaIcon.SystemIcon; import com.apple.laf.AquaUtils.RecyclableObject; import com.apple.laf.AquaUtils.RecyclableSingleton; -import java.util.Arrays; -import java.util.List; -import sun.awt.image.MultiResolutionBufferedImage; import sun.awt.image.MultiResolutionImage; +import sun.awt.image.MultiResolutionCachedImage; public class AquaImageFactory { public static IconUIResource getConfirmImageIcon() { @@ -125,9 +123,9 @@ public class AquaImageFactory { private static final int kAlertIconSize = 64; static IconUIResource getAppIconCompositedOn(final Image background) { - if (background instanceof MultiResolutionBufferedImage) { + if (background instanceof MultiResolutionCachedImage) { int width = background.getWidth(null); - Image mrIconImage = ((MultiResolutionBufferedImage) background).map( + Image mrIconImage = ((MultiResolutionCachedImage) background).map( rv -> getAppIconImageCompositedOn(rv, rv.getWidth(null) / width)); return new IconUIResource(new ImageIcon(mrIconImage)); } @@ -306,21 +304,7 @@ public class AquaImageFactory { private static Image getNSIcon(String imageName) { Image icon = Toolkit.getDefaultToolkit() .getImage("NSImage://" + imageName); - - if (icon instanceof MultiResolutionImage) { - return icon; - } - - int w = icon.getWidth(null); - int h = icon.getHeight(null); - - Dimension[] sizes = new Dimension[]{ - new Dimension(w, h), new Dimension(2 * w, 2 * h) - }; - - return new MultiResolutionBufferedImage(icon, sizes, (width, height) -> - AquaUtils.getCImageCreator().createImageFromName( - imageName, width, height)); + return icon; } public static class NineSliceMetrics { diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaPainter.java b/jdk/src/macosx/classes/com/apple/laf/AquaPainter.java index ee4fcba1a4d..a2ebaf1c920 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaPainter.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaPainter.java @@ -174,11 +174,7 @@ abstract class AquaPainter <T extends JRSUIState> { bounds, controlState); Image img = cache.getImage(key); if (img == null) { - - Image baseImage = createImage(imgX, imgY, imgW, imgH, bounds, - control, controlState); - - img = new MultiResolutionBufferedImage(baseImage, + img = new MultiResolutionCachedImage(imgW, imgH, (rvWidth, rvHeight) -> createImage(imgX, imgY, rvWidth, rvHeight, bounds, control, controlState)); diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaUtils.java b/jdk/src/macosx/classes/com/apple/laf/AquaUtils.java index a20897f7b31..078435b161b 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaUtils.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaUtils.java @@ -48,7 +48,7 @@ import sun.security.action.GetPropertyAction; import sun.swing.SwingUtilities2; import com.apple.laf.AquaImageFactory.SlicedImageControl; -import sun.awt.image.MultiResolutionBufferedImage; +import sun.awt.image.MultiResolutionCachedImage; final class AquaUtils { @@ -124,8 +124,8 @@ final class AquaUtils { static Image generateLightenedImage(final Image image, final int percent) { final GrayFilter filter = new GrayFilter(true, percent); - return (image instanceof MultiResolutionBufferedImage) - ? ((MultiResolutionBufferedImage) image).map( + return (image instanceof MultiResolutionCachedImage) + ? ((MultiResolutionCachedImage) image).map( rv -> generateLightenedImage(rv, filter)) : generateLightenedImage(image, filter); } diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CImage.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CImage.java index 17815d4882e..69bdab05734 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CImage.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CImage.java @@ -32,7 +32,7 @@ import java.awt.image.*; import java.util.Arrays; import java.util.List; import sun.awt.image.MultiResolutionImage; -import sun.awt.image.MultiResolutionBufferedImage; +import sun.awt.image.MultiResolutionCachedImage; import sun.awt.image.SunWritableRaster; @@ -62,41 +62,41 @@ public class CImage extends CFRetainedResource { // This is used to create a CImage with an NSImage pointer. It MUST be a CFRetained // NSImage, and the CImage takes ownership of the non-GC retain. If callers need the // NSImage themselves, they MUST call retain on the NSImage themselves. - public BufferedImage createImageUsingNativeSize(final long image) { + public Image createImageUsingNativeSize(final long image) { if (image == 0) return null; final Dimension2D size = nativeGetNSImageSize(image); - return createBufferedImage(image, size.getWidth(), size.getHeight()); + return createImage(image, size.getWidth(), size.getHeight()); } // the width and height passed in as a parameter could differ than the width and the height of the NSImage (image), in that case, the image will be scaled - BufferedImage createBufferedImage(long image, double width, double height) { + Image createImage(long image, double width, double height) { if (image == 0) throw new Error("Unable to instantiate CImage with null native image reference."); return createImageWithSize(image, width, height); } - public BufferedImage createImageWithSize(final long image, final double width, final double height) { + public Image createImageWithSize(final long image, final double width, final double height) { final CImage img = new CImage(image); img.resize(width, height); return img.toImage(); } // This is used to create a CImage that represents the icon of the given file. - public BufferedImage createImageOfFile(final String file, final int width, final int height) { - return createBufferedImage(nativeCreateNSImageOfFileFromLaunchServices(file), width, height); + public Image createImageOfFile(final String file, final int width, final int height) { + return createImage(nativeCreateNSImageOfFileFromLaunchServices(file), width, height); } - public BufferedImage createImageFromFile(final String file, final double width, final double height) { + public Image createImageFromFile(final String file, final double width, final double height) { final long image = nativeCreateNSImageFromFileContents(file); nativeSetNSImageSize(image, width, height); - return createBufferedImage(image, width, height); + return createImage(image, width, height); } - public BufferedImage createSystemImageFromSelector(final String iconSelector, final int width, final int height) { - return createBufferedImage(nativeCreateNSImageFromIconSelector(getSelectorAsInt(iconSelector)), width, height); + public Image createSystemImageFromSelector(final String iconSelector, final int width, final int height) { + return createImage(nativeCreateNSImageFromIconSelector(getSelectorAsInt(iconSelector)), width, height); } public Image createImageFromName(final String name, final int width, final int height) { - return createBufferedImage(nativeCreateNSImageFromImageName(name), width, height); + return createImage(nativeCreateNSImageFromImageName(name), width, height); } public Image createImageFromName(final String name) { @@ -232,7 +232,7 @@ public class CImage extends CFRetainedResource { } /** @return A MultiResolution image created from nsImagePtr, or null. */ - private BufferedImage toImage() { + private Image toImage() { if (ptr == 0) return null; final Dimension2D size = nativeGetNSImageSize(ptr); @@ -243,11 +243,11 @@ public class CImage extends CFRetainedResource { = nativeGetNSImageRepresentationSizes(ptr, size.getWidth(), size.getHeight()); - BufferedImage baseImage = toImage(w, h, w, h); - - return sizes == null || sizes.length < 2 ? baseImage - : new MultiResolutionBufferedImage(baseImage, sizes, - (width, height) -> toImage(w, h, width, height)); + return sizes == null || sizes.length < 2 ? + new MultiResolutionCachedImage(w, h, (width, height) + -> toImage(w, h, width, height)) + : new MultiResolutionCachedImage(w, h, sizes, (width, height) + -> toImage(w, h, width, height)); } private BufferedImage toImage(int srcWidth, int srcHeight, int dstWidth, int dstHeight) { diff --git a/jdk/src/share/classes/sun/awt/image/AbstractMultiResolutionImage.java b/jdk/src/share/classes/sun/awt/image/AbstractMultiResolutionImage.java new file mode 100644 index 00000000000..5116f517ff0 --- /dev/null +++ b/jdk/src/share/classes/sun/awt/image/AbstractMultiResolutionImage.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 sun.awt.image; + +import java.awt.Graphics; +import java.awt.Image; +import java.awt.image.*; + +/** + * This class provides default implementations for the + * <code>MultiResolutionImage</code> interface. The developer needs only + * to subclass this abstract class and define the <code>getResolutionVariant</code>, + * <code>getResolutionVariants</code>, and <code>getBaseImage</code> methods. + * + * + * For example, + * {@code + * public class CustomMultiResolutionImage extends AbstractMultiResolutionImage { + * + * int baseImageIndex; + * Image[] resolutionVariants; + * + * public CustomMultiResolutionImage(int baseImageIndex, + * Image... resolutionVariants) { + * this.baseImageIndex = baseImageIndex; + * this.resolutionVariants = resolutionVariants; + * } + * + * @Override + * public Image getResolutionVariant(float logicalDPIX, float logicalDPIY, + * float baseImageWidth, float baseImageHeight, + * float destImageWidth, float destImageHeight) { + * // return a resolution variant based on the given logical DPI, + * // base image size, or destination image size + * } + * + * @Override + * public List<Image> getResolutionVariants() { + * return Arrays.asList(resolutionVariants); + * } + * + * protected Image getBaseImage() { + * return resolutionVariants[baseImageIndex]; + * } + * } + * } + * + * @see java.awt.Image + * @see java.awt.image.MultiResolutionImage + * + * @since 1.9 + */ +public abstract class AbstractMultiResolutionImage extends java.awt.Image + implements MultiResolutionImage { + + /** + * @inheritDoc + */ + @Override + public int getWidth(ImageObserver observer) { + return getBaseImage().getWidth(null); + } + + /** + * @inheritDoc + */ + @Override + public int getHeight(ImageObserver observer) { + return getBaseImage().getHeight(null); + } + + /** + * @inheritDoc + */ + @Override + public ImageProducer getSource() { + return getBaseImage().getSource(); + } + + /** + * @inheritDoc + */ + @Override + public Graphics getGraphics() { + return getBaseImage().getGraphics(); + + } + + /** + * @inheritDoc + */ + @Override + public Object getProperty(String name, ImageObserver observer) { + return getBaseImage().getProperty(name, observer); + } + + /** + * @return base image + */ + protected abstract Image getBaseImage(); +} diff --git a/jdk/src/share/classes/sun/awt/image/MultiResolutionBufferedImage.java b/jdk/src/share/classes/sun/awt/image/MultiResolutionCachedImage.java similarity index 80% rename from jdk/src/share/classes/sun/awt/image/MultiResolutionBufferedImage.java rename to jdk/src/share/classes/sun/awt/image/MultiResolutionCachedImage.java index 74db8273416..376827c0885 100644 --- a/jdk/src/share/classes/sun/awt/image/MultiResolutionBufferedImage.java +++ b/jdk/src/share/classes/sun/awt/image/MultiResolutionCachedImage.java @@ -26,9 +26,7 @@ package sun.awt.image; import java.awt.Dimension; import java.awt.Image; -import java.awt.Graphics; import java.awt.geom.Dimension2D; -import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; import java.util.Arrays; import java.util.List; @@ -36,50 +34,39 @@ import java.util.function.Function; import java.util.function.BiFunction; import java.util.stream.Collectors; -public class MultiResolutionBufferedImage extends BufferedImage - implements MultiResolutionImage { +public class MultiResolutionCachedImage extends AbstractMultiResolutionImage { - private final BiFunction<Integer, Integer, Image> mapper; + private final int baseImageWidth; + private final int baseImageHeight; private final Dimension2D[] sizes; + private final BiFunction<Integer, Integer, Image> mapper; private int availableInfo; - public MultiResolutionBufferedImage(Image baseImage, + public MultiResolutionCachedImage(int baseImageWidth, int baseImageHeight, BiFunction<Integer, Integer, Image> mapper) { - this(baseImage, new Dimension[]{new Dimension( - baseImage.getWidth(null), baseImage.getHeight(null)) + this(baseImageWidth, baseImageHeight, new Dimension[]{new Dimension( + baseImageWidth, baseImageHeight) }, mapper); } - public MultiResolutionBufferedImage(Image baseImage, + public MultiResolutionCachedImage(int baseImageWidth, int baseImageHeight, Dimension2D[] sizes, BiFunction<Integer, Integer, Image> mapper) { - super(baseImage.getWidth(null), baseImage.getHeight(null), - BufferedImage.TYPE_INT_ARGB_PRE); + this.baseImageWidth = baseImageWidth; + this.baseImageHeight = baseImageHeight; this.sizes = sizes; this.mapper = mapper; - this.availableInfo = getInfo(baseImage); - Graphics g = getGraphics(); - g.drawImage(baseImage, 0, 0, null); - g.dispose(); } @Override public Image getResolutionVariant(int width, int height) { - int baseWidth = getWidth(); - int baseHeight = getHeight(); - - if (baseWidth == width && baseHeight == height) { - return this; - } - ImageCache cache = ImageCache.getInstance(); ImageCacheKey key = new ImageCacheKey(this, width, height); Image resolutionVariant = cache.getImage(key); if (resolutionVariant == null) { resolutionVariant = mapper.apply(width, height); cache.setImage(key, resolutionVariant); - preload(resolutionVariant, availableInfo); } - + preload(resolutionVariant, availableInfo); return resolutionVariant; } @@ -90,30 +77,39 @@ public class MultiResolutionBufferedImage extends BufferedImage (int) size.getHeight())).collect(Collectors.toList()); } - public MultiResolutionBufferedImage map(Function<Image, Image> mapper) { - return new MultiResolutionBufferedImage(mapper.apply(this), sizes, - (width, height) -> + public MultiResolutionCachedImage map(Function<Image, Image> mapper) { + return new MultiResolutionCachedImage(baseImageWidth, baseImageHeight, + sizes, (width, height) -> mapper.apply(getResolutionVariant(width, height))); } @Override public int getWidth(ImageObserver observer) { - availableInfo |= ImageObserver.WIDTH; + updateInfo(observer, ImageObserver.WIDTH); return super.getWidth(observer); } @Override public int getHeight(ImageObserver observer) { - availableInfo |= ImageObserver.HEIGHT; + updateInfo(observer, ImageObserver.HEIGHT); return super.getHeight(observer); } @Override public Object getProperty(String name, ImageObserver observer) { - availableInfo |= ImageObserver.PROPERTIES; + updateInfo(observer, ImageObserver.PROPERTIES); return super.getProperty(name, observer); } + @Override + protected Image getBaseImage() { + return getResolutionVariant(baseImageWidth, baseImageHeight); + } + + private void updateInfo(ImageObserver observer, int info) { + availableInfo |= (observer == null) ? ImageObserver.ALLBITS : info; + } + private static int getInfo(Image image) { if (image instanceof ToolkitImage) { return ((ToolkitImage) image).getImageRep().check( diff --git a/jdk/test/javax/swing/JMenuItem/8031573/bug8031573.java b/jdk/test/javax/swing/JMenuItem/8031573/bug8031573.java index 5cb1dc5047f..2d36db7a171 100644 --- a/jdk/test/javax/swing/JMenuItem/8031573/bug8031573.java +++ b/jdk/test/javax/swing/JMenuItem/8031573/bug8031573.java @@ -28,7 +28,7 @@ import javax.swing.JMenuBar; import javax.swing.SwingUtilities; /* @test - * @bug 8031573 + * @bug 8031573 8040279 * @summary [macosx] Checkmarks of JCheckBoxMenuItems aren't rendered * in high resolution on Retina * @author Alexander Scherbatiy diff --git a/jdk/test/javax/swing/JOptionPane/8024926/bug8024926.java b/jdk/test/javax/swing/JOptionPane/8024926/bug8024926.java index 42f976b03c0..185537f3b5b 100644 --- a/jdk/test/javax/swing/JOptionPane/8024926/bug8024926.java +++ b/jdk/test/javax/swing/JOptionPane/8024926/bug8024926.java @@ -31,7 +31,7 @@ import sun.awt.OSInfo; /** * @test - * @bug 8024926 + * @bug 8024926 8040279 * @summary [macosx] AquaIcon HiDPI support * @author Alexander Scherbatiy * @run applet/manual=yesno bug8024926.html From 7059ba15c3e1fbfffcb883b96cbbca5574507fcd Mon Sep 17 00:00:00 2001 From: Petr Pchelko <pchelko@openjdk.org> Date: Thu, 24 Apr 2014 20:22:58 +0400 Subject: [PATCH 024/157] 7124250: [macosx] JOptionPane dialogs show wrong icons Reviewed-by: serb, leonidr --- .../com/apple/laf/AquaImageFactory.java | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaImageFactory.java b/jdk/src/macosx/classes/com/apple/laf/AquaImageFactory.java index 9e0f34f7a4c..4838ba48879 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaImageFactory.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaImageFactory.java @@ -55,7 +55,7 @@ public class AquaImageFactory { return new IconUIResource(new AquaIcon.CachingScalingIcon(kAlertIconSize, kAlertIconSize) { Image createImage() { - return getThisApplicationsIcon(kAlertIconSize, kAlertIconSize); + return getGenericJavaIcon(); } }); } @@ -81,24 +81,6 @@ public class AquaImageFactory { return getAppIconCompositedOn(lockIcon); } - static Image getThisApplicationsIcon(final int width, final int height) { - final String path = getPathToThisApplication(); - - if (path == null) { - return getGenericJavaIcon(); - } - - if (path.endsWith("/Home/bin")) { - return getGenericJavaIcon(); - } - - if (path.startsWith("/usr/bin")) { - return getGenericJavaIcon(); - } - - return AquaUtils.getCImageCreator().createImageOfFile(path, height, width); - } - static Image getGenericJavaIcon() { return java.security.AccessController.doPrivileged(new PrivilegedAction<Image>() { public Image run() { @@ -142,7 +124,7 @@ public class AquaImageFactory { final Icon smallAppIconScaled = new AquaIcon.CachingScalingIcon( kAlertSubIconSize, kAlertSubIconSize) { Image createImage() { - return getThisApplicationsIcon(kAlertSubIconSize, kAlertSubIconSize); + return getGenericJavaIcon(); } }; @@ -514,4 +496,4 @@ public class AquaImageFactory { public static Color getSelectionInactiveForegroundColorUIResource() { return new SystemColorProxy(LWCToolkit.getAppleColor(LWCToolkit.INACTIVE_SELECTION_FOREGROUND_COLOR)); } -} \ No newline at end of file +} From c25473bb3827e3b8e53694d148a615c7cd14e6ae Mon Sep 17 00:00:00 2001 From: Petr Pchelko <pchelko@openjdk.org> Date: Fri, 25 Apr 2014 16:27:30 +0400 Subject: [PATCH 025/157] 8041572: [macosx] huge native memory leak in AWTWindow.m Reviewed-by: serb, anthony --- jdk/src/macosx/native/sun/awt/AWTWindow.m | 9 ++++++--- jdk/src/macosx/native/sun/awt/CGraphicsDevice.m | 4 +++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/jdk/src/macosx/native/sun/awt/AWTWindow.m b/jdk/src/macosx/native/sun/awt/AWTWindow.m index c2577584886..6a9c1166e84 100644 --- a/jdk/src/macosx/native/sun/awt/AWTWindow.m +++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m @@ -261,7 +261,8 @@ AWT_ASSERT_APPKIT_THREAD; // returns id for the topmost window under mouse + (NSInteger) getTopmostWindowUnderMouseID { - + NSInteger result = -1; + NSRect screenRect = [[NSScreen mainScreen] frame]; NSPoint nsMouseLocation = [NSEvent mouseLocation]; CGPoint cgMouseLocation = CGPointMake(nsMouseLocation.x, screenRect.size.height - nsMouseLocation.y); @@ -274,11 +275,13 @@ AWT_ASSERT_APPKIT_THREAD; CGRect rect; CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect); if (CGRectContainsPoint(rect, cgMouseLocation)) { - return [[window objectForKey:(id)kCGWindowNumber] integerValue]; + result = [[window objectForKey:(id)kCGWindowNumber] integerValue]; + break; } } } - return -1; + [windows release]; + return result; } // checks that this window is under the mouse cursor and this point is not overlapped by others windows diff --git a/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m b/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m index 9b94b82abbc..4d3b587c174 100644 --- a/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m +++ b/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m @@ -66,7 +66,8 @@ static CFMutableArrayRef getAllValidDisplayModes(jint displayID){ CFArrayAppendValue(validModes, cRef); } } - + CFRelease(allModes); + CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(displayID); BOOL containsCurrentMode = NO; @@ -81,6 +82,7 @@ static CFMutableArrayRef getAllValidDisplayModes(jint displayID){ if (!containsCurrentMode) { CFArrayAppendValue(validModes, currentMode); } + CGDisplayModeRelease(currentMode); return validModes; } From 844cf2d704ada1bbf613504d6c2d21c058b9af44 Mon Sep 17 00:00:00 2001 From: Petr Pchelko <pchelko@openjdk.org> Date: Fri, 25 Apr 2014 16:39:13 +0400 Subject: [PATCH 026/157] 8041490: PIT: [macosx] Crash in system tray functionality check test Reviewed-by: anthony, serb --- .../sun/lwawt/macosx/CWarningWindow.java | 4 ++ .../WarningWindowDisposeCrashTest.java | 54 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 jdk/test/java/awt/security/WarningWindowDisposeTest/WarningWindowDisposeCrashTest.java diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java index fc72ef79474..0acc67feed6 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java @@ -309,6 +309,10 @@ public final class CWarningWindow extends CPlatformWindow @Override public void dispose() { cancelTasks(); + SurfaceData surfaceData = contentView.getSurfaceData(); + if (surfaceData != null) { + surfaceData.invalidate(); + } super.dispose(); } diff --git a/jdk/test/java/awt/security/WarningWindowDisposeTest/WarningWindowDisposeCrashTest.java b/jdk/test/java/awt/security/WarningWindowDisposeTest/WarningWindowDisposeCrashTest.java new file mode 100644 index 00000000000..298059054d9 --- /dev/null +++ b/jdk/test/java/awt/security/WarningWindowDisposeTest/WarningWindowDisposeCrashTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + @bug 8041490 + @summary tests that the WarningWindow's surface is invalidated on dispose + @author Petr Pchelko + @run main/othervm WarningWindowDisposeCrashTest +*/ + + +import sun.applet.AppletSecurity; +import sun.awt.SunToolkit; + +import java.awt.*; + +public class WarningWindowDisposeCrashTest { + public static void main(String[] args) throws Exception { + System.setSecurityManager(new AppletSecurity() { + @Override + public void checkPackageAccess (String s){ + } + }); + + Frame f = new Frame(); + f.setVisible(true); + ((SunToolkit) Toolkit.getDefaultToolkit()).realSync(); + Thread.sleep(1000); + f.dispose(); + // If the bug is present VM could crash after this call + for (int i = 0; i < 1000; i++) Toolkit.getDefaultToolkit().sync(); + } +} From 01e8b57668fb27fbc9ef52627db027d5edcf5ab4 Mon Sep 17 00:00:00 2001 From: Petr Pchelko <pchelko@openjdk.org> Date: Mon, 28 Apr 2014 16:45:43 +0400 Subject: [PATCH 027/157] 8041987: [macosx] setDisplayMode crashes Reviewed-by: anthony, serb --- .../macosx/native/sun/awt/CGraphicsDevice.m | 9 +- .../DisplayChangeVITest.java | 245 ++++++++++++++++++ 2 files changed, 250 insertions(+), 4 deletions(-) create mode 100644 jdk/test/java/awt/FullScreen/DisplayChangeVITest/DisplayChangeVITest.java diff --git a/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m b/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m index 4d3b587c174..e20792a231d 100644 --- a/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m +++ b/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m @@ -237,17 +237,19 @@ Java_sun_awt_CGraphicsDevice_nativeSetDisplayMode { JNF_COCOA_ENTER(env); CFArrayRef allModes = getAllValidDisplayModes(displayID); - CGDisplayModeRef closestMatch = getBestModeForParameters(allModes, (int)w, (int)h, (int)bpp, (int)refrate); + __block CGError retCode = kCGErrorSuccess; if (closestMatch != NULL) { - [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ + CGDisplayModeRetain(closestMatch); + [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ CGDisplayConfigRef config; retCode = CGBeginDisplayConfiguration(&config); if (retCode == kCGErrorSuccess) { CGConfigureDisplayWithDisplayMode(config, displayID, closestMatch, NULL); retCode = CGCompleteDisplayConfiguration(config, kCGConfigureForAppOnly); } + CGDisplayModeRelease(closestMatch); }]; } else { [JNFException raise:env as:kIllegalArgumentException reason:"Invalid display mode"]; @@ -255,8 +257,7 @@ Java_sun_awt_CGraphicsDevice_nativeSetDisplayMode if (retCode != kCGErrorSuccess){ [JNFException raise:env as:kIllegalArgumentException reason:"Unable to set display mode!"]; - } - + } CFRelease(allModes); JNF_COCOA_EXIT(env); } diff --git a/jdk/test/java/awt/FullScreen/DisplayChangeVITest/DisplayChangeVITest.java b/jdk/test/java/awt/FullScreen/DisplayChangeVITest/DisplayChangeVITest.java new file mode 100644 index 00000000000..ae7ab9f1908 --- /dev/null +++ b/jdk/test/java/awt/FullScreen/DisplayChangeVITest/DisplayChangeVITest.java @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @bug 6366359 + * @summary Test that we don't crash when changing from 8 to 16/32 bit modes + * @author Dmitri.Trembovetski@Sun.COM area=FullScreen + * @run main/othervm/timeout=200 DisplayChangeVITest + * @run main/othervm/timeout=200 -Dsun.java2d.d3d=false DisplayChangeVITest + * @run main/othervm/timeout=200 -Dsun.java2d.opengl=true DisplayChangeVITest + */ + +import java.awt.Color; +import java.awt.DisplayMode; +import java.awt.Graphics; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; +import java.lang.Exception; +import java.lang.Thread; +import java.util.ArrayList; +import java.util.Random; +import javax.swing.JFrame; + +/** + * The test enters fullscreen mode (if it's supported) and then tries + * to switch between display moes with different depths and dimensions + * while doing both rendering to the screen (via a VolatileImage) + * and Swing repainting just to make things more chaotic. + * + * The procedure is repeated TEST_REPS times (3 by default). + * + * Don't pay attention to what happens on the screen, it won't be pretty. + * If the test doesn't crash or throw exceptions, it passes, otherwise + * it fails. + */ +public class DisplayChangeVITest extends JFrame implements Runnable { + + private final Random rnd = new Random(); + private VolatileImage bb; + private BufferedImage sprite; + private VolatileImage volSprite; + + private static boolean done = false; + private static final Object lock = new Object(); + private static final int TEST_REPS = 3; + + private ArrayList<DisplayMode> dms; + + DisplayChangeVITest() { + selectDisplayModes(); + addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { + synchronized (lock) { + done = true; + } + } + } + }); + sprite = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB); + sprite.getRaster().getDataBuffer(); + Graphics g = sprite.getGraphics(); + g.setColor(Color.yellow); + g.fillRect(0, 0, sprite.getWidth(), sprite.getHeight()); + } + + void render(Graphics g) { + do { + // volatile images validated here + initBackbuffer(); + + g.setColor(Color.black); + g.fillRect(0, 0, getWidth(), getHeight()); + + Graphics gg = bb.getGraphics(); + gg.setColor(new Color(rnd.nextInt(0x00ffffff))); + gg.fillRect(0, 0, bb.getWidth(), bb.getHeight()); + for (int x = 0; x < 10; x++) { + gg.drawImage(sprite, x*200, 0, null); + gg.drawImage(volSprite, x*200, 500, null); + } + + g.drawImage(bb, 0, 0, null); + } while (bb.contentsLost()); + } + + private static void sleep(long msec) { + try { Thread.sleep(msec); } catch (InterruptedException e) {} + } + + private int reps = 0; + public void run() { + GraphicsDevice gd = getGraphicsConfiguration().getDevice(); + if (gd.isDisplayChangeSupported() && dms.size() > 0) { + while (!done && reps++ < TEST_REPS) { + for (DisplayMode dm : dms) { + System.err.printf("Entering DisplayMode[%dx%dx%d]\n", + dm.getWidth(), dm.getHeight(), dm.getBitDepth()); + gd.setDisplayMode(dm); + + initBackbuffer(); + for (int i = 0; i < 10; i++) { + // render to the screen + render(getGraphics()); + // ask Swing to repaint + repaint(); + sleep(100); + } + sleep(1500); + } + } + } else { + System.err.println("Display mode change " + + "not supported. Test passed."); + } + dispose(); + synchronized (lock) { + done = true; + lock.notify(); + } + } + + private void createBackbuffer() { + if (bb == null || + bb.getWidth() != getWidth() || bb.getHeight() != getHeight()) + { + bb = createVolatileImage(getWidth(), getHeight()); + } + } + + private void initBackbuffer() { + createBackbuffer(); + + int res = bb.validate(getGraphicsConfiguration()); + if (res == VolatileImage.IMAGE_INCOMPATIBLE) { + bb = null; + createBackbuffer(); + bb.validate(getGraphicsConfiguration()); + res = VolatileImage.IMAGE_RESTORED; + } + if (res == VolatileImage.IMAGE_RESTORED) { + Graphics g = bb.getGraphics(); + g.setColor(new Color(rnd.nextInt(0x00ffffff))); + g.fillRect(0, 0, bb.getWidth(), bb.getHeight()); + + volSprite = createVolatileImage(100, 100); + } + volSprite.validate(getGraphicsConfiguration()); + } + + private void selectDisplayModes() { + GraphicsDevice gd = + GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice(); + dms = new ArrayList<DisplayMode>(); + DisplayMode dmArray[] = gd.getDisplayModes(); + boolean found8 = false, found16 = false, + found24 = false, found32 = false; + for (DisplayMode dm : dmArray) { + if (!found8 && + (dm.getBitDepth() == 8 || + dm.getBitDepth() == DisplayMode.BIT_DEPTH_MULTI) && + (dm.getWidth() >= 800 && dm.getWidth() < 1024)) + { + dms.add(dm); + found8 = true; + continue; + } + if (!found32 && + (dm.getBitDepth() == 32 || + dm.getBitDepth() == DisplayMode.BIT_DEPTH_MULTI) && + dm.getWidth() >= 1280) + { + dms.add(dm); + found32 = true; + continue; + } + if (!found16 && + dm.getBitDepth() == 16 && + (dm.getWidth() >= 1024 && dm.getWidth() < 1280)) + { + dms.add(dm); + found16 = true; + continue; + } + if (found8 && found16 && found32) { + break; + } + } + System.err.println("Found display modes:"); + for (DisplayMode dm : dms) { + System.err.printf("DisplayMode[%dx%dx%d]\n", + dm.getWidth(), dm.getHeight(), dm.getBitDepth()); + } + } + + public static void main(String[] args) throws Exception { + DisplayChangeVITest test = new DisplayChangeVITest(); + GraphicsDevice gd = + GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice(); + if (gd.isFullScreenSupported()) { + gd.setFullScreenWindow(test); + Thread t = new Thread(test); + t.run(); + synchronized (lock) { + while (!done) { + try { + lock.wait(50); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } + } + System.err.println("Test Passed."); + } else { + System.err.println("Full screen not supported. Test passed."); + } + } +} From c7f7685c508af7155e1abf6405e4730d6780e1c6 Mon Sep 17 00:00:00 2001 From: Vivi An <vivi.an@oracle.com> Date: Mon, 28 Apr 2014 11:03:52 -0700 Subject: [PATCH 028/157] 8036819: JAB: mneumonics not read for textboxes Reviewed-by: alexsch --- .../share/classes/javax/swing/JComponent.java | 13 +- .../swing/JTextField/8036819/bug8036819.java | 132 ++++++++++++++++++ 2 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 jdk/test/javax/swing/JTextField/8036819/bug8036819.java diff --git a/jdk/src/share/classes/javax/swing/JComponent.java b/jdk/src/share/classes/javax/swing/JComponent.java index 98c4d7fb5dd..2d2745957e7 100644 --- a/jdk/src/share/classes/javax/swing/JComponent.java +++ b/jdk/src/share/classes/javax/swing/JComponent.java @@ -3986,7 +3986,18 @@ public abstract class JComponent extends Container implements Serializable, * @see AccessibleKeyBinding * @since 1.4 */ - public AccessibleKeyBinding getAccessibleKeyBinding() { + public AccessibleKeyBinding getAccessibleKeyBinding(){ + // Try to get the linked label's mnemonic if it exists + Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY); + if (o instanceof Accessible){ + AccessibleContext ac = ((Accessible) o).getAccessibleContext(); + if (ac != null){ + AccessibleComponent comp = ac.getAccessibleComponent(); + if (! (comp instanceof AccessibleExtendedComponent)) + return null; + return ((AccessibleExtendedComponent)comp).getAccessibleKeyBinding(); + } + } return null; } } // inner class AccessibleJComponent diff --git a/jdk/test/javax/swing/JTextField/8036819/bug8036819.java b/jdk/test/javax/swing/JTextField/8036819/bug8036819.java new file mode 100644 index 00000000000..558be4c9769 --- /dev/null +++ b/jdk/test/javax/swing/JTextField/8036819/bug8036819.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @library ../../regtesthelpers + * @build Util + * @bug 8036819 + * @summary JAB: mnemonics not read for textboxes + * @author Vivi An + * @run main bug8036819 + */ + +import javax.swing.*; +import javax.swing.event.*; +import java.awt.event.*; +import java.awt.*; +import sun.awt.SunToolkit; +import javax.accessibility.*; + +public class bug8036819 { + + public static volatile Boolean passed = false; + + public static void main(String args[]) throws Throwable { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + createAndShowGUI(); + } + }); + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + toolkit.realSync(); + + Robot robo = new Robot(); + robo.setAutoDelay(300); + + // Using mnemonic key to focus on the textfield + Util.hitMnemonics(robo, KeyEvent.VK_P); + toolkit.realSync(); + + if (!passed){ + throw new RuntimeException("Test failed."); + } + } + + private static void createAndShowGUI() { + JFrame mainFrame = new JFrame("bug 8036819"); + + JLabel usernameLabel = new JLabel("Username: "); + JTextField usernameField = new JTextField(20); + usernameLabel.setDisplayedMnemonic(KeyEvent.VK_U); + usernameLabel.setLabelFor(usernameField); + + JLabel pwdLabel = new JLabel("Password: "); + JTextField pwdField = new JTextField(20); + pwdLabel.setDisplayedMnemonic(KeyEvent.VK_P); + pwdLabel.setLabelFor(pwdField); + + pwdField.addKeyListener( + new KeyListener(){ + @Override + public void keyPressed(KeyEvent keyEvent) { + } + + @Override + public void keyTyped(KeyEvent keyEvent) { + } + + @Override + public void keyReleased(KeyEvent keyEvent){ + JComponent comp = (JComponent) pwdField; + AccessibleContext ac = comp.getAccessibleContext(); + AccessibleExtendedComponent aec = (AccessibleExtendedComponent)ac.getAccessibleComponent(); + AccessibleKeyBinding akb = aec.getAccessibleKeyBinding(); + if (akb != null){ + int count = akb.getAccessibleKeyBindingCount(); + if (count != 1){ + passed = false; + return; + } + + // there is 1 accessible key for the text field + System.out.println("Retrieved AccessibleKeyBinding for textfield " + count); + + // the key code is KeyEvent.VK_P + Object o = akb.getAccessibleKeyBinding(0); + if (o instanceof KeyStroke){ + javax.swing.KeyStroke key = (javax.swing.KeyStroke)o; + System.out.println("keystroke is " + key.getKeyCode()); + if (key.getKeyCode() == KeyEvent.VK_P) + passed = true; + } + } + } + } + ); + + mainFrame.getContentPane().add(usernameLabel); + mainFrame.getContentPane().add(usernameField); + mainFrame.getContentPane().add(pwdLabel); + mainFrame.getContentPane().add(pwdField); + + mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + mainFrame.setLayout(new FlowLayout(FlowLayout.LEFT)); + + mainFrame.setSize(200, 200); + mainFrame.setLocation(200, 200); + mainFrame.setVisible(true); + mainFrame.toFront(); + } + } From cb91afdb8cb3561f6bbf68ab116d5732f4139dc4 Mon Sep 17 00:00:00 2001 From: Henry Jen <henryjen@openjdk.org> Date: Mon, 28 Apr 2014 19:05:49 -0700 Subject: [PATCH 029/157] 8039642: Fix raw and unchecked warnings in sun.awt.* Reviewed-by: darcy, prr, flar --- jdk/src/share/classes/java/awt/Menu.java | 8 +- .../share/classes/sun/awt/AWTAccessor.java | 4 +- jdk/src/share/classes/sun/awt/AppContext.java | 1 + .../classes/sun/awt/FontConfiguration.java | 44 ++++----- jdk/src/share/classes/sun/awt/HToolkit.java | 3 +- .../classes/sun/awt/HeadlessToolkit.java | 3 +- .../share/classes/sun/awt/PlatformFont.java | 11 +-- jdk/src/share/classes/sun/awt/SunToolkit.java | 2 + .../sun/awt/datatransfer/DataTransferer.java | 45 ++++----- .../sun/awt/datatransfer/SunClipboard.java | 6 +- .../awt/datatransfer/TransferableProxy.java | 20 ++-- .../sun/awt/dnd/SunDragSourceContextPeer.java | 2 +- .../sun/awt/dnd/SunDropTargetContextPeer.java | 8 +- .../share/classes/sun/awt/geom/AreaOp.java | 56 +++++------ .../share/classes/sun/awt/geom/Crossings.java | 16 ++-- jdk/src/share/classes/sun/awt/geom/Curve.java | 8 +- .../share/classes/sun/awt/geom/Order2.java | 4 +- .../share/classes/sun/awt/geom/Order3.java | 4 +- .../sun/awt/image/BufImgSurfaceData.java | 2 +- .../sun/awt/image/GifImageDecoder.java | 2 +- .../classes/sun/awt/image/ImageDecoder.java | 4 +- .../classes/sun/awt/image/ImageFetcher.java | 41 ++++---- .../sun/awt/image/ImageRepresentation.java | 2 +- .../classes/sun/awt/image/ImagingLib.java | 4 +- .../sun/awt/image/JPEGImageDecoder.java | 6 +- .../sun/awt/image/OffScreenImageSource.java | 6 +- .../sun/awt/image/PNGImageDecoder.java | 4 +- .../classes/sun/awt/image/ToolkitImage.java | 6 +- .../classes/sun/awt/shell/ShellFolder.java | 12 ++- .../sun/awt/shell/ShellFolderColumnInfo.java | 10 +- .../sun/awt/util/IdentityArrayList.java | 7 +- .../sun/awt/util/IdentityLinkedList.java | 11 ++- .../classes/sun/awt/X11/InfoWindow.java | 5 +- .../classes/sun/awt/X11/ListHelper.java | 16 ++-- .../awt/X11/MotifDnDDragSourceProtocol.java | 3 +- .../solaris/classes/sun/awt/X11/Native.java | 21 ++--- .../classes/sun/awt/X11/XAWTXSettings.java | 8 +- .../classes/sun/awt/X11/XAtomList.java | 2 +- .../classes/sun/awt/X11/XAwtState.java | 12 +-- .../classes/sun/awt/X11/XBaseMenuWindow.java | 6 +- .../classes/sun/awt/X11/XComponentPeer.java | 14 +-- .../sun/awt/X11/XCreateWindowParams.java | 6 +- .../classes/sun/awt/X11/XDataTransferer.java | 3 +- .../sun/awt/X11/XDnDDragSourceProtocol.java | 3 +- .../sun/awt/X11/XDragAndDropProtocols.java | 24 ++--- .../sun/awt/X11/XDragSourceContextPeer.java | 24 +++-- .../sun/awt/X11/XDragSourceProtocol.java | 6 +- .../sun/awt/X11/XDropTargetContextPeer.java | 17 ++-- .../awt/X11/XDropTargetEventProcessor.java | 5 +- .../sun/awt/X11/XDropTargetProtocol.java | 6 +- .../sun/awt/X11/XDropTargetRegistry.java | 53 +++++------ .../sun/awt/X11/XEmbeddingContainer.java | 2 +- .../classes/sun/awt/X11/XFileDialogPeer.java | 6 +- .../classes/sun/awt/X11/XListPeer.java | 16 ++-- .../classes/sun/awt/X11/XMSelection.java | 24 ++--- .../classes/sun/awt/X11/XMenuBarPeer.java | 6 +- .../classes/sun/awt/X11/XMenuPeer.java | 2 +- .../classes/sun/awt/X11/XMenuWindow.java | 4 +- .../classes/sun/awt/X11/XPopupMenuPeer.java | 4 +- .../classes/sun/awt/X11/XSelection.java | 6 +- .../solaris/classes/sun/awt/X11/XToolkit.java | 94 +++++++++---------- .../classes/sun/awt/X11/XTrayIconPeer.java | 2 +- jdk/src/solaris/classes/sun/awt/X11/XWM.java | 5 +- .../solaris/classes/sun/awt/X11/XWindow.java | 8 +- .../classes/sun/awt/X11/XWindowPeer.java | 2 +- .../classes/sun/awt/X11CustomCursor.java | 6 +- .../classes/sun/awt/X11FontManager.java | 42 ++++----- .../classes/sun/awt/X11GraphicsDevice.java | 8 +- .../sun/awt/X11GraphicsEnvironment.java | 14 +-- .../classes/sun/awt/X11InputMethod.java | 28 +++--- .../solaris/classes/sun/awt/XSettings.java | 8 +- .../sun/awt/motif/MFontConfiguration.java | 6 +- 72 files changed, 452 insertions(+), 437 deletions(-) diff --git a/jdk/src/share/classes/java/awt/Menu.java b/jdk/src/share/classes/java/awt/Menu.java index 629371868d1..ae8e50ea7e1 100644 --- a/jdk/src/share/classes/java/awt/Menu.java +++ b/jdk/src/share/classes/java/awt/Menu.java @@ -66,7 +66,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible { AWTAccessor.setMenuAccessor( new AWTAccessor.MenuAccessor() { - public Vector<MenuComponent> getItems(Menu menu) { + public Vector<MenuItem> getItems(Menu menu) { return menu.items; } }); @@ -78,7 +78,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible { * @serial * @see #countItems() */ - Vector<MenuComponent> items = new Vector<>(); + Vector<MenuItem> items = new Vector<>(); /** * This field indicates whether the menu has the @@ -252,7 +252,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible { * be called on the toolkit thread. */ final MenuItem getItemImpl(int index) { - return (MenuItem)items.elementAt(index); + return items.elementAt(index); } /** @@ -544,7 +544,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible { // HeadlessException will be thrown from MenuComponent's readObject s.defaultReadObject(); for(int i = 0; i < items.size(); i++) { - MenuItem item = (MenuItem)items.elementAt(i); + MenuItem item = items.elementAt(i); item.parent = this; } } diff --git a/jdk/src/share/classes/sun/awt/AWTAccessor.java b/jdk/src/share/classes/sun/awt/AWTAccessor.java index b99ccdfe2ee..1d60a1c332d 100644 --- a/jdk/src/share/classes/sun/awt/AWTAccessor.java +++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java @@ -621,7 +621,7 @@ public final class AWTAccessor { /** * Returns menus */ - Vector getMenus(MenuBar menuBar); + Vector<Menu> getMenus(MenuBar menuBar); } /** @@ -663,7 +663,7 @@ public final class AWTAccessor { /** * Returns vector of the items that are part of the Menu */ - Vector getItems(Menu menu); + Vector<MenuItem> getItems(Menu menu); } /** diff --git a/jdk/src/share/classes/sun/awt/AppContext.java b/jdk/src/share/classes/sun/awt/AppContext.java index 5959e54dea4..23653ba7387 100644 --- a/jdk/src/share/classes/sun/awt/AppContext.java +++ b/jdk/src/share/classes/sun/awt/AppContext.java @@ -890,6 +890,7 @@ public final class AppContext { Supplier<T> supplier) { final AppContext appContext = AppContext.getAppContext(); + @SuppressWarnings("unchecked") SoftReference<T> ref = (SoftReference<T>) appContext.get(key); if (ref != null) { final T object = ref.get(); diff --git a/jdk/src/share/classes/sun/awt/FontConfiguration.java b/jdk/src/share/classes/sun/awt/FontConfiguration.java index f95b36805df..c234b534633 100644 --- a/jdk/src/share/classes/sun/awt/FontConfiguration.java +++ b/jdk/src/share/classes/sun/awt/FontConfiguration.java @@ -64,7 +64,7 @@ public abstract class FontConfiguration { protected static String osName; protected static String encoding; // canonical name of default nio charset protected static Locale startupLocale = null; - protected static Hashtable localeMap = null; + protected static Hashtable<String, String> localeMap = null; private static FontConfiguration fontConfig; private static PlatformLogger logger; protected static boolean isProperties = true; @@ -159,15 +159,15 @@ public abstract class FontConfiguration { short fontNameID = compFontNameIDs[0][0][0]; short fileNameID = getComponentFileID(fontNameID); final String fileName = mapFileName(getComponentFileName(fileNameID)); - Boolean exists = (Boolean)java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + Boolean exists = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction<Boolean>() { + public Boolean run() { try { File f = new File(fileName); return Boolean.valueOf(f.exists()); } catch (Exception e) { - return false; + return Boolean.FALSE; } } }); @@ -534,11 +534,11 @@ public abstract class FontConfiguration { private short remapLocaleMap(int fontIndex, int styleIndex, short scriptID, short fontID) { String scriptName = getString(table_scriptIDs[scriptID]); - String value = (String)localeMap.get(scriptName); + String value = localeMap.get(scriptName); if (value == null) { String fontName = fontNames[fontIndex]; String styleName = styleNames[styleIndex]; - value = (String)localeMap.get(fontName + "." + styleName + "." + scriptName); + value = localeMap.get(fontName + "." + styleName + "." + scriptName); } if (value == null) { return fontID; @@ -746,7 +746,7 @@ public abstract class FontConfiguration { /* Mappings from file encoding to font config name for font supporting * the corresponding language. This is filled in by initReorderMap() */ - protected HashMap reorderMap = null; + protected HashMap<String, Object> reorderMap = null; /* Platform-specific mappings */ protected abstract void initReorderMap(); @@ -777,7 +777,7 @@ public abstract class FontConfiguration { if (fontConfig.reorderMap == null) { fontConfig.initReorderMap(); } - HashMap reorderMap = fontConfig.reorderMap; + HashMap<String, Object> reorderMap = fontConfig.reorderMap; /* Find the most specific mapping */ String language = startupLocale.getLanguage(); @@ -817,9 +817,9 @@ public abstract class FontConfiguration { } } - private static Vector splitSequence(String sequence) { + private static Vector<String> splitSequence(String sequence) { //String.split would be more convenient, but incurs big performance penalty - Vector parts = new Vector(); + Vector<String> parts = new Vector<>(); int start = 0; int end; while ((end = sequence.indexOf(',', start)) >= 0) { @@ -833,14 +833,14 @@ public abstract class FontConfiguration { } protected String[] split(String sequence) { - Vector v = splitSequence(sequence); - return (String[])v.toArray(new String[0]); + Vector<String> v = splitSequence(sequence); + return v.toArray(new String[0]); } //////////////////////////////////////////////////////////////////////// // Methods for extracting information from the fontconfig data for AWT// //////////////////////////////////////////////////////////////////////// - private Hashtable charsetRegistry = new Hashtable(5); + private Hashtable<String, Charset> charsetRegistry = new Hashtable<>(5); /** * Returns FontDescriptors describing the physical fonts used for the @@ -932,9 +932,9 @@ public abstract class FontConfiguration { Charset fc = null; if (charsetName.equals("default")) { - fc = (Charset) charsetRegistry.get(fontName); + fc = charsetRegistry.get(fontName); } else { - fc = (Charset) charsetRegistry.get(charsetName); + fc = charsetRegistry.get(charsetName); } if (fc != null) { return fc.newEncoder(); @@ -943,8 +943,8 @@ public abstract class FontConfiguration { if (!charsetName.startsWith("sun.awt.") && !charsetName.equals("default")) { fc = Charset.forName(charsetName); } else { - Class fcc = (Class) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + Class<?> fcc = AccessController.doPrivileged(new PrivilegedAction<Class<?>>() { + public Class<?> run() { try { return Class.forName(charsetName, true, ClassLoader.getSystemClassLoader()); @@ -1377,9 +1377,9 @@ public abstract class FontConfiguration { //This method will only be called during build time, do we //need do PrivilegedAction? - String osName = (String)java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + String osName = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction<String>() { + public String run() { return System.getProperty("os.name"); } }); @@ -2139,7 +2139,7 @@ public abstract class FontConfiguration { boolean has1252 = false; //get the scriptID list - String[] ss = (String[])splitSequence(value).toArray(EMPTY_STRING_ARRAY); + String[] ss = splitSequence(value).toArray(EMPTY_STRING_ARRAY); short [] sa = new short[ss.length]; for (int i = 0; i < ss.length; i++) { if ("alphabetic/default".equals(ss[i])) { diff --git a/jdk/src/share/classes/sun/awt/HToolkit.java b/jdk/src/share/classes/sun/awt/HToolkit.java index fdce8ccdcfc..81edd5ef641 100644 --- a/jdk/src/share/classes/sun/awt/HToolkit.java +++ b/jdk/src/share/classes/sun/awt/HToolkit.java @@ -214,7 +214,8 @@ public class HToolkit extends SunToolkit throw new HeadlessException(); } - public Map mapInputMethodHighlight(InputMethodHighlight highlight) + public Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlight( + InputMethodHighlight highlight) throws HeadlessException { throw new HeadlessException(); } diff --git a/jdk/src/share/classes/sun/awt/HeadlessToolkit.java b/jdk/src/share/classes/sun/awt/HeadlessToolkit.java index 9d68bd48b1e..08890486486 100644 --- a/jdk/src/share/classes/sun/awt/HeadlessToolkit.java +++ b/jdk/src/share/classes/sun/awt/HeadlessToolkit.java @@ -29,6 +29,7 @@ import java.awt.*; import java.awt.dnd.*; import java.awt.dnd.peer.DragSourceContextPeer; import java.awt.event.*; +import java.awt.font.TextAttribute; import java.awt.im.InputMethodHighlight; import java.awt.image.*; import java.awt.datatransfer.Clipboard; @@ -224,7 +225,7 @@ public class HeadlessToolkit extends Toolkit throw new HeadlessException(); } - public Map mapInputMethodHighlight(InputMethodHighlight highlight) + public Map<TextAttribute, ?> mapInputMethodHighlight(InputMethodHighlight highlight) throws HeadlessException { throw new HeadlessException(); } diff --git a/jdk/src/share/classes/sun/awt/PlatformFont.java b/jdk/src/share/classes/sun/awt/PlatformFont.java index f88b192715f..02596457d6f 100644 --- a/jdk/src/share/classes/sun/awt/PlatformFont.java +++ b/jdk/src/share/classes/sun/awt/PlatformFont.java @@ -143,7 +143,7 @@ public abstract class PlatformFont implements FontPeer { if (len < 1) { return new CharsetString[0]; } - Vector mcs = null; + Vector<CharsetString> mcs = null; char[] tmpStr = new char[len]; char tmpChar = defaultChar; boolean encoded = false; @@ -198,7 +198,7 @@ public abstract class PlatformFont implements FontPeer { } if (currentFont != fd){ if (mcs == null) { - mcs = new Vector(3); + mcs = new Vector<>(3); } mcs.addElement(new CharsetString(tmpStr, lastIndex, i-lastIndex, currentFont)); @@ -209,16 +209,13 @@ public abstract class PlatformFont implements FontPeer { } CharsetString[] result; CharsetString cs = new CharsetString(tmpStr, lastIndex, - len-lastIndex, currentFont); + len-lastIndex, currentFont); if (mcs == null) { result = new CharsetString[1]; result[0] = cs; } else { mcs.addElement(cs); - result = new CharsetString[mcs.size()]; - for (int i = 0; i < mcs.size(); i++){ - result[i] = (CharsetString)mcs.elementAt(i); - } + result = mcs.toArray(new CharsetString[mcs.size()]); } return result; } diff --git a/jdk/src/share/classes/sun/awt/SunToolkit.java b/jdk/src/share/classes/sun/awt/SunToolkit.java index 1cb15b78a01..6739a603c5d 100644 --- a/jdk/src/share/classes/sun/awt/SunToolkit.java +++ b/jdk/src/share/classes/sun/awt/SunToolkit.java @@ -1915,6 +1915,7 @@ public abstract class SunToolkit extends Toolkit public synchronized void setWindowDeactivationTime(Window w, long time) { AppContext ctx = getAppContext(w); + @SuppressWarnings("unchecked") WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY); if (map == null) { map = new WeakHashMap<Window, Long>(); @@ -1925,6 +1926,7 @@ public abstract class SunToolkit extends Toolkit public synchronized long getWindowDeactivationTime(Window w) { AppContext ctx = getAppContext(w); + @SuppressWarnings("unchecked") WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY); if (map == null) { return -1; diff --git a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java index d9c8334df8a..367d90e0b90 100644 --- a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java +++ b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java @@ -324,7 +324,7 @@ public abstract class DataTransferer { return false; } - Class rep_class = flavor.getRepresentationClass(); + Class<?> rep_class = flavor.getRepresentationClass(); if (flavor.isRepresentationClassReader() || String.class.equals(rep_class) || @@ -696,7 +696,7 @@ public abstract class DataTransferer { * DataFlavors and data formats * @throws NullPointerException if formats or map is <code>null</code> */ - public Set getFlavorsForFormatsAsSet(long[] formats, FlavorTable map) { + public Set<DataFlavor> getFlavorsForFormatsAsSet(long[] formats, FlavorTable map) { Set<DataFlavor> flavorSet = new HashSet<>(formats.length); for (long format : formats) { @@ -1085,7 +1085,7 @@ search: throw new IOException("data translation failed"); } - final List list = (List)obj; + final List<?> list = (List<?>)obj; final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents); @@ -1113,7 +1113,7 @@ search: if (targetCharset == null) { targetCharset = "UTF-8"; } - final List list = (List)obj; + final List<?> list = (List<?>)obj; final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents); final ArrayList<String> fileList = castToFiles(list, userProtectionDomain); final ArrayList<String> uriList = new ArrayList<>(fileList.size()); @@ -1258,7 +1258,7 @@ search: return true; } - private ArrayList<String> castToFiles(final List files, + private ArrayList<String> castToFiles(final List<?> files, final ProtectionDomain userProtectionDomain) throws IOException { try { return AccessController.doPrivileged((PrivilegedExceptionAction<ArrayList<String>>) () -> { @@ -1636,7 +1636,7 @@ search: * instance of the Class as its sole parameter. */ private Object constructFlavoredObject(Object arg, DataFlavor flavor, - Class clazz) + Class<?> clazz) throws IOException { final Class<?> dfrc = flavor.getRepresentationClass(); @@ -1644,19 +1644,19 @@ search: if (clazz.equals(dfrc)) { return arg; // simple case } else { - Constructor[] constructors; + Constructor<?>[] constructors; try { constructors = AccessController.doPrivileged( - (PrivilegedAction<Constructor[]>) dfrc::getConstructors); + (PrivilegedAction<Constructor<?>[]>) dfrc::getConstructors); } catch (SecurityException se) { throw new IOException(se.getMessage()); } - Constructor constructor = Stream.of(constructors) + Constructor<?> constructor = Stream.of(constructors) .filter(c -> Modifier.isPublic(c.getModifiers())) .filter(c -> { - Class[] ptypes = c.getParameterTypes(); + Class<?>[] ptypes = c.getParameterTypes(); return ptypes != null && ptypes.length == 1 && clazz.equals(ptypes[0]); @@ -1865,7 +1865,8 @@ search: byte[] bytes, String mimeType) throws IOException { - Iterator readerIterator = ImageIO.getImageReadersByMIMEType(mimeType); + Iterator<ImageReader> readerIterator = + ImageIO.getImageReadersByMIMEType(mimeType); if (!readerIterator.hasNext()) { throw new IOException("No registered service provider can decode " + @@ -1875,7 +1876,7 @@ search: IOException ioe = null; while (readerIterator.hasNext()) { - ImageReader imageReader = (ImageReader)readerIterator.next(); + ImageReader imageReader = readerIterator.next(); try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) { try (ImageInputStream imageInputStream = ImageIO.createImageInputStream(bais)) { ImageReadParam param = imageReader.getDefaultReadParam(); @@ -1918,7 +1919,8 @@ search: throws IOException { IOException originalIOE = null; - Iterator writerIterator = ImageIO.getImageWritersByMIMEType(mimeType); + Iterator<ImageWriter> writerIterator = + ImageIO.getImageWritersByMIMEType(mimeType); if (!writerIterator.hasNext()) { throw new IOException("No registered service provider can encode " + @@ -1977,7 +1979,8 @@ search: String mimeType) throws IOException { - Iterator writerIterator = ImageIO.getImageWritersByMIMEType(mimeType); + Iterator<ImageWriter> writerIterator = + ImageIO.getImageWritersByMIMEType(mimeType); ImageTypeSpecifier typeSpecifier = new ImageTypeSpecifier(renderedImage); @@ -1986,7 +1989,7 @@ search: IOException ioe = null; while (writerIterator.hasNext()) { - ImageWriter imageWriter = (ImageWriter)writerIterator.next(); + ImageWriter imageWriter = writerIterator.next(); ImageWriterSpi writerSpi = imageWriter.getOriginatingProvider(); if (!writerSpi.canEncodeImage(typeSpecifier)) { @@ -2070,7 +2073,7 @@ search: public byte[] convertData(final Object source, final Transferable contents, final long format, - final Map formatMap, + final Map<Long, DataFlavor> formatMap, final boolean isToolkitThread) throws IOException { @@ -2093,7 +2096,7 @@ search: } byte[] data = null; try { - DataFlavor flavor = (DataFlavor)formatMap.get(format); + DataFlavor flavor = formatMap.get(format); if (flavor != null) { data = translateTransferable(contents, flavor, format); } @@ -2134,7 +2137,7 @@ search: } finally { getToolkitThreadBlockedHandler().unlock(); } else { - DataFlavor flavor = (DataFlavor)formatMap.get(format); + DataFlavor flavor = formatMap.get(format); if (flavor != null) { ret = translateTransferable(contents, flavor, format); } @@ -2183,7 +2186,7 @@ search: * Helper function to convert a Set of DataFlavors to a sorted array. * The array will be sorted according to <code>DataFlavorComparator</code>. */ - public static DataFlavor[] setToSortedDataFlavorArray(Set flavorsSet) { + public static DataFlavor[] setToSortedDataFlavorArray(Set<DataFlavor> flavorsSet) { DataFlavor[] flavors = new DataFlavor[flavorsSet.size()]; flavorsSet.toArray(flavors); final Comparator<DataFlavor> comparator = @@ -2544,12 +2547,12 @@ search: String primaryType1 = flavor1.getPrimaryType(); String subType1 = flavor1.getSubType(); String mimeType1 = primaryType1 + "/" + subType1; - Class class1 = flavor1.getRepresentationClass(); + Class<?> class1 = flavor1.getRepresentationClass(); String primaryType2 = flavor2.getPrimaryType(); String subType2 = flavor2.getSubType(); String mimeType2 = primaryType2 + "/" + subType2; - Class class2 = flavor2.getRepresentationClass(); + Class<?> class2 = flavor2.getRepresentationClass(); if (flavor1.isFlavorTextType() && flavor2.isFlavorTextType()) { // First, compare MIME types diff --git a/jdk/src/share/classes/sun/awt/datatransfer/SunClipboard.java b/jdk/src/share/classes/sun/awt/datatransfer/SunClipboard.java index 77162cbadd3..258a298adbe 100644 --- a/jdk/src/share/classes/sun/awt/datatransfer/SunClipboard.java +++ b/jdk/src/share/classes/sun/awt/datatransfer/SunClipboard.java @@ -78,7 +78,7 @@ public abstract class SunClipboard extends Clipboard * this clipboard. It is used for tracking changes * of <code>DataFlavor</code>s available on this clipboard. */ - private volatile Set currentDataFlavors; + private volatile Set<DataFlavor> currentDataFlavors; public SunClipboard(String name) { @@ -338,7 +338,7 @@ public abstract class SunClipboard extends Clipboard protected abstract byte[] getClipboardData(long format) throws IOException; - private static Set formatArrayAsDataFlavorSet(long[] formats) { + private static Set<DataFlavor> formatArrayAsDataFlavorSet(long[] formats) { return (formats == null) ? null : DataTransferer.getInstance(). getFlavorsForFormatsAsSet(formats, getDefaultFlavorTable()); @@ -417,7 +417,7 @@ public abstract class SunClipboard extends Clipboard * this clipboard */ public void checkChange(long[] formats) { - Set prevDataFlavors = currentDataFlavors; + Set<DataFlavor> prevDataFlavors = currentDataFlavors; currentDataFlavors = formatArrayAsDataFlavorSet(formats); if (Objects.equals(prevDataFlavors, currentDataFlavors)) { diff --git a/jdk/src/share/classes/sun/awt/datatransfer/TransferableProxy.java b/jdk/src/share/classes/sun/awt/datatransfer/TransferableProxy.java index ac79ecf7127..39ba273ec54 100644 --- a/jdk/src/share/classes/sun/awt/datatransfer/TransferableProxy.java +++ b/jdk/src/share/classes/sun/awt/datatransfer/TransferableProxy.java @@ -111,9 +111,9 @@ final class ClassLoaderObjectOutputStream extends ObjectOutputStream { } protected void annotateClass(final Class<?> cl) throws IOException { - ClassLoader classLoader = - (ClassLoader)AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + ClassLoader classLoader = AccessController.doPrivileged( + new PrivilegedAction<ClassLoader>() { + public ClassLoader run() { return cl.getClassLoader(); } }); @@ -124,14 +124,14 @@ final class ClassLoaderObjectOutputStream extends ObjectOutputStream { map.put(s, classLoader); } protected void annotateProxyClass(final Class<?> cl) throws IOException { - ClassLoader classLoader = - (ClassLoader)AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + ClassLoader classLoader = AccessController.doPrivileged( + new PrivilegedAction<ClassLoader>() { + public ClassLoader run() { return cl.getClassLoader(); } }); - Class[] interfaces = cl.getInterfaces(); + Class<?>[] interfaces = cl.getInterfaces(); Set<String> s = new HashSet<String>(interfaces.length); for (int i = 0; i < interfaces.length; i++) { s.add(interfaces[i].getName()); @@ -141,7 +141,7 @@ final class ClassLoaderObjectOutputStream extends ObjectOutputStream { } Map<Set<String>, ClassLoader> getClassLoaderMap() { - return new HashMap(map); + return new HashMap<>(map); } } @@ -191,9 +191,9 @@ final class ClassLoaderObjectInputStream extends ObjectInputStream { boolean hasNonPublicInterface = false; // define proxy in class loader of non-public interface(s), if any - Class[] classObjs = new Class[interfaces.length]; + Class<?>[] classObjs = new Class<?>[interfaces.length]; for (int i = 0; i < interfaces.length; i++) { - Class cl = Class.forName(interfaces[i], false, classLoader); + Class<?> cl = Class.forName(interfaces[i], false, classLoader); if ((cl.getModifiers() & Modifier.PUBLIC) == 0) { if (hasNonPublicInterface) { if (nonPublicLoader != cl.getClassLoader()) { diff --git a/jdk/src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java b/jdk/src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java index ae0a642dcb2..8baa689296f 100644 --- a/jdk/src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java +++ b/jdk/src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java @@ -146,7 +146,7 @@ public abstract class SunDragSourceContextPeer implements DragSourceContextPeer } protected abstract void startDrag(Transferable trans, - long[] formats, Map formatMap); + long[] formats, Map<Long, DataFlavor> formatMap); /** * set cursor diff --git a/jdk/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java b/jdk/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java index 842b387f6f4..a880f1235f6 100644 --- a/jdk/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java +++ b/jdk/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java @@ -252,11 +252,11 @@ public abstract class SunDropTargetContextPeer implements DropTargetContextPeer, throw new InvalidDnDOperationException("No drop current"); } - Map flavorMap = DataTransferer.getInstance().getFlavorsForFormats - (currentT, DataTransferer.adaptFlavorMap + Map<DataFlavor, Long> flavorMap = DataTransferer.getInstance() + .getFlavorsForFormats(currentT, DataTransferer.adaptFlavorMap (currentDT.getFlavorMap())); - lFormat = (Long)flavorMap.get(df); + lFormat = flavorMap.get(df); if (lFormat == null) { throw new UnsupportedFlavorException(df); } @@ -745,7 +745,7 @@ public abstract class SunDropTargetContextPeer implements DropTargetContextPeer, // dispatcher state fields private int returnValue = 0; // set of events to be dispatched by this dispatcher - private final HashSet eventSet = new HashSet(3); + private final HashSet<SunDropTargetEvent> eventSet = new HashSet<>(3); static final ToolkitThreadBlockedHandler handler = DataTransferer.getInstance().getToolkitThreadBlockedHandler(); diff --git a/jdk/src/share/classes/sun/awt/geom/AreaOp.java b/jdk/src/share/classes/sun/awt/geom/AreaOp.java index dd9e957cc28..bdbf2cb2b7e 100644 --- a/jdk/src/share/classes/sun/awt/geom/AreaOp.java +++ b/jdk/src/share/classes/sun/awt/geom/AreaOp.java @@ -152,36 +152,36 @@ public abstract class AreaOp { public abstract int getState(); - public Vector calculate(Vector left, Vector right) { - Vector edges = new Vector(); + public Vector<Curve> calculate(Vector<Curve> left, Vector<Curve> right) { + Vector<Edge> edges = new Vector<>(); addEdges(edges, left, AreaOp.CTAG_LEFT); addEdges(edges, right, AreaOp.CTAG_RIGHT); - edges = pruneEdges(edges); + Vector<Curve> curves = pruneEdges(edges); if (false) { System.out.println("result: "); - int numcurves = edges.size(); - Curve[] curvelist = (Curve[]) edges.toArray(new Curve[numcurves]); + int numcurves = curves.size(); + Curve[] curvelist = curves.toArray(new Curve[numcurves]); for (int i = 0; i < numcurves; i++) { System.out.println("curvelist["+i+"] = "+curvelist[i]); } } - return edges; + return curves; } - private static void addEdges(Vector edges, Vector curves, int curvetag) { - Enumeration enum_ = curves.elements(); + private static void addEdges(Vector<Edge> edges, Vector<Curve> curves, int curvetag) { + Enumeration<Curve> enum_ = curves.elements(); while (enum_.hasMoreElements()) { - Curve c = (Curve) enum_.nextElement(); + Curve c = enum_.nextElement(); if (c.getOrder() > 0) { edges.add(new Edge(c, curvetag)); } } } - private static Comparator YXTopComparator = new Comparator() { - public int compare(Object o1, Object o2) { - Curve c1 = ((Edge) o1).getCurve(); - Curve c2 = ((Edge) o2).getCurve(); + private static Comparator<Edge> YXTopComparator = new Comparator<Edge>() { + public int compare(Edge o1, Edge o2) { + Curve c1 = o1.getCurve(); + Curve c2 = o2.getCurve(); double v1, v2; if ((v1 = c1.getYTop()) == (v2 = c2.getYTop())) { if ((v1 = c1.getXTop()) == (v2 = c2.getXTop())) { @@ -195,12 +195,13 @@ public abstract class AreaOp { } }; - private Vector pruneEdges(Vector edges) { + private Vector<Curve> pruneEdges(Vector<Edge> edges) { int numedges = edges.size(); if (numedges < 2) { - return edges; + // empty vector is expected with less than 2 edges + return new Vector<>(); } - Edge[] edgelist = (Edge[]) edges.toArray(new Edge[numedges]); + Edge[] edgelist = edges.toArray(new Edge[numedges]); Arrays.sort(edgelist, YXTopComparator); if (false) { System.out.println("pruning: "); @@ -214,9 +215,9 @@ public abstract class AreaOp { int cur = 0; int next = 0; double yrange[] = new double[2]; - Vector subcurves = new Vector(); - Vector chains = new Vector(); - Vector links = new Vector(); + Vector<CurveLink> subcurves = new Vector<>(); + Vector<ChainEnd> chains = new Vector<>(); + Vector<CurveLink> links = new Vector<>(); // Active edges are between left (inclusive) and right (exclusive) while (left < numedges) { double y = yrange[0]; @@ -385,7 +386,7 @@ public abstract class AreaOp { if (false) { System.out.println("new links:"); for (int i = 0; i < links.size(); i++) { - CurveLink link = (CurveLink) links.elementAt(i); + CurveLink link = links.elementAt(i); System.out.println(" "+link.getSubCurve()); } } @@ -396,10 +397,10 @@ public abstract class AreaOp { yrange[0] = yend; } finalizeSubCurves(subcurves, chains); - Vector ret = new Vector(); - Enumeration enum_ = subcurves.elements(); + Vector<Curve> ret = new Vector<>(); + Enumeration<CurveLink> enum_ = subcurves.elements(); while (enum_.hasMoreElements()) { - CurveLink link = (CurveLink) enum_.nextElement(); + CurveLink link = enum_.nextElement(); ret.add(link.getMoveto()); CurveLink nextlink = link; while ((nextlink = nextlink.getNext()) != null) { @@ -413,7 +414,8 @@ public abstract class AreaOp { return ret; } - public static void finalizeSubCurves(Vector subcurves, Vector chains) { + public static void finalizeSubCurves(Vector<CurveLink> subcurves, + Vector<ChainEnd> chains) { int numchains = chains.size(); if (numchains == 0) { return; @@ -437,9 +439,9 @@ public abstract class AreaOp { private static CurveLink[] EmptyLinkList = new CurveLink[2]; private static ChainEnd[] EmptyChainList = new ChainEnd[2]; - public static void resolveLinks(Vector subcurves, - Vector chains, - Vector links) + public static void resolveLinks(Vector<CurveLink> subcurves, + Vector<ChainEnd> chains, + Vector<CurveLink> links) { int numlinks = links.size(); CurveLink[] linklist; diff --git a/jdk/src/share/classes/sun/awt/geom/Crossings.java b/jdk/src/share/classes/sun/awt/geom/Crossings.java index 7ab97bce80c..76a29a15d45 100644 --- a/jdk/src/share/classes/sun/awt/geom/Crossings.java +++ b/jdk/src/share/classes/sun/awt/geom/Crossings.java @@ -77,14 +77,14 @@ public abstract class Crossings { public abstract boolean covers(double ystart, double yend); - public static Crossings findCrossings(Vector curves, + public static Crossings findCrossings(Vector<? extends Curve> curves, double xlo, double ylo, double xhi, double yhi) { Crossings cross = new EvenOdd(xlo, ylo, xhi, yhi); - Enumeration enum_ = curves.elements(); + Enumeration<? extends Curve> enum_ = curves.elements(); while (enum_.hasMoreElements()) { - Curve c = (Curve) enum_.nextElement(); + Curve c = enum_.nextElement(); if (c.accumulateCrossings(cross)) { return null; } @@ -237,7 +237,7 @@ public abstract class Crossings { return false; } - private Vector tmp = new Vector(); + private Vector<Curve> tmp = new Vector<>(); public boolean accumulateQuad(double x0, double y0, double coords[]) { if (y0 < ylo && coords[1] < ylo && coords[3] < ylo) { @@ -258,9 +258,9 @@ public abstract class Crossings { return false; } Curve.insertQuad(tmp, x0, y0, coords); - Enumeration enum_ = tmp.elements(); + Enumeration<Curve> enum_ = tmp.elements(); while (enum_.hasMoreElements()) { - Curve c = (Curve) enum_.nextElement(); + Curve c = enum_.nextElement(); if (c.accumulateCrossings(this)) { return true; } @@ -296,9 +296,9 @@ public abstract class Crossings { return false; } Curve.insertCubic(tmp, x0, y0, coords); - Enumeration enum_ = tmp.elements(); + Enumeration<Curve> enum_ = tmp.elements(); while (enum_.hasMoreElements()) { - Curve c = (Curve) enum_.nextElement(); + Curve c = enum_.nextElement(); if (c.accumulateCrossings(this)) { return true; } diff --git a/jdk/src/share/classes/sun/awt/geom/Curve.java b/jdk/src/share/classes/sun/awt/geom/Curve.java index 871be17f4c8..bc478da02b3 100644 --- a/jdk/src/share/classes/sun/awt/geom/Curve.java +++ b/jdk/src/share/classes/sun/awt/geom/Curve.java @@ -38,11 +38,11 @@ public abstract class Curve { protected int direction; - public static void insertMove(Vector curves, double x, double y) { + public static void insertMove(Vector<Curve> curves, double x, double y) { curves.add(new Order0(x, y)); } - public static void insertLine(Vector curves, + public static void insertLine(Vector<Curve> curves, double x0, double y0, double x1, double y1) { @@ -59,7 +59,7 @@ public abstract class Curve { } } - public static void insertQuad(Vector curves, + public static void insertQuad(Vector<Curve> curves, double x0, double y0, double coords[]) { @@ -82,7 +82,7 @@ public abstract class Curve { } } - public static void insertCubic(Vector curves, + public static void insertCubic(Vector<Curve> curves, double x0, double y0, double coords[]) { diff --git a/jdk/src/share/classes/sun/awt/geom/Order2.java b/jdk/src/share/classes/sun/awt/geom/Order2.java index 69218f5a95e..64d37c88e27 100644 --- a/jdk/src/share/classes/sun/awt/geom/Order2.java +++ b/jdk/src/share/classes/sun/awt/geom/Order2.java @@ -47,7 +47,7 @@ final class Order2 extends Curve { private double ycoeff1; private double ycoeff2; - public static void insert(Vector curves, double tmp[], + public static void insert(Vector<Curve> curves, double tmp[], double x0, double y0, double cx0, double cy0, double x1, double y1, @@ -74,7 +74,7 @@ final class Order2 extends Curve { tmp[i1 + 4], tmp[i1 + 5], direction); } - public static void addInstance(Vector curves, + public static void addInstance(Vector<Curve> curves, double x0, double y0, double cx0, double cy0, double x1, double y1, diff --git a/jdk/src/share/classes/sun/awt/geom/Order3.java b/jdk/src/share/classes/sun/awt/geom/Order3.java index ad49c676db3..9c9e5962aea 100644 --- a/jdk/src/share/classes/sun/awt/geom/Order3.java +++ b/jdk/src/share/classes/sun/awt/geom/Order3.java @@ -53,7 +53,7 @@ final class Order3 extends Curve { private double ycoeff2; private double ycoeff3; - public static void insert(Vector curves, double tmp[], + public static void insert(Vector<Curve> curves, double tmp[], double x0, double y0, double cx0, double cy0, double cx1, double cy1, @@ -105,7 +105,7 @@ final class Order3 extends Curve { } } - public static void addInstance(Vector curves, + public static void addInstance(Vector<Curve> curves, double x0, double y0, double cx0, double cy0, double cx1, double cy1, diff --git a/jdk/src/share/classes/sun/awt/image/BufImgSurfaceData.java b/jdk/src/share/classes/sun/awt/image/BufImgSurfaceData.java index efc4bc97ec4..ac26802b027 100644 --- a/jdk/src/share/classes/sun/awt/image/BufImgSurfaceData.java +++ b/jdk/src/share/classes/sun/awt/image/BufImgSurfaceData.java @@ -51,7 +51,7 @@ public class BufImgSurfaceData extends SurfaceData { private BufferedImageGraphicsConfig graphicsConfig; RenderLoops solidloops; - private static native void initIDs(Class ICM, Class ICMColorData); + private static native void initIDs(Class<?> ICM, Class<?> ICMColorData); private static final int DCM_RGBX_RED_MASK = 0xff000000; private static final int DCM_RGBX_GREEN_MASK = 0x00ff0000; diff --git a/jdk/src/share/classes/sun/awt/image/GifImageDecoder.java b/jdk/src/share/classes/sun/awt/image/GifImageDecoder.java index bd8efa8d1a3..33640165fb2 100644 --- a/jdk/src/share/classes/sun/awt/image/GifImageDecoder.java +++ b/jdk/src/share/classes/sun/awt/image/GifImageDecoder.java @@ -61,7 +61,7 @@ public class GifImageDecoder extends ImageDecoder { int trans_pixel = -1; IndexColorModel global_model; - Hashtable props = new Hashtable(); + Hashtable<String, Object> props = new Hashtable<>(); byte[] saved_image; IndexColorModel saved_model; diff --git a/jdk/src/share/classes/sun/awt/image/ImageDecoder.java b/jdk/src/share/classes/sun/awt/image/ImageDecoder.java index 643ec638f11..7f4bbd85efa 100644 --- a/jdk/src/share/classes/sun/awt/image/ImageDecoder.java +++ b/jdk/src/share/classes/sun/awt/image/ImageDecoder.java @@ -83,7 +83,7 @@ public abstract class ImageDecoder { return count; } - protected int setProperties(Hashtable props) { + protected int setProperties(Hashtable<?,?> props) { ImageConsumerQueue cq = null; int count = 0; while ((cq = nextConsumer(cq)) != null) { @@ -164,7 +164,7 @@ public abstract class ImageDecoder { source.doneDecoding(this); close(); java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction<Object>() { public Object run() { feeder.interrupt(); return null; diff --git a/jdk/src/share/classes/sun/awt/image/ImageFetcher.java b/jdk/src/share/classes/sun/awt/image/ImageFetcher.java index a5af63512c7..eaccf335db0 100644 --- a/jdk/src/share/classes/sun/awt/image/ImageFetcher.java +++ b/jdk/src/share/classes/sun/awt/image/ImageFetcher.java @@ -152,7 +152,7 @@ class ImageFetcher extends Thread { info.numWaiting--; } } - src = (ImageFetchable) info.waitList.elementAt(0); + src = info.waitList.elementAt(0); info.waitList.removeElement(src); } return src; @@ -303,26 +303,25 @@ class ImageFetcher extends Thread { final ThreadGroup fetcherGroup = fetcherThreadGroup; java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - for (int i = 0; i < info.fetchers.length; i++) { - if (info.fetchers[i] == null) { - ImageFetcher f = new ImageFetcher( - fetcherGroup, i); - try { - f.start(); - info.fetchers[i] = f; - info.numFetchers++; - break; - } catch (Error e) { + new java.security.PrivilegedAction<Object>() { + public Object run() { + for (int i = 0; i < info.fetchers.length; i++) { + if (info.fetchers[i] == null) { + ImageFetcher f = new ImageFetcher(fetcherGroup, i); + try { + f.start(); + info.fetchers[i] = f; + info.numFetchers++; + break; + } catch (Error e) { + } } + } + return null; } - } - return null; - } - }); - return; - } + }); + return; + } } @@ -337,13 +336,13 @@ class FetcherInfo { Thread[] fetchers; int numFetchers; int numWaiting; - Vector waitList; + Vector<ImageFetchable> waitList; private FetcherInfo() { fetchers = new Thread[MAX_NUM_FETCHERS_PER_APPCONTEXT]; numFetchers = 0; numWaiting = 0; - waitList = new Vector(); + waitList = new Vector<>(); } /* The key to put()/get() the FetcherInfo into/from the AppContext. */ diff --git a/jdk/src/share/classes/sun/awt/image/ImageRepresentation.java b/jdk/src/share/classes/sun/awt/image/ImageRepresentation.java index 77ee7339a59..90bb2ac6388 100644 --- a/jdk/src/share/classes/sun/awt/image/ImageRepresentation.java +++ b/jdk/src/share/classes/sun/awt/image/ImageRepresentation.java @@ -185,7 +185,7 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer protected BufferedImage createImage(ColorModel cm, WritableRaster raster, boolean isRasterPremultiplied, - Hashtable properties) + Hashtable<?,?> properties) { BufferedImage bi = new BufferedImage(cm, raster, isRasterPremultiplied, null); diff --git a/jdk/src/share/classes/sun/awt/image/ImagingLib.java b/jdk/src/share/classes/sun/awt/image/ImagingLib.java index 90ad81836c8..683b8fe7e75 100644 --- a/jdk/src/share/classes/sun/awt/image/ImagingLib.java +++ b/jdk/src/share/classes/sun/awt/image/ImagingLib.java @@ -61,7 +61,7 @@ public class ImagingLib { private static final int AFFINE_OP = 1; private static final int CONVOLVE_OP = 2; - private static Class[] nativeOpClass = new Class[NUM_NATIVE_OPS]; + private static Class<?>[] nativeOpClass = new Class<?>[NUM_NATIVE_OPS]; /** * Returned value indicates whether the library initailization was @@ -134,7 +134,7 @@ public class ImagingLib { } - private static int getNativeOpIndex(Class opClass) { + private static int getNativeOpIndex(Class<?> opClass) { // // Search for this class in cached list of // classes supplying native acceleration diff --git a/jdk/src/share/classes/sun/awt/image/JPEGImageDecoder.java b/jdk/src/share/classes/sun/awt/image/JPEGImageDecoder.java index 872ffc01974..70dacb195c3 100644 --- a/jdk/src/share/classes/sun/awt/image/JPEGImageDecoder.java +++ b/jdk/src/share/classes/sun/awt/image/JPEGImageDecoder.java @@ -47,8 +47,8 @@ public class JPEGImageDecoder extends ImageDecoder { private static ColorModel ARGBcolormodel; private static ColorModel Graycolormodel; - private static final Class InputStreamClass = InputStream.class; - private static native void initIDs(Class InputStreamClass); + private static final Class<?> InputStreamClass = InputStream.class; + private static native void initIDs(Class<?> InputStreamClass); private ColorModel colormodel; @@ -73,7 +73,7 @@ public class JPEGImageDecoder extends ImageDecoder { private native void readImage(InputStream is, byte buf[]) throws ImageFormatException, IOException; - Hashtable props = new Hashtable(); + Hashtable<String, Object> props = new Hashtable<>(); public JPEGImageDecoder(InputStreamImageSource src, InputStream is) { super(src, is); diff --git a/jdk/src/share/classes/sun/awt/image/OffScreenImageSource.java b/jdk/src/share/classes/sun/awt/image/OffScreenImageSource.java index c1b0453a65b..3dcdde01574 100644 --- a/jdk/src/share/classes/sun/awt/image/OffScreenImageSource.java +++ b/jdk/src/share/classes/sun/awt/image/OffScreenImageSource.java @@ -40,15 +40,15 @@ public class OffScreenImageSource implements ImageProducer { BufferedImage image; int width; int height; - Hashtable properties; + Hashtable<?, ?> properties; public OffScreenImageSource(BufferedImage image, - Hashtable properties) { + Hashtable<?, ?> properties) { this.image = image; if (properties != null) { this.properties = properties; } else { - this.properties = new Hashtable(); + this.properties = new Hashtable<String, Object>(); } width = image.getWidth(); height = image.getHeight(); diff --git a/jdk/src/share/classes/sun/awt/image/PNGImageDecoder.java b/jdk/src/share/classes/sun/awt/image/PNGImageDecoder.java index adbdb766da1..7f78de6e982 100644 --- a/jdk/src/share/classes/sun/awt/image/PNGImageDecoder.java +++ b/jdk/src/share/classes/sun/awt/image/PNGImageDecoder.java @@ -68,7 +68,7 @@ public class PNGImageDecoder extends ImageDecoder private int filterMethod; private int interlaceMethod; private int gamma = 100000; - private java.util.Hashtable properties; + private java.util.Hashtable<String, Object> properties; /* this is not needed ImageConsumer target; */ @@ -83,7 +83,7 @@ public class PNGImageDecoder extends ImageDecoder private void property(String key,Object value) { if(value==null) return; - if(properties==null) properties=new java.util.Hashtable(); + if(properties==null) properties=new java.util.Hashtable<>(); properties.put(key,value); } private void property(String key,float value) { diff --git a/jdk/src/share/classes/sun/awt/image/ToolkitImage.java b/jdk/src/share/classes/sun/awt/image/ToolkitImage.java index 885648d2265..b1f5873f106 100644 --- a/jdk/src/share/classes/sun/awt/image/ToolkitImage.java +++ b/jdk/src/share/classes/sun/awt/image/ToolkitImage.java @@ -79,7 +79,7 @@ public class ToolkitImage extends Image { private int width = -1; private int height = -1; - private Hashtable properties; + private Hashtable<?, ?> properties; private int availinfo; @@ -254,9 +254,9 @@ public class ToolkitImage extends Image { addInfo(ImageObserver.WIDTH | ImageObserver.HEIGHT); } - void setProperties(Hashtable props) { + void setProperties(Hashtable<?, ?> props) { if (props == null) { - props = new Hashtable(); + props = new Hashtable<String, Object>(); } properties = props; addInfo(ImageObserver.PROPERTIES); diff --git a/jdk/src/share/classes/sun/awt/shell/ShellFolder.java b/jdk/src/share/classes/sun/awt/shell/ShellFolder.java index e8a9407276d..3795e146f2a 100644 --- a/jdk/src/share/classes/sun/awt/shell/ShellFolder.java +++ b/jdk/src/share/classes/sun/awt/shell/ShellFolder.java @@ -127,14 +127,14 @@ public abstract class ShellFolder extends File { File[] files = super.listFiles(); if (!includeHiddenFiles) { - Vector v = new Vector(); + Vector<File> v = new Vector<>(); int nameCount = (files == null) ? 0 : files.length; for (int i = 0; i < nameCount; i++) { if (!files[i].isHidden()) { v.addElement(files[i]); } } - files = (File[])v.toArray(new File[v.size()]); + files = v.toArray(new File[v.size()]); } return files; @@ -208,7 +208,7 @@ public abstract class ShellFolder extends File { static { String managerClassName = (String)Toolkit.getDefaultToolkit(). getDesktopProperty("Shell.shellFolderManager"); - Class managerClass = null; + Class<?> managerClass = null; try { managerClass = ReflectUtil.forName(managerClassName); // swallow the exceptions below and use default shell folder @@ -554,7 +554,7 @@ public abstract class ShellFolder extends File { /** * Provides a default comparator for the default column set */ - private static final Comparator DEFAULT_COMPARATOR = new Comparator() { + private static final Comparator<Object> DEFAULT_COMPARATOR = new Comparator<Object>() { public int compare(Object o1, Object o2) { int gt; @@ -565,7 +565,9 @@ public abstract class ShellFolder extends File { } else if (o1 == null && o2 != null) { gt = -1; } else if (o1 instanceof Comparable) { - gt = ((Comparable) o1).compareTo(o2); + @SuppressWarnings("unchecked") + Comparable<Object> o = (Comparable<Object>) o1; + gt = o.compareTo(o2); } else { gt = 0; } diff --git a/jdk/src/share/classes/sun/awt/shell/ShellFolderColumnInfo.java b/jdk/src/share/classes/sun/awt/shell/ShellFolderColumnInfo.java index 3836b04eb32..88dffacec2b 100644 --- a/jdk/src/share/classes/sun/awt/shell/ShellFolderColumnInfo.java +++ b/jdk/src/share/classes/sun/awt/shell/ShellFolderColumnInfo.java @@ -38,7 +38,7 @@ public class ShellFolderColumnInfo { */ private Integer alignment; private SortOrder sortOrder; - private Comparator comparator; + private Comparator<?> comparator; /** * <code>false</code> (default) if the {@link comparator} expects folders as arguments, * and <code>true</code> if folder's column values. The first option is used default for comparison @@ -49,7 +49,7 @@ public class ShellFolderColumnInfo { public ShellFolderColumnInfo(String title, Integer width, Integer alignment, boolean visible, - SortOrder sortOrder, Comparator comparator, + SortOrder sortOrder, Comparator<?> comparator, boolean compareByColumn) { this.title = title; this.width = width; @@ -62,7 +62,7 @@ public class ShellFolderColumnInfo { public ShellFolderColumnInfo(String title, Integer width, Integer alignment, boolean visible, - SortOrder sortOrder, Comparator comparator) { + SortOrder sortOrder, Comparator<?> comparator) { this(title, width, alignment, visible, sortOrder, comparator, false); } @@ -115,11 +115,11 @@ public class ShellFolderColumnInfo { this.sortOrder = sortOrder; } - public Comparator getComparator() { + public Comparator<?> getComparator() { return comparator; } - public void setComparator(Comparator comparator) { + public void setComparator(Comparator<?> comparator) { this.comparator = comparator; } diff --git a/jdk/src/share/classes/sun/awt/util/IdentityArrayList.java b/jdk/src/share/classes/sun/awt/util/IdentityArrayList.java index bf66f427d72..c88452289cb 100644 --- a/jdk/src/share/classes/sun/awt/util/IdentityArrayList.java +++ b/jdk/src/share/classes/sun/awt/util/IdentityArrayList.java @@ -285,6 +285,7 @@ public class IdentityArrayList<E> extends AbstractList<E> * this list * @throws NullPointerException if the specified array is null */ + @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { if (a.length < size) // Make a new array of a's runtime type, but my contents: @@ -307,7 +308,9 @@ public class IdentityArrayList<E> extends AbstractList<E> public E get(int index) { rangeCheck(index); - return (E) elementData[index]; + @SuppressWarnings("unchecked") + E rv = (E) elementData[index]; + return rv; } /** @@ -322,6 +325,7 @@ public class IdentityArrayList<E> extends AbstractList<E> public E set(int index, E element) { rangeCheck(index); + @SuppressWarnings("unchecked") E oldValue = (E) elementData[index]; elementData[index] = element; return oldValue; @@ -371,6 +375,7 @@ public class IdentityArrayList<E> extends AbstractList<E> rangeCheck(index); modCount++; + @SuppressWarnings("unchecked") E oldValue = (E) elementData[index]; int numMoved = size - index - 1; diff --git a/jdk/src/share/classes/sun/awt/util/IdentityLinkedList.java b/jdk/src/share/classes/sun/awt/util/IdentityLinkedList.java index 77e0f0062aa..690264ab4d9 100644 --- a/jdk/src/share/classes/sun/awt/util/IdentityLinkedList.java +++ b/jdk/src/share/classes/sun/awt/util/IdentityLinkedList.java @@ -280,7 +280,9 @@ public class IdentityLinkedList<E> Entry<E> successor = (index==size ? header : entry(index)); Entry<E> predecessor = successor.previous; for (int i=0; i<numNew; i++) { - Entry<E> e = new Entry<E>((E)a[i], successor, predecessor); + @SuppressWarnings("unchecked") + E tmp = (E) a[i]; + Entry<E> e = new Entry<E>(tmp, successor, predecessor); predecessor.next = e; predecessor = e; } @@ -396,7 +398,7 @@ public class IdentityLinkedList<E> */ public int indexOf(Object o) { int index = 0; - for (Entry e = header.next; e != header; e = e.next) { + for (Entry<E> e = header.next; e != header; e = e.next) { if (o == e.element) { return index; } @@ -418,7 +420,7 @@ public class IdentityLinkedList<E> */ public int lastIndexOf(Object o) { int index = size; - for (Entry e = header.previous; e != header; e = e.previous) { + for (Entry<E> e = header.previous; e != header; e = e.previous) { index--; if (o == e.element) { return index; @@ -787,7 +789,7 @@ public class IdentityLinkedList<E> } /** Adapter to provide descending iterators via ListItr.previous */ - private class DescendingIterator implements Iterator { + private class DescendingIterator implements Iterator<E> { final ListItr itr = new ListItr(size()); public boolean hasNext() { return itr.hasPrevious(); @@ -860,6 +862,7 @@ public class IdentityLinkedList<E> * this list * @throws NullPointerException if the specified array is null */ + @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { if (a.length < size) a = (T[])java.lang.reflect.Array.newInstance( diff --git a/jdk/src/solaris/classes/sun/awt/X11/InfoWindow.java b/jdk/src/solaris/classes/sun/awt/X11/InfoWindow.java index 334d1d1c036..fb8b050a7e8 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/InfoWindow.java +++ b/jdk/src/solaris/classes/sun/awt/X11/InfoWindow.java @@ -207,8 +207,9 @@ public abstract class InfoWindow extends Window { textLabel.setText(tooltipString); } - Point pointer = (Point)AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + Point pointer = AccessController.doPrivileged( + new PrivilegedAction<Point>() { + public Point run() { if (!isPointerOverTrayIcon(liveArguments.getBounds())) { return null; } diff --git a/jdk/src/solaris/classes/sun/awt/X11/ListHelper.java b/jdk/src/solaris/classes/sun/awt/X11/ListHelper.java index 0a83eaaf829..caf1c2df5ae 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/ListHelper.java +++ b/jdk/src/solaris/classes/sun/awt/X11/ListHelper.java @@ -55,10 +55,10 @@ public class ListHelper implements XScrollbarClient { private final int SCROLLBAR_WIDTH; // Width of a scrollbar - private java.util.List items; // List of items + private java.util.List<String> items; // List of items // TODO: maybe this would be better as a simple int[] - private java.util.List selected; // List of selected items + private java.util.List<Integer> selected; // List of selected items private boolean multiSelect; // Can multiple items be selected // at once? private int focusedIndex; @@ -100,8 +100,8 @@ public class ListHelper implements XScrollbarClient { this.peer = peer; this.colors = colors; this.multiSelect = multiSelect; - items = new ArrayList(initialSize); - selected = new ArrayList(1); + items = new ArrayList<>(initialSize); + selected = new ArrayList<>(1); selected.add(Integer.valueOf(-1)); this.maxVisItems = maxVisItems; @@ -190,7 +190,7 @@ public class ListHelper implements XScrollbarClient { /* if called for multiselect, return -1 */ public int getSelectedIndex() { if (!multiSelect) { - Integer val = (Integer)selected.get(0); + Integer val = selected.get(0); return val.intValue(); } return -1; @@ -217,7 +217,7 @@ public class ListHelper implements XScrollbarClient { } public String getItem(int index) { - return (String) items.get(index); + return items.get(index); } /**********************************************************************/ @@ -576,9 +576,9 @@ public class ListHelper implements XScrollbarClient { } boolean isItemSelected(int index) { - Iterator itr = selected.iterator(); + Iterator<Integer> itr = selected.iterator(); while (itr.hasNext()) { - Integer val = (Integer)itr.next(); + Integer val = itr.next(); if (val.intValue() == index) { return true; } diff --git a/jdk/src/solaris/classes/sun/awt/X11/MotifDnDDragSourceProtocol.java b/jdk/src/solaris/classes/sun/awt/X11/MotifDnDDragSourceProtocol.java index 35109ebac70..6acc9d683ea 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/MotifDnDDragSourceProtocol.java +++ b/jdk/src/solaris/classes/sun/awt/X11/MotifDnDDragSourceProtocol.java @@ -26,6 +26,7 @@ package sun.awt.X11; import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.DataFlavor; import java.awt.dnd.DnDConstants; import java.awt.dnd.InvalidDnDOperationException; @@ -65,7 +66,7 @@ class MotifDnDDragSourceProtocol extends XDragSourceProtocol } protected void initializeDragImpl(int actions, Transferable contents, - Map formatMap, long[] formats) + Map<Long, DataFlavor> formatMap, long[] formats) throws InvalidDnDOperationException, IllegalArgumentException, XException { diff --git a/jdk/src/solaris/classes/sun/awt/X11/Native.java b/jdk/src/solaris/classes/sun/awt/X11/Native.java index 14628b833ec..f61654643f2 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/Native.java +++ b/jdk/src/solaris/classes/sun/awt/X11/Native.java @@ -43,13 +43,12 @@ class Native { static int dataModel; static { - String dataModelProp = (String)AccessController. - doPrivileged( - new PrivilegedAction() { - public Object run() { - return System.getProperty("sun.arch.data.model"); - } - }); + String dataModelProp = AccessController.doPrivileged( + new PrivilegedAction<String>() { + public String run() { + return System.getProperty("sun.arch.data.model"); + } + }); try { dataModel = Integer.parseInt(dataModelProp); } catch (Exception e) { @@ -333,9 +332,9 @@ class Native { * Stores Java Vector of Longs into memory. Memory location is treated as array * of native <code>long</code>s */ - static void putLong(long ptr, Vector arr) { + static void putLong(long ptr, Vector<Long> arr) { for (int i = 0; i < arr.size(); i ++, ptr += getLongSize()) { - putLong(ptr, ((Long)arr.elementAt(i)).longValue()); + putLong(ptr, arr.elementAt(i).longValue()); } } @@ -343,9 +342,9 @@ class Native { * Stores Java Vector of Longs into memory. Memory location is treated as array * of native <code>long</code>s. Array is stored in reverse order */ - static void putLongReverse(long ptr, Vector arr) { + static void putLongReverse(long ptr, Vector<Long> arr) { for (int i = arr.size()-1; i >= 0; i--, ptr += getLongSize()) { - putLong(ptr, ((Long)arr.elementAt(i)).longValue()); + putLong(ptr, arr.elementAt(i).longValue()); } } /** diff --git a/jdk/src/solaris/classes/sun/awt/X11/XAWTXSettings.java b/jdk/src/solaris/classes/sun/awt/X11/XAWTXSettings.java index 48fcae52f0b..4c7b19c14cc 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XAWTXSettings.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XAWTXSettings.java @@ -98,7 +98,7 @@ class XAWTXSettings extends XSettings implements XMSelectionListener { * should be "good enough" for most cases. */ - Map updatedSettings = null; + Map<String, Object> updatedSettings = null; XToolkit.awtLock(); try { long display = XToolkit.getDisplay(); @@ -112,7 +112,7 @@ class XAWTXSettings extends XSettings implements XMSelectionListener { } private void updateXSettings(int screen, long owner) { - final Map updatedSettings = getUpdatedSettings(owner); + final Map<String, Object> updatedSettings = getUpdatedSettings(owner); // this method is called under awt lock and usually on toolkit thread // but parseXSettings() causes public code execution, so we need to transfer // this to EDT @@ -123,7 +123,7 @@ class XAWTXSettings extends XSettings implements XMSelectionListener { }); } - private Map getUpdatedSettings(final long owner) { + private Map<String, Object> getUpdatedSettings(final long owner) { if (log.isLoggable(PlatformLogger.Level.FINE)) { log.fine("owner =" + owner); } @@ -131,7 +131,7 @@ class XAWTXSettings extends XSettings implements XMSelectionListener { return null; } - Map settings = null; + Map<String, Object> settings = null; try { WindowPropertyGetter getter = new WindowPropertyGetter(owner, xSettingsPropertyAtom, 0, MAX_LENGTH, diff --git a/jdk/src/solaris/classes/sun/awt/X11/XAtomList.java b/jdk/src/solaris/classes/sun/awt/X11/XAtomList.java index 7b53b6d2e95..a998850eb4c 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XAtomList.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XAtomList.java @@ -157,7 +157,7 @@ class XAtomList { public String toString() { StringBuffer buf = new StringBuffer(); buf.append("["); - Iterator iter = atoms.iterator(); + Iterator<XAtom> iter = atoms.iterator(); while (iter.hasNext()) { buf.append(iter.next().toString()); if (iter.hasNext()) { diff --git a/jdk/src/solaris/classes/sun/awt/X11/XAwtState.java b/jdk/src/solaris/classes/sun/awt/X11/XAwtState.java index 872f9ea851b..b0a8186c77a 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XAwtState.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XAwtState.java @@ -40,7 +40,7 @@ class XAwtState { * The mouse is over this component. * If the component is not disabled, it received MOUSE_ENTERED but no MOUSE_EXITED. */ - private static WeakReference componentMouseEnteredRef = null; + private static WeakReference<Component> componentMouseEnteredRef = null; static void setComponentMouseEntered(Component component) { XToolkit.awtLock(); @@ -50,7 +50,7 @@ class XAwtState { return; } if (component != getComponentMouseEntered()) { - componentMouseEnteredRef = new WeakReference(component); + componentMouseEnteredRef = new WeakReference<>(component); } } finally { XToolkit.awtUnlock(); @@ -63,7 +63,7 @@ class XAwtState { if (componentMouseEnteredRef == null) { return null; } - return (Component)componentMouseEnteredRef.get(); + return componentMouseEnteredRef.get(); } finally { XToolkit.awtUnlock(); } @@ -83,7 +83,7 @@ class XAwtState { return inManualGrab; } - private static WeakReference grabWindowRef = null; + private static WeakReference<XBaseWindow> grabWindowRef = null; /** * The X Active Grab overrides any other active grab by the same @@ -112,7 +112,7 @@ class XAwtState { return; } if (grabWindow != getGrabWindow()) { - grabWindowRef = new WeakReference(grabWindow); + grabWindowRef = new WeakReference<>(grabWindow); } } finally { XToolkit.awtUnlock(); @@ -125,7 +125,7 @@ class XAwtState { if (grabWindowRef == null) { return null; } - XBaseWindow xbw = (XBaseWindow)grabWindowRef.get(); + XBaseWindow xbw = grabWindowRef.get(); if( xbw != null && xbw.isDisposed() ) { xbw = null; grabWindowRef = null; diff --git a/jdk/src/solaris/classes/sun/awt/X11/XBaseMenuWindow.java b/jdk/src/solaris/classes/sun/awt/X11/XBaseMenuWindow.java index 1d82f04a78c..53aae040883 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XBaseMenuWindow.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XBaseMenuWindow.java @@ -231,7 +231,7 @@ abstract public class XBaseMenuWindow extends XWindow { */ void instantPreInit(XCreateWindowParams params) { super.instantPreInit(params); - items = new ArrayList(); + items = new ArrayList<>(); } /************************************************ @@ -367,10 +367,10 @@ abstract public class XBaseMenuWindow extends XWindow { * Clears items vector and loads specified vector * @param items vector to be loaded */ - public void reloadItems(Vector items) { + public void reloadItems(Vector<? extends MenuItem> items) { synchronized(getMenuTreeLock()) { this.items.clear(); - MenuItem[] itemArray = (MenuItem[])items.toArray(new MenuItem[] {}); + MenuItem[] itemArray = items.toArray(new MenuItem[] {}); int itemCnt = itemArray.length; for(int i = 0; i < itemCnt; i++) { addItem(itemArray[i]); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java index 6d3385cef46..6cc706278fc 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java @@ -236,8 +236,8 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget return false; } - private static Class seClass; - private static Constructor seCtor; + private static Class<?> seClass; + private static Constructor<?> seCtor; final static AWTEvent wrapInSequenced(AWTEvent event) { try { @@ -246,9 +246,11 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget } if (seCtor == null) { - seCtor = (Constructor) AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - Constructor ctor = seClass.getConstructor(new Class[] { AWTEvent.class }); + seCtor = AccessController.doPrivileged(new + PrivilegedExceptionAction<Constructor<?>>() { + public Constructor<?> run() throws Exception { + Constructor<?> ctor = seClass.getConstructor( + new Class<?>[] { AWTEvent.class }); ctor.setAccessible(true); return ctor; } @@ -1322,7 +1324,7 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget } } - private void addTree(Collection order, Set set, Container cont) { + private void addTree(Collection<Long> order, Set<Long> set, Container cont) { for (int i = 0; i < cont.getComponentCount(); i++) { Component comp = cont.getComponent(i); ComponentPeer peer = comp.getPeer(); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XCreateWindowParams.java b/jdk/src/solaris/classes/sun/awt/X11/XCreateWindowParams.java index 32d83f193ce..da263eb4890 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XCreateWindowParams.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XCreateWindowParams.java @@ -30,7 +30,7 @@ import java.util.Iterator; import java.util.Map; @SuppressWarnings("serial") // JDK-implementation class -public class XCreateWindowParams extends HashMap { +public class XCreateWindowParams extends HashMap<Object, Object> { public XCreateWindowParams() { } public XCreateWindowParams(Object[] map) { @@ -82,9 +82,9 @@ public class XCreateWindowParams extends HashMap { } public String toString() { StringBuffer buf = new StringBuffer(); - Iterator eIter = entrySet().iterator(); + Iterator<Map.Entry<Object, Object>> eIter = entrySet().iterator(); while (eIter.hasNext()) { - Map.Entry entry = (Map.Entry)eIter.next(); + Map.Entry<Object, Object> entry = eIter.next(); buf.append(entry.getKey() + ": " + entry.getValue() + "\n"); } return buf.toString(); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java b/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java index fd9cbb8f13c..36204203c23 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java @@ -49,6 +49,7 @@ import java.util.LinkedHashSet; import java.util.List; import javax.imageio.ImageIO; +import javax.imageio.ImageReader; import javax.imageio.ImageTypeSpecifier; import javax.imageio.ImageWriter; import javax.imageio.spi.ImageWriterSpi; @@ -333,7 +334,7 @@ public class XDataTransferer extends DataTransferer { // flavors to enable dynamic text native-to-flavor mapping generation. // See SystemFlavorMap.getFlavorsForNative() for details. if ("image".equals(primaryType)) { - Iterator readers = ImageIO.getImageReadersByMIMEType(baseType); + Iterator<ImageReader> readers = ImageIO.getImageReadersByMIMEType(baseType); if (readers.hasNext()) { flavors.add(DataFlavor.imageFlavor); } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDnDDragSourceProtocol.java b/jdk/src/solaris/classes/sun/awt/X11/XDnDDragSourceProtocol.java index b1e6f2ad041..4648a836679 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDnDDragSourceProtocol.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDnDDragSourceProtocol.java @@ -26,6 +26,7 @@ package sun.awt.X11; import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.DataFlavor; import java.awt.dnd.DnDConstants; import java.awt.dnd.InvalidDnDOperationException; @@ -70,7 +71,7 @@ class XDnDDragSourceProtocol extends XDragSourceProtocol { * @returns true if the initialized successfully. */ protected void initializeDragImpl(int actions, Transferable contents, - Map formatMap, long[] formats) + Map<Long, DataFlavor> formatMap, long[] formats) throws InvalidDnDOperationException, IllegalArgumentException, XException { assert XToolkit.isAWTLockHeldByCurrentThread(); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDragAndDropProtocols.java b/jdk/src/solaris/classes/sun/awt/X11/XDragAndDropProtocols.java index b236881aec4..161fc285a02 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDragAndDropProtocols.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDragAndDropProtocols.java @@ -36,8 +36,8 @@ import java.util.List; * @since 1.5 */ final class XDragAndDropProtocols { - private final static List dragProtocols; - private final static List dropProtocols; + private final static List<XDragSourceProtocol> dragProtocols; + private final static List<XDropTargetProtocol> dropProtocols; public static final String XDnD = "XDnD"; public static final String MotifDnD = "MotifDnD"; @@ -50,7 +50,7 @@ final class XDragAndDropProtocols { XDropTargetProtocolListener dropTargetProtocolListener = XDropTargetContextPeer.getXDropTargetProtocolListener(); - List tDragSourceProtocols = new ArrayList(); + List<XDragSourceProtocol> tDragSourceProtocols = new ArrayList<>(); XDragSourceProtocol xdndDragSourceProtocol = XDnDDragSourceProtocol.createInstance(dragSourceProtocolListener); tDragSourceProtocols.add(xdndDragSourceProtocol); @@ -58,7 +58,7 @@ final class XDragAndDropProtocols { MotifDnDDragSourceProtocol.createInstance(dragSourceProtocolListener); tDragSourceProtocols.add(motifdndDragSourceProtocol); - List tDropTargetProtocols = new ArrayList(); + List<XDropTargetProtocol> tDropTargetProtocols = new ArrayList<>(); XDropTargetProtocol xdndDropTargetProtocol = XDnDDropTargetProtocol.createInstance(dropTargetProtocolListener); tDropTargetProtocols.add(xdndDropTargetProtocol); @@ -70,11 +70,11 @@ final class XDragAndDropProtocols { dropProtocols = Collections.unmodifiableList(tDropTargetProtocols); } - static Iterator getDragSourceProtocols() { + static Iterator<XDragSourceProtocol> getDragSourceProtocols() { return dragProtocols.iterator(); } - static Iterator getDropTargetProtocols() { + static Iterator<XDropTargetProtocol> getDropTargetProtocols() { return dropProtocols.iterator(); } @@ -88,10 +88,10 @@ final class XDragAndDropProtocols { return null; } - Iterator dragProtocols = XDragAndDropProtocols.getDragSourceProtocols(); + Iterator<XDragSourceProtocol> dragProtocols = + XDragAndDropProtocols.getDragSourceProtocols(); while (dragProtocols.hasNext()) { - XDragSourceProtocol dragProtocol = - (XDragSourceProtocol)dragProtocols.next(); + XDragSourceProtocol dragProtocol = dragProtocols.next(); if (dragProtocol.getProtocolName().equals(name)) { return dragProtocol; } @@ -110,10 +110,10 @@ final class XDragAndDropProtocols { return null; } - Iterator dropProtocols = XDragAndDropProtocols.getDropTargetProtocols(); + Iterator<XDropTargetProtocol> dropProtocols = + XDragAndDropProtocols.getDropTargetProtocols(); while (dropProtocols.hasNext()) { - XDropTargetProtocol dropProtocol = - (XDropTargetProtocol)dropProtocols.next(); + XDropTargetProtocol dropProtocol = dropProtocols.next(); if (dropProtocol.getProtocolName().equals(name)) { return dropProtocol; } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDragSourceContextPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XDragSourceContextPeer.java index f376b395823..2d67a31a036 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDragSourceContextPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDragSourceContextPeer.java @@ -29,6 +29,7 @@ import java.awt.Component; import java.awt.Cursor; import java.awt.Window; +import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.dnd.DnDConstants; @@ -110,7 +111,7 @@ public final class XDragSourceContextPeer } protected void startDrag(Transferable transferable, - long[] formats, Map formatMap) { + long[] formats, Map<Long, DataFlavor> formatMap) { Component component = getTrigger().getComponent(); Component c = null; XWindowPeer wpeer = null; @@ -161,9 +162,10 @@ public final class XDragSourceContextPeer int dropActions = getDragSourceContext().getSourceActions(); - Iterator dragProtocols = XDragAndDropProtocols.getDragSourceProtocols(); + Iterator<XDragSourceProtocol> dragProtocols = + XDragAndDropProtocols.getDragSourceProtocols(); while (dragProtocols.hasNext()) { - XDragSourceProtocol dragProtocol = (XDragSourceProtocol)dragProtocols.next(); + XDragSourceProtocol dragProtocol = dragProtocols.next(); try { dragProtocol.initializeDrag(dropActions, transferable, formatMap, formats); @@ -313,9 +315,10 @@ public final class XDragSourceContextPeer dragDropFinished(false, DnDConstants.ACTION_NONE, xRoot, yRoot); } - Iterator dragProtocols = XDragAndDropProtocols.getDragSourceProtocols(); + Iterator<XDragSourceProtocol> dragProtocols = + XDragAndDropProtocols.getDragSourceProtocols(); while (dragProtocols.hasNext()) { - XDragSourceProtocol dragProtocol = (XDragSourceProtocol)dragProtocols.next(); + XDragSourceProtocol dragProtocol = dragProtocols.next(); try { dragProtocol.cleanup(); } catch (XException xe) { @@ -418,9 +421,10 @@ public final class XDragSourceContextPeer } if (clientWindow != 0) { - Iterator dragProtocols = XDragAndDropProtocols.getDragSourceProtocols(); + Iterator<XDragSourceProtocol> dragProtocols = + XDragAndDropProtocols.getDragSourceProtocols(); while (dragProtocols.hasNext()) { - XDragSourceProtocol dragProtocol = (XDragSourceProtocol)dragProtocols.next(); + XDragSourceProtocol dragProtocol = dragProtocols.next(); if (dragProtocol.attachTargetWindow(clientWindow, time)) { protocol = dragProtocol; break; @@ -550,10 +554,10 @@ public final class XDragSourceContextPeer XClientMessageEvent xclient = ev.get_xclient(); - Iterator dragProtocols = XDragAndDropProtocols.getDragSourceProtocols(); + Iterator<XDragSourceProtocol> dragProtocols = + XDragAndDropProtocols.getDragSourceProtocols(); while (dragProtocols.hasNext()) { - XDragSourceProtocol dragProtocol = - (XDragSourceProtocol)dragProtocols.next(); + XDragSourceProtocol dragProtocol = dragProtocols.next(); if (dragProtocol.processProxyModeEvent(xclient, getProxyModeSourceWindow())) { return true; diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDragSourceProtocol.java b/jdk/src/solaris/classes/sun/awt/X11/XDragSourceProtocol.java index 6779a156688..20e16f4954e 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDragSourceProtocol.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDragSourceProtocol.java @@ -26,6 +26,7 @@ package sun.awt.X11; import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.DataFlavor; import java.awt.dnd.DnDConstants; import java.awt.dnd.InvalidDnDOperationException; @@ -84,7 +85,7 @@ abstract class XDragSourceProtocol { * @throws XException if some X call failed. */ public final void initializeDrag(int actions, Transferable contents, - Map formatMap, long[] formats) + Map<Long, DataFlavor> formatMap, long[] formats) throws InvalidDnDOperationException, IllegalArgumentException, XException { XToolkit.awtLock(); @@ -110,7 +111,8 @@ abstract class XDragSourceProtocol { /* The caller must hold AWT_LOCK. */ protected abstract void initializeDragImpl(int actions, Transferable contents, - Map formatMap, long[] formats) + Map<Long, DataFlavor> formatMap, + long[] formats) throws InvalidDnDOperationException, IllegalArgumentException, XException; /** diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDropTargetContextPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XDropTargetContextPeer.java index 4b5818ab9de..26daceff51a 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDropTargetContextPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDropTargetContextPeer.java @@ -89,12 +89,12 @@ final class XDropTargetContextPeer extends SunDropTargetContextPeer { /* If the event was not consumed, send a response to the source. */ try { if (ctxt != 0 && !e.isConsumed()) { - Iterator dropTargetProtocols = + Iterator<XDropTargetProtocol> dropTargetProtocols = XDragAndDropProtocols.getDropTargetProtocols(); while (dropTargetProtocols.hasNext()) { XDropTargetProtocol dropTargetProtocol = - (XDropTargetProtocol)dropTargetProtocols.next(); + dropTargetProtocols.next(); if (dropTargetProtocol.sendResponse(ctxt, e.getID(), returnValue)) { break; @@ -116,12 +116,12 @@ final class XDropTargetContextPeer extends SunDropTargetContextPeer { if (ctxt != 0) { try { - Iterator dropTargetProtocols = + Iterator<XDropTargetProtocol> dropTargetProtocols = XDragAndDropProtocols.getDropTargetProtocols(); while (dropTargetProtocols.hasNext()) { XDropTargetProtocol dropTargetProtocol = - (XDropTargetProtocol)dropTargetProtocols.next(); + dropTargetProtocols.next(); if (dropTargetProtocol.sendDropDone(ctxt, success, dropAction)) { break; @@ -140,12 +140,12 @@ final class XDropTargetContextPeer extends SunDropTargetContextPeer { long ctxt = getNativeDragContext(); if (ctxt != 0) { - Iterator dropTargetProtocols = + Iterator<XDropTargetProtocol> dropTargetProtocols = XDragAndDropProtocols.getDropTargetProtocols(); while (dropTargetProtocols.hasNext()) { XDropTargetProtocol dropTargetProtocol = - (XDropTargetProtocol)dropTargetProtocols.next(); + dropTargetProtocols.next(); // getData throws IAE if ctxt is not for this protocol. try { return dropTargetProtocol.getData(ctxt, format); @@ -221,12 +221,11 @@ final class XDropTargetContextPeer extends SunDropTargetContextPeer { public void forwardEventToEmbedded(long embedded, long ctxt, int eventID) { - Iterator dropTargetProtocols = + Iterator<XDropTargetProtocol> dropTargetProtocols = XDragAndDropProtocols.getDropTargetProtocols(); while (dropTargetProtocols.hasNext()) { - XDropTargetProtocol dropTargetProtocol = - (XDropTargetProtocol)dropTargetProtocols.next(); + XDropTargetProtocol dropTargetProtocol = dropTargetProtocols.next(); if (dropTargetProtocol.forwardEventToEmbedded(embedded, ctxt, eventID)) { break; diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDropTargetEventProcessor.java b/jdk/src/solaris/classes/sun/awt/X11/XDropTargetEventProcessor.java index 26a4941788d..a3d9e2fec1c 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDropTargetEventProcessor.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDropTargetEventProcessor.java @@ -79,12 +79,11 @@ final class XDropTargetEventProcessor { } if (protocol == null) { - Iterator dropTargetProtocols = + Iterator<XDropTargetProtocol> dropTargetProtocols = XDragAndDropProtocols.getDropTargetProtocols(); while (dropTargetProtocols.hasNext()) { - XDropTargetProtocol dropTargetProtocol = - (XDropTargetProtocol)dropTargetProtocols.next(); + XDropTargetProtocol dropTargetProtocol = dropTargetProtocols.next(); // Don't try to process it again with the current protocol. if (dropTargetProtocol == curProtocol) { continue; diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDropTargetProtocol.java b/jdk/src/solaris/classes/sun/awt/X11/XDropTargetProtocol.java index 2ba4cf2af8d..d4526c993fe 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDropTargetProtocol.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDropTargetProtocol.java @@ -295,7 +295,8 @@ abstract class XDropTargetProtocol { } /* Access to HashMap is synchronized on this XDropTargetProtocol instance. */ - private final HashMap embedderRegistry = new HashMap(); + private final HashMap<Long, EmbedderRegistryEntry> embedderRegistry = + new HashMap<>(); protected final void putEmbedderRegistryEntry(long embedder, boolean overriden, @@ -310,8 +311,7 @@ abstract class XDropTargetProtocol { protected final EmbedderRegistryEntry getEmbedderRegistryEntry(long embedder) { synchronized (this) { - return - (EmbedderRegistryEntry)embedderRegistry.get(Long.valueOf(embedder)); + return embedderRegistry.get(Long.valueOf(embedder)); } } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java b/jdk/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java index b8a8441379e..aa3d2da55bb 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java @@ -141,10 +141,10 @@ final class XDropTargetRegistry { } public long[] getSites() { long[] ret = new long[sites.size()]; - Iterator iter = sites.iterator(); + Iterator<Long> iter = sites.iterator(); int index = 0; while (iter.hasNext()) { - Long l = (Long)iter.next(); + Long l = iter.next(); ret[index++] = l.longValue(); } return ret; @@ -199,14 +199,13 @@ final class XDropTargetRegistry { private EmbeddedDropSiteEntry registerEmbedderDropSite(long embedder) { assert XToolkit.isAWTLockHeldByCurrentThread(); - Iterator dropTargetProtocols = + Iterator<XDropTargetProtocol> dropTargetProtocols = XDragAndDropProtocols.getDropTargetProtocols(); // The list of protocols supported by the embedder. - List<XDropTargetProtocol> embedderProtocols = new ArrayList(); + List<XDropTargetProtocol> embedderProtocols = new ArrayList<>(); while (dropTargetProtocols.hasNext()) { - XDropTargetProtocol dropTargetProtocol = - (XDropTargetProtocol)dropTargetProtocols.next(); + XDropTargetProtocol dropTargetProtocol = dropTargetProtocols.next(); if (dropTargetProtocol.isProtocolSupported(embedder)) { embedderProtocols.add(dropTargetProtocol); } @@ -262,7 +261,7 @@ final class XDropTargetRegistry { private void registerProtocols(long embedder, boolean protocols, List<XDropTargetProtocol> supportedProtocols) { - Iterator dropTargetProtocols = null; + Iterator<XDropTargetProtocol> dropTargetProtocols = null; /* * By default, we register a drop site that supports all dnd @@ -289,8 +288,7 @@ final class XDropTargetRegistry { XlibWrapper.XGrabServer(XToolkit.getDisplay()); try { while (dropTargetProtocols.hasNext()) { - XDropTargetProtocol dropTargetProtocol = - (XDropTargetProtocol)dropTargetProtocols.next(); + XDropTargetProtocol dropTargetProtocol = dropTargetProtocols.next(); if ((protocols == XEMBED_PROTOCOLS) == dropTargetProtocol.isXEmbedSupported()) { dropTargetProtocol.registerEmbedderDropSite(embedder); @@ -310,14 +308,13 @@ final class XDropTargetRegistry { assert XToolkit.isAWTLockHeldByCurrentThread(); - Iterator dropTargetProtocols = + Iterator<XDropTargetProtocol> dropTargetProtocols = XDragAndDropProtocols.getDropTargetProtocols(); // The list of protocols supported by the embedder. - List<XDropTargetProtocol> embedderProtocols = new ArrayList(); + List<XDropTargetProtocol> embedderProtocols = new ArrayList<>(); while (dropTargetProtocols.hasNext()) { - XDropTargetProtocol dropTargetProtocol = - (XDropTargetProtocol)dropTargetProtocols.next(); + XDropTargetProtocol dropTargetProtocol = dropTargetProtocols.next(); if (dropTargetProtocol.isProtocolSupported(embedder)) { embedderProtocols.add(dropTargetProtocol); } @@ -361,8 +358,7 @@ final class XDropTargetRegistry { XlibWrapper.XGrabServer(XToolkit.getDisplay()); try { while (dropTargetProtocols.hasNext()) { - XDropTargetProtocol dropTargetProtocol = - (XDropTargetProtocol)dropTargetProtocols.next(); + XDropTargetProtocol dropTargetProtocol = dropTargetProtocols.next(); if (!isXEmbedServer || !dropTargetProtocol.isXEmbedSupported()) { dropTargetProtocol.registerEmbedderDropSite(embedder); } @@ -376,7 +372,7 @@ final class XDropTargetRegistry { EmbeddedDropSiteEntry entry) { assert XToolkit.isAWTLockHeldByCurrentThread(); - Iterator dropTargetProtocols = + Iterator<XDropTargetProtocol> dropTargetProtocols = XDragAndDropProtocols.getDropTargetProtocols(); /* Grab server, since we are working with the window that belongs to @@ -384,8 +380,7 @@ final class XDropTargetRegistry { XlibWrapper.XGrabServer(XToolkit.getDisplay()); try { while (dropTargetProtocols.hasNext()) { - XDropTargetProtocol dropTargetProtocol = - (XDropTargetProtocol)dropTargetProtocols.next(); + XDropTargetProtocol dropTargetProtocol = dropTargetProtocols.next(); dropTargetProtocol.unregisterEmbedderDropSite(embedder); } @@ -470,14 +465,14 @@ final class XDropTargetRegistry { registerProtocols(toplevel, XEMBED_PROTOCOLS, entry.getSupportedProtocols()); } else { - Iterator dropTargetProtocols = + Iterator<XDropTargetProtocol> dropTargetProtocols = XDragAndDropProtocols.getDropTargetProtocols(); // Register the embedded window as a plain drop site with // all DnD protocols that are supported by XEmbed. while (dropTargetProtocols.hasNext()) { XDropTargetProtocol dropTargetProtocol = - (XDropTargetProtocol)dropTargetProtocols.next(); + dropTargetProtocols.next(); if (dropTargetProtocol.isXEmbedSupported()) { dropTargetProtocol.registerEmbedderDropSite(window); } @@ -558,12 +553,12 @@ final class XDropTargetRegistry { } if (toplevel == window) { - Iterator dropTargetProtocols = + Iterator<XDropTargetProtocol> dropTargetProtocols = XDragAndDropProtocols.getDropTargetProtocols(); while (dropTargetProtocols.hasNext()) { XDropTargetProtocol dropTargetProtocol = - (XDropTargetProtocol)dropTargetProtocols.next(); + dropTargetProtocols.next(); dropTargetProtocol.registerDropTarget(toplevel); } } else { @@ -584,13 +579,13 @@ final class XDropTargetRegistry { long toplevel = getToplevelWindow(window); if (toplevel == window) { - Iterator dropProtocols = + Iterator<XDropTargetProtocol> dropProtocols = XDragAndDropProtocols.getDropTargetProtocols(); removeDelayedRegistrationEntry(window); while (dropProtocols.hasNext()) { - XDropTargetProtocol dropProtocol = (XDropTargetProtocol)dropProtocols.next(); + XDropTargetProtocol dropProtocol = dropProtocols.next(); dropProtocol.unregisterDropTarget(window); } } else { @@ -615,12 +610,11 @@ final class XDropTargetRegistry { } registerEmbeddedDropSite(canvasWindow, clientWindow); - Iterator dropTargetProtocols = + Iterator<XDropTargetProtocol> dropTargetProtocols = XDragAndDropProtocols.getDropTargetProtocols(); while (dropTargetProtocols.hasNext()) { - XDropTargetProtocol dropTargetProtocol = - (XDropTargetProtocol)dropTargetProtocols.next(); + XDropTargetProtocol dropTargetProtocol = dropTargetProtocols.next(); dropTargetProtocol.registerEmbeddedDropSite(clientWindow); } @@ -634,12 +628,11 @@ final class XDropTargetRegistry { if (logger.isLoggable(PlatformLogger.Level.FINE)) { logger.fine(" XEmbed drop site will be unregistered for " + Long.toHexString(clientWindow)); } - Iterator dropTargetProtocols = + Iterator<XDropTargetProtocol> dropTargetProtocols = XDragAndDropProtocols.getDropTargetProtocols(); while (dropTargetProtocols.hasNext()) { - XDropTargetProtocol dropTargetProtocol = - (XDropTargetProtocol)dropTargetProtocols.next(); + XDropTargetProtocol dropTargetProtocol = dropTargetProtocols.next(); dropTargetProtocol.unregisterEmbeddedDropSite(clientWindow); } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddingContainer.java b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddingContainer.java index e23fb93aef8..4096f435e33 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddingContainer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddingContainer.java @@ -32,7 +32,7 @@ import java.lang.reflect.*; import sun.awt.AWTAccessor; public class XEmbeddingContainer extends XEmbedHelper implements XEventDispatcher { - HashMap children = new HashMap(); + HashMap<Long, java.awt.peer.ComponentPeer> children = new HashMap<>(); XEmbeddingContainer() { } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XFileDialogPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XFileDialogPeer.java index b3d0731d5f0..bb13ffda5df 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XFileDialogPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XFileDialogPeer.java @@ -146,9 +146,9 @@ class XFileDialogPeer extends XDialogPeer implements FileDialogPeer, ActionListe savedDir = target.getDirectory(); // Shouldn't save 'user.dir' to 'savedDir' // since getDirectory() will be incorrect after handleCancel - userDir = (String)AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + userDir = AccessController.doPrivileged( + new PrivilegedAction<String>() { + public String run() { return System.getProperty("user.dir"); } }); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XListPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XListPeer.java index 91b02d797b8..77545589889 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XListPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XListPeer.java @@ -70,7 +70,7 @@ class XListPeer extends XComponentPeer implements ListPeer, XScrollbarClient { ListPainter painter; // TODO: ick - Vector? - Vector items; + Vector<String> items; boolean multipleSelections; int active = NONE; @@ -139,7 +139,7 @@ class XListPeer extends XComponentPeer implements ListPeer, XScrollbarClient { super.preInit(params); // Stuff that must be initialized before layout() is called - items = new Vector(); + items = new Vector<>(); createVerScrollbar(); createHorScrollbar(); @@ -281,7 +281,7 @@ class XListPeer extends XComponentPeer implements ListPeer, XScrollbarClient { int m = 0; int end = items.size(); for(int i = 0 ; i < end ; i++) { - int l = fm.stringWidth(((String)items.elementAt(i))); + int l = fm.stringWidth(items.elementAt(i)); m = Math.max(m, l); } return m; @@ -292,7 +292,7 @@ class XListPeer extends XComponentPeer implements ListPeer, XScrollbarClient { */ int getItemWidth(int i) { FontMetrics fm = getFontMetrics(getFont()); - return fm.stringWidth((String)items.elementAt(i)); + return fm.stringWidth(items.elementAt(i)); } /** @@ -659,7 +659,7 @@ class XListPeer extends XComponentPeer implements ListPeer, XScrollbarClient { ( clickCount % 2 == 0 ) ) { postEvent(new ActionEvent(target, ActionEvent.ACTION_PERFORMED, - (String)items.elementAt(currentIndex), + items.elementAt(currentIndex), mouseEvent.getWhen(), mouseEvent.getModifiers())); // No ext mods } else if (active == WINDOW) { @@ -986,7 +986,7 @@ class XListPeer extends XComponentPeer implements ListPeer, XScrollbarClient { if (selected.length > 0) { postEvent(new ActionEvent((List)target, ActionEvent.ACTION_PERFORMED, - (String)items.elementAt(getFocusIndex()), + items.elementAt(getFocusIndex()), e.getWhen(), e.getModifiers())); // ActionEvent doesn't have // extended modifiers. @@ -1343,7 +1343,7 @@ class XListPeer extends XComponentPeer implements ListPeer, XScrollbarClient { */ public void clear() { selected = new int[0]; - items = new Vector(); + items = new Vector<>(); currentIndex = -1; // Fixed 6291736: ITEM_STATE_CHANGED triggered after List.removeAll(), XToolkit // We should update 'focusIndex' variable more carefully @@ -1926,7 +1926,7 @@ class XListPeer extends XComponentPeer implements ListPeer, XScrollbarClient { } else { g.setColor(getListForeground()); } - String str = (String)items.elementAt(index); + String str = items.elementAt(index); g.drawString(str, x - hsb.getValue(), y + fontAscent); } else { // Clear the remaining area around the item - focus area and the rest of border diff --git a/jdk/src/solaris/classes/sun/awt/X11/XMSelection.java b/jdk/src/solaris/classes/sun/awt/X11/XMSelection.java index a74dad630e7..066a83aae8c 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XMSelection.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XMSelection.java @@ -60,7 +60,7 @@ public class XMSelection { String selectionName; /* list of listeners to be called for events */ - Vector listeners; + Vector<XMSelectionListener> listeners; /* X atom array (one per screen) for this selection */ XAtom atoms[]; @@ -75,7 +75,7 @@ public class XMSelection { static XAtom XA_MANAGER; - static HashMap selectionMap; + static HashMap<Long, XMSelection> selectionMap; static { long display = XToolkit.getDisplay(); @@ -90,7 +90,7 @@ public class XMSelection { initScreen(display,screen); } - selectionMap = new HashMap(); + selectionMap = new HashMap<>(); } static void initScreen(long display, final int screen) { @@ -227,7 +227,7 @@ public class XMSelection { static XMSelection getInstance(long selection) { - return (XMSelection) selectionMap.get(Long.valueOf(selection)); + return selectionMap.get(Long.valueOf(selection)); } @@ -259,7 +259,7 @@ public class XMSelection { public synchronized void addSelectionListener(XMSelectionListener listener) { if (listeners == null) { - listeners = new Vector(); + listeners = new Vector<>(); } listeners.add(listener); } @@ -270,7 +270,7 @@ public class XMSelection { } } - synchronized Collection getListeners() { + synchronized Collection<XMSelectionListener> getListeners() { return listeners; } @@ -310,9 +310,9 @@ public class XMSelection { log.fine("Selection Changed : Screen = " + screen + "Event =" + ev); } if (listeners != null) { - Iterator iter = listeners.iterator(); + Iterator<XMSelectionListener> iter = listeners.iterator(); while (iter.hasNext()) { - XMSelectionListener disp = (XMSelectionListener) iter.next(); + XMSelectionListener disp = iter.next(); disp.selectionChanged(screen, this, ev.get_window(), ev); } } @@ -323,9 +323,9 @@ public class XMSelection { log.fine("Owner dead : Screen = " + screen + "Event =" + de); } if (listeners != null) { - Iterator iter = listeners.iterator(); + Iterator<XMSelectionListener> iter = listeners.iterator(); while (iter.hasNext()) { - XMSelectionListener disp = (XMSelectionListener) iter.next(); + XMSelectionListener disp = iter.next(); disp.ownerDeath(screen, this, de.get_window()); } @@ -349,9 +349,9 @@ public class XMSelection { synchronized void dispatchOwnerChangedEvent(XEvent ev, int screen, long owner, long data, long timestamp) { if (listeners != null) { - Iterator iter = listeners.iterator(); + Iterator<XMSelectionListener> iter = listeners.iterator(); while (iter.hasNext()) { - XMSelectionListener disp = (XMSelectionListener) iter.next(); + XMSelectionListener disp = iter.next(); disp.ownerChanged(screen,this, owner, data, timestamp); } } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XMenuBarPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XMenuBarPeer.java index c1b568bc0fb..d8f3f17655b 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XMenuBarPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XMenuBarPeer.java @@ -195,10 +195,10 @@ public class XMenuBarPeer extends XBaseMenuWindow implements MenuBarPeer { void postInit(XCreateWindowParams params) { super.postInit(params); // Get menus from the target. - Vector targetMenuVector = AWTAccessor.getMenuBarAccessor() - .getMenus(menuBarTarget); + Vector<Menu> targetMenuVector = AWTAccessor.getMenuBarAccessor() + .getMenus(menuBarTarget); Menu targetHelpMenu = AWTAccessor.getMenuBarAccessor() - .getHelpMenu(menuBarTarget); + .getHelpMenu(menuBarTarget); reloadItems(targetMenuVector); if (targetHelpMenu != null) { addHelpMenu(targetHelpMenu); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XMenuPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XMenuPeer.java index 067efa13d3a..6aea4c9eacc 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XMenuPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XMenuPeer.java @@ -143,7 +143,7 @@ public class XMenuPeer extends XMenuItemPeer implements MenuPeer { * Access to target's fields * ************************************************/ - Vector getTargetItems() { + Vector<MenuItem> getTargetItems() { return AWTAccessor.getMenuAccessor().getItems((Menu)getTarget()); } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XMenuWindow.java b/jdk/src/solaris/classes/sun/awt/X11/XMenuWindow.java index 9863c983873..b5fbfca919c 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XMenuWindow.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XMenuWindow.java @@ -164,7 +164,7 @@ public class XMenuWindow extends XBaseMenuWindow { this.menuPeer = menuPeer; this.target = menuPeer.getContainer().target; // Get menus from the target. - Vector targetItemVector = null; + Vector<MenuItem> targetItemVector = null; targetItemVector = getMenuTargetItems(); reloadItems(targetItemVector); } @@ -356,7 +356,7 @@ public class XMenuWindow extends XBaseMenuWindow { * Reads vector of items from target * This function is overriden in XPopupMenuPeer */ - Vector getMenuTargetItems() { + Vector<MenuItem> getMenuTargetItems() { return menuPeer.getTargetItems(); } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java index 81c60dd55b2..03a4db3f9f9 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java @@ -134,7 +134,7 @@ public class XPopupMenuPeer extends XMenuWindow implements PopupMenuPeer { public void show(Event e) { target = (Component)e.target; // Get menus from the target. - Vector targetItemVector = getMenuTargetItems(); + Vector<MenuItem> targetItemVector = getMenuTargetItems(); if (targetItemVector != null) { reloadItems(targetItemVector); //Fix for 6287092: JCK15a: api/java_awt/interactive/event/EventTests.html#EventTest0015 fails, mustang @@ -188,7 +188,7 @@ public class XPopupMenuPeer extends XMenuWindow implements PopupMenuPeer { return AWTAccessor.getMenuItemAccessor().isEnabled(popupMenuTarget); } - Vector getMenuTargetItems() { + Vector<MenuItem> getMenuTargetItems() { if (popupMenuTarget == null) { return null; } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XSelection.java b/jdk/src/solaris/classes/sun/awt/X11/XSelection.java index 36ebc8e6dba..33f792d7a0b 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XSelection.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XSelection.java @@ -25,6 +25,7 @@ package sun.awt.X11; +import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.io.ByteArrayOutputStream; @@ -87,7 +88,7 @@ public final class XSelection { /* The contents supplied by the current owner. */ private Transferable contents = null; /* The format-to-flavor map for the current owner. */ - private Map formatMap = null; + private Map<Long, DataFlavor> formatMap = null; /* The formats supported by the current owner was set. */ private long[] formats = null; /* The AppContext in which the current owner was set. */ @@ -134,7 +135,8 @@ public final class XSelection { return selectionAtom; } - public synchronized boolean setOwner(Transferable contents, Map formatMap, + public synchronized boolean setOwner(Transferable contents, + Map<Long, DataFlavor> formatMap, long[] formats, long time) { long owner = XWindow.getXAWTRootWindow().getWindow(); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java index 3648e874b6a..6ae75161b10 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java @@ -36,6 +36,7 @@ import java.awt.dnd.DragGestureRecognizer; import java.awt.dnd.MouseDragGestureRecognizer; import java.awt.dnd.InvalidDnDOperationException; import java.awt.dnd.peer.DragSourceContextPeer; +import java.awt.font.TextAttribute; import java.awt.im.InputMethodHighlight; import java.awt.im.spi.InputMethodDescriptor; import java.awt.image.ColorModel; @@ -99,9 +100,9 @@ public final class XToolkit extends UNIXToolkit implements Runnable { private FontConfigManager fcManager = new FontConfigManager(); static int arrowCursor; - static TreeMap winMap = new TreeMap(); - static HashMap specialPeerMap = new HashMap(); - static HashMap winToDispatcher = new HashMap(); + static TreeMap<Long, XBaseWindow> winMap = new TreeMap<>(); + static HashMap<Object, Object> specialPeerMap = new HashMap<>(); + static HashMap<Long, Collection<XEventDispatcher>> winToDispatcher = new HashMap<>(); private static long _display; static UIDefaults uidefaults; static X11GraphicsEnvironment localEnv; @@ -358,16 +359,16 @@ public final class XToolkit extends UNIXToolkit implements Runnable { } static XBaseWindow windowToXWindow(long window) { synchronized(winMap) { - return (XBaseWindow) winMap.get(Long.valueOf(window)); + return winMap.get(Long.valueOf(window)); } } static void addEventDispatcher(long window, XEventDispatcher dispatcher) { synchronized(winToDispatcher) { Long key = Long.valueOf(window); - Collection dispatchers = (Collection)winToDispatcher.get(key); + Collection<XEventDispatcher> dispatchers = winToDispatcher.get(key); if (dispatchers == null) { - dispatchers = new Vector(); + dispatchers = new Vector<>(); winToDispatcher.put(key, dispatchers); } dispatchers.add(dispatcher); @@ -376,7 +377,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable { static void removeEventDispatcher(long window, XEventDispatcher dispatcher) { synchronized(winToDispatcher) { Long key = Long.valueOf(window); - Collection dispatchers = (Collection)winToDispatcher.get(key); + Collection<XEventDispatcher> dispatchers = winToDispatcher.get(key); if (dispatchers != null) { dispatchers.remove(dispatcher); } @@ -493,18 +494,18 @@ public final class XToolkit extends UNIXToolkit implements Runnable { } XBaseWindow.dispatchToWindow(ev); - Collection dispatchers = null; + Collection<XEventDispatcher> dispatchers = null; synchronized(winToDispatcher) { Long key = Long.valueOf(xany.get_window()); - dispatchers = (Collection)winToDispatcher.get(key); + dispatchers = winToDispatcher.get(key); if (dispatchers != null) { // Clone it to avoid synchronization during dispatching - dispatchers = new Vector(dispatchers); + dispatchers = new Vector<>(dispatchers); } } if (dispatchers != null) { - Iterator iter = dispatchers.iterator(); + Iterator<XEventDispatcher> iter = dispatchers.iterator(); while (iter.hasNext()) { - XEventDispatcher disp = (XEventDispatcher)iter.next(); + XEventDispatcher disp = iter.next(); disp.dispatchEvent(ev); } } @@ -764,7 +765,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable { Insets insets = new Insets(0, 0, 0, 0); - java.util.List search = new LinkedList(); + java.util.List<Object> search = new LinkedList<>(); search.add(root); search.add(0); while (!search.isEmpty()) @@ -929,6 +930,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable { return XDragSourceContextPeer.createDragSourceContextPeer(dge); } + @SuppressWarnings("unchecked") public <T extends DragGestureRecognizer> T createDragGestureRecognizer(Class<T> recognizerClass, DragSource ds, @@ -1147,7 +1149,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable { return 2; // Black and white. } - public Map mapInputMethodHighlight(InputMethodHighlight highlight) { + public Map<TextAttribute, ?> mapInputMethodHighlight( InputMethodHighlight highlight) { return XInputMethod.mapInputMethodHighlight(highlight); } @Override @@ -1338,31 +1340,25 @@ public final class XToolkit extends UNIXToolkit implements Runnable { static void dumpPeers() { if (log.isLoggable(PlatformLogger.Level.FINE)) { log.fine("Mapped windows:"); - Iterator iter = winMap.entrySet().iterator(); - while (iter.hasNext()) { - Map.Entry entry = (Map.Entry)iter.next(); - log.fine(entry.getKey() + "->" + entry.getValue()); - if (entry.getValue() instanceof XComponentPeer) { - Component target = (Component)((XComponentPeer)entry.getValue()).getTarget(); + winMap.forEach((k, v) -> { + log.fine(k + "->" + v); + if (v instanceof XComponentPeer) { + Component target = (Component)((XComponentPeer)v).getTarget(); log.fine("\ttarget: " + target); } - } + }); SunToolkit.dumpPeers(log); log.fine("Mapped special peers:"); - iter = specialPeerMap.entrySet().iterator(); - while (iter.hasNext()) { - Map.Entry entry = (Map.Entry)iter.next(); - log.fine(entry.getKey() + "->" + entry.getValue()); - } + specialPeerMap.forEach((k, v) -> { + log.fine(k + "->" + v); + }); log.fine("Mapped dispatchers:"); - iter = winToDispatcher.entrySet().iterator(); - while (iter.hasNext()) { - Map.Entry entry = (Map.Entry)iter.next(); - log.fine(entry.getKey() + "->" + entry.getValue()); - } + winToDispatcher.forEach((k, v) -> { + log.fine(k + "->" + v); + }); } } @@ -1586,16 +1582,16 @@ public final class XToolkit extends UNIXToolkit implements Runnable { * <code>loadXSettings</code>. It is called from the System EDT * if triggered by an XSETTINGS change. */ - void parseXSettings(int screen_XXX_ignored,Map updatedSettings) { + void parseXSettings(int screen_XXX_ignored,Map<String, Object> updatedSettings) { if (updatedSettings == null || updatedSettings.isEmpty()) { return; } - Iterator i = updatedSettings.entrySet().iterator(); + Iterator<Map.Entry<String, Object>> i = updatedSettings.entrySet().iterator(); while (i.hasNext()) { - Map.Entry e = (Map.Entry)i.next(); - String name = (String)e.getKey(); + Map.Entry<String, Object> e = i.next(); + String name = e.getKey(); name = "gnome." + name; setDesktopProperty(name, e.getValue()); @@ -1692,7 +1688,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable { long window = 0; try{ // get any application window - window = ((Long)(winMap.firstKey())).longValue(); + window = winMap.firstKey().longValue(); }catch(NoSuchElementException nex) { // get root window window = getDefaultRootWindow(); @@ -1798,7 +1794,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable { } - private static SortedMap timeoutTasks; + private static SortedMap<Long, java.util.List<Runnable>> timeoutTasks; /** * Removed the task from the list of waiting-to-be called tasks. @@ -1819,10 +1815,10 @@ public final class XToolkit extends UNIXToolkit implements Runnable { } return; } - Collection values = timeoutTasks.values(); - Iterator iter = values.iterator(); + Collection<java.util.List<Runnable>> values = timeoutTasks.values(); + Iterator<java.util.List<Runnable>> iter = values.iterator(); while (iter.hasNext()) { - java.util.List list = (java.util.List)iter.next(); + java.util.List<Runnable> list = iter.next(); boolean removed = false; if (list.contains(task)) { list.remove(task); @@ -1869,13 +1865,13 @@ public final class XToolkit extends UNIXToolkit implements Runnable { } if (timeoutTasks == null) { - timeoutTasks = new TreeMap(); + timeoutTasks = new TreeMap<>(); } Long time = Long.valueOf(System.currentTimeMillis() + interval); - java.util.List tasks = (java.util.List)timeoutTasks.get(time); + java.util.List<Runnable> tasks = timeoutTasks.get(time); if (tasks == null) { - tasks = new ArrayList(1); + tasks = new ArrayList<>(1); timeoutTasks.put(time, tasks); } tasks.add(task); @@ -1897,7 +1893,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable { if (timeoutTasks == null || timeoutTasks.isEmpty()) { return -1L; } - return (Long)timeoutTasks.firstKey(); + return timeoutTasks.firstKey(); } finally { awtUnlock(); } @@ -1918,13 +1914,13 @@ public final class XToolkit extends UNIXToolkit implements Runnable { } Long currentTime = Long.valueOf(System.currentTimeMillis()); - Long time = (Long)timeoutTasks.firstKey(); + Long time = timeoutTasks.firstKey(); while (time.compareTo(currentTime) <= 0) { - java.util.List tasks = (java.util.List)timeoutTasks.remove(time); + java.util.List<Runnable> tasks = timeoutTasks.remove(time); - for (Iterator iter = tasks.iterator(); iter.hasNext();) { - Runnable task = (Runnable)iter.next(); + for (Iterator<Runnable> iter = tasks.iterator(); iter.hasNext();) { + Runnable task = iter.next(); if (timeoutTaskLog.isLoggable(PlatformLogger.Level.FINER)) { timeoutTaskLog.finer("XToolkit.callTimeoutTasks(): current time={0}" + @@ -1943,7 +1939,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable { if (timeoutTasks.isEmpty()) { break; } - time = (Long)timeoutTasks.firstKey(); + time = timeoutTasks.firstKey(); } } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java index 86e6e064fc0..4b0a1aec85d 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java @@ -85,7 +85,7 @@ public class XTrayIconPeer implements TrayIconPeer, // Fix for 6317038: as EmbeddedFrame is instance of Frame, it is blocked // by modal dialogs, but in the case of TrayIcon it shouldn't. So we // set ModalExclusion property on it. - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { eframe.setModalExclusionType(Dialog.ModalExclusionType.TOOLKIT_EXCLUDE); return null; diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWM.java b/jdk/src/solaris/classes/sun/awt/X11/XWM.java index 26c4b472883..dd98eb01279 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XWM.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XWM.java @@ -1072,6 +1072,7 @@ final class XWM * Returns all protocols supporting given protocol interface */ <T> Collection<T> getProtocols(Class<T> protocolInterface) { + @SuppressWarnings("unchecked") Collection<T> res = (Collection<T>) protocolsMap.get(protocolInterface); if (res != null) { return res; @@ -1322,9 +1323,9 @@ final class XWM } } - HashMap storedInsets = new HashMap(); + HashMap<Class<?>, Insets> storedInsets = new HashMap<>(); Insets guessInsets(XDecoratedPeer window) { - Insets res = (Insets)storedInsets.get(window.getClass()); + Insets res = storedInsets.get(window.getClass()); if (res == null) { switch (WMID) { case ENLIGHTEN_WM: diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java index d59ac88d3a0..b7d2a7488f4 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java @@ -59,7 +59,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { static int lastX = 0, lastY = 0; static long lastTime = 0; static long lastButton = 0; - static WeakReference lastWindowRef = null; + static WeakReference<XWindow> lastWindowRef = null; static int clickCount = 0; // used to check if we need to re-create surfaceData. @@ -692,7 +692,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { if (type == XConstants.ButtonPress) { //Allow this mouse button to generate CLICK event on next ButtonRelease mouseButtonClickAllowed |= XlibUtil.getButtonMask(lbutton); - XWindow lastWindow = (lastWindowRef != null) ? ((XWindow)lastWindowRef.get()):(null); + XWindow lastWindow = (lastWindowRef != null) ? (lastWindowRef.get()):(null); /* multiclick checking */ @@ -705,7 +705,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { clickCount++; } else { clickCount = 1; - lastWindowRef = new WeakReference(this); + lastWindowRef = new WeakReference<>(this); lastButton = lbutton; lastX = x; lastY = y; @@ -820,7 +820,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { */ int x = xme.get_x(); int y = xme.get_y(); - XWindow lastWindow = (lastWindowRef != null) ? ((XWindow)lastWindowRef.get()):(null); + XWindow lastWindow = (lastWindowRef != null) ? (lastWindowRef.get()):(null); if (!(lastWindow == this && (xme.get_time() - lastTime) < XToolkit.getMultiClickTime() && diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java index 521bbc145b3..bebd7212e9e 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java @@ -950,7 +950,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, // make new hash of toplevels of all windows from 'windows' hash. // FIXME: do not call them "toplevel" as it is misleading. // - HashSet toplevels = new HashSet(); + HashSet<Long> toplevels = new HashSet<>(); long topl = 0, mytopl = 0; for (XWindowPeer xp : windows) { diff --git a/jdk/src/solaris/classes/sun/awt/X11CustomCursor.java b/jdk/src/solaris/classes/sun/awt/X11CustomCursor.java index 969e7c5116e..c39fcbacda7 100644 --- a/jdk/src/solaris/classes/sun/awt/X11CustomCursor.java +++ b/jdk/src/solaris/classes/sun/awt/X11CustomCursor.java @@ -47,7 +47,7 @@ public abstract class X11CustomCursor extends CustomCursor { protected void createNativeCursor(Image im, int[] pixels, int width, int height, int xHotSpot, int yHotSpot) { - class CCount implements Comparable { + class CCount implements Comparable<CCount> { int color; int count; @@ -56,8 +56,8 @@ public abstract class X11CustomCursor extends CustomCursor { count = ct; } - public int compareTo(Object cc) { - return ((CCount)cc).count - count; + public int compareTo(CCount cc) { + return cc.count - count; } } diff --git a/jdk/src/solaris/classes/sun/awt/X11FontManager.java b/jdk/src/solaris/classes/sun/awt/X11FontManager.java index c9d2ebc9ba4..987f669cc38 100644 --- a/jdk/src/solaris/classes/sun/awt/X11FontManager.java +++ b/jdk/src/solaris/classes/sun/awt/X11FontManager.java @@ -59,7 +59,7 @@ public class X11FontManager extends SunFontManager { * E.g., the -0-0-0-0-p-0- reported by X is -*-%d-*-*-p-*- in the font * configuration files. We need to remove that part for comparisons. */ - private static Map fontNameMap = new HashMap(); + private static Map<String, String> fontNameMap = new HashMap<>(); /* * xlfdMap is a map from a platform path like @@ -72,7 +72,7 @@ public class X11FontManager extends SunFontManager { * the full XLFD string like :- * "-ricoh-hg gothic b-medium-r-normal--0-0-0-0-m-0-jisx0201.1976-0" */ - private static Map xlfdMap = new HashMap(); + private static Map<String, Vector<String>> xlfdMap = new HashMap<>(); /* xFontDirsMap is also a map from a font ID to a font filepath. * The difference from fontNameMap is just that it does not have @@ -88,7 +88,7 @@ public class X11FontManager extends SunFontManager { * X11 font directory, then precautions must be taken to include both * directories. */ - private static Map xFontDirsMap; + private static Map<String, String> xFontDirsMap; /* * This is the set of font directories needed to be on the X font path @@ -121,7 +121,7 @@ public class X11FontManager extends SunFontManager { * of the singleton GE instance is already synchronised and that is * the only code path that accesses this map. */ - private static HashMap registeredDirs = new HashMap(); + private static HashMap<String, Object> registeredDirs = new HashMap<>(); /* Array of directories to be added to the X11 font path. * Used by static method called from Toolkits which use X11 fonts. @@ -183,7 +183,7 @@ public class X11FontManager extends SunFontManager { * Add this XLFD (platform name) to the list of known * ones for this file. */ - Vector xVal = (Vector) xlfdMap.get(fileName); + Vector<String> xVal = xlfdMap.get(fileName); if (xVal == null) { /* Try to be robust on Linux distros which move fonts * around by verifying that the fileName represents a @@ -194,7 +194,7 @@ public class X11FontManager extends SunFontManager { fileName = null; } if (fileName != null) { - xVal = new Vector(); + xVal = new Vector<>(); xVal.add(platName); xlfdMap.put(fileName, xVal); } @@ -211,7 +211,7 @@ public class X11FontManager extends SunFontManager { } if (fontID != null) { - fileName = (String)fontNameMap.get(fontID); + fileName = fontNameMap.get(fontID); /* On Linux check for the Lucida Oblique fonts */ if (fileName == null && FontUtilities.isLinux && !isOpenJDK()) { if (oblmap == null) { @@ -235,7 +235,7 @@ public class X11FontManager extends SunFontManager { FontUtilities.getLogger() .warning("** Finished registering all font paths"); } - fileName = (String)fontNameMap.get(fontID); + fileName = fontNameMap.get(fontID); } if (fileName == null && !isHeadless()) { /* Query X11 directly to see if this font is available @@ -245,7 +245,7 @@ public class X11FontManager extends SunFontManager { } if (fileName == null) { fontID = switchFontIDForName(platName); - fileName = (String)fontNameMap.get(fontID); + fileName = fontNameMap.get(fontID); } if (fileName != null) { fontNameMap.put(fontID, fileName); @@ -257,8 +257,8 @@ public class X11FontManager extends SunFontManager { @Override protected String[] getNativeNames(String fontFileName, String platformName) { - Vector nativeNames; - if ((nativeNames=(Vector)xlfdMap.get(fontFileName))==null) { + Vector<String> nativeNames; + if ((nativeNames=xlfdMap.get(fontFileName))==null) { if (platformName == null) { return null; } else { @@ -271,7 +271,7 @@ public class X11FontManager extends SunFontManager { } } else { int len = nativeNames.size(); - return (String[])nativeNames.toArray(new String[len]); + return nativeNames.toArray(new String[len]); } } @@ -366,7 +366,7 @@ public class X11FontManager extends SunFontManager { } String fontPart = st.sval.substring(breakPos+1); String fontID = specificFontIDForName(fontPart); - String sVal = (String) fontNameMap.get(fontID); + String sVal = fontNameMap.get(fontID); if (FontUtilities.debugFonts()) { PlatformLogger logger = FontUtilities.getLogger(); @@ -386,14 +386,14 @@ public class X11FontManager extends SunFontManager { * wants to use the native rasteriser. */ if (xFontDirsMap == null) { - xFontDirsMap = new HashMap(); + xFontDirsMap = new HashMap<>(); } xFontDirsMap.put(fontID, path); fullPath = file.getCanonicalPath(); } catch (IOException e) { fullPath = path + File.separator + fileName; } - Vector xVal = (Vector) xlfdMap.get(fullPath); + Vector<String> xVal = xlfdMap.get(fullPath); if (FontUtilities.debugFonts()) { FontUtilities.getLogger() .info("fullPath=" + fullPath + @@ -408,7 +408,7 @@ public class X11FontManager extends SunFontManager { } fontNameMap.put(fontID, fullPath); if (xVal == null) { - xVal = new Vector(); + xVal = new Vector<>(); xlfdMap.put (fullPath, xVal); } xVal.add(fontPart); @@ -447,8 +447,8 @@ public class X11FontManager extends SunFontManager { * will typically not ever need to initialise it so it can be null. */ xFontDirsMap = null; - xlfdMap = new HashMap(1); - fontNameMap = new HashMap(1); + xlfdMap = new HashMap<>(1); + fontNameMap = new HashMap<>(1); } private String getObliqueLucidaFontID(String fontID) { @@ -579,10 +579,10 @@ public class X11FontManager extends SunFontManager { String fileName = null; String fontID = specificFontIDForName(name); if (fontID != null) { - fileName = (String)fontNameMap.get(fontID); + fileName = fontNameMap.get(fontID); if (fileName == null) { fontID = switchFontIDForName(name); - fileName = (String)fontNameMap.get(fontID); + fileName = fontNameMap.get(fontID); } if (fileName == null) { fileName = getDefaultFontFile(); @@ -685,7 +685,7 @@ public class X11FontManager extends SunFontManager { getPlatformFontPathFromFontConfig(); if (xFontDirsMap != null) { String fontID = specificFontIDForName(platformName); - String dirName = (String)xFontDirsMap.get(fontID); + String dirName = xFontDirsMap.get(fontID); if (dirName != null) { fontConfigDirs.add(dirName); } diff --git a/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java b/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java index 10365f9a647..4e5bb1bd3d9 100644 --- a/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java +++ b/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java @@ -56,7 +56,7 @@ public class X11GraphicsDevice implements DisplayChangedListener { int screen; - HashMap x11ProxyKeyMap = new HashMap(); + HashMap<SurfaceType, Object> x11ProxyKeyMap = new HashMap<>(); private static AWTPermission fullScreenExclusivePermission; private static Boolean xrandrExtSupported; @@ -127,7 +127,7 @@ public class X11GraphicsDevice GraphicsConfiguration[] configs; GraphicsConfiguration defaultConfig; - HashSet doubleBufferVisuals; + HashSet<Integer> doubleBufferVisuals; /** * Returns all of the graphics @@ -159,7 +159,7 @@ public class X11GraphicsDevice boolean dbeSupported = isDBESupported(); if (dbeSupported && doubleBufferVisuals == null) { - doubleBufferVisuals = new HashSet(); + doubleBufferVisuals = new HashSet<>(); getDoubleBufferVisuals(screen); } for ( ; i < num; i++) { @@ -249,7 +249,7 @@ public class X11GraphicsDevice int depth = getConfigDepth(0, screen); boolean doubleBuffer = false; if (isDBESupported() && doubleBufferVisuals == null) { - doubleBufferVisuals = new HashSet(); + doubleBufferVisuals = new HashSet<>(); getDoubleBufferVisuals(screen); doubleBuffer = doubleBufferVisuals.contains(Integer.valueOf(visNum)); diff --git a/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java b/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java index 547af9c3bed..02f491d6707 100644 --- a/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java +++ b/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java @@ -72,7 +72,7 @@ public class X11GraphicsEnvironment static { java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction<Object>() { public Object run() { System.loadLibrary("awt"); @@ -254,12 +254,12 @@ public class X11GraphicsEnvironment return true; } - Boolean result = (Boolean)java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + Boolean result = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction<Boolean>() { + public Boolean run() { InetAddress remAddr[] = null; - Enumeration locals = null; - Enumeration interfaces = null; + Enumeration<InetAddress> locals = null; + Enumeration<NetworkInterface> interfaces = null; try { interfaces = NetworkInterface.getNetworkInterfaces(); remAddr = InetAddress.getAllByName(hostName); @@ -275,7 +275,7 @@ public class X11GraphicsEnvironment } for (; interfaces.hasMoreElements();) { - locals = ((NetworkInterface)interfaces.nextElement()).getInetAddresses(); + locals = interfaces.nextElement().getInetAddresses(); for (; locals.hasMoreElements();) { for (int i = 0; i < remAddr.length; i++) { if (locals.nextElement().equals(remAddr[i])) { diff --git a/jdk/src/solaris/classes/sun/awt/X11InputMethod.java b/jdk/src/solaris/classes/sun/awt/X11InputMethod.java index 29135e1a37c..444a2a66aaf 100644 --- a/jdk/src/solaris/classes/sun/awt/X11InputMethod.java +++ b/jdk/src/solaris/classes/sun/awt/X11InputMethod.java @@ -100,7 +100,7 @@ public abstract class X11InputMethod extends InputMethodAdapter { private boolean isLastTemporary = false; private boolean isActive = false; private boolean isActiveClient = false; - private static Map[] highlightStyles; + private static Map<TextAttribute, ?>[] highlightStyles; private boolean disposed = false; //reset the XIC if necessary @@ -136,31 +136,29 @@ public abstract class X11InputMethod extends InputMethodAdapter { // Initialize highlight mapping table static { - Map styles[] = new Map[4]; - HashMap map; + @SuppressWarnings({"unchecked", "rawtypes"}) + Map<TextAttribute, ?> styles[] = new Map[4]; + HashMap<TextAttribute, Object> map; // UNSELECTED_RAW_TEXT_HIGHLIGHT - map = new HashMap(1); - map.put(TextAttribute.WEIGHT, - TextAttribute.WEIGHT_BOLD); + map = new HashMap<>(1); + map.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD); styles[0] = Collections.unmodifiableMap(map); // SELECTED_RAW_TEXT_HIGHLIGHT - map = new HashMap(1); - map.put(TextAttribute.SWAP_COLORS, - TextAttribute.SWAP_COLORS_ON); + map = new HashMap<>(1); + map.put(TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON); styles[1] = Collections.unmodifiableMap(map); // UNSELECTED_CONVERTED_TEXT_HIGHLIGHT - map = new HashMap(1); + map = new HashMap<>(1); map.put(TextAttribute.INPUT_METHOD_UNDERLINE, - TextAttribute.UNDERLINE_LOW_ONE_PIXEL); + TextAttribute.UNDERLINE_LOW_ONE_PIXEL); styles[2] = Collections.unmodifiableMap(map); // SELECTED_CONVERTED_TEXT_HIGHLIGHT - map = new HashMap(1); - map.put(TextAttribute.SWAP_COLORS, - TextAttribute.SWAP_COLORS_ON); + map = new HashMap<>(1); + map.put(TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON); styles[3] = Collections.unmodifiableMap(map); highlightStyles = styles; @@ -433,7 +431,7 @@ public abstract class X11InputMethod extends InputMethodAdapter { /** * @see java.awt.Toolkit#mapInputMethodHighlight */ - public static Map mapInputMethodHighlight(InputMethodHighlight highlight) { + public static Map<TextAttribute, ?> mapInputMethodHighlight(InputMethodHighlight highlight) { int index; int state = highlight.getState(); if (state == InputMethodHighlight.RAW_TEXT) { diff --git a/jdk/src/solaris/classes/sun/awt/XSettings.java b/jdk/src/solaris/classes/sun/awt/XSettings.java index 987b80ba778..59fb9a08ad2 100644 --- a/jdk/src/solaris/classes/sun/awt/XSettings.java +++ b/jdk/src/solaris/classes/sun/awt/XSettings.java @@ -52,7 +52,7 @@ public class XSettings { * settings manager. * @return a <code>Map</code> of changed settings. */ - public Map update(byte[] data) { + public Map<String, Object> update(byte[] data) { return (new Update(data)).update(); } @@ -79,7 +79,7 @@ public class XSettings { private int nsettings = 0; private boolean isValid; - private HashMap updatedSettings; + private HashMap<String, Object> updatedSettings; /** @@ -113,7 +113,7 @@ public class XSettings { idx = 8; nsettings = getINT32(); - updatedSettings = new HashMap(); + updatedSettings = new HashMap<>(); isValid = true; } @@ -213,7 +213,7 @@ public class XSettings { /** * Update settings. */ - public Map update() { + public Map<String, Object> update() { if (!isValid) { return null; } diff --git a/jdk/src/solaris/classes/sun/awt/motif/MFontConfiguration.java b/jdk/src/solaris/classes/sun/awt/motif/MFontConfiguration.java index 6c28d201779..b1d05fa671a 100644 --- a/jdk/src/solaris/classes/sun/awt/motif/MFontConfiguration.java +++ b/jdk/src/solaris/classes/sun/awt/motif/MFontConfiguration.java @@ -67,7 +67,7 @@ public class MFontConfiguration extends FontConfiguration { * the fontconfig files. */ protected void initReorderMap() { - reorderMap = new HashMap(); + reorderMap = new HashMap<>(); if (osName == null) { /* null means SunOS */ initReorderMapForSolaris(); } else { @@ -240,7 +240,7 @@ public class MFontConfiguration extends FontConfiguration { return "sun.awt.Symbol"; } } - String encoding = (String) encodingMap.get(xlfdEncoding); + String encoding = encodingMap.get(xlfdEncoding); if (encoding == null) { encoding = "default"; } @@ -288,7 +288,7 @@ public class MFontConfiguration extends FontConfiguration { /* methods for table setup ***********************************************/ - private static HashMap encodingMap = new HashMap(); + private static HashMap<String, String> encodingMap = new HashMap<>(); private void initTables() { // encodingMap maps XLFD encoding component to From 0224281ecb9eeb69639851c53592c664e51798f4 Mon Sep 17 00:00:00 2001 From: Yuri Nesterenko <yan@openjdk.org> Date: Tue, 29 Apr 2014 14:32:38 +0400 Subject: [PATCH 030/157] 8041592: [TEST_BUG] Move 42 AWT hw/lw mixing tests to jdk Reviewed-by: anthony, pchelko --- .../Mixing/AWT_Mixing/FrameBorderCounter.java | 95 +++ .../GlassPaneOverlappingTestBase.java | 144 ++++ .../HierarchyBoundsListenerMixingTest.java | 692 +++++++++++++++ .../JButtonInGlassPaneOverlapping.java | 51 ++ .../Mixing/AWT_Mixing/JButtonOverlapping.java | 51 ++ .../AWT_Mixing/JColorChooserOverlapping.java | 54 ++ .../AWT_Mixing/JComboBoxOverlapping.java | 99 +++ .../JEditorPaneInGlassPaneOverlapping.java | 53 ++ .../AWT_Mixing/JEditorPaneOverlapping.java | 50 ++ .../JGlassPaneInternalFrameOverlapping.java | 127 +++ .../AWT_Mixing/JGlassPaneMoveOverlapping.java | 167 ++++ .../JInternalFrameMoveOverlapping.java | 124 +++ .../AWT_Mixing/JInternalFrameOverlapping.java | 102 +++ .../JLabelInGlassPaneOverlapping.java | 53 ++ .../Mixing/AWT_Mixing/JLabelOverlapping.java | 52 ++ .../JListInGlassPaneOverlapping.java | 50 ++ .../Mixing/AWT_Mixing/JListOverlapping.java | 49 ++ .../AWT_Mixing/JMenuBarOverlapping.java | 149 ++++ .../JPanelInGlassPaneOverlapping.java | 53 ++ .../Mixing/AWT_Mixing/JPanelOverlapping.java | 52 ++ .../AWT_Mixing/JPopupMenuOverlapping.java | 124 +++ .../JProgressBarInGlassPaneOverlapping.java | 53 ++ .../AWT_Mixing/JProgressBarOverlapping.java | 52 ++ .../JScrollBarInGlassPaneOverlapping.java | 67 ++ .../AWT_Mixing/JScrollBarOverlapping.java | 66 ++ .../AWT_Mixing/JScrollPaneOverlapping.java | 129 +++ .../JSliderInGlassPaneOverlapping.java | 52 ++ .../Mixing/AWT_Mixing/JSliderOverlapping.java | 51 ++ .../JSpinnerInGlassPaneOverlapping.java | 67 ++ .../AWT_Mixing/JSpinnerOverlapping.java | 64 ++ .../AWT_Mixing/JSplitPaneOverlapping.java | 130 +++ .../JTableInGlassPaneOverlapping.java | 87 ++ .../Mixing/AWT_Mixing/JTableOverlapping.java | 73 ++ .../JTextAreaInGlassPaneOverlapping.java | 53 ++ .../AWT_Mixing/JTextAreaOverlapping.java | 52 ++ .../JTextFieldInGlassPaneOverlapping.java | 53 ++ .../AWT_Mixing/JTextFieldOverlapping.java | 52 ++ .../JToggleButtonInGlassPaneOverlapping.java | 51 ++ .../AWT_Mixing/JToggleButtonOverlapping.java | 50 ++ .../AWT_Mixing/MixingFrameResizing.java | 127 +++ .../AWT_Mixing/MixingPanelsResizing.java | 462 ++++++++++ .../Mixing/AWT_Mixing/OpaqueOverlapping.java | 164 ++++ .../AWT_Mixing/OpaqueOverlappingChoice.java | 48 ++ .../AWT_Mixing/OverlappingTestBase.java | 800 ++++++++++++++++++ .../AWT_Mixing/SimpleOverlappingTestBase.java | 160 ++++ jdk/test/java/awt/Mixing/AWT_Mixing/Util.java | 601 +++++++++++++ .../AWT_Mixing/ViewportOverlapping.java | 151 ++++ 47 files changed, 6106 insertions(+) create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/FrameBorderCounter.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/GlassPaneOverlappingTestBase.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/HierarchyBoundsListenerMixingTest.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JButtonInGlassPaneOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JButtonOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JColorChooserOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JEditorPaneInGlassPaneOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JEditorPaneOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JGlassPaneInternalFrameOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JInternalFrameMoveOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JInternalFrameOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JLabelInGlassPaneOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JLabelOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JListInGlassPaneOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JListOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JMenuBarOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JPanelInGlassPaneOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JPanelOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JPopupMenuOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JProgressBarInGlassPaneOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JProgressBarOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JScrollBarInGlassPaneOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JScrollBarOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JScrollPaneOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JSliderInGlassPaneOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JSliderOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JSpinnerInGlassPaneOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JSpinnerOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JSplitPaneOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JTableInGlassPaneOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JTableOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JTextAreaInGlassPaneOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JTextAreaOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JTextFieldInGlassPaneOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JTextFieldOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JToggleButtonInGlassPaneOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/JToggleButtonOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/MixingFrameResizing.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/OpaqueOverlappingChoice.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/OverlappingTestBase.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/SimpleOverlappingTestBase.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/Util.java create mode 100644 jdk/test/java/awt/Mixing/AWT_Mixing/ViewportOverlapping.java diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/FrameBorderCounter.java b/jdk/test/java/awt/Mixing/AWT_Mixing/FrameBorderCounter.java new file mode 100644 index 00000000000..a7380cece35 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/FrameBorderCounter.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.MouseEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowAdapter; + +public class FrameBorderCounter { + + private static Frame frame; + private static Frame background; + private static Dimension size; + private static Point location; + private static Point entered; + + public static void main(String[] args) throws Exception { + final Robot robot = new Robot(); + EventQueue.invokeAndWait(new Runnable() { + public void run() { + robot.mouseMove(0, 0); + } + }); + EventQueue.invokeAndWait(new Runnable() { + public void run() { + background = new Frame(); + background.setBounds(100, 100, 300, 300); + background.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + entered = e.getLocationOnScreen(); + System.err.println("[ENTERED] : " + entered); + } + }); + background.setVisible(true); + } + }); + EventQueue.invokeAndWait(new Runnable() { + public void run() { + frame = new Frame("Frame"); + frame.setBounds(200, 200, 100, 100); + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + frame.setVisible(true); + } + }); + Thread.sleep(1000); + EventQueue.invokeAndWait(new Runnable() { + public void run() { + location = frame.getLocationOnScreen(); + size = frame.getSize(); + } + }); + int out = 20; + for (int x = location.x + size.width - out; x <= location.x + size.width + out; ++x) { + robot.mouseMove(x, location.y + size.height / 2); + Thread.sleep(50); + } + System.err.println("[LOCATION] : " + location); + System.err.println("[SIZE] : " + size); + Thread.sleep(250); + int shift = entered.x - location.x - size.width - 1; + System.err.println("Done"); + System.out.println(shift); + frame.dispose(); + background.dispose(); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/GlassPaneOverlappingTestBase.java b/jdk/test/java/awt/Mixing/AWT_Mixing/GlassPaneOverlappingTestBase.java new file mode 100644 index 00000000000..6b7ba1cc60e --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/GlassPaneOverlappingTestBase.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.Container; +import java.awt.Point; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.InputEvent; +import java.lang.reflect.InvocationTargetException; +import javax.swing.JFrame; +import javax.swing.SpringLayout; +import javax.swing.SwingUtilities; + +/** + * Base class for testing overlapping of Swing and AWT component put into GlassPane. + * Validates drawing and event delivery at the components intersection. + * <p> See {@link OverlappingTestBase} for usage + * + * @author Sergey Grinev + */ +public abstract class GlassPaneOverlappingTestBase extends SimpleOverlappingTestBase { + + /** + * If true components is additionally tested to be correctly drawn after resize. + */ + protected boolean testResize = true; + private JFrame f = null; + private volatile Point ancestorLoc; + + /** + * Setups GlassPane with lightweight component returned by {@link SimpleOverlappingTestBase#getSwingComponent() } + * Called by base class. + */ + @Override + protected void prepareControls() { + wasLWClicked = false; + + if(f != null) { + f.setVisible(false); + } + f = new JFrame("Mixing : GlassPane Overlapping test"); + f.setLayout(new SpringLayout()); + f.setSize(200, 200); + + propagateAWTControls(f); + + f.getGlassPane().setVisible(true); + Container glassPane = (Container) f.getGlassPane(); + glassPane.setLayout(null); + + testedComponent = getSwingComponent(); + if (useDefaultClickValidation) { + testedComponent.addMouseListener(new MouseAdapter() { + + @Override + public void mouseClicked(MouseEvent e) { + //System.err.println("lw mouse clicked"); + wasLWClicked = true; + } + }); + } + testedComponent.setBounds(0, 0, testedComponent.getPreferredSize().width, testedComponent.getPreferredSize().height); + glassPane.add(testedComponent); + + f.setVisible(true); + } + + public GlassPaneOverlappingTestBase() { + super(); + } + + public GlassPaneOverlappingTestBase(boolean defaultClickValidation) { + super(defaultClickValidation); + } + + /** + * Run test by {@link OverlappingTestBase#clickAndBlink(java.awt.Robot, java.awt.Point) } validation for current lightweight component. + * <p>Also resize component and repeat validation in the resized area. + * <p>Called by base class. + * @return true if test passed + * @see GlassPaneOverlappingTestBase#testResize + */ + @Override + protected boolean performTest() { + if (!super.performTest()) { + return false; + } + if (testResize) { + wasLWClicked = false; + try { + SwingUtilities.invokeAndWait(new Runnable() { + + public void run() { + testedComponent.setBounds(0, 0, testedComponent.getPreferredSize().width, testedComponent.getPreferredSize().height + 20); + ancestorLoc = f.getLocationOnScreen(); + } + }); + } catch (InterruptedException ex) { + fail(ex.getMessage()); + } catch (InvocationTargetException ex) { + fail(ex.getMessage()); + } + Point lLoc = testedComponent.getLocationOnScreen(); + lLoc.translate(1, testedComponent.getPreferredSize().height + 1); + + /* this is a workaround for certain jtreg(?) focus issue: + tests fail starting after failing mixing tests but always pass alone. + */ + Util.waitForIdle(robot); + ancestorLoc.translate(f.getWidth()/2-15, 2); + robot.mouseMove(ancestorLoc.x, ancestorLoc.y); + Util.waitForIdle(robot); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.delay(50); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + Util.waitForIdle(robot); + + clickAndBlink(robot, lLoc); + return wasLWClicked; + } else { + return true; + } + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/HierarchyBoundsListenerMixingTest.java b/jdk/test/java/awt/Mixing/AWT_Mixing/HierarchyBoundsListenerMixingTest.java new file mode 100644 index 00000000000..13e600b30e5 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/HierarchyBoundsListenerMixingTest.java @@ -0,0 +1,692 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.*; +import java.awt.event.*; +import java.lang.reflect.InvocationTargetException; +import javax.swing.SwingUtilities; +import java.io.*; + +/** + * AWT Mixing test for HierarchyBoundsListener ancestors. + * <p>See <a href="https://bugs.openjdk.java.net/browse/JDK-6768230">CR6768230</a> for details. + */ +/* +@test +@bug 6768230 +@summary Mixing test for HierarchyBoundsListener ancestors +@build FrameBorderCounter +@run main HierarchyBoundsListenerMixingTest + */ +public class HierarchyBoundsListenerMixingTest { + + protected void prepareControls() { + dummy = new Frame(); + dummy.setSize(100, 100); + dummy.setLocation(0, 350); + dummy.setVisible(true); + + frame = new Frame("Test Frame"); + frame.setLayout(new FlowLayout()); + + panel = new Panel(); + button = new Button("Button"); + label = new Label("Label"); + list = new List(); + list.add("One"); + list.add("Two"); + list.add("Three"); + choice = new Choice(); + choice.add("Red"); + choice.add("Orange"); + choice.add("Yellow"); + checkbox = new Checkbox("Checkbox"); + scrollbar = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, 255); + textfield = new TextField(15); + textarea = new TextArea(5, 15); + + components = new Component[] { + panel, button, label, list, choice, checkbox, scrollbar, textfield, textarea + }; + ancestorResized = new boolean[components.length]; + ancestorMoved = new boolean[components.length]; + + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent event) { + System.err.println("User closed the window"); + System.exit(1); + } + }); + + HierarchyBoundsListener listener = new HierarchyBoundsListenerImpl(); + for (int i = 0; i < components.length; i++) { + components[i].addHierarchyBoundsListener(listener); + frame.add(components[i]); + } + frame.setSize(300, 300); + frame.setVisible(true); + } + + private int frameBorderCounter() { + String JAVA_HOME = System.getProperty("java.home"); + + try { + Process p = Runtime.getRuntime().exec(JAVA_HOME + "/bin/java FrameBorderCounter"); + try { + p.waitFor(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + if (p.exitValue() != 0) { + throw new RuntimeException("FrameBorderCounter exited with not null code!\n" + readInputStream(p.getErrorStream())); + } + return Integer.parseInt(readInputStream(p.getInputStream()).trim()); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + private String readInputStream(InputStream is) throws IOException { + byte[] buffer = new byte[4096]; + int len = 0; + StringBuilder sb = new StringBuilder(); + try (InputStreamReader isr = new InputStreamReader(is)) { + while ((len = is.read(buffer)) > 0) { + sb.append(new String(buffer, 0, len)); + } + } + return sb.toString(); + } + + protected boolean performTest() { + int BORDER_SHIFT = frameBorderCounter(); + BORDER_SHIFT = Math.abs(BORDER_SHIFT) == 1 ? BORDER_SHIFT : BORDER_SHIFT / 2; + Robot robot = null; + try { + robot = new Robot(); + Thread.sleep(delay * 10); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + + robot.mouseMove((int) components[0].getLocationOnScreen().x + components[0].getSize().width / 2, + (int) components[0].getLocationOnScreen().y + components[0].getSize().height / 2); + robot.delay(delay); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.delay(delay); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.delay(delay); + + resetValues(); + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + frame.setSize(new Dimension(frame.getSize().width + 10, frame.getSize().height + 10)); + frame.invalidate(); + frame.validate(); + } + }); + } catch (Exception e) { + e.printStackTrace(); + passed = false; + } + if (! resizeTriggered) { + synchronized (resizeLock) { + try { + resizeLock.wait(delay * 10); + } catch (Exception e) { + } + } + } + for (int i = 0; i < components.length; i++) { + if (! ancestorResized[i]) { + System.err.println("FAIL: Frame resized using API call. " + + "Ancestor resized event did not occur for " + components[i].getClass()); + passed = false; + } + } + if (moveCount > 0) { + System.err.println("FAIL: Ancestor moved event occured when Frame resized using API"); + passed = false; + } + robot.delay(delay * 5); + + resetValues(); + int x = (int) frame.getLocationOnScreen().x; + int y = (int) frame.getLocationOnScreen().y; + int w = frame.getSize().width; + int h = frame.getSize().height; + + robot.mouseMove(x + w + BORDER_SHIFT, y + h / 2); + robot.delay(delay); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.delay(delay); + for (int i = 0; i < 20; i++) { + robot.mouseMove(x + w + i + BORDER_SHIFT, y + h / 2); + robot.delay(50); + } + robot.delay(delay); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + if (! resizeTriggered) { + synchronized (resizeLock) { + try { + resizeLock.wait(delay * 10); + } catch (Exception e) { + } + } + } + + for (int i = 0; i < components.length; i++) { + if (! ancestorResized[i]) { + System.err.println("FAIL: Frame resized using mouse action. " + + "Ancestor resized event did not occur for " + + components[i].getClass()); + passed = false; + } + } + if (moveCount > 0) { + System.err.println("FAIL: Ancestor moved event occured when Frame resized using mouse"); + passed = false; + } + + resetValues(); + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + frame.setLocation(frame.getLocation().x + 20, frame.getLocation().y + 20); + frame.invalidate(); + frame.validate(); + } + }); + } catch (Exception e) { + e.printStackTrace(); + passed = false; + } + if (! moveTriggered) { + synchronized (moveLock) { + try { + moveLock.wait(delay * 10); + } catch (Exception e) { + } + } + } + for (int i = 0; i < components.length; i++) { + if (! ancestorMoved[i]) { + System.err.println("FAIL: Frame moved using API call. " + + "Ancestor moved event did not occur for " + components[i].getClass()); + passed = false; + } + } + if (resizeCount > 0) { + System.err.println("FAIL: Ancestor resized event occured when Frame moved using API"); + passed = false; + } + robot.delay(delay * 10); + + resetValues(); + x = (int) frame.getLocationOnScreen().x; + y = (int) frame.getLocationOnScreen().y; + w = frame.getSize().width; + h = frame.getSize().height; + + //Click on the dummy frame so that the test frame loses focus. This is to workaround + //a bug in Linux AS. + robot.mouseMove((int) dummy.getLocationOnScreen().x + dummy.getSize().width / 2, + (int) dummy.getLocationOnScreen().y + dummy.getSize().height / 2); + robot.delay(delay); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.delay(delay); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.delay(delay); + + robot.mouseMove(x + w / 2, y + 10); + robot.delay(delay); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.delay(delay); + for (int i = 1; i <= 20; i++) { + robot.mouseMove(x + w / 2 + i, y + 10); + robot.delay(50); + } + robot.delay(delay); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + if (! moveTriggered) { + synchronized (moveLock) { + try { + moveLock.wait(delay * 10); + } catch (Exception e) { + } + } + } + + for (int i = 0; i < components.length; i++) { + if (! ancestorMoved[i]) { + System.err.println("FAIL: Frame moved using mouse action. " + + "Ancestor moved event did not occur for " + components[i].getClass()); + passed = false; + } + } + if (resizeCount > 0) { + System.err.println("FAIL: Ancestor resized event occured when Frame moved using mouse"); + passed = false; + } + + return passed; + } + + private void resetValues() { + moveTriggered = false; + resizeTriggered = false; + moveCount = 0; + resizeCount = 0; + for (int i = 0; i < ancestorResized.length; i++) { + ancestorResized[i] = false; + ancestorMoved[i] = false; + } + } + + private void keyType(int key, Robot robot) throws Exception { + robot.keyPress(key); + robot.delay(keyDelay); + robot.keyRelease(key); + robot.delay(keyDelay); + } + + class HierarchyBoundsListenerImpl implements HierarchyBoundsListener { + // checks for Ancestor_Moved events + public void ancestorMoved(HierarchyEvent ce) { + if (check) { + System.out.println("Moved " + ce.getComponent()); + } + for (int i = 0; i < components.length; i++) { + if (components[i].equals(ce.getComponent())) { + //setting this array for purpose of checking ancestor_moved. + ancestorMoved[i] = true; + moveCount++; + if (moveCount == components.length) { + moveTriggered = true; + synchronized (moveLock) { + try { + moveLock.notifyAll(); + } catch (Exception e) { + } + } + } + } + } + } + // checks for Ancestor_Moved events + public void ancestorResized(HierarchyEvent ce) { + if (check) { + System.out.println("Resized " + ce.getComponent()); + } + for (int i = 0; i < components.length; i++) { + if (components[i].equals(ce.getComponent())) { + if (! frame.equals(ce.getChanged()) || ce.getChangedParent() != null) { + System.err.println("FAIL: Invalid value of HierarchyEvent.getXXX"); + System.err.println("ce.getChanged() : " + ce.getChanged()); + System.err.println("ce.getChangedParent() : " + ce.getChangedParent()); + passed = false; + } + //setting this array for purpose of checking ancestor_resized + ancestorResized[i] = true; + resizeCount++; + if (resizeCount == components.length) { + resizeTriggered = true; + synchronized (resizeLock) { + try { + resizeLock.notifyAll(); + } catch (Exception e) { + } + } + } + } + } + } + } + + private Frame frame, dummy; + private Panel panel; + private Button button; + private Label label; + private List list; + private Choice choice; + private Checkbox checkbox; + private Scrollbar scrollbar; + private TextField textfield; + private TextArea textarea; + private Component[] components; + private boolean[] ancestorResized; + private boolean[] ancestorMoved; + + private int delay = 500; + private int keyDelay = 50; + private int moveCount = 0; + private int resizeCount = 0; + + private boolean passed = true; + private boolean moveTriggered = false; + private boolean resizeTriggered = false; + private final Object moveLock = new Object(); + private final Object resizeLock = new Object(); + + private boolean check = false; + + private void invoke() throws InterruptedException { + try { + SwingUtilities.invokeAndWait(new Runnable() { + + public void run() { + prepareControls(); + } + }); + try { + Thread.sleep(1000); // wait for graphic effects on systems like Win7 + } catch (InterruptedException ex) { + } + if (!performTest()) { + fail("Test failed"); + } + } catch (InvocationTargetException ex) { + fail(ex.getMessage()); + } + } + + /***************************************************** + * Standard Test Machinery Section + * DO NOT modify anything in this section -- it's a + * standard chunk of code which has all of the + * synchronisation necessary for the test harness. + * By keeping it the same in all tests, it is easier + * to read and understand someone else's test, as + * well as insuring that all tests behave correctly + * with the test harness. + * There is a section following this for test- + * classes + ******************************************************/ + private static void init() throws InterruptedException { + //*** Create instructions for the user here *** + //System.setProperty("sun.awt.disableMixing", "true"); + + String[] instructions = { + "This is an AUTOMATIC test, simply wait until it is done.", + "The result (passed or failed) will be shown in the", + "message window below." + }; + Sysout.createDialog(); + Sysout.printInstructions(instructions); + + HierarchyBoundsListenerMixingTest instance = new HierarchyBoundsListenerMixingTest(); + + instance.invoke(); + + pass(); + }//End init() + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + private static Thread mainThread = null; + private static int sleepTime = 300000; + + // Not sure about what happens if multiple of this test are + // instantiated in the same VM. Being static (and using + // static vars), it aint gonna work. Not worrying about + // it for now. + public static void main(String args[]) throws InterruptedException { + mainThread = Thread.currentThread(); + try { + init(); + } catch (TestPassedException e) { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test pass nor test fail has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try { + Thread.sleep(sleepTime); + //Timed out, so fail the test + throw new RuntimeException("Timed out after " + sleepTime / 1000 + " seconds"); + } catch (InterruptedException e) { + //The test harness may have interrupted the test. If so, rethrow the exception + // so that the harness gets it and deals with it. + if (!testGeneratedInterrupt) { + throw e; + } + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + + if (theTestPassed == false) { + throw new RuntimeException(failureMessage); + } + } + + }//main + + public static synchronized void setTimeoutTo(int seconds) { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() { + Sysout.println("The test passed."); + Sysout.println("The test is over, hit Ctl-C to stop Java VM"); + //first check if this is executing in main thread + if (mainThread == Thread.currentThread()) { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() { + //test writer didn't specify why test failed, so give generic + fail("it just plain failed! :-)"); + } + + public static synchronized void fail(String whyFailed) { + Sysout.println("The test failed: " + whyFailed); + Sysout.println("The test is over, hit Ctl-C to stop Java VM"); + //check if this called from main thread + if (mainThread == Thread.currentThread()) { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException(whyFailed); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() +}// class LWComboBox +class TestPassedException extends RuntimeException { +} + +//*********** End Standard Test Machinery Section ********** +//************ Begin classes defined for the test **************** +// if want to make listeners, here is the recommended place for them, then instantiate +// them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface +{ +static int newVar = 0; + +public void eventDispatched(AWTEvent e) +{ +//Counting events to see if we get enough +eventCount++; + +if( eventCount == 20 ) +{ +//got enough events, so pass + +LWComboBox.pass(); +} +else if( tries == 20 ) +{ +//tried too many times without getting enough events so fail + +LWComboBox.fail(); +} + +}// eventDispatched() + +}// NewClass class + + */ +//************** End classes defined for the test ******************* +/**************************************************** +Standard Test Machinery +DO NOT modify anything below -- it's a standard +chunk of code whose purpose is to make user +interaction uniform, and thereby make it simpler +to read and understand someone else's test. + ****************************************************/ +/** +This is part of the standard test machinery. +It creates a dialog (with the instructions), and is the interface +for sending text messages to the user. +To print the instructions, send an array of strings to Sysout.createDialog +WithInstructions method. Put one line of instructions per array entry. +To display a message for the tester to see, simply call Sysout.println +with the string to be displayed. +This mimics System.out.println but works within the test harness as well +as standalone. + */ +class Sysout { + + private static TestDialog dialog; + + public static void createDialogWithInstructions(String[] instructions) { + dialog = new TestDialog(new Frame(), "Instructions"); + dialog.printInstructions(instructions); + dialog.setVisible(true); + println("Any messages for the tester will display here."); + } + + public static void createDialog() { + dialog = new TestDialog(new Frame(), "Instructions"); + String[] defInstr = {"Instructions will appear here. ", ""}; + dialog.printInstructions(defInstr); + dialog.setVisible(true); + println("Any messages for the tester will display here."); + } + + public static void printInstructions(String[] instructions) { + dialog.printInstructions(instructions); + } + + public static void println(String messageIn) { + dialog.displayMessage(messageIn); + System.out.println(messageIn); + } +}// Sysout class + +/** +This is part of the standard test machinery. It provides a place for the +test instructions to be displayed, and a place for interactive messages +to the user to be displayed. +To have the test instructions displayed, see Sysout. +To have a message to the user be displayed, see Sysout. +Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog(Frame frame, String name) { + super(frame, name); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea("", 15, maxStringLength, scrollBoth); + add("North", instructionsText); + + messageText = new TextArea("", 5, maxStringLength, scrollBoth); + add("Center", messageText); + + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions(String[] instructions) { + //Clear out any current instructions + instructionsText.setText(""); + + //Go down array of instruction strings + + String printStr, remainingStr; + for (int i = 0; i < instructions.length; i++) { + //chop up each into pieces maxSringLength long + remainingStr = instructions[i]; + while (remainingStr.length() > 0) { + //if longer than max then chop off first max chars to print + if (remainingStr.length() >= maxStringLength) { + //Try to chop on a word boundary + int posOfSpace = remainingStr.lastIndexOf(' ', maxStringLength - 1); + + if (posOfSpace <= 0) { + posOfSpace = maxStringLength - 1; + } + + printStr = remainingStr.substring(0, posOfSpace + 1); + remainingStr = remainingStr.substring(posOfSpace + 1); + } //else just print + else { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append(printStr + "\n"); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage(String messageIn) { + messageText.append(messageIn + "\n"); + System.out.println(messageIn); + } +}// TestDialog class + diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JButtonInGlassPaneOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JButtonInGlassPaneOverlapping.java new file mode 100644 index 00000000000..11aef8209bd --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JButtonInGlassPaneOverlapping.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JButton } component in GlassPane. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JButton +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JButtonInGlassPaneOverlapping + */ +public class JButtonInGlassPaneOverlapping extends GlassPaneOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JButton ch = new JButton(); + ch.setText("Swing component"); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JButtonInGlassPaneOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JButtonOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JButtonOverlapping.java new file mode 100644 index 00000000000..119c131cc85 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JButtonOverlapping.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JButton } component. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JButton +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JButtonOverlapping + */ +public class JButtonOverlapping extends SimpleOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JButton ch = new JButton(); + ch.setText("Swing component"); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JButtonOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JColorChooserOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JColorChooserOverlapping.java new file mode 100644 index 00000000000..c756041db65 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JColorChooserOverlapping.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JColorChooser } component. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JColorChooser +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JColorChooserOverlapping + */ +public class JColorChooserOverlapping extends SimpleOverlappingTestBase { + + public JColorChooserOverlapping() { + super(false); + } + + @Override + protected JComponent getSwingComponent() { + wasLWClicked = true; + JColorChooser ch = new JColorChooser(); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JColorChooserOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java new file mode 100644 index 00000000000..b0887068a09 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.BoxLayout; +import javax.swing.JComboBox; +import javax.swing.JFrame; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JCombobox } component. + * <p>This test creates combobox and test if heavyweight component is drawn correctly then dropdown is shown. + * <p>See base class for details. + */ +/* +@test +@summary Overlapping test for javax.swing.JScrollPane +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JComboBoxOverlapping + */ +public class JComboBoxOverlapping extends OverlappingTestBase { + + private boolean lwClicked = false; + private Point loc; + private Point loc2; + + {testEmbeddedFrame = true;} + + protected void prepareControls() { + final JFrame frame = new JFrame("Mixing : Dropdown Overlapping test"); + frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS)); + frame.setSize(200, 200); + frame.setVisible(true); + + final JComboBox cb = new JComboBox(petStrings); + cb.setPreferredSize(new Dimension(frame.getContentPane().getWidth(), 20)); + cb.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + if (e.getSource() == cb) { + lwClicked = true; + } + } + }); + + frame.add(cb); + propagateAWTControls(frame); + frame.setVisible(true); + loc = cb.getLocationOnScreen(); + loc2 = frame.getContentPane().getLocationOnScreen(); + } + + @Override + protected boolean performTest() { + // run robot + Robot robot = Util.createRobot(); + robot.setAutoDelay(ROBOT_DELAY); + + loc2.translate(75, 75); + pixelPreCheck(robot, loc2, currentAwtControl); + + loc.translate(3, 3); + clickAndBlink(robot, loc, false); + + clickAndBlink(robot, loc2, false); + + return lwClicked; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JComboBoxOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JEditorPaneInGlassPaneOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JEditorPaneInGlassPaneOverlapping.java new file mode 100644 index 00000000000..d14f078aa2d --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JEditorPaneInGlassPaneOverlapping.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.Point; +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JBEditorPane } component in GlassPane. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JLabel +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JEditorPaneInGlassPaneOverlapping + */ +public class JEditorPaneInGlassPaneOverlapping extends GlassPaneOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JEditorPane ch = new JEditorPane(); + ch.setText("<b>Swing component</b>"); + OverlappingTestBase.shift = new Point(12, 12); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JEditorPaneInGlassPaneOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JEditorPaneOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JEditorPaneOverlapping.java new file mode 100644 index 00000000000..513ca0dce7f --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JEditorPaneOverlapping.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JEditorPane } component. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JLabel +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JEditorPaneOverlapping + */ +public class JEditorPaneOverlapping extends SimpleOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JEditorPane ch = new JEditorPane(); + ch.setText("<b>Swing component</b>"); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JEditorPaneOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JGlassPaneInternalFrameOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JGlassPaneInternalFrameOverlapping.java new file mode 100644 index 00000000000..3e2575375e8 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JGlassPaneInternalFrameOverlapping.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Container; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.SwingUtilities; + +/** + * AWT/Swing overlapping test with JInternalFrame being put in GlassPane. + * See <a href="https://bugs.openjdk.java.net/browse/JDK-6637655">JDK-6637655</a> and + * <a href="https://bugs.openjdk.java.net/browse/JDK-6985776">JDK-6985776</a>. + * <p>See base class for details. + */ +/* +@test +@bug 6637655 6985776 +@summary Overlapping test for javax.swing.JScrollPane +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JGlassPaneInternalFrameOverlapping + */ +public class JGlassPaneInternalFrameOverlapping extends OverlappingTestBase { + + private boolean lwClicked = true; + private Point lLoc; + private Point lLoc2; + private JInternalFrame internalFrame; + + protected boolean performTest() { + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + lLoc = internalFrame.getContentPane().getLocationOnScreen(); + lLoc2 = lLoc.getLocation(); + lLoc2.translate(0, internalFrame.getContentPane().getHeight() + 10); + } + }); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + // run robot + Robot robot = Util.createRobot(); + robot.setAutoDelay(ROBOT_DELAY); + + clickAndBlink(robot, lLoc); + + Color c = robot.getPixelColor(lLoc2.x, lLoc2.y); + robot.mouseMove(lLoc2.x, lLoc2.y); + if (!c.equals(AWT_BACKGROUND_COLOR) && + currentAwtControl.getClass() != java.awt.Scrollbar.class && + currentAwtControl.getClass() != java.awt.Choice.class) { + fail("The HW component did not pass pixel color check and is not drawn correctly"); + } + + return lwClicked; + } + + // {debugClassName = "Choice";} + + @Override + protected void prepareControls() { + JFrame frame = new JFrame("Glass Pane children test"); + frame.setLayout(null); + + Container contentPane = frame.getContentPane(); + contentPane.setLayout(new BorderLayout()); + super.propagateAWTControls(contentPane); + + Container glassPane = (Container) frame.getRootPane().getGlassPane(); + glassPane.setVisible(true); + glassPane.setLayout(null); + + internalFrame = new JInternalFrame("Internal Frame", true); + internalFrame.setBounds(50, 0, 200, 100); + internalFrame.setVisible(true); + glassPane.add(internalFrame); + + internalFrame.addMouseListener(new MouseAdapter() { + + @Override + public void mouseClicked(MouseEvent e) { + lwClicked = true; + } + }); + + frame.setSize(300, 180); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + if (System.getProperty("os.name").toLowerCase().contains("os x")) { + System.out.println("Aqua L&F ignores setting color to component. Test passes on Mac OS X."); + return; + } + instance = new JGlassPaneInternalFrameOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java new file mode 100644 index 00000000000..43e060a2438 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Container; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.SwingUtilities; + +/** + * AWT/Swing overlapping test with JInternalFrame being moved in GlassPane. + * See <a href="https://bugs.openjdk.java.net/browse/JDK-6637655">JDK-6637655</a> and + * <a href="https://bugs.openjdk.java.net/browse/JDK-6981919">JDK-6981919</a>. + * <p>See base class for details. + */ +/* +@test +@bug 6637655 6981919 +@summary Overlapping test for javax.swing.JScrollPane +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JGlassPaneMoveOverlapping + */ +public class JGlassPaneMoveOverlapping extends OverlappingTestBase { + + private boolean lwClicked = true; + private volatile Point lLoc; + private volatile Point lLoc2; + + private JInternalFrame internalFrame; + private JFrame frame = null; + private volatile Point frameLoc; + + protected boolean performTest() { + + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + lLoc = internalFrame.getContentPane().getLocationOnScreen(); + lLoc2 = lLoc.getLocation(); + lLoc2.translate(0, internalFrame.getHeight()); + frameLoc = frame.getLocationOnScreen(); + frameLoc.translate(frame.getWidth()/2, 3); + } + }); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + + // run robot + Robot robot = Util.createRobot(); + robot.setAutoDelay(ROBOT_DELAY); + + // force focus on JFrame (jtreg workaround) + robot.mouseMove(frameLoc.x, frameLoc.y); + Util.waitForIdle(robot); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.delay(50); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + Util.waitForIdle(robot); + + + //slow move + robot.mouseMove(lLoc.x + 25, lLoc.y - 5); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.delay(100); + robot.mouseMove(lLoc.x + 45, lLoc.y - 5); + robot.delay(100); + robot.mouseMove(lLoc.x + internalWidth - 75, lLoc.y - 5); + robot.delay(100); + robot.mouseMove(lLoc.x + internalWidth - 55, lLoc.y - 5); + robot.delay(100); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + Color c2 = robot.getPixelColor(lLoc.x + internalWidth + 15, lLoc.y - 5); + if (c2.equals(AWT_BACKGROUND_COLOR)) { + error("Foreground frame is not drawn properly"); + } + Color c = robot.getPixelColor(lLoc.x + internalWidth - 95, lLoc.y + 5); + robot.mouseMove(lLoc.x + internalWidth - 95, lLoc.y + 5); + System.out.println("color: " + c + " " + AWT_BACKGROUND_COLOR); + if (!c.equals(AWT_BACKGROUND_COLOR) && currentAwtControl.getClass() != java.awt.Scrollbar.class) { + error("Background AWT component is not drawn properly"); + } + + return true; + } + + // {debugClassName = "Choice";} + + private static void error(String st) { + //System.out.println(st); + fail(st); + } + + private static final int internalWidth = 200; + + @Override + protected void prepareControls() { + if(frame != null) { + frame.setVisible(false); + } + frame = new JFrame("Glass Pane children test"); + frame.setLayout(null); + + Container contentPane = frame.getContentPane(); + contentPane.setLayout(new BorderLayout()); + super.propagateAWTControls(contentPane); + + Container glassPane = (Container) frame.getRootPane().getGlassPane(); + glassPane.setVisible(true); + glassPane.setLayout(null); + + internalFrame = new JInternalFrame("Internal Frame", true); + internalFrame.setBounds(50, 0, internalWidth, 100); + internalFrame.setVisible(true); + glassPane.add(internalFrame); + + internalFrame.addMouseListener(new MouseAdapter() { + + @Override + public void mouseClicked(MouseEvent e) { + lwClicked = true; + } + }); + + frame.setSize(400, 180); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + if (System.getProperty("os.name").toLowerCase().contains("os x")) { + System.out.println("Aqua L&F ignores setting color to component. Test passes on Mac OS X."); + return; + } + instance = new JGlassPaneMoveOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JInternalFrameMoveOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JInternalFrameMoveOverlapping.java new file mode 100644 index 00000000000..99a9e015921 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JInternalFrameMoveOverlapping.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import javax.swing.JButton; +import javax.swing.JDesktopPane; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JInternalFrame } component during move. + * <p>See <a href="http://monaco.sfbay.sun.com/detail.jsf?cr=6985399">CR6768230</a> for details and base class for test info. + */ +/* +@test +@bug 6985399 +@summary Overlapping test for javax.swing.JScrollPane +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JInternalFrameMoveOverlapping + */ +public class JInternalFrameMoveOverlapping extends OverlappingTestBase { + + private boolean lwClicked = true; + private Point locTopFrame; + private Point locTarget; + + protected boolean performTest() { + // run robot + Robot robot = Util.createRobot(); + robot.setAutoDelay(ROBOT_DELAY); + + robot.mouseMove(locTopFrame.x + 25, locTopFrame.y + 25); + robot.mousePress(InputEvent.BUTTON1_MASK); + try { + Thread.sleep(500); + } catch (InterruptedException ex) { + } + robot.mouseMove(locTopFrame.x + (locTarget.x - locTopFrame.x)/2, locTopFrame.y + (locTarget.y - locTopFrame.y)/2); + try { + Thread.sleep(500); + } catch (InterruptedException ex) { + } + robot.mouseMove(locTarget.x, locTarget.y); + try { + Thread.sleep(500); + } catch (InterruptedException ex) { + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + clickAndBlink(robot, locTarget); + + return lwClicked; + } + + //static {debugClassName = "Choice";} + + @Override + protected void prepareControls() { + + + JDesktopPane desktopPane = new JDesktopPane(); + + JInternalFrame bottomFrame = new JInternalFrame("bottom frame", false, false, false, false); + bottomFrame.setSize(220, 220); + super.propagateAWTControls(bottomFrame); + desktopPane.add(bottomFrame); + bottomFrame.setVisible(true); + + JInternalFrame topFrame = new JInternalFrame("top frame", false, false, false, false); + topFrame.setSize(200, 200); + topFrame.add(new JButton("LW Button") { + + { + addMouseListener(new MouseAdapter() { + + @Override + public void mouseClicked(MouseEvent e) { + lwClicked = true; + } + }); + } + }); + desktopPane.add(topFrame); + topFrame.setVisible(true); + + JFrame frame = new JFrame("Test Window"); + frame.setSize(300, 300); + frame.setContentPane(desktopPane); + frame.setVisible(true); + + locTopFrame = topFrame.getLocationOnScreen(); + locTarget = new Point(locTopFrame.x + bottomFrame.getWidth() / 2, locTopFrame.y + bottomFrame.getHeight()/2); + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JInternalFrameMoveOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JInternalFrameOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JInternalFrameOverlapping.java new file mode 100644 index 00000000000..320a82adcce --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JInternalFrameOverlapping.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import javax.swing.JButton; +import javax.swing.JDesktopPane; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JInternalFrame } component. + * <p>See base class for test info. + */ +/* +@test +@summary Overlapping test for javax.swing.JScrollPane +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JInternalFrameOverlapping + */ +public class JInternalFrameOverlapping extends OverlappingTestBase { + + private boolean lwClicked = true; + private Point lLoc; + + protected boolean performTest() { + + + // run robot + Robot robot = Util.createRobot(); + robot.setAutoDelay(ROBOT_DELAY); + + clickAndBlink(robot, lLoc); + + return lwClicked; + } + + /** + * Creating two JInternalFrames in JDesktopPanes. Put lightweight component into one frame and heavyweight into another. + */ + @Override + protected void prepareControls() { + JDesktopPane desktopPane = new JDesktopPane(); + + JFrame frame = new JFrame("Test Window"); + frame.setSize(300, 300); + frame.setContentPane(desktopPane); + frame.setVisible(true); + JInternalFrame bottomFrame = new JInternalFrame("bottom frame", false, false, false, false); + bottomFrame.setSize(220, 220); + desktopPane.add(bottomFrame); + bottomFrame.setVisible(true); + + super.propagateAWTControls(bottomFrame); + JInternalFrame topFrame = new JInternalFrame("top frame", false, false, false, false); + topFrame.setSize(200, 200); + JButton jbutton = new JButton("LW Button") {{ + addMouseListener(new MouseAdapter() { + + @Override + public void mouseClicked(MouseEvent e) { + lwClicked = true; + } + }); + }}; + topFrame.add(jbutton); + desktopPane.add(topFrame); + topFrame.setVisible(true); + lLoc = jbutton.getLocationOnScreen(); + lLoc.translate(jbutton.getWidth()/2, jbutton.getWidth()/2); //click at middle of the button + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JInternalFrameOverlapping(); + OverlappingTestBase.doMain(args); + } + +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JLabelInGlassPaneOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JLabelInGlassPaneOverlapping.java new file mode 100644 index 00000000000..bdde7409344 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JLabelInGlassPaneOverlapping.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.Dimension; +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JLabel } component in GlassPane. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JLabel +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JLabelInGlassPaneOverlapping + */ +public class JLabelInGlassPaneOverlapping extends GlassPaneOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JLabel ch = new JLabel(); + ch.setPreferredSize(new Dimension(50, 50)); + ch.setText("Swing component"); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JLabelInGlassPaneOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JLabelOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JLabelOverlapping.java new file mode 100644 index 00000000000..e6038bc8038 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JLabelOverlapping.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.Dimension; +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JLabel } component. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JLabel +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JLabelOverlapping + */ +public class JLabelOverlapping extends SimpleOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JLabel ch = new JLabel(); + ch.setPreferredSize(new Dimension(50, 50)); + ch.setText("Swing component"); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JLabelOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JListInGlassPaneOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JListInGlassPaneOverlapping.java new file mode 100644 index 00000000000..4a2e1419bae --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JListInGlassPaneOverlapping.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JList } component in GlassPane. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JList +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JListInGlassPaneOverlapping + */ +public class JListInGlassPaneOverlapping extends GlassPaneOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JList ch = new JList(new String[] {"one", "two", "three"}); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JListInGlassPaneOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JListOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JListOverlapping.java new file mode 100644 index 00000000000..76ee46ccbfa --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JListOverlapping.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JList } component. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JList +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JListOverlapping + */ +public class JListOverlapping extends SimpleOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JList ch = new JList(new String[] {"one", "two", "three", "four"}); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JListOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JMenuBarOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JMenuBarOverlapping.java new file mode 100644 index 00000000000..5ae75bd55b7 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JMenuBarOverlapping.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.Color; +import java.awt.GridLayout; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JSeparator; +import javax.swing.SwingUtilities; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JMenuBar } and {@link javax.swing.JSeparator} components. + * <p>This test creates menu bar and test if heavyweight component is drawn correctly then menu dropdown is shown. + * <p>See base class for test info. + */ +/* +@test +@summary Overlapping test for javax.swing.JScrollPane +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JMenuBarOverlapping + */ +public class JMenuBarOverlapping extends OverlappingTestBase { + + {testEmbeddedFrame = true;} + + private boolean lwClicked = false; + private boolean spClicked = false; + private Point loc; + private Point loc2; + private Point sepLoc; + private JFrame frame; + private JMenuBar menuBar; + JSeparator separator; + + protected void prepareControls() { + frame = new JFrame("Mixing : Dropdown Overlapping test"); + frame.setLayout(new GridLayout(0,1)); + frame.setSize(200, 200); + frame.setVisible(true); + + menuBar = new JMenuBar(); + JMenu menu = new JMenu("Test Menu"); + ActionListener menuListener = new ActionListener() { + + public void actionPerformed(ActionEvent event) { + lwClicked = true; + } + }; + + JMenuItem item; + menu.add(item = new JMenuItem("first")); + item.addActionListener(menuListener); + separator = new JSeparator(); + separator.addMouseListener(new MouseAdapter() { + + @Override + public void mouseClicked(MouseEvent e) { + spClicked = true; + } + }); + menu.add(separator); + + for (int i = 0; i < petStrings.length; i++) { + menu.add(item = new JMenuItem(petStrings[i])); + item.addActionListener(menuListener); + } + menuBar.add(menu); + frame.setJMenuBar(menuBar); + + propagateAWTControls(frame); + frame.setVisible(true); + } + + @Override + protected boolean performTest() { + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + loc = menuBar.getLocationOnScreen(); + loc2 = frame.getContentPane().getLocationOnScreen(); + } + }); + } catch (Exception e) { + } + // run robot + Robot robot = Util.createRobot(); + robot.setAutoDelay(ROBOT_DELAY); + + loc2.translate(75, 75); + pixelPreCheck(robot, loc2, currentAwtControl); + + loc.translate(3, 3); + clickAndBlink(robot, loc, false); + + clickAndBlink(robot, loc2, false); + + clickAndBlink(robot, loc, false); + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + sepLoc = separator.getLocationOnScreen(); + } + }); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + sepLoc.translate(20, 1); + clickAndBlink(robot, sepLoc, false); + + clickAndBlink(robot, loc, false); // close menu before running next step + return lwClicked && spClicked; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JMenuBarOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JPanelInGlassPaneOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JPanelInGlassPaneOverlapping.java new file mode 100644 index 00000000000..189a17b000f --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JPanelInGlassPaneOverlapping.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.Dimension; +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JPanel } component in GlassPane. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JPanel +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JPanelInGlassPaneOverlapping + */ +public class JPanelInGlassPaneOverlapping extends GlassPaneOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JPanel ch = new JPanel(); + ch.setPreferredSize(new Dimension(50, 50)); + ch.setBorder(BorderFactory.createTitledBorder("Swing Component")); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JPanelInGlassPaneOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JPanelOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JPanelOverlapping.java new file mode 100644 index 00000000000..5decd49d461 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JPanelOverlapping.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.Dimension; +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JPanel } component. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JPanel +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JPanelOverlapping + */ +public class JPanelOverlapping extends SimpleOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JPanel ch = new JPanel(); + ch.setPreferredSize(new Dimension(50, 50)); + ch.setBorder(BorderFactory.createTitledBorder("Swing Component")); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JPanelOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JPopupMenuOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JPopupMenuOverlapping.java new file mode 100644 index 00000000000..fead4e441fd --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JPopupMenuOverlapping.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.Color; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.lang.reflect.InvocationTargetException; +import javax.swing.JFrame; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.SpringLayout; +import javax.swing.SwingUtilities; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JPopupMenu } component. + * <p>This test creates menu and test if heavyweight component is drawn correctly then menu dropdown is shown. + * <p>See base class for test info. + */ +/* +@test +@summary Overlapping test for javax.swing.JScrollPane +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JPopupMenuOverlapping + */ +public class JPopupMenuOverlapping extends OverlappingTestBase { + + {testEmbeddedFrame = true;} + + private boolean lwClicked = false; + private Point loc; + private JPopupMenu popup; + private JFrame frame=null; + + protected void prepareControls() { + if(frame != null) { + frame.setVisible(false); + } + frame = new JFrame("Mixing : Dropdown Overlapping test"); + frame.setLayout(new SpringLayout()); + frame.setSize(200, 200); + + popup = new JPopupMenu(); + ActionListener menuListener = new ActionListener() { + + public void actionPerformed(ActionEvent event) { + lwClicked = true; + } + }; + JMenuItem item; + for (int i = 0; i < petStrings.length; i++) { + popup.add(item = new JMenuItem(petStrings[i])); + item.addActionListener(menuListener); + } + propagateAWTControls(frame); + frame.setVisible(true); + loc = frame.getContentPane().getLocationOnScreen(); + } + + @Override + protected boolean performTest() { + // run robot + Robot robot = Util.createRobot(); + robot.setAutoDelay(ROBOT_DELAY); + + loc.translate(75, 75); + + pixelPreCheck(robot, loc, currentAwtControl); + + try { + SwingUtilities.invokeAndWait(new Runnable() { + + public void run() { + popup.show(frame.getContentPane(), 15, 15); + } + }); + + robot.waitForIdle(); + + clickAndBlink(robot, loc, false); + + SwingUtilities.invokeAndWait(new Runnable() { + + public void run() { + popup.setVisible(false); + } + }); + } catch (InterruptedException ex) { + fail(ex.getMessage()); + } catch (InvocationTargetException ex) { + fail(ex.getMessage()); + } + + return lwClicked; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JPopupMenuOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JProgressBarInGlassPaneOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JProgressBarInGlassPaneOverlapping.java new file mode 100644 index 00000000000..1f60eefe5d6 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JProgressBarInGlassPaneOverlapping.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.Dimension; +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JProgressBar } component in GlassPane. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JProgressBar +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JProgressBarInGlassPaneOverlapping + */ +public class JProgressBarInGlassPaneOverlapping extends GlassPaneOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JProgressBar ch = new JProgressBar(); + ch.setValue(50); + ch.setPreferredSize(new Dimension(50, 50)); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JProgressBarInGlassPaneOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JProgressBarOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JProgressBarOverlapping.java new file mode 100644 index 00000000000..3db75cc6e4d --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JProgressBarOverlapping.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.Dimension; +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JProgressBar } component. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JProgressBar +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JProgressBarOverlapping + */ +public class JProgressBarOverlapping extends SimpleOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JProgressBar ch = new JProgressBar(); + ch.setValue(50); + ch.setPreferredSize(new Dimension(50, 50)); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JProgressBarOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JScrollBarInGlassPaneOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JScrollBarInGlassPaneOverlapping.java new file mode 100644 index 00000000000..a12a6f8b5af --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JScrollBarInGlassPaneOverlapping.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.Point; +import java.awt.Dimension; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JScrollBar } component in GlassPane. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JScrollBar +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JScrollBarInGlassPaneOverlapping + */ +public class JScrollBarInGlassPaneOverlapping extends GlassPaneOverlappingTestBase { + + public JScrollBarInGlassPaneOverlapping() { + super(false); + } + + @Override + protected JComponent getSwingComponent() { + JScrollBar ch = new JScrollBar(JScrollBar.VERTICAL); + ch.setPreferredSize(new Dimension(50, 50)); + ch.setValue(50); + ch.addAdjustmentListener(new AdjustmentListener() { + + public void adjustmentValueChanged(AdjustmentEvent e) { + wasLWClicked = true; + } + }); + OverlappingTestBase.shift = new Point(20, 16); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JScrollBarInGlassPaneOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JScrollBarOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JScrollBarOverlapping.java new file mode 100644 index 00000000000..9a3dd8e0a8a --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JScrollBarOverlapping.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.Point; +import java.awt.Dimension; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JScrollBar } component. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JScrollBar +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JScrollBarOverlapping + */ +public class JScrollBarOverlapping extends SimpleOverlappingTestBase { + + public JScrollBarOverlapping() { + super(false); + } + + @Override + protected JComponent getSwingComponent() { + JScrollBar ch = new JScrollBar(JScrollBar.VERTICAL); + ch.setPreferredSize(new Dimension(50, 50)); + ch.setValue(50); + ch.addAdjustmentListener(new AdjustmentListener() { + + public void adjustmentValueChanged(AdjustmentEvent e) { + wasLWClicked = true; + } + }); + OverlappingTestBase.shift = new Point(20, 16); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JScrollBarOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JScrollPaneOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JScrollPaneOverlapping.java new file mode 100644 index 00000000000..d4ae51d38e4 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JScrollPaneOverlapping.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JScrollPane } component. + * <p>See base class for test info. + */ +/* +@test +@summary Overlapping test for javax.swing.JScrollPane +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JScrollPaneOverlapping + */ +public class JScrollPaneOverlapping extends OverlappingTestBase { + +// {testEmbeddedFrame = true;} + + private boolean horizontalClicked = false; + private boolean verticalClicked = false; + private Point hLoc; + private Point vLoc; + + private JFrame f; + private JPanel p; + private JScrollPane scrollPane; + + protected void prepareControls() { + + f = new JFrame("JScrollPane"); + f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + f.setSize(120, 120); + + p = new JPanel(new GridLayout(0, 1)); + + scrollPane = new JScrollPane(p); + scrollPane.setPreferredSize(new Dimension(300,300)); + scrollPane.setHorizontalScrollBarPolicy( + JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); + scrollPane.setVerticalScrollBarPolicy( + JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + + scrollPane.getHorizontalScrollBar().setValue(1); + scrollPane.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() { + + public void adjustmentValueChanged(AdjustmentEvent e) { + horizontalClicked = true; + } + }); + + scrollPane.getVerticalScrollBar().setValue(1); + scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { + + public void adjustmentValueChanged(AdjustmentEvent e) { + verticalClicked = true; + } + }); + + f.getContentPane().add(scrollPane); + f.setVisible(true); + propagateAWTControls(p); +// JButton b = new JButton("Space extender"); +// b.setPreferredSize(new Dimension(150,150)); +// p.add( b ); + + //b.requestFocus(); // to change the look of AWT component, especially Choice + } + + @Override + protected boolean performTest() { + // run robot + Robot robot = Util.createRobot(); + robot.setAutoDelay(ROBOT_DELAY); + + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + hLoc = scrollPane.getHorizontalScrollBar().getLocationOnScreen(); + vLoc = scrollPane.getVerticalScrollBar().getLocationOnScreen(); + } + }); + } catch (Exception e) { + } + hLoc.translate(2, 2); + vLoc.translate(2, 2); + + clickAndBlink(robot, hLoc, false); + clickAndBlink(robot, vLoc, false); + + return horizontalClicked && verticalClicked; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JScrollPaneOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JSliderInGlassPaneOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JSliderInGlassPaneOverlapping.java new file mode 100644 index 00000000000..8cdafc17903 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JSliderInGlassPaneOverlapping.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.Dimension; +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JSlider } component in GlassPane. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JSlider +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JSliderInGlassPaneOverlapping + */ +public class JSliderInGlassPaneOverlapping extends GlassPaneOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JSlider ch = new JSlider(); + ch.setPreferredSize(new Dimension(50, 50)); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JSliderInGlassPaneOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JSliderOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JSliderOverlapping.java new file mode 100644 index 00000000000..f6553db0311 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JSliderOverlapping.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.Dimension; +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JSlider } component. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JSlider +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JSliderOverlapping + */ +public class JSliderOverlapping extends SimpleOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JSlider ch = new JSlider(); + ch.setPreferredSize(new Dimension(50, 50)); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JSliderOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JSpinnerInGlassPaneOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JSpinnerInGlassPaneOverlapping.java new file mode 100644 index 00000000000..1c60597c5a2 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JSpinnerInGlassPaneOverlapping.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.Dimension; +import javax.swing.event.ChangeEvent; +import javax.swing.*; +import javax.swing.event.ChangeListener; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JSpinner } component in GlassPane. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JSpinner +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JSpinnerInGlassPaneOverlapping + */ +public class JSpinnerInGlassPaneOverlapping extends GlassPaneOverlappingTestBase { + + {testResize = false;} + + public JSpinnerInGlassPaneOverlapping() { + super(false); + } + +// static {debugClassName = "Choice";} + @Override + protected JComponent getSwingComponent() { + JSpinner ch = new JSpinner(); + ch.setPreferredSize(new Dimension(30, 50)); + ch.addChangeListener(new ChangeListener() { + + public void stateChanged(ChangeEvent e) { + wasLWClicked = true; + } + }); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JSpinnerInGlassPaneOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JSpinnerOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JSpinnerOverlapping.java new file mode 100644 index 00000000000..90e4e5b85e9 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JSpinnerOverlapping.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.Dimension; +import javax.swing.event.ChangeEvent; +import javax.swing.*; +import javax.swing.event.ChangeListener; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JSpinner } component. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JSpinner +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JSpinnerOverlapping + */ +public class JSpinnerOverlapping extends SimpleOverlappingTestBase { + + public JSpinnerOverlapping() { + super(false); + } + +// static {debugClassName = "Choice";} + @Override + protected JComponent getSwingComponent() { + JSpinner ch = new JSpinner(); + ch.setPreferredSize(new Dimension(30, 50)); + ch.addChangeListener(new ChangeListener() { + + public void stateChanged(ChangeEvent e) { + wasLWClicked = true; + } + }); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JSpinnerOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JSplitPaneOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JSplitPaneOverlapping.java new file mode 100644 index 00000000000..c4f2265824a --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JSplitPaneOverlapping.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.SwingUtilities; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JSplitPane } component. + * <p>This test creates puts heavyweight and lightweight components into different panels and test if splitter image and components itself are drawn correctly. + * <p>See base class for test info. + */ +/* +@test +@bug 6986109 +@summary Overlapping test for javax.swing.JSplitPane +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JSplitPaneOverlapping + */ +public class JSplitPaneOverlapping extends OverlappingTestBase { + + private boolean clicked = false; + private Point splitterLoc; + private JScrollPane sp1; + private JScrollPane sp2; + + protected void prepareControls() { + JFrame frame = new JFrame("SplitPane Mixing"); + JPanel p = new JPanel(new GridLayout()); + p.setPreferredSize(new Dimension(500, 500)); + propagateAWTControls(p); + sp1 = new JScrollPane(p); + + JButton button = new JButton("JButton"); + button.setBackground(Color.RED); + button.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + clicked = true; + } + }); + sp2 = new JScrollPane(button); + + JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, sp1, sp2); + splitPane.setOneTouchExpandable(false); + splitPane.setDividerLocation(150); + + splitPane.setPreferredSize(new Dimension(400, 200)); + + frame.getContentPane().add(splitPane); + frame.pack(); + frame.setVisible(true); + } + + private static final boolean ignoreFail = false; + + @Override + protected boolean performTest() { + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + splitterLoc = sp2.getLocationOnScreen(); + Point leftLoc = sp1.getLocationOnScreen(); + leftLoc.translate(sp1.getWidth(), 0); + splitterLoc.translate(-(splitterLoc.x - leftLoc.x) / 2, 30); + } + }); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + // run robot + Robot robot = Util.createRobot(); + robot.setAutoDelay(ROBOT_DELAY); + + robot.mouseMove(splitterLoc.x, splitterLoc.y); + Util.waitForIdle(robot); + + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseMove(splitterLoc.x - 50, splitterLoc.y); + Color c = robot.getPixelColor(splitterLoc.x - 50, splitterLoc.y); + System.out.println("Actual: "+c+", (not) expected: "+AWT_VERIFY_COLOR+" at "+(splitterLoc.x - 50)+", "+ splitterLoc.y); + if (!ignoreFail && c.equals(AWT_VERIFY_COLOR)) { + fail("The JSplitPane drag-n-drop image did not pass pixel color check and is overlapped"); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + clickAndBlink(robot, splitterLoc); + + return clicked; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JSplitPaneOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JTableInGlassPaneOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JTableInGlassPaneOverlapping.java new file mode 100644 index 00000000000..af4803b9c50 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JTableInGlassPaneOverlapping.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import javax.swing.JComponent; +import javax.swing.JTable; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JTable } component in GlassPane. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for JTable +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JTableInGlassPaneOverlapping + */ +public class JTableInGlassPaneOverlapping extends GlassPaneOverlappingTestBase { + + { + testResize = false; + } + + @Override + protected JComponent getSwingComponent() { + // Create columns names + String columnNames[] = {"Column 1", "Column 2", "Column 3"}; + + // Create some data + String dataValues[][] = { + {"12", "234", "67"}, + {"-123", "43", "853"}, + {"93", "89.2", "109"}, + {"279", "9033", "3092"}, + {"12", "234", "67"}, + {"-123", "43", "853"}, + {"93", "89.2", "109"}, + {"279", "9033", "3092"}, + {"12", "234", "67"}, + {"-123", "43", "853"}, + {"93", "89.2", "109"}, + {"279", "9033", "3092"}, + {"12", "234", "67"}, + {"-123", "43", "853"}, + {"93", "89.2", "109"}, + {"279", "9033", "3092"} + }; + + // Create a new table instance + JTable jt = new JTable(dataValues, columnNames); + jt.getModel().addTableModelListener(new TableModelListener() { + + public void tableChanged(TableModelEvent e) { + System.err.println("table changed"); + } + }); + return jt; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JTableInGlassPaneOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JTableOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JTableOverlapping.java new file mode 100644 index 00000000000..d96732feedc --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JTableOverlapping.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JTable } component. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for JTable +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JTableOverlapping + */ +public class JTableOverlapping extends SimpleOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + // Create columns names + String columnNames[] = { "Column 1", "Column 2", "Column 3" }; + + // Create some data + String dataValues[][] = + { + { "12", "234", "67" }, + { "-123", "43", "853" }, + { "93", "89.2", "109" }, + { "279", "9033", "3092" }, + { "12", "234", "67" }, + { "-123", "43", "853" }, + { "93", "89.2", "109" }, + { "279", "9033", "3092" }, + { "12", "234", "67" }, + { "-123", "43", "853" }, + { "93", "89.2", "109" }, + { "279", "9033", "3092" }, + { "12", "234", "67" }, + { "-123", "43", "853" }, + { "93", "89.2", "109" }, + { "279", "9033", "3092" } + }; + + // Create a new table instance + return new JTable( dataValues, columnNames ); + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JTableOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JTextAreaInGlassPaneOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JTextAreaInGlassPaneOverlapping.java new file mode 100644 index 00000000000..dba86e2747f --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JTextAreaInGlassPaneOverlapping.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.Dimension; +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JTextArea } component in GlassPane. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JLabel +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JTextAreaInGlassPaneOverlapping + */ +public class JTextAreaInGlassPaneOverlapping extends GlassPaneOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JTextArea ch = new JTextArea(); + ch.setPreferredSize(new Dimension(50, 50)); + ch.setText("Swing component"); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JTextAreaInGlassPaneOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JTextAreaOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JTextAreaOverlapping.java new file mode 100644 index 00000000000..51f2b5ffddb --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JTextAreaOverlapping.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.Dimension; +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JTextArea } component. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JLabel +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JTextAreaOverlapping + */ +public class JTextAreaOverlapping extends SimpleOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JTextArea ch = new JTextArea(); + ch.setPreferredSize(new Dimension(50, 50)); + ch.setText("Swing component"); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JTextAreaOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JTextFieldInGlassPaneOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JTextFieldInGlassPaneOverlapping.java new file mode 100644 index 00000000000..d6dd69436ea --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JTextFieldInGlassPaneOverlapping.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.Dimension; +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JTextField } component in GlassPane. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JLabel +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JTextFieldInGlassPaneOverlapping + */ +public class JTextFieldInGlassPaneOverlapping extends GlassPaneOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JTextField ch = new JTextField(); + ch.setPreferredSize(new Dimension(50, 50)); + ch.setText("Swing component"); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JTextFieldInGlassPaneOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JTextFieldOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JTextFieldOverlapping.java new file mode 100644 index 00000000000..ffaecdcb589 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JTextFieldOverlapping.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.Dimension; +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JTextField } component. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JLabel +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JTextFieldOverlapping + */ +public class JTextFieldOverlapping extends SimpleOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JTextField ch = new JTextField(); + ch.setPreferredSize(new Dimension(50, 50)); + ch.setText("Swing component"); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JTextFieldOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JToggleButtonInGlassPaneOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JToggleButtonInGlassPaneOverlapping.java new file mode 100644 index 00000000000..3c4a62d9f50 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JToggleButtonInGlassPaneOverlapping.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JToggleButton } component in GlassPane. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JToggleButton +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JToggleButtonInGlassPaneOverlapping + */ +public class JToggleButtonInGlassPaneOverlapping extends GlassPaneOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JToggleButton ch = new JToggleButton(); + ch.setText("Swing component"); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JToggleButtonInGlassPaneOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/JToggleButtonOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/JToggleButtonOverlapping.java new file mode 100644 index 00000000000..3b311d71e10 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/JToggleButtonOverlapping.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import javax.swing.*; + +/** + * AWT/Swing overlapping test for {@link javax.swing.JToggleButton } component. + * <p>See base class for details. + */ +/* +@test +@summary Simple Overlapping test for javax.swing.JToggleButton +@author sergey.grinev@oracle.com: area=awt.mixing +@run main JToggleButtonOverlapping + */ +public class JToggleButtonOverlapping extends SimpleOverlappingTestBase { + + @Override + protected JComponent getSwingComponent() { + JToggleButton ch = new JToggleButton(); + ch.setText("Swing component"); + return ch; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new JToggleButtonOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/MixingFrameResizing.java b/jdk/test/java/awt/Mixing/AWT_Mixing/MixingFrameResizing.java new file mode 100644 index 00000000000..fd15ca1dc85 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/MixingFrameResizing.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import javax.swing.JFrame; +import javax.swing.SpringLayout; +import javax.swing.SwingUtilities; + +/** + * AWT/Swing overlapping test. + * <p>This test puts heavyweight component into JFrame and verifies that it's being drawn correctly after resizing the frame. + * <p>See base class for test info. + */ +/* +@test +@bug 6777370 +@summary Issues when resizing the JFrame with HW components +@author sergey.grinev@oracle.com: area=awt.mixing +@run main MixingFrameResizing + */ +public class MixingFrameResizing extends OverlappingTestBase { + + {testEmbeddedFrame = true;} + + private JFrame frame = null; + private Point lLoc; + private Point lLoc2; + private Dimension size; + + protected void prepareControls() { + if(frame != null) { + frame.setVisible(false); + } + frame = new JFrame("Mixing : Frame Resizing test"); + frame.setLayout(new SpringLayout()); + frame.setSize(50, 50); + frame.setVisible(true); + propagateAWTControls(frame); + Util.waitTillShown(frame); + } + + @Override + protected boolean performTest() { + int BORDER_SHIFT = frameBorderCounter(); + BORDER_SHIFT = Math.abs(BORDER_SHIFT) == 1 ? BORDER_SHIFT : (BORDER_SHIFT / 2); + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + lLoc = frame.getLocationOnScreen(); + size = frame.getSize(); + lLoc2 = frame.getContentPane().getLocationOnScreen(); + } + }); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + Robot robot = Util.createRobot(); + robot.setAutoDelay(ROBOT_DELAY/2); + + // resize window + robot.mouseMove(lLoc.x + size.width / 2 + BORDER_SHIFT, lLoc.y + size.height + BORDER_SHIFT); + Util.waitForIdle(robot); + robot.mousePress(InputEvent.BUTTON1_MASK); + for (int i = 0; i < 10; i++) { + robot.mouseMove(lLoc.x + size.width / 2 + BORDER_SHIFT, lLoc.y + size.height + BORDER_SHIFT + 20 * i); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + robot.mouseMove(lLoc.x + size.width + BORDER_SHIFT, lLoc.y + size.height + BORDER_SHIFT); + Util.waitForIdle(robot); + robot.mousePress(InputEvent.BUTTON1_MASK); + for (int i = 0; i < 10; i++) { + robot.mouseMove(lLoc.x + size.width + BORDER_SHIFT + 20 * i, lLoc.y + size.height + BORDER_SHIFT); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + Util.waitForIdle(robot); + // check if component is visible on the opened space + try { + Thread.sleep(300); //some more wait for Solaris (for some reason) + }catch(Exception ex) {} + lLoc2.translate(75, 75); + Color c = robot.getPixelColor(lLoc2.x, lLoc2.y); + System.out.println("Actual: "+c+", expected: "+AWT_VERIFY_COLOR); + + if (!c.equals(AWT_VERIFY_COLOR)) { + fail("HW component is not visible after resizing"); + } + + return true; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + if (System.getProperty("os.name").toLowerCase().contains("os x")) { + System.out.println("Aqua L&F ignores setting color to component. Test passes on Mac OS X."); + return; + } + instance = new MixingFrameResizing(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java b/jdk/test/java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java new file mode 100644 index 00000000000..d7e46b9ffc6 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java @@ -0,0 +1,462 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.*; +import java.awt.event.InputEvent; +import javax.swing.*; +import java.io.*; + +/** + * AWT/Swing overlapping test for Panel and JPanel behavior during resizing. + * <p>See <a href="https://bugs.openjdk.java.net/browse/JDK-6786219">JDK-6786219</a> for details + */ +/* +@test +@bug 6786219 +@summary Issues when resizing the frame after mixing of heavy weight & light weight components +@author sergey.grinev@oracle.com: area=awt.mixing +@build FrameBorderCounter +@run main MixingPanelsResizing + */ +public class MixingPanelsResizing { + + static volatile boolean failed = false; + + private static JFrame frame; + private static JButton jbutton; + private static Button awtButton; + private static JButton jbutton2; + private static Button awtButton2; + private static final Color jbColor = Color.RED; + private static final Color awtColor = Color.ORANGE; + private static final Color jb2Color = Color.BLUE; + private static final Color awt2Color = Color.CYAN; + private static final int ROBOT_DELAY = 500; + + private static Point lLoc; + private static int borderShift; + + private static int frameBorderCounter() { + String JAVA_HOME = System.getProperty("java.home"); + try { + Process p = Runtime.getRuntime().exec(JAVA_HOME + "/bin/java FrameBorderCounter"); + try { + p.waitFor(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + if (p.exitValue() != 0) { + throw new RuntimeException("FrameBorderCounter exited with not null code!\n" + readInputStream(p.getErrorStream())); + } + return Integer.parseInt(readInputStream(p.getInputStream()).trim()); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + private static String readInputStream(InputStream is) throws IOException { + byte[] buffer = new byte[4096]; + int len = 0; + StringBuilder sb = new StringBuilder(); + try (InputStreamReader isr = new InputStreamReader(is)) { + while ((len = is.read(buffer)) > 0) { + sb.append(new String(buffer, 0, len)); + } + } + return sb.toString(); + } + + private static void init() throws Exception { + //*** Create instructions for the user here *** + + borderShift = frameBorderCounter(); + borderShift = Math.abs(borderShift) == 1 ? borderShift : (borderShift / 2); + String[] instructions = { + "This is an AUTOMATIC test, simply wait until it is done.", + "The result (passed or failed) will be shown in the", + "message window below." + }; + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + Sysout.createDialog(); + Sysout.printInstructions(instructions); + + // prepare controls + + frame = new JFrame(); + + Panel awtPanel = new Panel(); + awtPanel.setBackground(Color.GREEN); + awtButton = new Button("AWTButton"); + awtPanel.add(awtButton); + awtButton.setForeground(awtColor); + awtButton.setBackground(awtColor); + jbutton = new JButton("SwingButton"); + awtPanel.add(jbutton); + jbutton.setForeground(jbColor); + jbutton.setBackground(jbColor); + + JPanel jPanel = new JPanel(); + jbutton2 = new JButton("SwingButton2"); + jPanel.add(jbutton2); + jbutton2.setForeground(jb2Color); + jbutton2.setBackground(jb2Color); + awtButton2 = new Button("AWT Button2"); + jPanel.add(awtButton2); + awtButton2.setForeground(awt2Color); + awtButton2.setBackground(awt2Color); + jPanel.setBackground(Color.YELLOW); + + frame.add(awtPanel, BorderLayout.SOUTH); + frame.add(jPanel, BorderLayout.NORTH); + + frame.pack(); + frame.setVisible(true); + } + }); + + ///////////////////////// + + final Robot robot = Util.createRobot(); + robot.setAutoDelay(ROBOT_DELAY); + + Util.waitForIdle(robot); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + lLoc = frame.getLocationOnScreen(); + lLoc.translate(frame.getWidth() + borderShift, frame.getHeight() + borderShift); + } + }); + + //grow + robot.mouseMove(lLoc.x, lLoc.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + + Runnable test = new Runnable() { + + public void run() { + Point btnLoc = jbutton.getLocationOnScreen(); + Color c = robot.getPixelColor(btnLoc.x + 5, btnLoc.y + 5); + if (!c.equals(jbColor)) { + fail("JButton was not redrawn properly on AWT Panel during move"); + } + + btnLoc = awtButton.getLocationOnScreen(); + c = robot.getPixelColor(btnLoc.x + 5, btnLoc.y + 5); + if (!c.equals(awtColor)) { + fail("AWT Button was not redrawn properly on AWT Panel during move"); + } + + btnLoc = jbutton2.getLocationOnScreen(); + c = robot.getPixelColor(btnLoc.x + 5, btnLoc.y + 5); + if (!c.equals(jb2Color)) { + fail("JButton was not redrawn properly on JPanel during move"); + } + + btnLoc = awtButton2.getLocationOnScreen(); + c = robot.getPixelColor(btnLoc.x + 5, btnLoc.y + 5); + if (!c.equals(awt2Color)) { + fail("ATW Button was not redrawn properly on JPanel during move"); + } + } + }; + + for (int i = 0; i < 30; i++) { + test.run(); + robot.mouseMove(lLoc.x + 20 * i, lLoc.y + 10 * i); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + //back + System.out.println("fast back"); + robot.mousePress(InputEvent.BUTTON1_MASK); + for (int i = 5; i >= 0; i--) { + test.run(); + robot.mouseMove(lLoc.x + 120 * i, lLoc.y + 60 * i); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + pass(); + }//End init() + /***************************************************** + * Standard Test Machinery Section + * DO NOT modify anything in this section -- it's a + * standard chunk of code which has all of the + * synchronisation necessary for the test harness. + * By keeping it the same in all tests, it is easier + * to read and understand someone else's test, as + * well as insuring that all tests behave correctly + * with the test harness. + * There is a section following this for test- + * classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + private static Thread mainThread = null; + private static int sleepTime = 300000; + + // Not sure about what happens if multiple of this test are + // instantiated in the same VM. Being static (and using + // static vars), it aint gonna work. Not worrying about + // it for now. + public static void main(String args[]) throws Exception { + if (!Toolkit.getDefaultToolkit().isDynamicLayoutActive()) { + System.out.println("Dynamic layout is not active. Test passes."); + return; + } + mainThread = Thread.currentThread(); + try { + init(); + } catch (TestPassedException e) { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test pass nor test fail has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try { + Thread.sleep(sleepTime); + //Timed out, so fail the test + throw new RuntimeException("Timed out after " + sleepTime / 1000 + " seconds"); + } catch (InterruptedException e) { + //The test harness may have interrupted the test. If so, rethrow the exception + // so that the harness gets it and deals with it. + if (!testGeneratedInterrupt) { + throw e; + } + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + + if (theTestPassed == false) { + throw new RuntimeException(failureMessage); + } + } + + }//main + + public static synchronized void setTimeoutTo(int seconds) { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() { + Sysout.println("The test passed."); + Sysout.println("The test is over, hit Ctl-C to stop Java VM"); + //first check if this is executing in main thread + if (mainThread == Thread.currentThread()) { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() { + //test writer didn't specify why test failed, so give generic + fail("it just plain failed! :-)"); + } + + public static synchronized void fail(String whyFailed) { + Sysout.println("The test failed: " + whyFailed); + Sysout.println("The test is over, hit Ctl-C to stop Java VM"); + //check if this called from main thread + if (mainThread == Thread.currentThread()) { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException(whyFailed); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() +}// class JButtonInGlassPane +class TestPassedException extends RuntimeException { +} + +//*********** End Standard Test Machinery Section ********** +//************ Begin classes defined for the test **************** +// if want to make listeners, here is the recommended place for them, then instantiate +// them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface +{ +static int newVar = 0; + +public void eventDispatched(AWTEvent e) +{ +//Counting events to see if we get enough +eventCount++; + +if( eventCount == 20 ) +{ +//got enough events, so pass + +JButtonInGlassPane.pass(); +} +else if( tries == 20 ) +{ +//tried too many times without getting enough events so fail + +JButtonInGlassPane.fail(); +} + +}// eventDispatched() + +}// NewClass class + + */ +//************** End classes defined for the test ******************* +/**************************************************** +Standard Test Machinery +DO NOT modify anything below -- it's a standard +chunk of code whose purpose is to make user +interaction uniform, and thereby make it simpler +to read and understand someone else's test. + ****************************************************/ +/** +This is part of the standard test machinery. +It creates a dialog (with the instructions), and is the interface +for sending text messages to the user. +To print the instructions, send an array of strings to Sysout.createDialog +WithInstructions method. Put one line of instructions per array entry. +To display a message for the tester to see, simply call Sysout.println +with the string to be displayed. +This mimics System.out.println but works within the test harness as well +as standalone. + */ +class Sysout { + + private static TestDialog dialog; + + public static void createDialogWithInstructions(String[] instructions) { + dialog = new TestDialog(new Frame(), "Instructions"); + dialog.printInstructions(instructions); + dialog.setVisible(true); + println("Any messages for the tester will display here."); + } + + public static void createDialog() { + dialog = new TestDialog(new Frame(), "Instructions"); + String[] defInstr = {"Instructions will appear here. ", ""}; + dialog.printInstructions(defInstr); + dialog.setVisible(true); + println("Any messages for the tester will display here."); + } + + public static void printInstructions(String[] instructions) { + dialog.printInstructions(instructions); + } + + public static void println(String messageIn) { + dialog.displayMessage(messageIn); + System.out.println(messageIn); + } +}// Sysout class + +/** +This is part of the standard test machinery. It provides a place for the +test instructions to be displayed, and a place for interactive messages +to the user to be displayed. +To have the test instructions displayed, see Sysout. +To have a message to the user be displayed, see Sysout. +Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog(Frame frame, String name) { + super(frame, name); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea("", 15, maxStringLength, scrollBoth); + add("North", instructionsText); + + messageText = new TextArea("", 5, maxStringLength, scrollBoth); + add("Center", messageText); + + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions(String[] instructions) { + //Clear out any current instructions + instructionsText.setText(""); + + //Go down array of instruction strings + + String printStr, remainingStr; + for (int i = 0; i < instructions.length; i++) { + //chop up each into pieces maxSringLength long + remainingStr = instructions[i]; + while (remainingStr.length() > 0) { + //if longer than max then chop off first max chars to print + if (remainingStr.length() >= maxStringLength) { + //Try to chop on a word boundary + int posOfSpace = remainingStr.lastIndexOf(' ', maxStringLength - 1); + + if (posOfSpace <= 0) { + posOfSpace = maxStringLength - 1; + } + + printStr = remainingStr.substring(0, posOfSpace + 1); + remainingStr = remainingStr.substring(posOfSpace + 1); + } //else just print + else { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append(printStr + "\n"); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage(String messageIn) { + messageText.append(messageIn + "\n"); + System.out.println(messageIn); + } +}// TestDialog class + diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java new file mode 100644 index 00000000000..fcfd9ce12be --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import com.sun.awt.AWTUtilities; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import javax.swing.JButton; +import javax.swing.SwingUtilities; + +/** + * AWT/Swing overlapping test for opaque Swing components. + * <p>This test verify if AWT components are drawn correctly under opaque components. + * <p>See <a href="https://bugs.openjdk.java.net/browse/JDK-6776743">JDK-6776743</a> for details + * <p>See base class for test info. + */ +/* +@test +@bug 6776743 +@summary Opaque overlapping test for each AWT component +@run main OpaqueOverlapping + */ +public class OpaqueOverlapping extends OverlappingTestBase { + + { + useClickValidation = false; + failMessage = "Opacity test mismatchs"; + + // CR 6994264 (Choice autohides dropdown on Solaris 10) + skipClassNames = new String[] { "Choice" }; + } + private String testSeq; + private final static String checkSeq = "010000101"; + private Point heavyLoc; + private JButton light; + private Frame frame = null; + + protected void prepareControls() { + testSeq = ""; + // Create components + if(frame != null) { + frame.setVisible(false); + } + frame = new Frame("OpaqueOverlapping mixing test"); + final Panel panel = new Panel(); + panel.setLayout(null); + + propagateAWTControls(panel); + + // Overlap the buttons + currentAwtControl.setBounds(30, 30, 200, 200); + + light = new JButton(" LW Button "); + light.setBounds(10, 10, 50, 50); + + // Put the components into the frame + panel.add(light); + frame.add(panel); + frame.setBounds(50, 50, 400, 400); + frame.setVisible(true); + + currentAwtControl.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + panel.setComponentZOrder(light, 0); + frame.validate(); + testSeq = testSeq + "0"; + } + }); + light.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent e) { + panel.setComponentZOrder(currentAwtControl, 0); + frame.validate(); + testSeq = testSeq + "1"; + } + }); + } + + @Override + protected boolean performTest() { + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + heavyLoc = currentAwtControl.getLocationOnScreen(); + } + }); + } catch (Exception e) { + } + Robot robot = Util.createRobot(); + robot.setAutoDelay(ROBOT_DELAY); + + Util.waitForIdle(robot); + + // Move the mouse pointer to the position where both + // components overlap + robot.mouseMove(heavyLoc.x + 5, heavyLoc.y + 5); + + // Now perform the click at this point for 9 times + // In the middle of the process toggle the opaque + // flag value. + for (int i = 0; i < 9; ++i) { + if (i == 3) { + AWTUtilities.setComponentMixingCutoutShape(light, + new Rectangle()); + } + if (i == 6) { + AWTUtilities.setComponentMixingCutoutShape(light, + null); + } + + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + Util.waitForIdle(robot); + + if (currentAwtControl.getClass() == java.awt.Choice.class && i != 1 && i != 6 && i != 8) { + // due to the fact that Choice doesn't get mouseClicked event if its dropdown is shown + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + Util.waitForIdle(robot); + } + } + + Util.waitForIdle(robot); + + boolean result = testSeq.equals(checkSeq); + if (!result) { + System.err.println("Expected: " + checkSeq); + System.err.println("Observed: " + testSeq); + } + return result; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new OpaqueOverlapping(); + OverlappingTestBase.doMain(args); + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/OpaqueOverlappingChoice.java b/jdk/test/java/awt/Mixing/AWT_Mixing/OpaqueOverlappingChoice.java new file mode 100644 index 00000000000..896b096b4bb --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/OpaqueOverlappingChoice.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +/** + * AWT/Swing overlapping test for opaque Choice. + * + * This test case was separated from {@link OpaqueOverlapping} due to CR 6994264 (Choice autohides dropdown on Solaris 10) + */ +/* +@test +@bug 6994264 +@summary Opaque overlapping test for Choice AWT component +@run main OpaqueOverlappingChoice + */ +public class OpaqueOverlappingChoice extends OpaqueOverlapping { + { + onlyClassName = "Choice"; + skipClassNames = null; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new OpaqueOverlappingChoice(); + OverlappingTestBase.doMain(args); + } +} + diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/OverlappingTestBase.java b/jdk/test/java/awt/Mixing/AWT_Mixing/OverlappingTestBase.java new file mode 100644 index 00000000000..f3730b89302 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/OverlappingTestBase.java @@ -0,0 +1,800 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.*; +import java.awt.event.*; +import java.awt.peer.ComponentPeer; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import javax.swing.*; +import sun.awt.*; +import java.io.*; + +/** + * <p>This class provides basis for AWT Mixing testing. + * <p>It provides all standard test machinery and should be used by + * extending and overriding next methods: + * <li> {@link OverlappingTestBase#prepareControls()} - setup UI components + * <li> {@link OverlappingTestBase#performTest()} - run particular test + * Those methods would be run in the loop for each AWT component. + * <p>Current AWT component should be added to the tested UI by {@link OverlappingTestBase#propagateAWTControls(java.awt.Container) ()}. + * There AWT components are prepared to be tested as being overlayed by other (e.g. Swing) components - they are colored to + * {@link OverlappingTestBase#AWT_BACKGROUND_COLOR} and throws failure on catching mouse event. + * <p> Validation of component being overlayed should be tested by {@link OverlappingTestBase#clickAndBlink(java.awt.Robot, java.awt.Point) } + * See each method javadoc for more details. + * + * <p>Due to test machinery limitations all test should be run from their own main() by calling next coe + * <code> + * public static void main(String args[]) throws InterruptedException { + * instance = new YourTestInstance(); + * OverlappingTestBase.doMain(args); + * } + * </code> + * + * @author Sergey Grinev + */ +public abstract class OverlappingTestBase { + // working variables + private static volatile boolean wasHWClicked = false; + private static volatile boolean passed = true; + // constants + /** + * Default color for AWT component used for validate correct drawing of overlapping. <b>Never</b> use it for lightweight components. + */ + protected static final Color AWT_BACKGROUND_COLOR = new Color(21, 244, 54); + protected static Color AWT_VERIFY_COLOR = AWT_BACKGROUND_COLOR; + protected static final int ROBOT_DELAY = 500; + private static final String[] simpleAwtControls = {"Button", "Checkbox", "Label", "TextArea"}; + /** + * Generic strings array. To be used for population of List based controls. + */ + protected static final String[] petStrings = {"Bird", "Cat", "Dog", "Rabbit", "Rhynocephalia Granda", "Bear", "Tiger", "Mustang"}; + // "properties" + /** + * Tests customization. Set this variable to test only control from java.awt + * <p>Usage of this variable should be marked with CR being the reason. + * <p>Do not use this variable simultaneously with {@link OverlappingTestBase#skipClassNames} + */ + protected String onlyClassName = null; + /** + * For customizing tests. List classes' simple names to skip them from testings. + * <p>Usage of this variable should be marked with CR being the reason. + */ + protected String[] skipClassNames = null; + /** + * Set to false to avoid event delivery validation + * @see OverlappingTestBase#clickAndBlink(java.awt.Robot, java.awt.Point, boolean) + */ + protected boolean useClickValidation = true; + /** + * Set to false if test doesn't supposed to verify EmbeddedFrame + */ + protected boolean testEmbeddedFrame = false; + /** + * Set this variable to true if testing embedded frame is impossible (on Mac, for instance, for now). + * The testEmbeddedFrame is explicitly set to true in dozen places. + */ + protected boolean skipTestingEmbeddedFrame = false; + + public static final boolean isMac = System.getProperty("os.name").toLowerCase().contains("os x"); + private boolean isFrameBorderCalculated; + private int borderShift; + + { if (Toolkit.getDefaultToolkit().getClass().getName().matches(".*L.*Toolkit")) { + // No EmbeddedFrame in LWToolkit/LWCToolkit, yet + // And it should be programmed some other way, too, in any case + System.err.println("skipTestingEmbeddedFrame"); + skipTestingEmbeddedFrame = true; + }else { + System.err.println("do not skipTestingEmbeddedFrame"); + } + } + + protected int frameBorderCounter() { + if (!isFrameBorderCalculated) { + try { + new FrameBorderCounter(); // force compilation by jtreg + String JAVA_HOME = System.getProperty("java.home"); + Process p = Runtime.getRuntime().exec(JAVA_HOME + "/bin/java FrameBorderCounter"); + try { + p.waitFor(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + if (p.exitValue() != 0) { + throw new RuntimeException("FrameBorderCounter exited with not null code!\n" + readInputStream(p.getErrorStream())); + } + borderShift = Integer.parseInt(readInputStream(p.getInputStream()).trim()); + isFrameBorderCalculated = true; + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } + } + return borderShift; + } + + public void getVerifyColor() { + try { + final int size = 200; + final SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + final Point[] p = new Point[1]; + SwingUtilities.invokeAndWait(new Runnable() { + public void run(){ + JFrame frame = new JFrame("set back"); + frame.getContentPane().setBackground(AWT_BACKGROUND_COLOR); + frame.setSize(size, size); + frame.setUndecorated(true); + frame.setVisible(true); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + p[0] = frame.getLocation(); + } + }); + Robot robot = new Robot(); + toolkit.realSync(); + Thread.sleep(ROBOT_DELAY); + AWT_VERIFY_COLOR = robot.getPixelColor(p[0].x+size/2, p[0].y+size/2); + System.out.println("Color will be compared with " + AWT_VERIFY_COLOR + " instead of " + AWT_BACKGROUND_COLOR); + } catch (Exception e) { + System.err.println("Cannot get verify color: "+e.getMessage()); + } + } + + private String readInputStream(InputStream is) throws IOException { + byte[] buffer = new byte[4096]; + int len = 0; + StringBuilder sb = new StringBuilder(); + try (InputStreamReader isr = new InputStreamReader(is)) { + while ((len = is.read(buffer)) > 0) { + sb.append(new String(buffer, 0, len)); + } + } + return sb.toString(); + } + + private void setupControl(final Component control) { + if (useClickValidation) { + control.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + System.err.println("ERROR: " + control.getClass() + " received mouse click."); + wasHWClicked = true; + } + }); + } + control.setBackground(AWT_BACKGROUND_COLOR); + control.setForeground(AWT_BACKGROUND_COLOR); + control.setPreferredSize(new Dimension(150, 150)); + control.setFocusable(false); + } + + private void addAwtControl(java.util.List<Component> container, final Component control) { + String simpleName = control.getClass().getSimpleName(); + if (onlyClassName != null && !simpleName.equals(onlyClassName)) { + return; + } + if (skipClassNames != null) { + for (String skipMe : skipClassNames) { + if (simpleName.equals(skipMe)) { + return; + } + } + } + setupControl(control); + container.add(control); + } + + private void addSimpleAwtControl(java.util.List<Component> container, String className) { + try { + Class definition = Class.forName("java.awt." + className); + Constructor constructor = definition.getConstructor(new Class[]{String.class}); + java.awt.Component component = (java.awt.Component) constructor.newInstance(new Object[]{"AWT Component " + className}); + addAwtControl(container, component); + } catch (Exception ex) { + System.err.println(ex.getMessage()); + fail("Setup error, this jdk doesn't have awt conrol " + className); + } + } + + /** + * Adds current AWT control to container + * <p>N.B.: if testEmbeddedFrame == true this method will also add EmbeddedFrame over Canvas + * and it should be called <b>after</b> Frame.setVisible(true) call + * @param container container to hold AWT component + */ + protected final void propagateAWTControls(Container container) { + if (currentAwtControl != null) { + container.add(currentAwtControl); + } else { // embedded frame + try { + + //create embedder + Canvas embedder = new Canvas(); + embedder.setBackground(Color.RED); + embedder.setPreferredSize(new Dimension(150, 150)); + container.add(embedder); + container.setVisible(true); // create peer + + long frameWindow = 0; + String getWindowMethodName = "getHWnd"; + if (Toolkit.getDefaultToolkit().getClass().getName().contains("XToolkit")) { + getWindowMethodName = "getWindow"; + } + ComponentPeer peer = embedder.getPeer(); +// System.err.println("Peer: " + peer); + Method getWindowMethod = peer.getClass().getMethod(getWindowMethodName); + frameWindow = (Long) getWindowMethod.invoke(peer); +// System.err.println("frame peer ID: " + frameWindow); + + String eframeClassName = "sun.awt.windows.WEmbeddedFrame"; + if (Toolkit.getDefaultToolkit().getClass().getName().contains("XToolkit")) { + eframeClassName = "sun.awt.X11.XEmbeddedFrame"; + } + Class eframeClass = Class.forName(eframeClassName); + Constructor eframeCtor = eframeClass.getConstructor(long.class); + EmbeddedFrame eframe = (EmbeddedFrame) eframeCtor.newInstance(frameWindow); + setupControl(eframe); + eframe.setSize(new Dimension(150, 150)); + eframe.setVisible(true); +// System.err.println(eframe.getSize()); + } catch (Exception ex) { + ex.printStackTrace(); + fail("Failed to instantiate EmbeddedFrame: " + ex.getMessage()); + } + } + } + private static final Font hugeFont = new Font("Arial", Font.BOLD, 70); + + private java.util.List<Component> getAWTControls() { + java.util.List<Component> components = new ArrayList<Component>(); + + for (String clazz : simpleAwtControls) { + addSimpleAwtControl(components, clazz); + } + + TextField tf = new TextField(); + tf.setFont(hugeFont); + addAwtControl(components, tf); + + // more complex controls + Choice c = new Choice(); + for (int i = 0; i < petStrings.length; i++) { + c.add(petStrings[i]); + } + addAwtControl(components, c); + c.setPreferredSize(null); + c.setFont(hugeFont); // to make control bigger as setPrefferedSize don't do his job here + + List l = new List(petStrings.length); + for (int i = 0; i < petStrings.length; i++) { + l.add(petStrings[i]); + } + addAwtControl(components, l); + + Canvas canvas = new Canvas(); + canvas.setSize(100, 200); + addAwtControl(components, canvas); + + Scrollbar sb = new Scrollbar(Scrollbar.VERTICAL, 500, 1, 0, 500); + addAwtControl(components, sb); + + Scrollbar sb2 = new Scrollbar(Scrollbar.HORIZONTAL, 500, 1, 0, 500); + addAwtControl(components, sb2); + + return components; + } + /** + * Default shift for {@link OverlappingTestBase#clickAndBlink(java.awt.Robot, java.awt.Point) } + */ + protected static Point shift = new Point(16, 16); + + /** + * Verifies point using specified AWT Robot. Supposes <code>defaultShift == true</code> for {@link OverlappingTestBase#clickAndBlink(java.awt.Robot, java.awt.Point, boolean) }. + * This method is used to verify controls by providing just their plain screen coordinates. + * @param robot AWT Robot. Usually created by {@link Util#createRobot() } + * @param lLoc point to verify + * @see OverlappingTestBase#clickAndBlink(java.awt.Robot, java.awt.Point, boolean) + */ + protected void clickAndBlink(Robot robot, Point lLoc) { + clickAndBlink(robot, lLoc, true); + } + /** + * Default failure message for color check + * @see OverlappingTestBase#performTest() + */ + protected String failMessageColorCheck = "The LW component did not pass pixel color check and is overlapped"; + /** + * Default failure message event check + * @see OverlappingTestBase#performTest() + */ + protected String failMessage = "The LW component did not received the click."; + + private static boolean isValidForPixelCheck(Component component) { + if ((component instanceof java.awt.Scrollbar) || isMac && (component instanceof java.awt.Button)) { + return false; + } + return true; + } + + /** + * Preliminary validation - should be run <b>before</b> overlapping happens to ensure test is correct. + * @param robot AWT Robot. Usually created by {@link Util#createRobot() } + * @param lLoc point to validate to be <b>of</b> {@link OverlappingTestBase#AWT_BACKGROUND_COLOR} + * @param component tested component, should be pointed out as not all components are valid for pixel check. + */ + protected void pixelPreCheck(Robot robot, Point lLoc, Component component) { + if (isValidForPixelCheck(component)) { + int tries = 10; + Color c = null; + while (tries-- > 0) { + c = robot.getPixelColor(lLoc.x, lLoc.y); + System.out.println("Precheck. color: "+c+" compare with "+AWT_VERIFY_COLOR); + if (c.equals(AWT_VERIFY_COLOR)) { + return; + } + try { + Thread.sleep(100); + } catch (InterruptedException e) { + } + } + System.err.println(lLoc + ": " + c); + fail("Dropdown test setup failure, colored part of AWT component is not located at click area"); + } + } + + /** + * Verifies point using specified AWT Robot. + * <p>Firstly, verifies point by color pixel check + * <p>Secondly, verifies event delivery by mouse click + * @param robot AWT Robot. Usually created by {@link Util#createRobot() } + * @param lLoc point to verify + * @param defaultShift if true verified position will be shifted by {@link OverlappingTestBase#shift }. + */ + protected void clickAndBlink(Robot robot, Point lLoc, boolean defaultShift) { + Point loc = lLoc.getLocation(); + //check color + Util.waitForIdle(robot); + try{ + Thread.sleep(500); + }catch(Exception exx){ + exx.printStackTrace(); + } + + if (defaultShift) { + loc.translate(shift.x, shift.y); + } + if (!(System.getProperty("os.name").toLowerCase().contains("os x"))) { + Color c = robot.getPixelColor(loc.x, loc.y); + System.out.println("C&B. color: "+c+" compare with "+AWT_VERIFY_COLOR); + if (c.equals(AWT_VERIFY_COLOR)) { + fail(failMessageColorCheck); + passed = false; + } + + // perform click + Util.waitForIdle(robot); + } + + robot.mouseMove(loc.x, loc.y); + + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + Util.waitForIdle(robot); + } + + /** + * This method should be overriden with code which setups UI for testing. + * Code in this method <b>will</b> be called only from AWT thread so Swing operations can be called directly. + * + * @see {@link OverlappingTestBase#propagateAWTControls(java.awt.Container) } for instructions about adding tested AWT control to UI + */ + protected abstract void prepareControls(); + + /** + * This method should be overriden with test execution. It will <b>not</b> be called from AWT thread so all Swing operations should be treated accordingly. + * @return true if test passed. Otherwise fail with default fail message. + * @see {@link OverlappingTestBase#failMessage} default fail message + */ + protected abstract boolean performTest(); + /** + * This method can be overriden with cleanup routines. It will be called from AWT thread so all Swing operations should be treated accordingly. + */ + protected void cleanup() { + // intentionally do nothing + } + /** + * Currect tested AWT Control. Usually shouldn't be accessed directly. + * + * @see {@link OverlappingTestBase#propagateAWTControls(java.awt.Container) } for instructions about adding tested AWT control to UI + */ + protected Component currentAwtControl; + + private void testComponent(Component component) throws InterruptedException, InvocationTargetException { + currentAwtControl = component; + System.out.println("Testing " + currentAwtControl.getClass().getSimpleName()); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + prepareControls(); + } + }); + if (component != null) { + Util.waitTillShown(component); + } + Util.waitForIdle(null); + try { + Thread.sleep(500); // wait for graphic effects on systems like Win7 + } catch (InterruptedException ex) { + } + if (!instance.performTest()) { + fail(failMessage); + passed = false; + } + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + cleanup(); + } + }); + } + + private void testEmbeddedFrame() throws InvocationTargetException, InterruptedException { + System.out.println("Testing EmbeddedFrame"); + currentAwtControl = null; + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + prepareControls(); + } + }); + Util.waitForIdle(null); + try { + Thread.sleep(500); // wait for graphic effects on systems like Win7 + } catch (InterruptedException ex) { + } + if (!instance.performTest()) { + fail(failMessage); + passed = false; + } + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + cleanup(); + } + }); + } + + private void testAwtControls() throws InterruptedException { + try { + for (Component component : getAWTControls()) { + testComponent(component); + } + if (testEmbeddedFrame && !skipTestingEmbeddedFrame) { + testEmbeddedFrame(); + } + } catch (InvocationTargetException ex) { + ex.printStackTrace(); + fail(ex.getMessage()); + } + } + /** + * Used by standard test machinery. See usage at {@link OverlappingTestBase } + */ + protected static OverlappingTestBase instance; + + protected OverlappingTestBase() { + getVerifyColor(); + } + + /***************************************************** + * Standard Test Machinery Section + * DO NOT modify anything in this section -- it's a + * standard chunk of code which has all of the + * synchronisation necessary for the test harness. + * By keeping it the same in all tests, it is easier + * to read and understand someone else's test, as + * well as insuring that all tests behave correctly + * with the test harness. + * There is a section following this for test- + * classes + ******************************************************/ + private static void init() throws InterruptedException { + //*** Create instructions for the user here *** + //System.setProperty("sun.awt.disableMixing", "true"); + + String[] instructions = { + "This is an AUTOMATIC test, simply wait until it is done.", + "The result (passed or failed) will be shown in the", + "message window below." + }; + Sysout.createDialog(); + Sysout.printInstructions(instructions); + + instance.testAwtControls(); + + if (wasHWClicked) { + fail("HW component received the click."); + passed = false; + } + if (passed) { + pass(); + } + }//End init() + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + private static Thread mainThread = null; + private static int sleepTime = 300000; + + // Not sure about what happens if multiple of this test are + // instantiated in the same VM. Being static (and using + // static vars), it aint gonna work. Not worrying about + // it for now. + /** + * Starting point for test runs. See usage at {@link OverlappingTestBase } + * @param args regular main args, not used. + * @throws InterruptedException + */ + public static void doMain(String args[]) throws InterruptedException { + mainThread = Thread.currentThread(); + try { + init(); + } catch (TestPassedException e) { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test pass nor test fail has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try { + Thread.sleep(sleepTime); + //Timed out, so fail the test + throw new RuntimeException("Timed out after " + sleepTime / 1000 + " seconds"); + } catch (InterruptedException e) { + //The test harness may have interrupted the test. If so, rethrow the exception + // so that the harness gets it and deals with it. + if (!testGeneratedInterrupt) { + throw e; + } + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + + if (theTestPassed == false) { + throw new RuntimeException(failureMessage); + } + } + + }//main + + /** + * Test will fail if not passed after this timeout. Default timeout is 300 seconds. + * @param seconds timeout in seconds + */ + public static synchronized void setTimeoutTo(int seconds) { + sleepTime = seconds * 1000; + } + + /** + * Set test as passed. Usually shoudn't be called directly. + */ + public static synchronized void pass() { + Sysout.println("The test passed."); + Sysout.println("The test is over, hit Ctl-C to stop Java VM"); + //first check if this is executing in main thread + if (mainThread == Thread.currentThread()) { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + /** + * Fail test generic message. + */ + public static synchronized void fail() { + //test writer didn't specify why test failed, so give generic + fail("it just plain failed! :-)"); + } + + /** + * Fail test providing specific reason. + * @param whyFailed reason + */ + public static synchronized void fail(String whyFailed) { + Sysout.println("The test failed: " + whyFailed); + Sysout.println("The test is over, hit Ctl-C to stop Java VM"); + //check if this called from main thread + if (mainThread == Thread.currentThread()) { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException(whyFailed); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() +}// class LWComboBox +class TestPassedException extends RuntimeException { +} + +//*********** End Standard Test Machinery Section ********** +//************ Begin classes defined for the test **************** +// if want to make listeners, here is the recommended place for them, then instantiate +// them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface +{ +static int newVar = 0; + +public void eventDispatched(AWTEvent e) +{ +//Counting events to see if we get enough +eventCount++; + +if( eventCount == 20 ) +{ +//got enough events, so pass + +LWComboBox.pass(); +} +else if( tries == 20 ) +{ +//tried too many times without getting enough events so fail + +LWComboBox.fail(); +} + +}// eventDispatched() + +}// NewClass class + + */ +//************** End classes defined for the test ******************* +/**************************************************** +Standard Test Machinery +DO NOT modify anything below -- it's a standard +chunk of code whose purpose is to make user +interaction uniform, and thereby make it simpler +to read and understand someone else's test. + ****************************************************/ +/** +This is part of the standard test machinery. +It creates a dialog (with the instructions), and is the interface +for sending text messages to the user. +To print the instructions, send an array of strings to Sysout.createDialog +WithInstructions method. Put one line of instructions per array entry. +To display a message for the tester to see, simply call Sysout.println +with the string to be displayed. +This mimics System.out.println but works within the test harness as well +as standalone. + */ +class Sysout { + private static TestDialog dialog; + + public static void createDialogWithInstructions(String[] instructions) { + dialog = new TestDialog(new Frame(), "Instructions"); + dialog.printInstructions(instructions); + //dialog.setVisible(true); + println("Any messages for the tester will display here."); + } + + public static void createDialog() { + dialog = new TestDialog(new Frame(), "Instructions"); + String[] defInstr = {"Instructions will appear here. ", ""}; + dialog.printInstructions(defInstr); + //dialog.setVisible(true); + println("Any messages for the tester will display here."); + } + + public static void printInstructions(String[] instructions) { + dialog.printInstructions(instructions); + } + + public static void println(String messageIn) { + dialog.displayMessage(messageIn); + System.out.println(messageIn); + } +}// Sysout class + +/** +This is part of the standard test machinery. It provides a place for the +test instructions to be displayed, and a place for interactive messages +to the user to be displayed. +To have the test instructions displayed, see Sysout. +To have a message to the user be displayed, see Sysout. +Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog(Frame frame, String name) { + super(frame, name); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea("", 15, maxStringLength, scrollBoth); + add("North", instructionsText); + + messageText = new TextArea("", 5, maxStringLength, scrollBoth); + add("Center", messageText); + + pack(); + + //setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions(String[] instructions) { + //Clear out any current instructions + instructionsText.setText(""); + + //Go down array of instruction strings + + String printStr, remainingStr; + for (int i = 0; i < instructions.length; i++) { + //chop up each into pieces maxSringLength long + remainingStr = instructions[i]; + while (remainingStr.length() > 0) { + //if longer than max then chop off first max chars to print + if (remainingStr.length() >= maxStringLength) { + //Try to chop on a word boundary + int posOfSpace = remainingStr.lastIndexOf(' ', maxStringLength - 1); + + if (posOfSpace <= 0) { + posOfSpace = maxStringLength - 1; + } + + printStr = remainingStr.substring(0, posOfSpace + 1); + remainingStr = remainingStr.substring(posOfSpace + 1); + } //else just print + else { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append(printStr + "\n"); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage(String messageIn) { + messageText.append(messageIn + "\n"); + System.out.println(messageIn); + } +}// TestDialog class + diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/SimpleOverlappingTestBase.java b/jdk/test/java/awt/Mixing/AWT_Mixing/SimpleOverlappingTestBase.java new file mode 100644 index 00000000000..4d81127a772 --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/SimpleOverlappingTestBase.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +/** + * Base class for testing overlapping of Swing and AWT component put into one frame. + * Validates drawing and event delivery at the components intersection. + * <p> See base class for usage + * + * @author Sergey Grinev +*/ +public abstract class SimpleOverlappingTestBase extends OverlappingTestBase { + + { + testEmbeddedFrame = true; + } + + /** + * Event delivery validation. If set to true (default) tested lightweight component will be provided + * with mouse listener which should be called in order for test to pass. + */ + protected final boolean useDefaultClickValidation; + + /** + * Constructor which sets {@link SimpleOverlappingTestBase#useDefaultClickValidation } + * @param defaultClickValidation + */ + protected SimpleOverlappingTestBase(boolean defaultClickValidation) { + super(); + this.useDefaultClickValidation = defaultClickValidation; + } + + public SimpleOverlappingTestBase() { + this(true); + } + + //overridables + /** + * Successors override this method providing swing component for testing + * @return swing component to test + */ + protected abstract JComponent getSwingComponent(); + + /** + * For tests debugging. Please, ignore. + */ + protected static final boolean debug = false; + + /** + * Should be set to true if test isn't using {@link SimpleOverlappingTestBase#useDefaultClickValidation } + */ + protected volatile boolean wasLWClicked = false; + + /** + * Current tested lightweight component + * @see SimpleOverlappingTestBase#getSwingComponent() + */ + protected JComponent testedComponent; + + /** + * Setups simple frame with lightweight component returned by {@link SimpleOverlappingTestBase#getSwingComponent() } + * Called by base class. + */ + protected void prepareControls() { + wasLWClicked = false; + + final JFrame f = new JFrame("Mixing : Simple Overlapping test"); + f.setLayout(new SpringLayout()); + f.setSize(200, 200); + + testedComponent = getSwingComponent(); + + if (useDefaultClickValidation) { + testedComponent.addMouseListener(new MouseAdapter() { + + @Override + public void mouseClicked(MouseEvent e) { + wasLWClicked = true; + f.setVisible(false); + } + }); + } + + if (!debug) { + f.add(testedComponent); + } else { + System.err.println("Warning: DEBUG MODE"); + } + + propagateAWTControls(f); + + f.setVisible(true); + } + + /** + * AWT Robot instance. Shouldn't be used in most cases. + */ + protected Robot robot; + + /** + * Run test by {@link OverlappingTestBase#clickAndBlink(java.awt.Robot, java.awt.Point) } validation for current lightweight component. + * <p>Called by base class. + * @return true if test passed + */ + protected boolean performTest() { + testedComponent.requestFocus(); + + // run robot + robot = Util.createRobot(); + robot.setAutoDelay(20); + + // get coord + Point lLoc = !debug ? testedComponent.getLocationOnScreen() : new Point(70, 30); + Util.waitForIdle(null); + /* this is a workaround for certain jtreg(?) focus issue: + tests fail starting after failing mixing tests but always pass alone. + */ + JFrame ancestor = (JFrame)(testedComponent.getTopLevelAncestor()); + if( ancestor != null ) { + Point ancestorLoc = ancestor.getLocationOnScreen(); + ancestorLoc.translate(ancestor.getWidth()/2-15, 2); + robot.mouseMove(ancestorLoc.x, ancestorLoc.y); + Util.waitForIdle(robot); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.delay(50); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + Util.waitForIdle(robot); + } + + clickAndBlink(robot, lLoc); + Util.waitForIdle(null); + + return wasLWClicked; + } + +} + diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/Util.java b/jdk/test/java/awt/Mixing/AWT_Mixing/Util.java new file mode 100644 index 00000000000..6bebdc881dc --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/Util.java @@ -0,0 +1,601 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.Component; +import java.awt.Frame; +import java.awt.Dialog; +import java.awt.Window; +import java.awt.Button; +import java.awt.Point; +import java.awt.Dimension; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.IllegalComponentStateException; +import java.awt.AWTException; +import java.awt.AWTEvent; + +import java.awt.event.InputEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.ActionEvent; +import java.awt.event.FocusEvent; +import java.awt.event.WindowListener; +import java.awt.event.WindowFocusListener; +import java.awt.event.FocusListener; +import java.awt.event.ActionListener; + +import java.awt.peer.FramePeer; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import java.security.PrivilegedAction; +import java.security.AccessController; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * <p>This class contains utilities useful for regression testing. + * <p>When using jtreg you would include this class into the build + * list via something like: + * <pre> + &library ../../../../share/lib/AWT_Mixing/src/regtesthelpers/ + &build Util + &run main YourTest + </pre> + * Note that if you are about to create a test based on + * Applet-template, then put those lines into html-file, not in java-file. + * <p> And put an + * import regtesthelpers.Util; + * into the java source of test. +*/ +public final class Util { + private Util() {} // this is a helper class with static methods :) + + /* + * @throws RuntimeException when creation failed + */ + public static Robot createRobot() { + try { + return new Robot(); + } catch (AWTException e) { + throw new RuntimeException("Error: unable to create robot", e); + } + } + + public static Frame createEmbeddedFrame(final Frame embedder) + throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, + InstantiationException, InvocationTargetException + { + Toolkit tk = Toolkit.getDefaultToolkit(); + FramePeer frame_peer = (FramePeer) embedder.getPeer(); + System.out.println("frame's peer = " + frame_peer); + if ("sun.awt.windows.WToolkit".equals(tk.getClass().getName())) { + Class comp_peer_class = + Class.forName("sun.awt.windows.WComponentPeer"); + System.out.println("comp peer class = " + comp_peer_class); + Field hwnd_field = comp_peer_class.getDeclaredField("hwnd"); + hwnd_field.setAccessible(true); + System.out.println("hwnd_field =" + hwnd_field); + long hwnd = hwnd_field.getLong(frame_peer); + System.out.println("hwnd = " + hwnd); + + Class clazz = Class.forName("sun.awt.windows.WEmbeddedFrame"); + Constructor constructor = clazz.getConstructor (new Class [] {Long.TYPE}); + return (Frame) constructor.newInstance (new Object[] {hwnd}); + } else if ("sun.awt.X11.XToolkit".equals(tk.getClass().getName())) { + Class x_base_window_class = Class.forName("sun.awt.X11.XBaseWindow"); + System.out.println("x_base_window_class = " + x_base_window_class); + Method get_window = x_base_window_class.getMethod("getWindow", new Class[0]); + System.out.println("get_window = " + get_window); + long window = (Long) get_window.invoke(frame_peer, new Object[0]); + System.out.println("window = " + window); + Class clazz = Class.forName("sun.awt.X11.XEmbeddedFrame"); + Constructor constructor = clazz.getConstructor (new Class [] {Long.TYPE, Boolean.TYPE}); + return (Frame) constructor.newInstance (new Object[] {window, true}); + } + + throw new RuntimeException("Unexpected toolkit - " + tk); + } + + /** + * Makes the window visible and waits until it's shown. + */ + public static void showWindowWait(Window win) { + win.setVisible(true); + waitTillShown(win); + } + + /** + * Moves mouse pointer in the center of given {@code comp} component + * using {@code robot} parameter. + */ + public static void pointOnComp(final Component comp, final Robot robot) { + Rectangle bounds = new Rectangle(comp.getLocationOnScreen(), comp.getSize()); + robot.mouseMove(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2); + } + + /** + * Moves mouse pointer in the center of a given {@code comp} component + * and performs a left mouse button click using the {@code robot} parameter + * with the {@code delay} delay between press and release. + */ + public static void clickOnComp(final Component comp, final Robot robot, int delay) { + pointOnComp(comp, robot); + robot.delay(delay); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.delay(delay); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + } + + /** + * Moves mouse pointer in the center of a given {@code comp} component + * and performs a left mouse button click using the {@code robot} parameter + * with the default delay between press and release. + */ + public static void clickOnComp(final Component comp, final Robot robot) { + clickOnComp(comp, robot, 50); + } + + /* + * Clicks on a title of Frame/Dialog. + * WARNING: it may fail on some platforms when the window is not wide enough. + */ + public static void clickOnTitle(final Window decoratedWindow, final Robot robot) { + Point p = decoratedWindow.getLocationOnScreen(); + Dimension d = decoratedWindow.getSize(); + + if (decoratedWindow instanceof Frame || decoratedWindow instanceof Dialog) { + robot.mouseMove(p.x + (int)(d.getWidth()/2), p.y + (int)decoratedWindow.getInsets().top/2); + robot.delay(50); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.delay(50); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + } + } + + public static void waitForIdle(final Robot robot) { + // we do not use robot for now, use SunToolkit.realSync() instead + ((sun.awt.SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + } + + public static Field getField(final Class klass, final String fieldName) { + return AccessController.doPrivileged(new PrivilegedAction<Field>() { + public Field run() { + try { + Field field = klass.getDeclaredField(fieldName); + assert (field != null); + field.setAccessible(true); + return field; + } catch (SecurityException se) { + throw new RuntimeException("Error: unexpected exception caught!", se); + } catch (NoSuchFieldException nsfe) { + throw new RuntimeException("Error: unexpected exception caught!", nsfe); + } + } + }); + } + + /* + * Waits for a notification and for a boolean condition to become true. + * The method returns when the above conditions are fullfilled or when the timeout + * occurs. + * + * @param condition the object to be notified and the booelan condition to wait for + * @param timeout the maximum time to wait in milliseconds + * @param catchExceptions if {@code true} the method catches InterruptedException + * @return the final boolean value of the {@code condition} + * @throws InterruptedException if the awaiting proccess has been interrupted + */ + public static boolean waitForConditionEx(final AtomicBoolean condition, long timeout) + throws InterruptedException + { + synchronized (condition) { + long startTime = System.currentTimeMillis(); + while (!condition.get()) { + condition.wait(timeout); + if (System.currentTimeMillis() - startTime >= timeout ) { + break; + } + } + } + return condition.get(); + } + + /* + * The same as {@code waitForConditionEx(AtomicBoolean, long)} except that it + * doesn't throw InterruptedException. + */ + public static boolean waitForCondition(final AtomicBoolean condition, long timeout) { + try { + return waitForConditionEx(condition, timeout); + } catch (InterruptedException e) { + throw new RuntimeException("Error: unexpected exception caught!", e); + } + } + + /* + * The same as {@code waitForConditionEx(AtomicBoolean, long)} but without a timeout. + */ + public static void waitForConditionEx(final AtomicBoolean condition) + throws InterruptedException + { + synchronized (condition) { + while (!condition.get()) { + condition.wait(); + } + } + } + + /* + * The same as {@code waitForConditionEx(AtomicBoolean)} except that it + * doesn't throw InterruptedException. + */ + public static void waitForCondition(final AtomicBoolean condition) { + try { + waitForConditionEx(condition); + } catch (InterruptedException e) { + throw new RuntimeException("Error: unexpected exception caught!", e); + } + } + + public static void waitTillShownEx(final Component comp) throws InterruptedException { + while (true) { + try { + Thread.sleep(100); + comp.getLocationOnScreen(); + break; + } catch (IllegalComponentStateException e) {} + } + } + public static void waitTillShown(final Component comp) { + try { + waitTillShownEx(comp); + } catch (InterruptedException e) { + throw new RuntimeException("Error: unexpected exception caught!", e); + } + } + + /** + * Drags from one point to another with the specified mouse button pressed. + * + * @param robot a robot to use for moving the mouse, etc. + * @param startPoint a start point of the drag + * @param endPoint an end point of the drag + * @param button one of {@code InputEvent.BUTTON1_MASK}, + * {@code InputEvent.BUTTON2_MASK}, {@code InputEvent.BUTTON3_MASK} + * + * @throws IllegalArgumentException if {@code button} is not one of + * {@code InputEvent.BUTTON1_MASK}, {@code InputEvent.BUTTON2_MASK}, + * {@code InputEvent.BUTTON3_MASK} + */ + public static void drag(Robot robot, Point startPoint, Point endPoint, int button) { + if (!(button == InputEvent.BUTTON1_MASK || button == InputEvent.BUTTON2_MASK + || button == InputEvent.BUTTON3_MASK)) + { + throw new IllegalArgumentException("invalid mouse button"); + } + + robot.mouseMove(startPoint.x, startPoint.y); + robot.mousePress(button); + try { + mouseMove(robot, startPoint, endPoint); + } finally { + robot.mouseRelease(button); + } + } + + /** + * Moves the mouse pointer from one point to another. + * Uses Bresenham's algorithm. + * + * @param robot a robot to use for moving the mouse + * @param startPoint a start point of the drag + * @param endPoint an end point of the drag + */ + public static void mouseMove(Robot robot, Point startPoint, Point endPoint) { + int dx = endPoint.x - startPoint.x; + int dy = endPoint.y - startPoint.y; + + int ax = Math.abs(dx) * 2; + int ay = Math.abs(dy) * 2; + + int sx = signWOZero(dx); + int sy = signWOZero(dy); + + int x = startPoint.x; + int y = startPoint.y; + + int d = 0; + + if (ax > ay) { + d = ay - ax/2; + while (true){ + robot.mouseMove(x, y); + robot.delay(50); + + if (x == endPoint.x){ + return; + } + if (d >= 0){ + y = y + sy; + d = d - ax; + } + x = x + sx; + d = d + ay; + } + } else { + d = ax - ay/2; + while (true){ + robot.mouseMove(x, y); + robot.delay(50); + + if (y == endPoint.y){ + return; + } + if (d >= 0){ + x = x + sx; + d = d - ay; + } + y = y + sy; + d = d + ax; + } + } + } + + private static int signWOZero(int i){ + return (i > 0)? 1: -1; + } + + private static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } + + /** Returns {@code WindowListener} instance that diposes {@code Window} on + * "window closing" event. + * + * @return the {@code WindowListener} instance that could be set + * on a {@code Window}. After that + * the {@code Window} is disposed when "window closed" + * event is sent to the {@code Window} + */ + public static WindowListener getClosingWindowAdapter() { + return new WindowAdapter () { + public void windowClosing(WindowEvent e) { + e.getWindow().dispose(); + } + }; + } + + /* + * The values directly map to the ones of + * sun.awt.X11.XWM & sun.awt.motif.MToolkit classes. + */ + public final static int + UNDETERMINED_WM = 1, + NO_WM = 2, + OTHER_WM = 3, + OPENLOOK_WM = 4, + MOTIF_WM = 5, + CDE_WM = 6, + ENLIGHTEN_WM = 7, + KDE2_WM = 8, + SAWFISH_WM = 9, + ICE_WM = 10, + METACITY_WM = 11, + COMPIZ_WM = 12, + LG3D_WM = 13; + + /* + * Returns -1 in case of not X Window or any problems. + */ + public static int getWMID() { + Class clazz = null; + try { + if ("sun.awt.X11.XToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) { + clazz = Class.forName("sun.awt.X11.XWM"); + } else if ("sun.awt.motif.MToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) { + clazz = Class.forName("sun.awt.motif.MToolkit"); + } + } catch (ClassNotFoundException cnfe) { + cnfe.printStackTrace(); + } + if (clazz == null) { + return -1; + } + + try { + final Class _clazz = clazz; + Method m_getWMID = (Method)AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + try { + Method method = _clazz.getDeclaredMethod("getWMID", new Class[] {}); + if (method != null) { + method.setAccessible(true); + } + return method; + } catch (NoSuchMethodException e) { + assert false; + } catch (SecurityException e) { + assert false; + } + return null; + } + }); + return ((Integer)m_getWMID.invoke(null, new Object[] {})).intValue(); + } catch (IllegalAccessException iae) { + iae.printStackTrace(); + } catch (InvocationTargetException ite) { + ite.printStackTrace(); + } + return -1; + } + + + //////////////////////////// + // Some stuff to test focus. + //////////////////////////// + + private static WindowGainedFocusListener wgfListener = new WindowGainedFocusListener(); + private static FocusGainedListener fgListener = new FocusGainedListener(); + private static ActionPerformedListener apListener = new ActionPerformedListener(); + + private abstract static class EventListener { + AtomicBoolean notifier = new AtomicBoolean(false); + Component comp; + boolean printEvent; + + public void listen(Component comp, boolean printEvent) { + this.comp = comp; + this.printEvent = printEvent; + notifier.set(false); + setListener(comp); + } + + public AtomicBoolean getNotifier() { + return notifier; + } + + abstract void setListener(Component comp); + + void printAndNotify(AWTEvent e) { + if (printEvent) { + System.err.println(e); + } + synchronized (notifier) { + notifier.set(true); + notifier.notifyAll(); + } + } + } + + private static class WindowGainedFocusListener extends EventListener implements WindowFocusListener { + + void setListener(Component comp) { + ((Window)comp).addWindowFocusListener(this); + } + + public void windowGainedFocus(WindowEvent e) { + + ((Window)comp).removeWindowFocusListener(this); + printAndNotify(e); + } + + public void windowLostFocus(WindowEvent e) {} + } + + private static class FocusGainedListener extends EventListener implements FocusListener { + + void setListener(Component comp) { + comp.addFocusListener(this); + } + + public void focusGained(FocusEvent e) { + comp.removeFocusListener(this); + printAndNotify(e); + } + + public void focusLost(FocusEvent e) {} + } + + private static class ActionPerformedListener extends EventListener implements ActionListener { + + void setListener(Component comp) { + ((Button)comp).addActionListener(this); + } + + public void actionPerformed(ActionEvent e) { + ((Button)comp).removeActionListener(this); + printAndNotify(e); + } + } + + private static boolean trackEvent(int eventID, Component comp, Runnable action, int time, boolean printEvent) { + EventListener listener = null; + + switch (eventID) { + case WindowEvent.WINDOW_GAINED_FOCUS: + listener = wgfListener; + break; + case FocusEvent.FOCUS_GAINED: + listener = fgListener; + break; + case ActionEvent.ACTION_PERFORMED: + listener = apListener; + break; + } + + listener.listen(comp, printEvent); + action.run(); + return Util.waitForCondition(listener.getNotifier(), time); + } + + /* + * Tracks WINDOW_GAINED_FOCUS event for a window caused by an action. + * @param window the window to track the event for + * @param action the action to perform + * @param time the max time to wait for the event + * @param printEvent should the event received be printed or doesn't + * @return true if the event has been received, otherwise false + */ + public static boolean trackWindowGainedFocus(Window window, Runnable action, int time, boolean printEvent) { + return trackEvent(WindowEvent.WINDOW_GAINED_FOCUS, window, action, time, printEvent); + } + + /* + * Tracks FOCUS_GAINED event for a component caused by an action. + * @see #trackWindowGainedFocus + */ + public static boolean trackFocusGained(Component comp, Runnable action, int time, boolean printEvent) { + return trackEvent(FocusEvent.FOCUS_GAINED, comp, action, time, printEvent); + } + + /* + * Tracks ACTION_PERFORMED event for a button caused by an action. + * @see #trackWindowGainedFocus + */ + public static boolean trackActionPerformed(Button button, Runnable action, int time, boolean printEvent) { + return trackEvent(ActionEvent.ACTION_PERFORMED, button, action, time, printEvent); + } + + /* + * Requests focus on the component provided and waits for the result. + * @return true if the component has been focused, false otherwise. + */ + public static boolean focusComponent(Component comp, int time) { + return focusComponent(comp, time, false); + } + public static boolean focusComponent(final Component comp, int time, boolean printEvent) { + return trackFocusGained(comp, + new Runnable() { + public void run() { + comp.requestFocus(); + } + }, + time, printEvent); + + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/ViewportOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/ViewportOverlapping.java new file mode 100644 index 00000000000..22e1e7730cd --- /dev/null +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/ViewportOverlapping.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; + +/** + * AWT/Swing overlapping test for viewport + * <p>This test verify if AWT components are drawn correctly being partially shown through viewport + * <p>See <a href="http://monaco.sfbay.sun.com/detail.jsf?cr=6778882">CR6778882</a> for details + * <p>See base class for test info. + */ +/* +@test +@bug 6778882 +@summary Viewport overlapping test for each AWT component +@author sergey.grinev@oracle.com: area=awt.mixing +@run main ViewportOverlapping + */ +public class ViewportOverlapping extends OverlappingTestBase { + + private volatile int frameClicked; + private Point hLoc; + private Point vLoc; + private Point testLoc; + private Point resizeLoc; + + private JFrame f; + private JPanel p; + private JButton b; + private JScrollPane scrollPane; + + protected void prepareControls() { + p = new JPanel(new GridLayout(0, 1)); + propagateAWTControls(p); + b = new JButton("Space extender"); + p.add(b); + p.setPreferredSize(new Dimension(500, 500)); + scrollPane = new JScrollPane(p); + + f = new JFrame(); + f.addMouseListener(new MouseAdapter() { + + @Override + public void mouseClicked(MouseEvent e) { + frameClicked++; + } + }); + f.getContentPane().add(scrollPane, BorderLayout.CENTER); + ((JComponent) f.getContentPane()).setBorder( + BorderFactory.createEmptyBorder(50, 50, 50, 50)); + f.setSize(400, 400); + f.setLocationRelativeTo(null); + f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + f.setVisible(true); + } + + @Override + protected boolean performTest() { + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + // prepare test data + frameClicked = 0; + + b.requestFocus(); + + scrollPane.getHorizontalScrollBar().setUnitIncrement(40); + scrollPane.getVerticalScrollBar().setUnitIncrement(40); + + hLoc = scrollPane.getHorizontalScrollBar().getLocationOnScreen(); + hLoc.translate(scrollPane.getHorizontalScrollBar().getWidth() - 3, 3); + vLoc = scrollPane.getVerticalScrollBar().getLocationOnScreen(); + vLoc.translate(3, scrollPane.getVerticalScrollBar().getHeight() - 3); + + testLoc = p.getLocationOnScreen(); + testLoc.translate(-3, -3); + + resizeLoc = f.getLocationOnScreen(); + resizeLoc.translate(f.getWidth() - 1, f.getHeight() - 1); + } + }); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + // run robot + Robot robot = Util.createRobot(); + robot.setAutoDelay(ROBOT_DELAY); + + robot.mouseMove(hLoc.x, hLoc.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + Util.waitForIdle(robot); + + robot.mouseMove(vLoc.x, vLoc.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + Util.waitForIdle(robot); + + clickAndBlink(robot, testLoc, false); + robot.mouseMove(resizeLoc.x, resizeLoc.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseMove(resizeLoc.x + 5, resizeLoc.y + 5); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + Util.waitForIdle(robot); + + clickAndBlink(robot, testLoc, false); + return frameClicked == 2; + } + + // this strange plumbing stuff is required due to "Standard Test Machinery" in base class + public static void main(String args[]) throws InterruptedException { + instance = new ViewportOverlapping(); + OverlappingTestBase.doMain(args); + } +} From 536ad9409e3bd922738d629c9608400aec5da041 Mon Sep 17 00:00:00 2001 From: Omair Majid <omajid@openjdk.org> Date: Tue, 29 Apr 2014 15:46:16 -0400 Subject: [PATCH 031/157] 8042159: Allow using a system-installed lcms2 Reviewed-by: andrew, ihse, prr --- jdk/make/lib/Awt2dLibraries.gmk | 29 +++++++++++++++---- .../share/native/sun/java2d/cmm/lcms/LCMS.c | 2 +- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/jdk/make/lib/Awt2dLibraries.gmk b/jdk/make/lib/Awt2dLibraries.gmk index de86e3f86a4..6d1cf628c65 100644 --- a/jdk/make/lib/Awt2dLibraries.gmk +++ b/jdk/make/lib/Awt2dLibraries.gmk @@ -657,17 +657,34 @@ endif ########################################################################################## +LIBLCMS_DIR := $(JDK_TOPDIR)/src/share/native/sun/java2d/cmm/lcms + +ifeq ($(USE_EXTERNAL_LCMS), true) + # If we're using an external library, we'll just need the wrapper part. + # By including it explicitely, all other files will be excluded. + BUILD_LIBLCMS_INCLUDE_FILES := LCMS.c + BUILD_LIBLCMS_HEADERS := +else + BUILD_LIBLCMS_INCLUDE_FILES := + # If we're using the bundled library, we'll need to include it in the + # include path explicitly. Otherwise the system headers will be used. + BUILD_LIBLCMS_HEADERS := -I$(LIBLCMS_DIR) +endif + # TODO: Update awt lib path when awt is converted $(eval $(call SetupNativeCompilation,BUILD_LIBLCMS, \ LIBRARY := lcms, \ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/share/native/sun/java2d/cmm/lcms, \ + SRC := $(LIBLCMS_DIR), \ + INCLUDE_FILES := $(BUILD_LIBLCMS_INCLUDE_FILES), \ LANG := C, \ OPTIMIZATION := HIGHEST, \ CFLAGS := $(filter-out -xc99=%none, $(CFLAGS_JDKLIB)) \ $(SHARED_LIBRARY_FLAGS) \ -I$(JDK_TOPDIR)/src/share/native/sun/java2d \ - -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug, \ + -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \ + $(BUILD_LIBLCMS_HEADERS) \ + $(LCMS_CFLAGS), \ CFLAGS_solaris := -xc99=no_lib, \ CFLAGS_windows := -DCMS_IS_WINDOWS_, \ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/liblcms/mapfile-vers, \ @@ -675,10 +692,10 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBLCMS, \ $(call SET_SHARED_LIBRARY_ORIGIN), \ LDFLAGS_solaris := /usr/lib$(OPENJDK_TARGET_CPU_ISADIR)/libm.so.2, \ LDFLAGS_windows := $(WIN_AWT_LIB) $(WIN_JAVA_LIB), \ - LDFLAGS_SUFFIX_solaris := -lawt -ljava -ljvm -lc, \ - LDFLAGS_SUFFIX_macosx := $(LIBM) -lawt -ljava -ljvm, \ - LDFLAGS_SUFFIX_linux := -lm -lawt -ljava -ljvm, \ - LDFLAGS_SUFFIX_aix := -lm -lawt -ljava -ljvm,\ + LDFLAGS_SUFFIX_solaris := -lawt -ljava -ljvm -lc $(LCMS_LIBS), \ + LDFLAGS_SUFFIX_macosx := $(LIBM) -lawt -ljava -ljvm $(LCMS_LIBS), \ + LDFLAGS_SUFFIX_linux := -lm -lawt -ljava -ljvm $(LCMS_LIBS), \ + LDFLAGS_SUFFIX_aix := -lm -lawt -ljava -ljvm $(LCMS_LIBS),\ VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ RC_FLAGS := $(RC_FLAGS) \ -D "JDK_FNAME=lcms.dll" \ diff --git a/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c b/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c index 8e687de0cdf..0939b00a761 100644 --- a/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c @@ -30,7 +30,7 @@ #include "jni_util.h" #include "Trace.h" #include "Disposer.h" -#include "lcms2.h" +#include <lcms2.h> #include "jlong.h" From bb2698cfa6f2bdc92c197f17a7d2f90003db05fa Mon Sep 17 00:00:00 2001 From: Petr Pchelko <pchelko@openjdk.org> Date: Wed, 30 Apr 2014 12:41:38 +0400 Subject: [PATCH 032/157] 8042087: [macosx] LWCToolkit.inokeAndWait is calling EventQueue.invokeLater Reviewed-by: anthony, serb --- .../classes/sun/lwawt/macosx/LWCToolkit.java | 69 ++++++++----------- 1 file changed, 29 insertions(+), 40 deletions(-) diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java index 4a153fc94d4..d0b6882b9a3 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java @@ -611,19 +611,20 @@ public final class LWCToolkit extends LWToolkit { } /** - * Kicks an event over to the appropriate eventqueue and waits for it to + * Kicks an event over to the appropriate event queue and waits for it to * finish To avoid deadlocking, we manually run the NSRunLoop while waiting * Any selector invoked using ThreadUtilities performOnMainThread will be * processed in doAWTRunLoop The InvocationEvent will call * LWCToolkit.stopAWTRunLoop() when finished, which will stop our manual - * runloop Does not dispatch native events while in the loop + * run loop. Does not dispatch native events while in the loop */ public static void invokeAndWait(Runnable runnable, Component component) throws InvocationTargetException { - final long mediator = createAWTRunLoopMediator(); + Objects.requireNonNull(component, "Null component provided to invokeAndWait"); + long mediator = createAWTRunLoopMediator(); InvocationEvent invocationEvent = - new InvocationEvent(component != null ? component : Toolkit.getDefaultToolkit(), + new InvocationEvent(component, runnable, () -> { if (mediator != 0) { @@ -632,49 +633,42 @@ public final class LWCToolkit extends LWToolkit { }, true); - if (component != null) { - AppContext appContext = SunToolkit.targetToAppContext(component); - SunToolkit.postEvent(appContext, invocationEvent); - - // 3746956 - flush events from PostEventQueue to prevent them from getting stuck and causing a deadlock - SunToolkit.flushPendingEvents(appContext); - } else { - // This should be the equivalent to EventQueue.invokeAndWait - ((LWCToolkit)Toolkit.getDefaultToolkit()).getSystemEventQueueForInvokeAndWait().postEvent(invocationEvent); - } - + AppContext appContext = SunToolkit.targetToAppContext(component); + SunToolkit.postEvent(appContext, invocationEvent); + // 3746956 - flush events from PostEventQueue to prevent them from getting stuck and causing a deadlock + SunToolkit.flushPendingEvents(appContext); doAWTRunLoop(mediator, false); - Throwable eventException = invocationEvent.getException(); - if (eventException != null) { - if (eventException instanceof UndeclaredThrowableException) { - eventException = ((UndeclaredThrowableException)eventException).getUndeclaredThrowable(); - } - throw new InvocationTargetException(eventException); - } + checkException(invocationEvent); } public static void invokeLater(Runnable event, Component component) throws InvocationTargetException { - final InvocationEvent invocationEvent = - new InvocationEvent(component != null ? component : Toolkit.getDefaultToolkit(), event); + Objects.requireNonNull(component, "Null component provided to invokeLater"); - if (component != null) { - final AppContext appContext = SunToolkit.targetToAppContext(component); - SunToolkit.postEvent(appContext, invocationEvent); + InvocationEvent invocationEvent = new InvocationEvent(component, event); - // 3746956 - flush events from PostEventQueue to prevent them from getting stuck and causing a deadlock - SunToolkit.flushPendingEvents(appContext); - } else { - // This should be the equivalent to EventQueue.invokeAndWait - ((LWCToolkit)Toolkit.getDefaultToolkit()).getSystemEventQueueForInvokeAndWait().postEvent(invocationEvent); - } + AppContext appContext = SunToolkit.targetToAppContext(component); + SunToolkit.postEvent(SunToolkit.targetToAppContext(component), invocationEvent); + // 3746956 - flush events from PostEventQueue to prevent them from getting stuck and causing a deadlock + SunToolkit.flushPendingEvents(appContext); - final Throwable eventException = invocationEvent.getException(); + checkException(invocationEvent); + } + + /** + * Checks if exception occurred while {@code InvocationEvent} was processed and rethrows it as + * an {@code InvocationTargetException} + * + * @param event the event to check for an exception + * @throws InvocationTargetException if exception occurred when event was processed + */ + private static void checkException(InvocationEvent event) throws InvocationTargetException { + Throwable eventException = event.getException(); if (eventException == null) return; if (eventException instanceof UndeclaredThrowableException) { - throw new InvocationTargetException(((UndeclaredThrowableException)eventException).getUndeclaredThrowable()); + eventException = ((UndeclaredThrowableException)eventException).getUndeclaredThrowable(); } throw new InvocationTargetException(eventException); } @@ -686,11 +680,6 @@ public final class LWCToolkit extends LWToolkit { */ native static void performOnMainThreadAfterDelay(Runnable r, long delay); - // This exists purely to get around permissions issues with getSystemEventQueueImpl - EventQueue getSystemEventQueueForInvokeAndWait() { - return getSystemEventQueueImpl(); - } - // DnD support @Override From b8cc933de8e73c5737be9cbc7d71a3cd386d671f Mon Sep 17 00:00:00 2001 From: Volker Simonis <simonis@openjdk.org> Date: Wed, 30 Apr 2014 11:29:29 +0200 Subject: [PATCH 033/157] 8042090: Fix invalid variable names sun/java2d/loops/ProcessPath.c Reviewed-by: prr --- .../native/sun/java2d/loops/ProcessPath.c | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/jdk/src/share/native/sun/java2d/loops/ProcessPath.c b/jdk/src/share/native/sun/java2d/loops/ProcessPath.c index 52d8dddb3d3..07eb3468926 100644 --- a/jdk/src/share/native/sun/java2d/loops/ProcessPath.c +++ b/jdk/src/share/native/sun/java2d/loops/ProcessPath.c @@ -189,34 +189,34 @@ #define PROCESS_POINT(hnd, fX, fY, checkBounds, pixelInfo) \ do { \ - jint _X = (fX)>> MDP_PREC; \ - jint _Y = (fY)>> MDP_PREC; \ + jint X_ = (fX)>> MDP_PREC; \ + jint Y_ = (fY)>> MDP_PREC; \ if (checkBounds && \ - (hnd->dhnd->yMin > _Y || \ - hnd->dhnd->yMax <= _Y || \ - hnd->dhnd->xMin > _X || \ - hnd->dhnd->xMax <= _X)) break; \ + (hnd->dhnd->yMin > Y_ || \ + hnd->dhnd->yMax <= Y_ || \ + hnd->dhnd->xMin > X_ || \ + hnd->dhnd->xMax <= X_)) break; \ /* \ - * (_X,_Y) should be inside boundaries \ + * (X_,Y_) should be inside boundaries \ * \ - * assert(hnd->dhnd->yMin <= _Y && \ - * hnd->dhnd->yMax > _Y && \ - * hnd->dhnd->xMin <= _X && \ - * hnd->dhnd->xMax > _X); \ + * assert(hnd->dhnd->yMin <= Y_ && \ + * hnd->dhnd->yMax > Y_ && \ + * hnd->dhnd->xMin <= X_ && \ + * hnd->dhnd->xMax > X_); \ * \ */ \ if (pixelInfo[0] == 0) { \ pixelInfo[0] = 1; \ - pixelInfo[1] = _X; \ - pixelInfo[2] = _Y; \ - pixelInfo[3] = _X; \ - pixelInfo[4] = _Y; \ - hnd->dhnd->pDrawPixel(hnd->dhnd, _X, _Y); \ - } else if ((_X != pixelInfo[3] || _Y != pixelInfo[4]) && \ - (_X != pixelInfo[1] || _Y != pixelInfo[2])) { \ - hnd->dhnd->pDrawPixel(hnd->dhnd, _X, _Y); \ - pixelInfo[3] = _X; \ - pixelInfo[4] = _Y; \ + pixelInfo[1] = X_; \ + pixelInfo[2] = Y_; \ + pixelInfo[3] = X_; \ + pixelInfo[4] = Y_; \ + hnd->dhnd->pDrawPixel(hnd->dhnd, X_, Y_); \ + } else if ((X_ != pixelInfo[3] || Y_ != pixelInfo[4]) && \ + (X_ != pixelInfo[1] || Y_ != pixelInfo[2])) { \ + hnd->dhnd->pDrawPixel(hnd->dhnd, X_, Y_); \ + pixelInfo[3] = X_; \ + pixelInfo[4] = Y_; \ } \ } while(0) From e787680bf15e351d63cd8a3453f6e618f4980abf Mon Sep 17 00:00:00 2001 From: Sergey Malenkov <malenkov@openjdk.org> Date: Wed, 30 Apr 2014 19:28:05 +0400 Subject: [PATCH 034/157] 8041917: unexcepted behavior of LineBorder while using Boolean variable true Reviewed-by: alexsch, serb --- jdk/src/share/classes/javax/swing/border/LineBorder.java | 4 ++-- jdk/test/javax/swing/border/Test4252164.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/border/LineBorder.java b/jdk/src/share/classes/javax/swing/border/LineBorder.java index 1e083c1164f..f29a244d2e8 100644 --- a/jdk/src/share/classes/javax/swing/border/LineBorder.java +++ b/jdk/src/share/classes/javax/swing/border/LineBorder.java @@ -134,8 +134,8 @@ public class LineBorder extends AbstractBorder int offs = this.thickness; int size = offs + offs; if (this.roundedCorners) { - int arc = offs + size; - outer = new RoundRectangle2D.Float(x, y, width, height, arc, arc); + float arc = .2f * offs; + outer = new RoundRectangle2D.Float(x, y, width, height, offs, offs); inner = new RoundRectangle2D.Float(x + offs, y + offs, width - size, height - size, arc, arc); } else { diff --git a/jdk/test/javax/swing/border/Test4252164.java b/jdk/test/javax/swing/border/Test4252164.java index 007e732cf2a..923df715054 100644 --- a/jdk/test/javax/swing/border/Test4252164.java +++ b/jdk/test/javax/swing/border/Test4252164.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4252164 + * @bug 4252164 8041917 * @summary Tests rounded LineBorder for components * @author Sergey Malenkov * @run applet/manual=yesno Test4252164.html From 6289e6c7e82943fdf88071f41422e79b0353416e Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov <serb@openjdk.org> Date: Mon, 5 May 2014 19:42:11 +0400 Subject: [PATCH 035/157] 8042212: [macosx] Toolkit.getScreenResolution() can return incorrect resolution Reviewed-by: anthony, pchelko --- jdk/src/macosx/native/sun/awt/CGraphicsDevice.m | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m b/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m index e20792a231d..a1813b6154d 100644 --- a/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m +++ b/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -156,14 +156,12 @@ JNIEXPORT jdouble JNICALL Java_sun_awt_CGraphicsDevice_nativeGetXResolution (JNIEnv *env, jclass class, jint displayID) { - // TODO: this is the physically correct answer, but we probably want - // to use NSScreen API instead... + // CGDisplayScreenSize can return 0 if displayID is invalid CGSize size = CGDisplayScreenSize(displayID); CGRect rect = CGDisplayBounds(displayID); // 1 inch == 25.4 mm jfloat inches = size.width / 25.4f; - jfloat dpi = rect.size.width / inches; - return dpi; + return inches > 0 ? rect.size.width / inches : 72; } /* @@ -175,14 +173,12 @@ JNIEXPORT jdouble JNICALL Java_sun_awt_CGraphicsDevice_nativeGetYResolution (JNIEnv *env, jclass class, jint displayID) { - // TODO: this is the physically correct answer, but we probably want - // to use NSScreen API instead... + // CGDisplayScreenSize can return 0 if displayID is invalid CGSize size = CGDisplayScreenSize(displayID); CGRect rect = CGDisplayBounds(displayID); // 1 inch == 25.4 mm jfloat inches = size.height / 25.4f; - jfloat dpi = rect.size.height / inches; - return dpi; + return inches > 0 ? rect.size.height / inches : 72; } /* From ac82d17097982c45994c6ac3bf6c631669844bf6 Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Mon, 5 May 2014 09:41:41 -0700 Subject: [PATCH 036/157] 8038838: Totally remove all vestiges of com.sun.image.codec.jpeg from JDK 9 Reviewed-by: bae, vadim --- jdk/make/mapfiles/libjpeg/mapfile-vers-closed | 4 ---- 1 file changed, 4 deletions(-) diff --git a/jdk/make/mapfiles/libjpeg/mapfile-vers-closed b/jdk/make/mapfiles/libjpeg/mapfile-vers-closed index 9b3724c4994..6f84d2da352 100644 --- a/jdk/make/mapfiles/libjpeg/mapfile-vers-closed +++ b/jdk/make/mapfiles/libjpeg/mapfile-vers-closed @@ -31,10 +31,6 @@ SUNWprivate_1.1 { Java_sun_awt_image_JPEGImageDecoder_initIDs; Java_sun_awt_image_JPEGImageDecoder_readImage; - Java_sun_awt_image_codec_JPEGImageDecoderImpl_initDecoder; - Java_sun_awt_image_codec_JPEGImageDecoderImpl_readJPEGStream; - Java_sun_awt_image_codec_JPEGImageEncoderImpl_initEncoder; - Java_sun_awt_image_codec_JPEGImageEncoderImpl_writeJPEGStream; Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_initReaderIDs; Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_initJPEGImageReader; From 1a24f81c1bd5da50fe5b96aa7b052da4387664dd Mon Sep 17 00:00:00 2001 From: Joe Darcy <darcy@openjdk.org> Date: Mon, 5 May 2014 23:19:00 -0700 Subject: [PATCH 037/157] 8042256: Fix raw and unchecked lint warnings in com.sun.media.sound Reviewed-by: prr --- .../com/sun/media/sound/AbstractLine.java | 2 +- .../sun/media/sound/AbstractMidiDevice.java | 8 ++++--- .../com/sun/media/sound/AbstractMixer.java | 22 ++++++++++--------- .../com/sun/media/sound/AlawCodec.java | 4 ++-- .../sound/AudioSynthesizerPropertyInfo.java | 2 +- .../sun/media/sound/DirectAudioDevice.java | 10 ++++----- .../com/sun/media/sound/EventDispatcher.java | 8 +++---- .../com/sun/media/sound/JDK13Services.java | 6 ++--- .../sun/media/sound/MidiInDeviceProvider.java | 4 ++-- .../media/sound/MidiOutDeviceProvider.java | 4 ++-- .../com/sun/media/sound/MidiUtils.java | 6 ++--- .../com/sun/media/sound/PCMtoPCMCodec.java | 8 +++---- .../com/sun/media/sound/PortMixer.java | 5 +++-- .../sun/media/sound/RealTimeSequencer.java | 22 +++++++++---------- .../com/sun/media/sound/SoftSynthesizer.java | 2 +- .../com/sun/media/sound/UlawCodec.java | 4 ++-- 16 files changed, 61 insertions(+), 56 deletions(-) diff --git a/jdk/src/share/classes/com/sun/media/sound/AbstractLine.java b/jdk/src/share/classes/com/sun/media/sound/AbstractLine.java index e6a7ba2d9cb..1d0393d35eb 100644 --- a/jdk/src/share/classes/com/sun/media/sound/AbstractLine.java +++ b/jdk/src/share/classes/com/sun/media/sound/AbstractLine.java @@ -48,7 +48,7 @@ abstract class AbstractLine implements Line { protected Control[] controls; AbstractMixer mixer; private boolean open = false; - private final Vector listeners = new Vector(); + private final Vector<Object> listeners = new Vector<>(); /** * Contains event dispatcher per thread group. diff --git a/jdk/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java b/jdk/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java index 4323970cafa..93c3926aaed 100644 --- a/jdk/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java +++ b/jdk/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java @@ -70,7 +70,7 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice /** List of Receivers and Transmitters that opened the device implicitely. */ - private List openKeepingObjects; + private List<Object> openKeepingObjects; /** * This is the device handle returned from native code @@ -284,6 +284,7 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice } + @SuppressWarnings("unchecked") // Cast of result of clone public final List<Receiver> getReceivers() { List<Receiver> recs; synchronized (traRecLock) { @@ -313,6 +314,7 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice } + @SuppressWarnings("unchecked") // Cast of result of clone public final List<Transmitter> getTransmitters() { List<Transmitter> tras; synchronized (traRecLock) { @@ -372,9 +374,9 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice /** Return the list of objects that have opened the device implicitely. */ - private synchronized List getOpenKeepingObjects() { + private synchronized List<Object> getOpenKeepingObjects() { if (openKeepingObjects == null) { - openKeepingObjects = new ArrayList(); + openKeepingObjects = new ArrayList<>(); } return openKeepingObjects; } diff --git a/jdk/src/share/classes/com/sun/media/sound/AbstractMixer.java b/jdk/src/share/classes/com/sun/media/sound/AbstractMixer.java index 1055fc6859e..83378615b77 100644 --- a/jdk/src/share/classes/com/sun/media/sound/AbstractMixer.java +++ b/jdk/src/share/classes/com/sun/media/sound/AbstractMixer.java @@ -90,13 +90,13 @@ abstract class AbstractMixer extends AbstractLine implements Mixer { /** * Source lines (ports) currently open */ - private final Vector sourceLines = new Vector(); + private final Vector<Line> sourceLines = new Vector<>(); /** * Target lines currently open. */ - private final Vector targetLines = new Vector(); + private final Vector<Line> targetLines = new Vector<>(); /** @@ -151,7 +151,7 @@ abstract class AbstractMixer extends AbstractLine implements Mixer { public final Line.Info[] getSourceLineInfo(Line.Info info) { int i; - Vector vec = new Vector(); + Vector<Line.Info> vec = new Vector<>(); for (i = 0; i < sourceLineInfo.length; i++) { @@ -162,7 +162,7 @@ abstract class AbstractMixer extends AbstractLine implements Mixer { Line.Info[] returnedArray = new Line.Info[vec.size()]; for (i = 0; i < returnedArray.length; i++) { - returnedArray[i] = (Line.Info)vec.elementAt(i); + returnedArray[i] = vec.elementAt(i); } return returnedArray; @@ -172,7 +172,7 @@ abstract class AbstractMixer extends AbstractLine implements Mixer { public final Line.Info[] getTargetLineInfo(Line.Info info) { int i; - Vector vec = new Vector(); + Vector<Line.Info> vec = new Vector<>(); for (i = 0; i < targetLineInfo.length; i++) { @@ -183,7 +183,7 @@ abstract class AbstractMixer extends AbstractLine implements Mixer { Line.Info[] returnedArray = new Line.Info[vec.size()]; for (i = 0; i < returnedArray.length; i++) { - returnedArray[i] = (Line.Info)vec.elementAt(i); + returnedArray[i] = vec.elementAt(i); } return returnedArray; @@ -231,7 +231,7 @@ abstract class AbstractMixer extends AbstractLine implements Mixer { localLines = new Line[sourceLines.size()]; for (int i = 0; i < localLines.length; i++) { - localLines[i] = (Line)sourceLines.elementAt(i); + localLines[i] = sourceLines.elementAt(i); } } @@ -248,7 +248,7 @@ abstract class AbstractMixer extends AbstractLine implements Mixer { localLines = new Line[targetLines.size()]; for (int i = 0; i < localLines.length; i++) { - localLines[i] = (Line)targetLines.elementAt(i); + localLines[i] = targetLines.elementAt(i); } } @@ -453,7 +453,8 @@ abstract class AbstractMixer extends AbstractLine implements Mixer { return; } - Vector localSourceLines = (Vector)sourceLines.clone(); + @SuppressWarnings("unchecked") + Vector<Line> localSourceLines = (Vector<Line>)sourceLines.clone(); for (int i = 0; i < localSourceLines.size(); i++) { // if any other open line is running, return @@ -468,7 +469,8 @@ abstract class AbstractMixer extends AbstractLine implements Mixer { } } - Vector localTargetLines = (Vector)targetLines.clone(); + @SuppressWarnings("unchecked") + Vector<Line> localTargetLines = (Vector<Line>)targetLines.clone(); for (int i = 0; i < localTargetLines.size(); i++) { // if any other open line is running, return diff --git a/jdk/src/share/classes/com/sun/media/sound/AlawCodec.java b/jdk/src/share/classes/com/sun/media/sound/AlawCodec.java index 367f318b06a..fbe63f6ff16 100644 --- a/jdk/src/share/classes/com/sun/media/sound/AlawCodec.java +++ b/jdk/src/share/classes/com/sun/media/sound/AlawCodec.java @@ -213,7 +213,7 @@ public final class AlawCodec extends SunCodec { private AudioFormat[] getOutputFormats(AudioFormat inputFormat) { - Vector formats = new Vector(); + Vector<AudioFormat> formats = new Vector<>(); AudioFormat format; if ( AudioFormat.Encoding.PCM_SIGNED.equals(inputFormat.getEncoding())) { @@ -248,7 +248,7 @@ public final class AlawCodec extends SunCodec { AudioFormat[] formatArray = new AudioFormat[formats.size()]; for (int i = 0; i < formatArray.length; i++) { - formatArray[i] = (AudioFormat)(formats.elementAt(i)); + formatArray[i] = formats.elementAt(i); } return formatArray; } diff --git a/jdk/src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java b/jdk/src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java index d4305523526..16bfaa20790 100644 --- a/jdk/src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java +++ b/jdk/src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java @@ -68,7 +68,7 @@ public final class AudioSynthesizerPropertyInfo { * The <code>valueClass</code> field specifies class * used in <code>value</code> field. */ - public Class valueClass = null; + public Class<?> valueClass = null; /** * An array of possible values if the value for the field * <code>AudioSynthesizerPropertyInfo.value</code> may be selected diff --git a/jdk/src/share/classes/com/sun/media/sound/DirectAudioDevice.java b/jdk/src/share/classes/com/sun/media/sound/DirectAudioDevice.java index 7c938bbb1c4..becf4981ba7 100644 --- a/jdk/src/share/classes/com/sun/media/sound/DirectAudioDevice.java +++ b/jdk/src/share/classes/com/sun/media/sound/DirectAudioDevice.java @@ -94,7 +94,7 @@ final class DirectAudioDevice extends AbstractMixer { } private DirectDLI createDataLineInfo(boolean isSource) { - Vector formats = new Vector(); + Vector<AudioFormat> formats = new Vector<>(); AudioFormat[] hardwareFormatArray = null; AudioFormat[] formatArray = null; @@ -107,7 +107,7 @@ final class DirectAudioDevice extends AbstractMixer { int formatArraySize = size; hardwareFormatArray = new AudioFormat[size]; for (int i = 0; i < size; i++) { - AudioFormat format = (AudioFormat)formats.elementAt(i); + AudioFormat format = formats.elementAt(i); hardwareFormatArray[i] = format; int bits = format.getSampleSizeInBits(); boolean isSigned = format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED); @@ -265,7 +265,7 @@ final class DirectAudioDevice extends AbstractMixer { return ((DirectAudioDeviceProvider.DirectAudioDeviceInfo) getMixerInfo()).getMaxSimulLines(); } - private static void addFormat(Vector v, int bits, int frameSizeInBytes, int channels, float sampleRate, + private static void addFormat(Vector<AudioFormat> v, int bits, int frameSizeInBytes, int channels, float sampleRate, int encoding, boolean signed, boolean bigEndian) { AudioFormat.Encoding enc = null; switch (encoding) { @@ -338,7 +338,7 @@ final class DirectAudioDevice extends AbstractMixer { private static final class DirectDLI extends DataLine.Info { final AudioFormat[] hardwareFormats; - private DirectDLI(Class clazz, AudioFormat[] formatArray, + private DirectDLI(Class<?> clazz, AudioFormat[] formatArray, AudioFormat[] hardwareFormatArray, int minBuffer, int maxBuffer) { super(clazz, formatArray, minBuffer, maxBuffer); @@ -1457,7 +1457,7 @@ final class DirectAudioDevice extends AbstractMixer { } // class DirectBAOS - + @SuppressWarnings("rawtypes") private static native void nGetFormats(int mixerIndex, int deviceID, boolean isSource, Vector formats); diff --git a/jdk/src/share/classes/com/sun/media/sound/EventDispatcher.java b/jdk/src/share/classes/com/sun/media/sound/EventDispatcher.java index 54b948af168..49709891bd0 100644 --- a/jdk/src/share/classes/com/sun/media/sound/EventDispatcher.java +++ b/jdk/src/share/classes/com/sun/media/sound/EventDispatcher.java @@ -57,7 +57,7 @@ final class EventDispatcher implements Runnable { /** * List of events */ - private final ArrayList eventQueue = new ArrayList(); + private final ArrayList<EventInfo> eventQueue = new ArrayList<>(); /** @@ -186,7 +186,7 @@ final class EventDispatcher implements Runnable { } if (eventQueue.size() > 0) { // Remove the event from the queue and dispatch it to the listeners. - eventInfo = (EventInfo) eventQueue.remove(0); + eventInfo = eventQueue.remove(0); } } // end of synchronized @@ -230,7 +230,7 @@ final class EventDispatcher implements Runnable { /** * Send audio and MIDI events. */ - void sendAudioEvents(Object event, List listeners) { + void sendAudioEvents(Object event, List<Object> listeners) { if ((listeners == null) || (listeners.size() == 0)) { // nothing to do @@ -392,7 +392,7 @@ final class EventDispatcher implements Runnable { * @param event the event to be dispatched * @param listeners listener list; will be copied */ - EventInfo(Object event, List listeners) { + EventInfo(Object event, List<Object> listeners) { this.event = event; this.listeners = listeners.toArray(); } diff --git a/jdk/src/share/classes/com/sun/media/sound/JDK13Services.java b/jdk/src/share/classes/com/sun/media/sound/JDK13Services.java index 9f19a8734e3..9c93d06dc23 100644 --- a/jdk/src/share/classes/com/sun/media/sound/JDK13Services.java +++ b/jdk/src/share/classes/com/sun/media/sound/JDK13Services.java @@ -118,7 +118,7 @@ public final class JDK13Services { (the part before the hash sign), if available. If the property is not set or the value has no provider class name part, null is returned. */ - public static synchronized String getDefaultProviderClassName(Class typeClass) { + public static synchronized String getDefaultProviderClassName(Class<?> typeClass) { String value = null; String defaultProviderSpec = getDefaultProvider(typeClass); if (defaultProviderSpec != null) { @@ -144,7 +144,7 @@ public final class JDK13Services { part after the hash sign), if available. If the property is not set or the value has no instance name part, null is returned. */ - public static synchronized String getDefaultInstanceName(Class typeClass) { + public static synchronized String getDefaultInstanceName(Class<?> typeClass) { String value = null; String defaultProviderSpec = getDefaultProvider(typeClass); if (defaultProviderSpec != null) { @@ -165,7 +165,7 @@ public final class JDK13Services { @return The complete value of the property, if available. If the property is not set, null is returned. */ - private static synchronized String getDefaultProvider(Class typeClass) { + private static synchronized String getDefaultProvider(Class<?> typeClass) { if (!SourceDataLine.class.equals(typeClass) && !TargetDataLine.class.equals(typeClass) && !Clip.class.equals(typeClass) diff --git a/jdk/src/share/classes/com/sun/media/sound/MidiInDeviceProvider.java b/jdk/src/share/classes/com/sun/media/sound/MidiInDeviceProvider.java index 1f397724e3f..5044dfeaa17 100644 --- a/jdk/src/share/classes/com/sun/media/sound/MidiInDeviceProvider.java +++ b/jdk/src/share/classes/com/sun/media/sound/MidiInDeviceProvider.java @@ -106,9 +106,9 @@ public final class MidiInDeviceProvider extends AbstractMidiDeviceProvider { * the new instance will not reflect that state... */ static final class MidiInDeviceInfo extends AbstractMidiDeviceProvider.Info { - private final Class providerClass; + private final Class<?> providerClass; - private MidiInDeviceInfo(int index, Class providerClass) { + private MidiInDeviceInfo(int index, Class<?> providerClass) { super(nGetName(index), nGetVendor(index), nGetDescription(index), nGetVersion(index), index); this.providerClass = providerClass; } diff --git a/jdk/src/share/classes/com/sun/media/sound/MidiOutDeviceProvider.java b/jdk/src/share/classes/com/sun/media/sound/MidiOutDeviceProvider.java index 75583ab1e65..eaacf0991be 100644 --- a/jdk/src/share/classes/com/sun/media/sound/MidiOutDeviceProvider.java +++ b/jdk/src/share/classes/com/sun/media/sound/MidiOutDeviceProvider.java @@ -104,9 +104,9 @@ public final class MidiOutDeviceProvider extends AbstractMidiDeviceProvider { * the new instance will not reflect that state... */ static final class MidiOutDeviceInfo extends AbstractMidiDeviceProvider.Info { - private final Class providerClass; + private final Class<?> providerClass; - private MidiOutDeviceInfo(int index, Class providerClass) { + private MidiOutDeviceInfo(int index, Class<?> providerClass) { super(nGetName(index), nGetVendor(index), nGetDescription(index), nGetVersion(index), index); this.providerClass = providerClass; } diff --git a/jdk/src/share/classes/com/sun/media/sound/MidiUtils.java b/jdk/src/share/classes/com/sun/media/sound/MidiUtils.java index a3f62efd29e..eecd33fe0b5 100644 --- a/jdk/src/share/classes/com/sun/media/sound/MidiUtils.java +++ b/jdk/src/share/classes/com/sun/media/sound/MidiUtils.java @@ -295,7 +295,7 @@ public final class MidiUtils { public synchronized void refresh(Sequence seq) { - ArrayList list = new ArrayList(); + ArrayList<MidiEvent> list = new ArrayList<>(); Track[] tracks = seq.getTracks(); if (tracks.length > 0) { // tempo events only occur in track 0 @@ -313,7 +313,7 @@ public final class MidiUtils { int size = list.size() + 1; firstTempoIsFake = true; if ((size > 1) - && (((MidiEvent) list.get(0)).getTick() == 0)) { + && (list.get(0).getTick() == 0)) { // do not need to add an initial tempo event at the beginning size--; firstTempoIsFake = false; @@ -328,7 +328,7 @@ public final class MidiUtils { e++; } for (int i = 0; i < list.size(); i++, e++) { - MidiEvent evt = (MidiEvent) list.get(i); + MidiEvent evt = list.get(i); ticks[e] = evt.getTick(); tempos[e] = getTempoMPQ(evt.getMessage()); } diff --git a/jdk/src/share/classes/com/sun/media/sound/PCMtoPCMCodec.java b/jdk/src/share/classes/com/sun/media/sound/PCMtoPCMCodec.java index 9a4f1a874b3..dbed920e6fa 100644 --- a/jdk/src/share/classes/com/sun/media/sound/PCMtoPCMCodec.java +++ b/jdk/src/share/classes/com/sun/media/sound/PCMtoPCMCodec.java @@ -91,7 +91,7 @@ public final class PCMtoPCMCodec extends SunCodec { // filter out targetEncoding from the old getOutputFormats( sourceFormat ) method AudioFormat[] formats = getOutputFormats( sourceFormat ); - Vector newFormats = new Vector(); + Vector<AudioFormat> newFormats = new Vector<>(); for(int i=0; i<formats.length; i++ ) { if( formats[i].getEncoding().equals( targetEncoding ) ) { newFormats.addElement( formats[i] ); @@ -101,7 +101,7 @@ public final class PCMtoPCMCodec extends SunCodec { AudioFormat[] formatArray = new AudioFormat[newFormats.size()]; for (int i = 0; i < formatArray.length; i++) { - formatArray[i] = (AudioFormat)(newFormats.elementAt(i)); + formatArray[i] = newFormats.elementAt(i); } return formatArray; @@ -181,7 +181,7 @@ public final class PCMtoPCMCodec extends SunCodec { /* public AudioFormat[] getOutputFormats(AudioFormat inputFormat) { */ private AudioFormat[] getOutputFormats(AudioFormat inputFormat) { - Vector formats = new Vector(); + Vector<AudioFormat> formats = new Vector<>(); AudioFormat format; int sampleSize = inputFormat.getSampleSizeInBits(); @@ -335,7 +335,7 @@ public final class PCMtoPCMCodec extends SunCodec { for (int i = 0; i < formatArray.length; i++) { - formatArray[i] = (AudioFormat)(formats.elementAt(i)); + formatArray[i] = formats.elementAt(i); } } diff --git a/jdk/src/share/classes/com/sun/media/sound/PortMixer.java b/jdk/src/share/classes/com/sun/media/sound/PortMixer.java index 705648004ff..ee0fbd064ae 100644 --- a/jdk/src/share/classes/com/sun/media/sound/PortMixer.java +++ b/jdk/src/share/classes/com/sun/media/sound/PortMixer.java @@ -253,12 +253,12 @@ final class PortMixer extends AbstractMixer { long newID = ((PortMixer) mixer).getID(); if ((id == 0) || (newID != id) || (controls.length == 0)) { id = newID; - Vector vector = new Vector(); + Vector<Control> vector = new Vector<>(); synchronized (vector) { nGetControls(id, portIndex, vector); controls = new Control[vector.size()]; for (int i = 0; i < controls.length; i++) { - controls[i] = (Control) vector.elementAt(i); + controls[i] = vector.elementAt(i); } } } else { @@ -494,6 +494,7 @@ final class PortMixer extends AbstractMixer { private static native String nGetPortName(long id, int portIndex); // fills the vector with the controls for this port + @SuppressWarnings("rawtypes") private static native void nGetControls(long id, int portIndex, Vector vector); // getters/setters for controls diff --git a/jdk/src/share/classes/com/sun/media/sound/RealTimeSequencer.java b/jdk/src/share/classes/com/sun/media/sound/RealTimeSequencer.java index 6ea2ec4b3c6..7252723e776 100644 --- a/jdk/src/share/classes/com/sun/media/sound/RealTimeSequencer.java +++ b/jdk/src/share/classes/com/sun/media/sound/RealTimeSequencer.java @@ -122,7 +122,7 @@ final class RealTimeSequencer extends AbstractMidiDevice /** * List of tracks to which we're recording */ - private final List recordingTracks = new ArrayList(); + private final List<RecordingTrack> recordingTracks = new ArrayList<>(); private long loopStart = 0; @@ -133,13 +133,13 @@ final class RealTimeSequencer extends AbstractMidiDevice /** * Meta event listeners */ - private final ArrayList metaEventListeners = new ArrayList(); + private final ArrayList<Object> metaEventListeners = new ArrayList<>(); /** * Control change listeners */ - private final ArrayList controllerEventListeners = new ArrayList(); + private final ArrayList<ControllerListElement> controllerEventListeners = new ArrayList<>(); /** automatic connection support */ @@ -645,7 +645,7 @@ final class RealTimeSequencer extends AbstractMidiDevice boolean flag = false; for(int i=0; i < controllerEventListeners.size(); i++) { - cve = (ControllerListElement) controllerEventListeners.get(i); + cve = controllerEventListeners.get(i); if (cve.listener.equals(listener)) { cve.addControllers(controllers); @@ -669,7 +669,7 @@ final class RealTimeSequencer extends AbstractMidiDevice ControllerListElement cve = null; boolean flag = false; for (int i=0; i < controllerEventListeners.size(); i++) { - cve = (ControllerListElement) controllerEventListeners.get(i); + cve = controllerEventListeners.get(i); if (cve.listener.equals(listener)) { cve.removeControllers(controllers); flag = true; @@ -940,9 +940,9 @@ final class RealTimeSequencer extends AbstractMidiDevice } ShortMessage msg = (ShortMessage) message; int controller = msg.getData1(); - List sendToListeners = new ArrayList(); + List<Object> sendToListeners = new ArrayList<>(); for (int i = 0; i < size; i++) { - ControllerListElement cve = (ControllerListElement) controllerEventListeners.get(i); + ControllerListElement cve = controllerEventListeners.get(i); for(int j = 0; j < cve.controllers.length; j++) { if (cve.controllers[j] == controller) { sendToListeners.add(cve.listener); @@ -1213,13 +1213,13 @@ final class RealTimeSequencer extends AbstractMidiDevice this.channel = channel; } - static RecordingTrack get(List recordingTracks, Track track) { + static RecordingTrack get(List<RecordingTrack> recordingTracks, Track track) { synchronized(recordingTracks) { int size = recordingTracks.size(); for (int i = 0; i < size; i++) { - RecordingTrack current = (RecordingTrack)recordingTracks.get(i); + RecordingTrack current = recordingTracks.get(i); if (current.track == track) { return current; } @@ -1228,12 +1228,12 @@ final class RealTimeSequencer extends AbstractMidiDevice return null; } - static Track get(List recordingTracks, int channel) { + static Track get(List<RecordingTrack> recordingTracks, int channel) { synchronized(recordingTracks) { int size = recordingTracks.size(); for (int i = 0; i < size; i++) { - RecordingTrack current = (RecordingTrack)recordingTracks.get(i); + RecordingTrack current = recordingTracks.get(i); if ((current.channel == channel) || (current.channel == -1)) { return current.track; } diff --git a/jdk/src/share/classes/com/sun/media/sound/SoftSynthesizer.java b/jdk/src/share/classes/com/sun/media/sound/SoftSynthesizer.java index 01a64c2dddf..2c6dff99fea 100644 --- a/jdk/src/share/classes/com/sun/media/sound/SoftSynthesizer.java +++ b/jdk/src/share/classes/com/sun/media/sound/SoftSynthesizer.java @@ -949,7 +949,7 @@ public final class SoftSynthesizer implements AudioSynthesizer, Object v = (info == null) ? null : info.get(item2.name); v = (v != null) ? v : storedProperties.getProperty(item2.name); if (v != null) { - Class c = (item2.valueClass); + Class<?> c = (item2.valueClass); if (c.isInstance(v)) item2.value = v; else if (v instanceof String) { diff --git a/jdk/src/share/classes/com/sun/media/sound/UlawCodec.java b/jdk/src/share/classes/com/sun/media/sound/UlawCodec.java index 7dda283a0da..337fe199788 100644 --- a/jdk/src/share/classes/com/sun/media/sound/UlawCodec.java +++ b/jdk/src/share/classes/com/sun/media/sound/UlawCodec.java @@ -198,7 +198,7 @@ public final class UlawCodec extends SunCodec { /* public AudioFormat[] getOutputFormats(AudioFormat inputFormat) { */ private AudioFormat[] getOutputFormats(AudioFormat inputFormat) { - Vector formats = new Vector(); + Vector<AudioFormat> formats = new Vector<>(); AudioFormat format; if ((inputFormat.getSampleSizeInBits() == 16) @@ -235,7 +235,7 @@ public final class UlawCodec extends SunCodec { AudioFormat[] formatArray = new AudioFormat[formats.size()]; for (int i = 0; i < formatArray.length; i++) { - formatArray[i] = (AudioFormat)(formats.elementAt(i)); + formatArray[i] = formats.elementAt(i); } return formatArray; } From 860e8d8ac711723a2c48893a3719144466532ec9 Mon Sep 17 00:00:00 2001 From: Joe Darcy <darcy@openjdk.org> Date: Mon, 5 May 2014 23:38:30 -0700 Subject: [PATCH 038/157] 8039109: Fix unchecked and raw lint warnings in java.awt Reviewed-by: pchelko, forax, flar, prr --- .../share/classes/java/awt/AWTKeyStroke.java | 15 ++++--- .../share/classes/java/awt/CardLayout.java | 1 + jdk/src/share/classes/java/awt/Component.java | 2 +- .../classes/java/awt/GraphicsEnvironment.java | 10 ++--- .../java/awt/KeyboardFocusManager.java | 14 ++++--- .../share/classes/java/awt/SystemTray.java | 6 ++- .../datatransfer/MimeTypeParameterList.java | 4 +- .../java/awt/dnd/DragGestureEvent.java | 3 +- jdk/src/share/classes/java/awt/geom/Area.java | 42 +++++++++---------- .../classes/java/awt/image/BufferedImage.java | 6 +-- .../java/awt/image/CropImageFilter.java | 3 +- .../java/awt/image/FilteredImageSource.java | 14 +++---- .../classes/java/awt/image/ImageFilter.java | 3 +- .../java/awt/image/MemoryImageSource.java | 22 +++++----- .../java/awt/image/ReplicateScaleFilter.java | 3 +- .../awt/image/renderable/ParameterBlock.java | 13 +++--- .../image/renderable/RenderableImageOp.java | 14 +++---- .../renderable/RenderableImageProducer.java | 12 +++--- .../share/classes/java/awt/print/Book.java | 8 ++-- .../classes/java/awt/print/PrinterJob.java | 8 ++-- 20 files changed, 109 insertions(+), 94 deletions(-) diff --git a/jdk/src/share/classes/java/awt/AWTKeyStroke.java b/jdk/src/share/classes/java/awt/AWTKeyStroke.java index c4e07b45530..4be729b8c89 100644 --- a/jdk/src/share/classes/java/awt/AWTKeyStroke.java +++ b/jdk/src/share/classes/java/awt/AWTKeyStroke.java @@ -86,7 +86,8 @@ public class AWTKeyStroke implements Serializable { * Must be called under locked AWTKeyStro */ private static Class<AWTKeyStroke> getAWTKeyStrokeClass() { - Class<AWTKeyStroke> clazz = (Class)AppContext.getAppContext().get(AWTKeyStroke.class); + @SuppressWarnings("unchecked") + Class<AWTKeyStroke> clazz = (Class<AWTKeyStroke>)AppContext.getAppContext().get(AWTKeyStroke.class); if (clazz == null) { clazz = AWTKeyStroke.class; AppContext.getAppContext().put(AWTKeyStroke.class, AWTKeyStroke.class); @@ -182,6 +183,7 @@ public class AWTKeyStroke implements Serializable { throw new IllegalArgumentException("subclass cannot be null"); } synchronized (AWTKeyStroke.class) { + @SuppressWarnings("unchecked") Class<AWTKeyStroke> keyStrokeClass = (Class)AppContext.getAppContext().get(AWTKeyStroke.class); if (keyStrokeClass != null && keyStrokeClass.equals(subclass)){ // Already registered @@ -192,7 +194,7 @@ public class AWTKeyStroke implements Serializable { throw new ClassCastException("subclass is not derived from AWTKeyStroke"); } - Constructor ctor = getCtor(subclass); + Constructor<?> ctor = getCtor(subclass); String couldNotInstantiate = "subclass could not be instantiated"; @@ -227,12 +229,12 @@ public class AWTKeyStroke implements Serializable { threat as accessible flag is set only for this Constructor object, not for Class constructor. */ - private static Constructor getCtor(final Class clazz) + private static Constructor<?> getCtor(final Class<?> clazz) { - Constructor ctor = AccessController.doPrivileged(new PrivilegedAction<Constructor>() { - public Constructor run() { + Constructor<?> ctor = AccessController.doPrivileged(new PrivilegedAction<Constructor<?>>() { + public Constructor<?> run() { try { - Constructor ctor = clazz.getDeclaredConstructor((Class[]) null); + Constructor<?> ctor = clazz.getDeclaredConstructor((Class<?>[]) null); if (ctor != null) { ctor.setAccessible(true); } @@ -249,6 +251,7 @@ public class AWTKeyStroke implements Serializable { private static synchronized AWTKeyStroke getCachedStroke (char keyChar, int keyCode, int modifiers, boolean onKeyRelease) { + @SuppressWarnings("unchecked") Map<AWTKeyStroke, AWTKeyStroke> cache = (Map)AppContext.getAppContext().get(APP_CONTEXT_CACHE_KEY); AWTKeyStroke cacheKey = (AWTKeyStroke)AppContext.getAppContext().get(APP_CONTEXT_KEYSTROKE_KEY); diff --git a/jdk/src/share/classes/java/awt/CardLayout.java b/jdk/src/share/classes/java/awt/CardLayout.java index 3ffb19fbee7..5e813fffbe9 100644 --- a/jdk/src/share/classes/java/awt/CardLayout.java +++ b/jdk/src/share/classes/java/awt/CardLayout.java @@ -560,6 +560,7 @@ public class CardLayout implements LayoutManager2, /** * Reads serializable fields from stream. */ + @SuppressWarnings("unchecked") private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException { diff --git a/jdk/src/share/classes/java/awt/Component.java b/jdk/src/share/classes/java/awt/Component.java index a7573c09a3c..cd6ae69de1d 100644 --- a/jdk/src/share/classes/java/awt/Component.java +++ b/jdk/src/share/classes/java/awt/Component.java @@ -6184,7 +6184,7 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * Parameter types of coalesceEvents(AWTEvent,AWTEVent). */ - private static final Class[] coalesceEventsParams = { + private static final Class<?>[] coalesceEventsParams = { AWTEvent.class, AWTEvent.class }; diff --git a/jdk/src/share/classes/java/awt/GraphicsEnvironment.java b/jdk/src/share/classes/java/awt/GraphicsEnvironment.java index 66ab39a45b1..e9e9080dba6 100644 --- a/jdk/src/share/classes/java/awt/GraphicsEnvironment.java +++ b/jdk/src/share/classes/java/awt/GraphicsEnvironment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -95,18 +95,18 @@ public abstract class GraphicsEnvironment { String nm = AccessController.doPrivileged(new GetPropertyAction("java.awt.graphicsenv", null)); try { // long t0 = System.currentTimeMillis(); - Class<GraphicsEnvironment> geCls; + Class<?> geCls; try { // First we try if the bootclassloader finds the requested // class. This way we can avoid to run in a privileged block. - geCls = (Class<GraphicsEnvironment>)Class.forName(nm); + geCls = Class.forName(nm); } catch (ClassNotFoundException ex) { // If the bootclassloader fails, we try again with the // application classloader. ClassLoader cl = ClassLoader.getSystemClassLoader(); - geCls = (Class<GraphicsEnvironment>)Class.forName(nm, true, cl); + geCls = Class.forName(nm, true, cl); } - ge = geCls.newInstance(); + ge = (GraphicsEnvironment)geCls.newInstance(); // long t1 = System.currentTimeMillis(); // System.out.println("GE creation took " + (t1-t0)+ "ms."); if (isHeadless()) { diff --git a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java index b02bb5b0dba..8758a2b50e3 100644 --- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java +++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java @@ -348,6 +348,7 @@ public abstract class KeyboardFocusManager * Component of those Windows that has no such array of its own explicitly * set. */ + @SuppressWarnings({"unchecked", "rawtypes"}) private Set<AWTKeyStroke>[] defaultFocusTraversalKeys = new Set[4]; /** @@ -422,7 +423,7 @@ public abstract class KeyboardFocusManager targetSet.add(AWTKeyStroke.getAWTKeyStroke(tokens.nextToken())); } return (targetSet.isEmpty()) - ? Collections.EMPTY_SET + ? Collections.emptySet() : Collections.unmodifiableSet(targetSet); } @@ -436,7 +437,7 @@ public abstract class KeyboardFocusManager work_set.add(defaultFocusTraversalKeyStrokes[i][j]); } defaultFocusTraversalKeys[i] = (work_set.isEmpty()) - ? Collections.EMPTY_SET + ? Collections.emptySet() : Collections.unmodifiableSet(work_set); } initPeer(); @@ -1750,11 +1751,12 @@ public abstract class KeyboardFocusManager * @see #addKeyEventDispatcher * @see #removeKeyEventDispatcher */ + @SuppressWarnings("unchecked") // Cast of result of clone protected synchronized java.util.List<KeyEventDispatcher> getKeyEventDispatchers() { return (keyEventDispatchers != null) - ? (java.util.List)keyEventDispatchers.clone() + ? (java.util.List<KeyEventDispatcher>)keyEventDispatchers.clone() : null; } @@ -1841,11 +1843,12 @@ public abstract class KeyboardFocusManager * @see #addKeyEventPostProcessor * @see #removeKeyEventPostProcessor */ + @SuppressWarnings("unchecked") // Cast of result of clone protected java.util.List<KeyEventPostProcessor> getKeyEventPostProcessors() { return (keyEventPostProcessors != null) - ? (java.util.List)keyEventPostProcessors.clone() + ? (java.util.List<KeyEventPostProcessor>)keyEventPostProcessors.clone() : null; } @@ -1907,8 +1910,7 @@ public abstract class KeyboardFocusManager * javax.swing.JComponent.runInputVerifier() using reflection. */ static synchronized Component getMostRecentFocusOwner(Window window) { - WeakReference<Component> weakValue = - (WeakReference)mostRecentFocusOwners.get(window); + WeakReference<Component> weakValue = mostRecentFocusOwners.get(window); return weakValue == null ? null : weakValue.get(); } diff --git a/jdk/src/share/classes/java/awt/SystemTray.java b/jdk/src/share/classes/java/awt/SystemTray.java index 7f3a5c31893..e542dfc1712 100644 --- a/jdk/src/share/classes/java/awt/SystemTray.java +++ b/jdk/src/share/classes/java/awt/SystemTray.java @@ -259,7 +259,9 @@ public class SystemTray { Vector<TrayIcon> icons = null; synchronized (this) { oldArray = systemTray.getTrayIcons(); - icons = (Vector<TrayIcon>)AppContext.getAppContext().get(TrayIcon.class); + @SuppressWarnings("unchecked") + Vector<TrayIcon> tmp = (Vector<TrayIcon>)AppContext.getAppContext().get(TrayIcon.class); + icons = tmp; if (icons == null) { icons = new Vector<TrayIcon>(3); AppContext.getAppContext().put(TrayIcon.class, icons); @@ -304,6 +306,7 @@ public class SystemTray { TrayIcon[] oldArray = null, newArray = null; synchronized (this) { oldArray = systemTray.getTrayIcons(); + @SuppressWarnings("unchecked") Vector<TrayIcon> icons = (Vector<TrayIcon>)AppContext.getAppContext().get(TrayIcon.class); // TrayIcon with no peer is not contained in the array. if (icons == null || !icons.remove(trayIcon)) { @@ -335,6 +338,7 @@ public class SystemTray { * @see TrayIcon */ public TrayIcon[] getTrayIcons() { + @SuppressWarnings("unchecked") Vector<TrayIcon> icons = (Vector<TrayIcon>)AppContext.getAppContext().get(TrayIcon.class); if (icons != null) { return icons.toArray(new TrayIcon[icons.size()]); diff --git a/jdk/src/share/classes/java/awt/datatransfer/MimeTypeParameterList.java b/jdk/src/share/classes/java/awt/datatransfer/MimeTypeParameterList.java index f4816b65d87..3a79886c2b4 100644 --- a/jdk/src/share/classes/java/awt/datatransfer/MimeTypeParameterList.java +++ b/jdk/src/share/classes/java/awt/datatransfer/MimeTypeParameterList.java @@ -296,14 +296,14 @@ class MimeTypeParameterList implements Cloneable { /** * @return a clone of this object */ - + @SuppressWarnings("unchecked") // Cast from clone public Object clone() { MimeTypeParameterList newObj = null; try { newObj = (MimeTypeParameterList)super.clone(); } catch (CloneNotSupportedException cannotHappen) { } - newObj.parameters = (Hashtable)parameters.clone(); + newObj.parameters = (Hashtable<String, String>)parameters.clone(); return newObj; } diff --git a/jdk/src/share/classes/java/awt/dnd/DragGestureEvent.java b/jdk/src/share/classes/java/awt/dnd/DragGestureEvent.java index e8827f44358..3dff336a794 100644 --- a/jdk/src/share/classes/java/awt/dnd/DragGestureEvent.java +++ b/jdk/src/share/classes/java/awt/dnd/DragGestureEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -357,6 +357,7 @@ public class DragGestureEvent extends EventObject { action = newAction; // Pre-1.4 support. 'events' was previously non-transient + @SuppressWarnings("rawtypes") List newEvents; try { newEvents = (List)f.get("events", null); diff --git a/jdk/src/share/classes/java/awt/geom/Area.java b/jdk/src/share/classes/java/awt/geom/Area.java index 507f212b4ea..ae5ab2f683b 100644 --- a/jdk/src/share/classes/java/awt/geom/Area.java +++ b/jdk/src/share/classes/java/awt/geom/Area.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -97,9 +97,9 @@ import sun.awt.geom.AreaOp; * @since 1.2 */ public class Area implements Shape, Cloneable { - private static Vector EmptyCurves = new Vector(); + private static Vector<Curve> EmptyCurves = new Vector<>(); - private Vector curves; + private Vector<Curve> curves; /** * Default constructor which creates an empty area. @@ -127,8 +127,8 @@ public class Area implements Shape, Cloneable { } } - private static Vector pathToCurves(PathIterator pi) { - Vector curves = new Vector(); + private static Vector<Curve> pathToCurves(PathIterator pi) { + Vector<Curve> curves = new Vector<>(); int windingRule = pi.getWindingRule(); // coords array is big enough for holding: // coordinates returned from currentSegment (6) @@ -334,7 +334,7 @@ public class Area implements Shape, Cloneable { * @since 1.2 */ public void reset() { - curves = new Vector(); + curves = new Vector<>(); invalidateBounds(); } @@ -357,9 +357,9 @@ public class Area implements Shape, Cloneable { * @since 1.2 */ public boolean isPolygonal() { - Enumeration enum_ = curves.elements(); + Enumeration<Curve> enum_ = curves.elements(); while (enum_.hasMoreElements()) { - if (((Curve) enum_.nextElement()).getOrder() > 1) { + if (enum_.nextElement().getOrder() > 1) { return false; } } @@ -381,8 +381,8 @@ public class Area implements Shape, Cloneable { if (size > 3) { return false; } - Curve c1 = (Curve) curves.get(1); - Curve c2 = (Curve) curves.get(2); + Curve c1 = curves.get(1); + Curve c2 = curves.get(2); if (c1.getOrder() != 1 || c2.getOrder() != 1) { return false; } @@ -411,10 +411,10 @@ public class Area implements Shape, Cloneable { if (curves.size() < 3) { return true; } - Enumeration enum_ = curves.elements(); + Enumeration<Curve> enum_ = curves.elements(); enum_.nextElement(); // First Order0 "moveto" while (enum_.hasMoreElements()) { - if (((Curve) enum_.nextElement()).getOrder() == 0) { + if (enum_.nextElement().getOrder() == 0) { return false; } } @@ -431,11 +431,11 @@ public class Area implements Shape, Cloneable { } Rectangle2D r = new Rectangle2D.Double(); if (curves.size() > 0) { - Curve c = (Curve) curves.get(0); + Curve c = curves.get(0); // First point is always an order 0 curve (moveto) r.setRect(c.getX0(), c.getY0(), 0, 0); for (int i = 1; i < curves.size(); i++) { - ((Curve) curves.get(i)).enlarge(r); + curves.get(i).enlarge(r); } } return (cachedBounds = r); @@ -507,7 +507,7 @@ public class Area implements Shape, Cloneable { if (other == null) { return false; } - Vector c = new AreaOp.XorOp().calculate(this.curves, other.curves); + Vector<Curve> c = new AreaOp.XorOp().calculate(this.curves, other.curves); return c.isEmpty(); } @@ -555,10 +555,10 @@ public class Area implements Shape, Cloneable { if (!getCachedBounds().contains(x, y)) { return false; } - Enumeration enum_ = curves.elements(); + Enumeration<Curve> enum_ = curves.elements(); int crossings = 0; while (enum_.hasMoreElements()) { - Curve c = (Curve) enum_.nextElement(); + Curve c = enum_.nextElement(); crossings += c.crossingsFor(x, y); } return ((crossings & 1) == 1); @@ -658,16 +658,16 @@ public class Area implements Shape, Cloneable { class AreaIterator implements PathIterator { private AffineTransform transform; - private Vector curves; + private Vector<Curve> curves; private int index; private Curve prevcurve; private Curve thiscurve; - public AreaIterator(Vector curves, AffineTransform at) { + public AreaIterator(Vector<Curve> curves, AffineTransform at) { this.curves = curves; this.transform = at; if (curves.size() >= 1) { - thiscurve = (Curve) curves.get(0); + thiscurve = curves.get(0); } } @@ -689,7 +689,7 @@ class AreaIterator implements PathIterator { prevcurve = thiscurve; index++; if (index < curves.size()) { - thiscurve = (Curve) curves.get(index); + thiscurve = curves.get(index); if (thiscurve.getOrder() != 0 && prevcurve.getX1() == thiscurve.getX0() && prevcurve.getY1() == thiscurve.getY0()) diff --git a/jdk/src/share/classes/java/awt/image/BufferedImage.java b/jdk/src/share/classes/java/awt/image/BufferedImage.java index bb272aacf69..0c819349135 100644 --- a/jdk/src/share/classes/java/awt/image/BufferedImage.java +++ b/jdk/src/share/classes/java/awt/image/BufferedImage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,7 +76,7 @@ public class BufferedImage extends java.awt.Image ColorModel colorModel; WritableRaster raster; OffScreenImageSource osis; - Hashtable properties; + Hashtable<?, ?> properties; boolean isAlphaPremultiplied;// If true, alpha has been premultiplied in // color channels @@ -1106,7 +1106,7 @@ public class BufferedImage extends java.awt.Image public ImageProducer getSource() { if (osis == null) { if (properties == null) { - properties = new Hashtable(); + properties = new Hashtable<>(); } osis = new OffScreenImageSource(this, properties); } diff --git a/jdk/src/share/classes/java/awt/image/CropImageFilter.java b/jdk/src/share/classes/java/awt/image/CropImageFilter.java index 4d75c9e0427..a1d241d33ed 100644 --- a/jdk/src/share/classes/java/awt/image/CropImageFilter.java +++ b/jdk/src/share/classes/java/awt/image/CropImageFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -79,6 +79,7 @@ public class CropImageFilter extends ImageFilter { * with the filtering operation. */ public void setProperties(Hashtable<?,?> props) { + @SuppressWarnings("unchecked") Hashtable<Object,Object> p = (Hashtable<Object,Object>)props.clone(); p.put("croprect", new Rectangle(cropX, cropY, cropW, cropH)); super.setProperties(p); diff --git a/jdk/src/share/classes/java/awt/image/FilteredImageSource.java b/jdk/src/share/classes/java/awt/image/FilteredImageSource.java index 2f58c096474..a7013159008 100644 --- a/jdk/src/share/classes/java/awt/image/FilteredImageSource.java +++ b/jdk/src/share/classes/java/awt/image/FilteredImageSource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,7 +68,7 @@ public class FilteredImageSource implements ImageProducer { filter = imgf; } - private Hashtable proxies; + private Hashtable<ImageConsumer, ImageFilter> proxies; /** * Adds the specified <code>ImageConsumer</code> @@ -94,7 +94,7 @@ public class FilteredImageSource implements ImageProducer { */ public synchronized void addConsumer(ImageConsumer ic) { if (proxies == null) { - proxies = new Hashtable(); + proxies = new Hashtable<>(); } if (!proxies.containsKey(ic)) { ImageFilter imgf = filter.getFilterInstance(ic); @@ -137,7 +137,7 @@ public class FilteredImageSource implements ImageProducer { */ public synchronized void removeConsumer(ImageConsumer ic) { if (proxies != null) { - ImageFilter imgf = (ImageFilter) proxies.get(ic); + ImageFilter imgf = proxies.get(ic); if (imgf != null) { src.removeConsumer(imgf); proxies.remove(ic); @@ -173,9 +173,9 @@ public class FilteredImageSource implements ImageProducer { */ public void startProduction(ImageConsumer ic) { if (proxies == null) { - proxies = new Hashtable(); + proxies = new Hashtable<>(); } - ImageFilter imgf = (ImageFilter) proxies.get(ic); + ImageFilter imgf = proxies.get(ic); if (imgf == null) { imgf = filter.getFilterInstance(ic); proxies.put(ic, imgf); @@ -200,7 +200,7 @@ public class FilteredImageSource implements ImageProducer { */ public void requestTopDownLeftRightResend(ImageConsumer ic) { if (proxies != null) { - ImageFilter imgf = (ImageFilter) proxies.get(ic); + ImageFilter imgf = proxies.get(ic); if (imgf != null) { imgf.resendTopDownLeftRight(src); } diff --git a/jdk/src/share/classes/java/awt/image/ImageFilter.java b/jdk/src/share/classes/java/awt/image/ImageFilter.java index 0b64d726b8e..33198346e03 100644 --- a/jdk/src/share/classes/java/awt/image/ImageFilter.java +++ b/jdk/src/share/classes/java/awt/image/ImageFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -104,6 +104,7 @@ public class ImageFilter implements ImageConsumer, Cloneable { * @exception NullPointerException if <code>props</code> is null */ public void setProperties(Hashtable<?,?> props) { + @SuppressWarnings("unchecked") Hashtable<Object,Object> p = (Hashtable<Object,Object>)props.clone(); Object o = p.get("filters"); if (o == null) { diff --git a/jdk/src/share/classes/java/awt/image/MemoryImageSource.java b/jdk/src/share/classes/java/awt/image/MemoryImageSource.java index 7046f5e4667..501714fda1f 100644 --- a/jdk/src/share/classes/java/awt/image/MemoryImageSource.java +++ b/jdk/src/share/classes/java/awt/image/MemoryImageSource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -111,8 +111,8 @@ public class MemoryImageSource implements ImageProducer { Object pixels; int pixeloffset; int pixelscan; - Hashtable properties; - Vector theConsumers = new Vector(); + Hashtable<?, ?> properties; + Vector<ImageConsumer> theConsumers = new Vector<>(); boolean animating; boolean fullbuffers; @@ -197,7 +197,7 @@ public class MemoryImageSource implements ImageProducer { } private void initialize(int w, int h, ColorModel cm, - Object pix, int off, int scan, Hashtable props) { + Object pix, int off, int scan, Hashtable<?,?> props) { width = w; height = h; model = cm; @@ -205,7 +205,7 @@ public class MemoryImageSource implements ImageProducer { pixeloffset = off; pixelscan = scan; if (props == null) { - props = new Hashtable(); + props = new Hashtable<>(); } properties = props; } @@ -343,9 +343,9 @@ public class MemoryImageSource implements ImageProducer { public synchronized void setAnimated(boolean animated) { this.animating = animated; if (!animating) { - Enumeration enum_ = theConsumers.elements(); + Enumeration<ImageConsumer> enum_ = theConsumers.elements(); while (enum_.hasMoreElements()) { - ImageConsumer ic = (ImageConsumer) enum_.nextElement(); + ImageConsumer ic = enum_.nextElement(); ic.imageComplete(ImageConsumer.STATICIMAGEDONE); if (isConsumer(ic)) { ic.imageComplete(ImageConsumer.IMAGEERROR); @@ -376,9 +376,9 @@ public class MemoryImageSource implements ImageProducer { } this.fullbuffers = fullbuffers; if (animating) { - Enumeration enum_ = theConsumers.elements(); + Enumeration<ImageConsumer> enum_ = theConsumers.elements(); while (enum_.hasMoreElements()) { - ImageConsumer ic = (ImageConsumer) enum_.nextElement(); + ImageConsumer ic = enum_.nextElement(); ic.setHints(fullbuffers ? (ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES) @@ -474,9 +474,9 @@ public class MemoryImageSource implements ImageProducer { if ((w <= 0 || h <= 0) && !framenotify) { return; } - Enumeration enum_ = theConsumers.elements(); + Enumeration<ImageConsumer> enum_ = theConsumers.elements(); while (enum_.hasMoreElements()) { - ImageConsumer ic = (ImageConsumer) enum_.nextElement(); + ImageConsumer ic = enum_.nextElement(); if (w > 0 && h > 0) { sendPixels(ic, x, y, w, h); } diff --git a/jdk/src/share/classes/java/awt/image/ReplicateScaleFilter.java b/jdk/src/share/classes/java/awt/image/ReplicateScaleFilter.java index 04a6fdfe52a..7330439f2c5 100644 --- a/jdk/src/share/classes/java/awt/image/ReplicateScaleFilter.java +++ b/jdk/src/share/classes/java/awt/image/ReplicateScaleFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -121,6 +121,7 @@ public class ReplicateScaleFilter extends ImageFilter { * with the filtering operation. */ public void setProperties(Hashtable<?,?> props) { + @SuppressWarnings("unchecked") Hashtable<Object,Object> p = (Hashtable<Object,Object>)props.clone(); String key = "rescale"; String val = destWidth + "x" + destHeight; diff --git a/jdk/src/share/classes/java/awt/image/renderable/ParameterBlock.java b/jdk/src/share/classes/java/awt/image/renderable/ParameterBlock.java index ca12bfc4c4b..bf14e8ce2d3 100644 --- a/jdk/src/share/classes/java/awt/image/renderable/ParameterBlock.java +++ b/jdk/src/share/classes/java/awt/image/renderable/ParameterBlock.java @@ -153,6 +153,7 @@ public class ParameterBlock implements Cloneable, Serializable { * * @return an Object clone of the <code>ParameterBlock</code>. */ + @SuppressWarnings("unchecked") // casts from clone public Object clone() { ParameterBlock theClone; @@ -164,10 +165,10 @@ public class ParameterBlock implements Cloneable, Serializable { } if (sources != null) { - theClone.setSources((Vector)sources.clone()); + theClone.setSources((Vector<Object>)sources.clone()); } if (parameters != null) { - theClone.setParameters((Vector)parameters.clone()); + theClone.setParameters((Vector<Object>)parameters.clone()); } return (Object) theClone; } @@ -280,7 +281,7 @@ public class ParameterBlock implements Cloneable, Serializable { /** Clears the list of source images. */ public void removeSources() { - sources = new Vector(); + sources = new Vector<>(); } /** @@ -313,7 +314,7 @@ public class ParameterBlock implements Cloneable, Serializable { /** Clears the list of parameters. */ public void removeParameters() { - parameters = new Vector(); + parameters = new Vector<>(); } /** @@ -696,9 +697,9 @@ public class ParameterBlock implements Cloneable, Serializable { * of the parameters. * @return an array of <code>Class</code> objects. */ - public Class [] getParamClasses() { + public Class<?>[] getParamClasses() { int numParams = getNumParameters(); - Class [] classes = new Class[numParams]; + Class<?>[] classes = new Class<?>[numParams]; int i; for (i = 0; i < numParams; i++) { diff --git a/jdk/src/share/classes/java/awt/image/renderable/RenderableImageOp.java b/jdk/src/share/classes/java/awt/image/renderable/RenderableImageOp.java index 6c51f65a8bf..9d5aaa954a8 100644 --- a/jdk/src/share/classes/java/awt/image/renderable/RenderableImageOp.java +++ b/jdk/src/share/classes/java/awt/image/renderable/RenderableImageOp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,11 +87,11 @@ public class RenderableImageOp implements RenderableImage { return getRenderableSources(); } - private Vector getRenderableSources() { - Vector sources = null; + private Vector<RenderableImage> getRenderableSources() { + Vector<RenderableImage> sources = null; if (paramBlock.getNumSources() > 0) { - sources = new Vector(); + sources = new Vector<>(); int i = 0; while (i < paramBlock.getNumSources()) { Object o = paramBlock.getSource(i); @@ -314,19 +314,19 @@ public class RenderableImageOp implements RenderableImage { // contains RenderableImage sources, they will be replaced by // RenderedImages. ParameterBlock renderedParamBlock = (ParameterBlock)paramBlock.clone(); - Vector sources = getRenderableSources(); + Vector<? extends Object> sources = getRenderableSources(); try { // This assumes that if there is no renderable source, that there // is a rendered source in paramBlock if (sources != null) { - Vector renderedSources = new Vector(); + Vector<Object> renderedSources = new Vector<>(); for (int i = 0; i < sources.size(); i++) { rcOut = myCRIF.mapRenderContext(i, renderContext, paramBlock, this); RenderedImage rdrdImage = - ((RenderableImage)sources.elementAt(i)).createRendering(rcOut); + ((RenderableImage)sources.elementAt(i)).createRendering(rcOut); if (rdrdImage == null) { return null; } diff --git a/jdk/src/share/classes/java/awt/image/renderable/RenderableImageProducer.java b/jdk/src/share/classes/java/awt/image/renderable/RenderableImageProducer.java index c5e357a28c2..206869ae1bf 100644 --- a/jdk/src/share/classes/java/awt/image/renderable/RenderableImageProducer.java +++ b/jdk/src/share/classes/java/awt/image/renderable/RenderableImageProducer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,7 +68,7 @@ public class RenderableImageProducer implements ImageProducer, Runnable { RenderContext rc; /** A Vector of image consumers. */ - Vector ics = new Vector(); + Vector<ImageConsumer> ics = new Vector<>(); /** * Constructs a new RenderableImageProducer from a RenderableImage @@ -177,12 +177,12 @@ public class RenderableImageProducer implements ImageProducer, Runnable { int width = raster.getWidth(); int height = raster.getHeight(); - Enumeration icList; + Enumeration<ImageConsumer> icList; ImageConsumer ic; // Set up the ImageConsumers icList = ics.elements(); while (icList.hasMoreElements()) { - ic = (ImageConsumer)icList.nextElement(); + ic = icList.nextElement(); ic.setDimensions(width,height); ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES | @@ -204,7 +204,7 @@ public class RenderableImageProducer implements ImageProducer, Runnable { // Now send the scanline to the Consumers icList = ics.elements(); while (icList.hasMoreElements()) { - ic = (ImageConsumer)icList.nextElement(); + ic = icList.nextElement(); ic.setPixels(0, j, width, 1, colorModel, pix, 0, width); } } @@ -212,7 +212,7 @@ public class RenderableImageProducer implements ImageProducer, Runnable { // Now tell the consumers we're done. icList = ics.elements(); while (icList.hasMoreElements()) { - ic = (ImageConsumer)icList.nextElement(); + ic = icList.nextElement(); ic.imageComplete(ImageConsumer.STATICIMAGEDONE); } } diff --git a/jdk/src/share/classes/java/awt/print/Book.java b/jdk/src/share/classes/java/awt/print/Book.java index 672b842e8e7..eaab083789c 100644 --- a/jdk/src/share/classes/java/awt/print/Book.java +++ b/jdk/src/share/classes/java/awt/print/Book.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ public class Book implements Pageable { /** * The set of pages that make up the Book. */ - private Vector mPages; + private Vector<BookPage> mPages; /* Instance Methods */ @@ -55,7 +55,7 @@ public class Book implements Pageable { * Creates a new, empty <code>Book</code>. */ public Book() { - mPages = new Vector(); + mPages = new Vector<>(); } /** @@ -167,7 +167,7 @@ public class Book implements Pageable { private BookPage getPage(int pageIndex) throws ArrayIndexOutOfBoundsException { - return (BookPage) mPages.elementAt(pageIndex); + return mPages.elementAt(pageIndex); } /** diff --git a/jdk/src/share/classes/java/awt/print/PrinterJob.java b/jdk/src/share/classes/java/awt/print/PrinterJob.java index b9b0d134d64..0c80d1490d4 100644 --- a/jdk/src/share/classes/java/awt/print/PrinterJob.java +++ b/jdk/src/share/classes/java/awt/print/PrinterJob.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,9 +74,9 @@ public abstract class PrinterJob { if (security != null) { security.checkPrintJobAccess(); } - return (PrinterJob) java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + return java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction<PrinterJob>() { + public PrinterJob run() { String nm = System.getProperty("java.awt.printerjob", null); try { return (PrinterJob)Class.forName(nm).newInstance(); From 0bb0984a41a1c37fc30e14d61b451ae51c6560c2 Mon Sep 17 00:00:00 2001 From: Petr Pchelko <pchelko@openjdk.org> Date: Wed, 7 May 2014 19:40:30 +0400 Subject: [PATCH 039/157] 8042585: [macosx] Unused code in LWCToolkit.m Reviewed-by: serb, azvegint --- jdk/src/macosx/native/sun/awt/LWCToolkit.m | 57 +--------------------- 1 file changed, 1 insertion(+), 56 deletions(-) diff --git a/jdk/src/macosx/native/sun/awt/LWCToolkit.m b/jdk/src/macosx/native/sun/awt/LWCToolkit.m index c78834547c3..7347ecdd251 100644 --- a/jdk/src/macosx/native/sun/awt/LWCToolkit.m +++ b/jdk/src/macosx/native/sun/awt/LWCToolkit.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -157,61 +157,6 @@ JNF_COCOA_ENTER(env); JNF_COCOA_EXIT(env); } -static JNF_CLASS_CACHE(jc_Component, "java/awt/Component"); -static JNF_MEMBER_CACHE(jf_Component_appContext, jc_Component, "appContext", "Lsun/awt/AppContext;"); -static JNF_CLASS_CACHE(jc_MenuComponent, "java/awt/MenuComponent"); -static JNF_MEMBER_CACHE(jf_MenuComponent_appContext, jc_MenuComponent, "appContext", "Lsun/awt/AppContext;"); - -/* - * Class: sun_awt_SunToolkit - * Method: getAppContext - * Signature: (Ljava/awt/Object;)Lsun/awt/AppContext; - */ -JNIEXPORT jobject JNICALL -Java_sun_awt_SunToolkit_getAppContext -(JNIEnv *env, jclass cls, jobject obj) -{ - jobject appContext = NULL; - -JNF_COCOA_ENTER(env); - - if (JNFIsInstanceOf(env, obj, &jc_Component)) { - appContext = JNFGetObjectField(env, obj, jf_Component_appContext); - } else if (JNFIsInstanceOf(env, obj, &jc_MenuComponent)) { - appContext = JNFGetObjectField(env, obj, jf_MenuComponent_appContext); - } - -JNF_COCOA_EXIT(env); - - return appContext; -} - -/* - * Class: sun_awt_SunToolkit - * Method: setAppContext - * Signature: (Ljava/lang/Object;Lsun/awt/AppContext;)Z - */ -JNIEXPORT jboolean JNICALL -Java_sun_awt_SunToolkit_setAppContext -(JNIEnv *env, jclass cls, jobject obj, jobject appContext) -{ - jboolean isComponent; - -JNF_COCOA_ENTER(env); - - if (JNFIsInstanceOf(env, obj, &jc_Component)) { - JNFSetObjectField(env, obj, jf_Component_appContext, appContext); - isComponent = JNI_TRUE; - } else if (JNFIsInstanceOf(env, obj, &jc_MenuComponent)) { - JNFSetObjectField(env, obj, jf_MenuComponent_appContext, appContext); - isComponent = JNI_FALSE; - } - -JNF_COCOA_EXIT(env); - - return isComponent; -} - /* * Class: sun_lwawt_macosx_LWCToolkit * Method: beep From ceed2af62067267e6607d69707748b87d14058d2 Mon Sep 17 00:00:00 2001 From: Petr Pchelko <pchelko@openjdk.org> Date: Wed, 7 May 2014 19:47:26 +0400 Subject: [PATCH 040/157] 8042219: [macosx] LWComponentPeer should not reference classes from sun.lwawt.macosx Reviewed-by: serb, azvegint --- .../classes/sun/lwawt/LWComponentPeer.java | 12 +++-- .../macosx/classes/sun/lwawt/LWToolkit.java | 5 +++ .../classes/sun/lwawt/PlatformDropTarget.java | 34 ++++++++++++++ .../classes/sun/lwawt/macosx/CDropTarget.java | 45 ++++++------------- .../classes/sun/lwawt/macosx/LWCToolkit.java | 9 +++- jdk/src/macosx/native/sun/awt/CDropTarget.h | 2 +- jdk/src/macosx/native/sun/awt/CDropTarget.m | 6 +-- 7 files changed, 70 insertions(+), 43 deletions(-) create mode 100644 jdk/src/macosx/classes/sun/lwawt/PlatformDropTarget.java diff --git a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java index 5880d06be4d..354f2538012 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java @@ -63,8 +63,6 @@ import javax.swing.JComponent; import javax.swing.SwingUtilities; import javax.swing.RepaintManager; -import sun.lwawt.macosx.CDropTarget; - import com.sun.java.swing.SwingUtilities3; public abstract class LWComponentPeer<T extends Component, D extends JComponent> @@ -137,7 +135,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent> private final Object dropTargetLock = new Object(); private int fNumDropTargets = 0; - private CDropTarget fDropTarget = null; + private PlatformDropTarget fDropTarget = null; private final PlatformComponent platformComponent; @@ -1063,11 +1061,11 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent> // if it's the first (or last) one for the component. Otherwise this call is a no-op. if (++fNumDropTargets == 1) { // Having a non-null drop target would be an error but let's check just in case: - if (fDropTarget != null) - System.err.println("CComponent.addDropTarget(): current drop target is non-null."); - + if (fDropTarget != null) { + throw new IllegalStateException("Current drop target is not null"); + } // Create a new drop target: - fDropTarget = CDropTarget.createDropTarget(dt, target, this); + fDropTarget = LWToolkit.getLWToolkit().createDropTarget(dt, target, this); } } } diff --git a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java index b18fdb004f1..315a19a7ff3 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java @@ -28,6 +28,7 @@ package sun.lwawt; import java.awt.*; import java.awt.List; import java.awt.datatransfer.*; +import java.awt.dnd.DropTarget; import java.awt.image.*; import java.awt.peer.*; import java.security.*; @@ -440,6 +441,10 @@ public abstract class LWToolkit extends SunToolkit implements Runnable { protected abstract FileDialogPeer createFileDialogPeer(FileDialog target); + protected abstract PlatformDropTarget createDropTarget(DropTarget dropTarget, + Component component, + LWComponentPeer<?, ?> peer); + // ---- UTILITY METHODS ---- // /* diff --git a/jdk/src/macosx/classes/sun/lwawt/PlatformDropTarget.java b/jdk/src/macosx/classes/sun/lwawt/PlatformDropTarget.java new file mode 100644 index 00000000000..e2a9a70e70f --- /dev/null +++ b/jdk/src/macosx/classes/sun/lwawt/PlatformDropTarget.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 sun.lwawt; + +public interface PlatformDropTarget { + + /** + * Release native dragging destination, if any + */ + void dispose(); +} diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CDropTarget.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CDropTarget.java index 910e1407a36..d4f4353d9ec 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CDropTarget.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CDropTarget.java @@ -25,54 +25,37 @@ package sun.lwawt.macosx; -import java.awt.Component; -import java.awt.peer.ComponentPeer; +import sun.lwawt.LWComponentPeer; +import sun.lwawt.PlatformDropTarget; + +import java.awt.*; import java.awt.dnd.DropTarget; -import sun.lwawt.LWComponentPeer; -import sun.lwawt.PlatformWindow; +final class CDropTarget implements PlatformDropTarget { + private long fNativeDropTarget; -public final class CDropTarget { - - Component fComponent; - ComponentPeer fPeer; - DropTarget fDropTarget; - private long fNativeDropTarget; - - public static CDropTarget createDropTarget(DropTarget dropTarget, Component component, ComponentPeer peer) { - return new CDropTarget(dropTarget, component, peer); - } - - private CDropTarget(DropTarget dropTarget, Component component, ComponentPeer peer) { - super(); - - fDropTarget = dropTarget; - fComponent = component; - fPeer = peer; - - long nativePeer = CPlatformWindow.getNativeViewPtr(((LWComponentPeer) peer).getPlatformWindow()); + CDropTarget(DropTarget dropTarget, Component component, LWComponentPeer<?, ?> peer) { + long nativePeer = CPlatformWindow.getNativeViewPtr(peer.getPlatformWindow()); if (nativePeer == 0L) return; // Unsupported for a window without a native view (plugin) // Create native dragging destination: - fNativeDropTarget = this.createNativeDropTarget(dropTarget, component, peer, nativePeer); + fNativeDropTarget = createNativeDropTarget(dropTarget, component, nativePeer); if (fNativeDropTarget == 0) { throw new IllegalStateException("CDropTarget.createNativeDropTarget() failed."); } } - public DropTarget getDropTarget() { - return fDropTarget; - } - + @Override public void dispose() { - // Release native dragging destination, if any: if (fNativeDropTarget != 0) { - this.releaseNativeDropTarget(fNativeDropTarget); + releaseNativeDropTarget(fNativeDropTarget); fNativeDropTarget = 0; } } - protected native long createNativeDropTarget(DropTarget dropTarget, Component component, ComponentPeer peer, long nativePeer); + protected native long createNativeDropTarget(DropTarget dropTarget, + Component component, + long nativePeer); protected native void releaseNativeDropTarget(long nativeDropTarget); } diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java index d0b6882b9a3..2bb5d4ac508 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java @@ -701,7 +701,14 @@ public final class LWCToolkit extends LWToolkit { return (T)dgr; } -// InputMethodSupport Method + @Override + protected PlatformDropTarget createDropTarget(DropTarget dropTarget, + Component component, + LWComponentPeer<?, ?> peer) { + return new CDropTarget(dropTarget, component, peer); + } + + // InputMethodSupport Method /** * Returns the default keyboard locale of the underlying operating system */ diff --git a/jdk/src/macosx/native/sun/awt/CDropTarget.h b/jdk/src/macosx/native/sun/awt/CDropTarget.h index b6cd156562b..3b87485add7 100644 --- a/jdk/src/macosx/native/sun/awt/CDropTarget.h +++ b/jdk/src/macosx/native/sun/awt/CDropTarget.h @@ -48,7 +48,7 @@ + (CDropTarget *) currentDropTarget; // Common methods: -- (id)init:(jobject)dropTarget component:(jobject)jcomponent peer:(jobject)jpeer control:(id)control; +- (id)init:(jobject)dropTarget component:(jobject)jcomponent control:(id)control; - (void)controlModelControlValid; - (void)removeFromView:(JNIEnv *)env; diff --git a/jdk/src/macosx/native/sun/awt/CDropTarget.m b/jdk/src/macosx/native/sun/awt/CDropTarget.m index 41b0a192c61..7e038ab7715 100644 --- a/jdk/src/macosx/native/sun/awt/CDropTarget.m +++ b/jdk/src/macosx/native/sun/awt/CDropTarget.m @@ -65,7 +65,7 @@ extern JNFClassInfo jc_CDropTargetContextPeer; return sCurrentDropTarget; } -- (id)init:(jobject)jdropTarget component:(jobject)jcomponent peer:(jobject)jpeer control:(id)control +- (id)init:(jobject)jdropTarget component:(jobject)jcomponent control:(id)control { self = [super init]; DLog2(@"[CDropTarget init]: %@\n", self); @@ -714,13 +714,13 @@ extern JNFClassInfo jc_CDropTargetContextPeer; * Signature: (Ljava/awt/dnd/DropTarget;Ljava/awt/Component;Ljava/awt/peer/ComponentPeer;J)J */ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CDropTarget_createNativeDropTarget - (JNIEnv *env, jobject jthis, jobject jdroptarget, jobject jcomponent, jobject jpeer, jlong jnativepeer) + (JNIEnv *env, jobject jthis, jobject jdroptarget, jobject jcomponent, jlong jnativepeer) { CDropTarget* dropTarget = nil; JNF_COCOA_ENTER(env); id controlObj = (id) jlong_to_ptr(jnativepeer); - dropTarget = [[CDropTarget alloc] init:jdroptarget component:jcomponent peer:jpeer control:controlObj]; + dropTarget = [[CDropTarget alloc] init:jdroptarget component:jcomponent control:controlObj]; JNF_COCOA_EXIT(env); return ptr_to_jlong(dropTarget); From b9113e4f414c37306bc07ccbf09abf4801d4c13b Mon Sep 17 00:00:00 2001 From: David DeHaven <david.dehaven@oracle.com> Date: Mon, 5 May 2014 23:21:27 -0700 Subject: [PATCH 041/157] 8042440: awt_Plugin no longer needed Reviewed-by: serb, pchelko --- jdk/make/lib/Awt2dLibraries.gmk | 1 - jdk/make/mapfiles/libawt/mapfile-mawt-vers | 7 +- jdk/make/mapfiles/libawt/mapfile-vers | 9 +- jdk/make/mapfiles/libawt/mapfile-vers-linux | 14 +- jdk/make/mapfiles/libawt_xawt/mapfile-vers | 8 +- .../solaris/native/sun/awt/awt_LoadLibrary.c | 54 ------- jdk/src/solaris/native/sun/awt/awt_Plugin.c | 149 ------------------ jdk/src/solaris/native/sun/awt/awt_Plugin.h | 54 ------- 8 files changed, 4 insertions(+), 292 deletions(-) delete mode 100644 jdk/src/solaris/native/sun/awt/awt_Plugin.c delete mode 100644 jdk/src/solaris/native/sun/awt/awt_Plugin.h diff --git a/jdk/make/lib/Awt2dLibraries.gmk b/jdk/make/lib/Awt2dLibraries.gmk index 00fa15c59ec..880a52ff096 100644 --- a/jdk/make/lib/Awt2dLibraries.gmk +++ b/jdk/make/lib/Awt2dLibraries.gmk @@ -606,7 +606,6 @@ ifeq ($(findstring $(OPENJDK_TARGET_OS),windows macosx),) debug_mem.c \ debug_trace.c \ debug_util.c \ - awt_Plugin.c \ gnome_interface.c \ gtk2_interface.c \ swing_GTKEngine.c \ diff --git a/jdk/make/mapfiles/libawt/mapfile-mawt-vers b/jdk/make/mapfiles/libawt/mapfile-mawt-vers index a50c13a62e5..b8ea1636c88 100644 --- a/jdk/make/mapfiles/libawt/mapfile-mawt-vers +++ b/jdk/make/mapfiles/libawt/mapfile-mawt-vers @@ -1,5 +1,5 @@ # -# Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -249,11 +249,6 @@ SUNWprivate_1.1 { Java_sun_awt_motif_XsessionWMcommand; Java_sun_awt_motif_XsessionWMcommand_New; - # Java Plugin - getAwtLockFunctions; - getAwtData; - getAwtDisplay; - # libfontmanager entry points AWTIsHeadless; AWTCountFonts; diff --git a/jdk/make/mapfiles/libawt/mapfile-vers b/jdk/make/mapfiles/libawt/mapfile-vers index 05ca7d538dd..b1c6a39ec1e 100644 --- a/jdk/make/mapfiles/libawt/mapfile-vers +++ b/jdk/make/mapfiles/libawt/mapfile-vers @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -173,13 +173,6 @@ SUNWprivate_1.1 { Java_sun_awt_motif_XsessionWMcommand; Java_sun_awt_motif_XsessionWMcommand_New; - # Java Plugin - # This is in awt_LoadLibrary.c and falls through to libmawt. - # Evidently plugin needs this for backward compatability. - getAwtLockFunctions; - getAwtData; - getAwtDisplay; - # libfontmanager entry points AWTIsHeadless; GrPrim_Sg2dGetCompInfo; diff --git a/jdk/make/mapfiles/libawt/mapfile-vers-linux b/jdk/make/mapfiles/libawt/mapfile-vers-linux index f8967e09462..922b015c68c 100644 --- a/jdk/make/mapfiles/libawt/mapfile-vers-linux +++ b/jdk/make/mapfiles/libawt/mapfile-vers-linux @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -152,13 +152,6 @@ SUNWprivate_1.1 { # Evidently CDE needs this for backward compatability. Java_sun_awt_motif_XsessionWMcommand; - # Java Plugin - # This is in awt_LoadLibrary.c and falls through to libmawt. - # Evidently plugin needs this for backward compatability. - getAwtLockFunctions; - getAwtData; - getAwtDisplay; - # libfontmanager entry points AWTIsHeadless; GrPrim_Sg2dGetCompInfo; @@ -283,11 +276,6 @@ SUNWprivate_1.1 { # CDE private entry point Java_sun_awt_motif_XsessionWMcommand; - # Java Plugin - getAwtLockFunctions; - getAwtData; - getAwtDisplay; - # libfontmanager entry points AWTIsHeadless; AWTCountFonts; diff --git a/jdk/make/mapfiles/libawt_xawt/mapfile-vers b/jdk/make/mapfiles/libawt_xawt/mapfile-vers index 15089a114ca..3ae8af3ddbf 100644 --- a/jdk/make/mapfiles/libawt_xawt/mapfile-vers +++ b/jdk/make/mapfiles/libawt_xawt/mapfile-vers @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -449,12 +449,6 @@ SUNWprivate_1.1 { awt_Lock; awt_GetComponent; - # Java Plugin - # This is in awt_LoadLibrary.c and falls through to libmawt. - # Evidently plugin needs this for backward compatability. - getAwtLockFunctions; - getAwtData; - getAwtDisplay; #XAWT entry point for CDE Java_sun_awt_motif_XsessionWMcommand; Java_sun_awt_motif_XsessionWMcommand_New; diff --git a/jdk/src/solaris/native/sun/awt/awt_LoadLibrary.c b/jdk/src/solaris/native/sun/awt/awt_LoadLibrary.c index 362d9d70dfb..59483027131 100644 --- a/jdk/src/solaris/native/sun/awt/awt_LoadLibrary.c +++ b/jdk/src/solaris/native/sun/awt/awt_LoadLibrary.c @@ -35,8 +35,6 @@ #include <sys/param.h> #include <sys/utsname.h> -#include "awt_Plugin.h" - #ifdef AIX #include "porting_aix.h" /* For the 'dladdr' function. */ #endif @@ -236,55 +234,3 @@ Java_sun_awt_motif_XsessionWMcommand_New(JNIEnv *env, jobjectArray jargv) (*XsessionWMcommand)(env, jargv); } - - -#define REFLECT_VOID_FUNCTION(name, arglist, paramlist) \ -typedef void name##_type arglist; \ -void name arglist \ -{ \ - static name##_type *name##_ptr = NULL; \ - if (name##_ptr == NULL && awtHandle == NULL) { \ - return; \ - } \ - name##_ptr = (name##_type *) \ - dlsym(awtHandle, #name); \ - if (name##_ptr == NULL) { \ - return; \ - } \ - (*name##_ptr)paramlist; \ -} - -#define REFLECT_FUNCTION(return_type, name, arglist, paramlist) \ -typedef return_type name##_type arglist; \ -return_type name arglist \ -{ \ - static name##_type *name##_ptr = NULL; \ - if (name##_ptr == NULL && awtHandle == NULL) { \ - return NULL; \ - } \ - name##_ptr = (name##_type *) \ - dlsym(awtHandle, #name); \ - if (name##_ptr == NULL) { \ - return NULL; \ - } \ - return (*name##_ptr)paramlist; \ -} - - -/* - * These entry point must remain in libawt.so ***for Java Plugin ONLY*** - * Reflect this call over to the correct libawt_<toolkit>.so. - */ - -REFLECT_VOID_FUNCTION(getAwtLockFunctions, - (void (**AwtLock)(JNIEnv *), void (**AwtUnlock)(JNIEnv *), - void (**AwtNoFlushUnlock)(JNIEnv *), void *reserved), - (AwtLock, AwtUnlock, AwtNoFlushUnlock, reserved)) - -REFLECT_VOID_FUNCTION(getAwtData, - (int32_t *awt_depth, Colormap *awt_cmap, Visual **awt_visual, - int32_t *awt_num_colors, void *pReserved), - (awt_depth, awt_cmap, awt_visual, - awt_num_colors, pReserved)) - -REFLECT_FUNCTION(Display *, getAwtDisplay, (void), ()) diff --git a/jdk/src/solaris/native/sun/awt/awt_Plugin.c b/jdk/src/solaris/native/sun/awt/awt_Plugin.c deleted file mode 100644 index 0b33ac2b23b..00000000000 --- a/jdk/src/solaris/native/sun/awt/awt_Plugin.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 1999, 2001, 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. - */ - -#ifdef HEADLESS - #error This file should not be included in headless library -#endif - -#include <jni.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <awt.h> -#include <awt_p.h> - -/* - * Fix 4221246: Provide utility function for Netscape to use to - * get AWT display, depth, colormap, and number of colors. - * - */ - -Display *getAwtDisplay(void) -{ - return awt_display; -} - -void getExtAwtData(Display *display, - int32_t screen, - int32_t *awt_depth, - Colormap *awt_cmap, - Visual **awt_visual, - int32_t *awt_num_colors, - void *pReserved) -{ - AwtGraphicsConfigDataPtr defaultConfig = NULL; - -#ifdef DEBUG - if (pReserved != NULL) { - jio_fprintf(stderr, - "getExtAwtData: warning: reserved pointer is not null\n"); - } -#endif - - if (screen >= 0) { - defaultConfig = getDefaultConfig(screen); - } - - if (defaultConfig) { - if (awt_depth != NULL) { - *awt_depth = defaultConfig->awt_depth; - } - - if (awt_cmap != NULL) { - *awt_cmap = defaultConfig->awt_cmap; - } - - if (awt_visual != NULL) { - *awt_visual = defaultConfig->awt_visInfo.visual; - } - - if (awt_num_colors != NULL) { - *awt_num_colors = defaultConfig->awt_num_colors; - } - } -} - -/* - * getAwtData provided for compatibility with Solaris 1.2 Java Plug-in - * - */ -void getAwtData(int32_t *awt_depth, - Colormap *awt_cmap, - Visual **awt_visual, - int32_t *awt_num_colors, - void *pReserved) -{ - Display *display = getAwtDisplay(); - - getExtAwtData(display, - DefaultScreen(display), - awt_depth, - awt_cmap, - awt_visual, - awt_num_colors, - pReserved); -} - -/* - * Fix 4221246: Provide utility funtion for Netscape to get - * function pointers to AWT lock functions. - * - */ - -static void awt_lock_wrapper(JNIEnv *env) { - AWT_LOCK(); -} - -static void awt_unlock_wrapper(JNIEnv *env) { - AWT_UNLOCK(); -} - -static void awt_noflush_unlock_wrapper(JNIEnv *env) { - AWT_NOFLUSH_UNLOCK(); -} - -void getAwtLockFunctions(void (**AwtLock)(JNIEnv *), - void (**AwtUnlock)(JNIEnv *), - void (**AwtNoFlushUnlock)(JNIEnv *), - void *pReserved) -{ -#ifdef DEBUG - if (pReserved != NULL) { - jio_fprintf(stderr, - "getAwtLockFunctions: warning: reserved pointer is not null\n"); - } -#endif - - if (AwtLock != NULL) { - *AwtLock = awt_lock_wrapper; - } - - if (AwtUnlock != NULL) { - *AwtUnlock = awt_unlock_wrapper; - } - - if (AwtNoFlushUnlock != NULL) { - *AwtNoFlushUnlock = awt_noflush_unlock_wrapper; - } -} diff --git a/jdk/src/solaris/native/sun/awt/awt_Plugin.h b/jdk/src/solaris/native/sun/awt/awt_Plugin.h deleted file mode 100644 index 434fabb7216..00000000000 --- a/jdk/src/solaris/native/sun/awt/awt_Plugin.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1999, 2001, 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. - */ - -/* - * Fix 4221246: Export functions for Netscape to use to get AWT info - */ - -#ifndef _AWT_PLUGIN_H_ -#define _AWT_PLUGIN_H_ - -#include <jni.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> - -void getAwtLockFunctions(void (**AwtLock)(JNIEnv *), - void (**AwtUnlock)(JNIEnv *), - void (**AwtNoFlushUnlock)(JNIEnv *), - void *); - -void getExtAwtData(Display *, - int32_t, - int32_t *, /* awt_depth */ - Colormap *, /* awt_cmap */ - Visual **, /* awt_visInfo.visual */ - int32_t *, /* awt_num_colors */ - void *); - -void getAwtData(int32_t *, Colormap *, Visual **, int32_t *, void *); - -Display *getAwtDisplay(void); - -#endif /* _AWT_PLUGIN_H_ */ From adcde492fa7da58311e730d0f24e6228b9cc6775 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu <zgu@openjdk.org> Date: Wed, 7 May 2014 06:03:31 -0700 Subject: [PATCH 042/157] 8041415: remove port.{cpp,hpp} files Hotspot should use standard headers and types Reviewed-by: coleenp, kvn --- hotspot/src/share/vm/adlc/adlc.hpp | 11 +- hotspot/src/share/vm/adlc/adlparse.hpp | 2 - hotspot/src/share/vm/adlc/filebuff.cpp | 2 - hotspot/src/share/vm/adlc/filebuff.hpp | 3 - hotspot/src/share/vm/adlc/output_h.cpp | 6 +- hotspot/src/share/vm/asm/assembler.cpp | 4 +- hotspot/src/share/vm/libadt/dict.cpp | 28 +-- hotspot/src/share/vm/libadt/dict.hpp | 21 +- hotspot/src/share/vm/libadt/port.cpp | 123 ----------- hotspot/src/share/vm/libadt/port.hpp | 208 ------------------ hotspot/src/share/vm/libadt/set.cpp | 9 - hotspot/src/share/vm/libadt/set.hpp | 3 - hotspot/src/share/vm/libadt/vectset.cpp | 67 +++--- hotspot/src/share/vm/libadt/vectset.hpp | 16 +- hotspot/src/share/vm/opto/block.cpp | 1 - hotspot/src/share/vm/opto/chaitin.hpp | 5 +- hotspot/src/share/vm/opto/compile.hpp | 1 - hotspot/src/share/vm/opto/divnode.cpp | 4 +- hotspot/src/share/vm/opto/domgraph.cpp | 5 +- hotspot/src/share/vm/opto/indexSet.cpp | 6 +- hotspot/src/share/vm/opto/indexSet.hpp | 24 +- hotspot/src/share/vm/opto/live.hpp | 1 - hotspot/src/share/vm/opto/loopnode.hpp | 10 +- hotspot/src/share/vm/opto/mulnode.cpp | 20 +- hotspot/src/share/vm/opto/node.hpp | 1 - hotspot/src/share/vm/opto/output.cpp | 6 +- hotspot/src/share/vm/opto/parse2.cpp | 10 +- hotspot/src/share/vm/opto/phase.hpp | 1 - hotspot/src/share/vm/opto/regmask.cpp | 6 +- hotspot/src/share/vm/opto/regmask.hpp | 5 +- hotspot/src/share/vm/opto/runtime.cpp | 2 +- hotspot/src/share/vm/opto/subnode.cpp | 4 +- hotspot/src/share/vm/opto/type.hpp | 1 - .../src/share/vm/precompiled/precompiled.hpp | 1 - 34 files changed, 120 insertions(+), 497 deletions(-) delete mode 100644 hotspot/src/share/vm/libadt/port.cpp delete mode 100644 hotspot/src/share/vm/libadt/port.hpp diff --git a/hotspot/src/share/vm/adlc/adlc.hpp b/hotspot/src/share/vm/adlc/adlc.hpp index 18f98884c3c..4ced0bf47bd 100644 --- a/hotspot/src/share/vm/adlc/adlc.hpp +++ b/hotspot/src/share/vm/adlc/adlc.hpp @@ -30,12 +30,13 @@ // // standard library constants -#include "stdio.h" -#include "stdlib.h" #include <iostream> -#include "string.h" -#include "ctype.h" -#include "stdarg.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <stdarg.h> #include <sys/types.h> /* Make sure that we have the intptr_t and uintptr_t definitions */ diff --git a/hotspot/src/share/vm/adlc/adlparse.hpp b/hotspot/src/share/vm/adlc/adlparse.hpp index 3ea00a24922..8907cf1754d 100644 --- a/hotspot/src/share/vm/adlc/adlparse.hpp +++ b/hotspot/src/share/vm/adlc/adlparse.hpp @@ -64,8 +64,6 @@ class PeepMatch; class PeepConstraint; class PeepReplace; -// class ostream; // ostream is a typedef in some systems - extern char *toUpper(const char *str); //---------------------------ADLParser----------------------------------------- diff --git a/hotspot/src/share/vm/adlc/filebuff.cpp b/hotspot/src/share/vm/adlc/filebuff.cpp index 71daa5cc4bd..bd4a8d161ed 100644 --- a/hotspot/src/share/vm/adlc/filebuff.cpp +++ b/hotspot/src/share/vm/adlc/filebuff.cpp @@ -25,8 +25,6 @@ // FILEBUFF.CPP - Routines for handling a parser file buffer #include "adlc.hpp" -using namespace std; - //------------------------------FileBuff--------------------------------------- // Create a new parsing buffer FileBuff::FileBuff( BufferedFile *fptr, ArchDesc& archDesc) : _fp(fptr), _AD(archDesc) { diff --git a/hotspot/src/share/vm/adlc/filebuff.hpp b/hotspot/src/share/vm/adlc/filebuff.hpp index 292fd1781f6..e2ed6a75665 100644 --- a/hotspot/src/share/vm/adlc/filebuff.hpp +++ b/hotspot/src/share/vm/adlc/filebuff.hpp @@ -26,9 +26,6 @@ #define SHARE_VM_ADLC_FILEBUFF_HPP // FILEBUFF.HPP - Definitions for parser file buffering routines -#include <iostream> - -using namespace std; // STRUCTURE FOR HANDLING INPUT AND OUTPUT FILES diff --git a/hotspot/src/share/vm/adlc/output_h.cpp b/hotspot/src/share/vm/adlc/output_h.cpp index 2279e75ecc5..ea401fa5d90 100644 --- a/hotspot/src/share/vm/adlc/output_h.cpp +++ b/hotspot/src/share/vm/adlc/output_h.cpp @@ -211,7 +211,7 @@ static void declareConstStorage(FILE *fp, FormDict &globals, OperandForm *oper) const char *type = oper->ideal_type(globals); if (!strcmp(type, "ConI")) { if (i > 0) fprintf(fp,", "); - fprintf(fp," int32 _c%d;\n", i); + fprintf(fp," int32_t _c%d;\n", i); } else if (!strcmp(type, "ConP")) { if (i > 0) fprintf(fp,", "); @@ -307,7 +307,7 @@ static void defineConstructor(FILE *fp, const char *name, uint num_consts, assert(num_consts == 1, "Bad component list detected.\n"); switch( constant_type ) { case Form::idealI : { - fprintf(fp,is_ideal_bool ? "BoolTest::mask c%d" : "int32 c%d", i); + fprintf(fp,is_ideal_bool ? "BoolTest::mask c%d" : "int32_t c%d", i); break; } case Form::idealN : { fprintf(fp,"const TypeNarrowOop *c%d", i); break; } @@ -326,7 +326,7 @@ static void defineConstructor(FILE *fp, const char *name, uint num_consts, while((comp = lst.iter()) != NULL) { if (!strcmp(comp->base_type(globals), "ConI")) { if (i > 0) fprintf(fp,", "); - fprintf(fp,"int32 c%d", i); + fprintf(fp,"int32_t c%d", i); i++; } else if (!strcmp(comp->base_type(globals), "ConP")) { diff --git a/hotspot/src/share/vm/asm/assembler.cpp b/hotspot/src/share/vm/asm/assembler.cpp index 0eadb5dc273..274aa872e6f 100644 --- a/hotspot/src/share/vm/asm/assembler.cpp +++ b/hotspot/src/share/vm/asm/assembler.cpp @@ -119,7 +119,7 @@ void AbstractAssembler::bind(Label& L) { L.patch_instructions((MacroAssembler*)this); } -void AbstractAssembler::generate_stack_overflow_check( int frame_size_in_bytes) { +void AbstractAssembler::generate_stack_overflow_check(int frame_size_in_bytes) { if (UseStackBanging) { // Each code entry causes one stack bang n pages down the stack where n // is configurable by StackShadowPages. The setting depends on the maximum @@ -134,7 +134,7 @@ void AbstractAssembler::generate_stack_overflow_check( int frame_size_in_bytes) // is greater than a page. const int page_size = os::vm_page_size(); - int bang_end = StackShadowPages*page_size; + int bang_end = StackShadowPages * page_size; // This is how far the previous frame's stack banging extended. const int bang_end_safe = bang_end; diff --git a/hotspot/src/share/vm/libadt/dict.cpp b/hotspot/src/share/vm/libadt/dict.cpp index 29c16bb41e0..4105ce15bbe 100644 --- a/hotspot/src/share/vm/libadt/dict.cpp +++ b/hotspot/src/share/vm/libadt/dict.cpp @@ -24,29 +24,17 @@ #include "precompiled.hpp" #include "libadt/dict.hpp" -#include "memory/allocation.inline.hpp" -#include "memory/resourceArea.hpp" -#include "runtime/thread.hpp" // Dictionaries - An Abstract Data Type // %%%%% includes not needed with AVM framework - Ungar -// #include "port.hpp" -//IMPLEMENTATION -// #include "dict.hpp" - #include <assert.h> -// The iostream is not needed and it gets confused for gcc by the -// define of bool. -// -// #include <iostream.h> - //------------------------------data----------------------------------------- // String hash tables #define MAXID 20 -static byte initflag = 0; // True after 1st initialization +static uint8_t initflag = 0; // True after 1st initialization static const char shft[MAXID] = {1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6}; static short xsum[MAXID]; @@ -281,7 +269,7 @@ void *Dict::operator [](const void *key) const { // CmpDict compares two dictionaries; they must have the same keys (their // keys must match using CmpKey) and they must have the same values (pointer // comparison). If so 1 is returned, if not 0 is returned. -int32 Dict::operator ==(const Dict &d2) const { +int32_t Dict::operator ==(const Dict &d2) const { if( _cnt != d2._cnt ) return 0; if( _hash != d2._hash ) return 0; if( _cmp != d2._cmp ) return 0; @@ -318,7 +306,7 @@ void Dict::print() { // C text shows excellent spreading of values for any size hash table. int hashstr(const void *t) { register char c, k = 0; - register int32 sum = 0; + register int32_t sum = 0; register const char *s = (const char *)t; while( ((c = *s++) != '\0') && (k < MAXID-1) ) { // Get characters till null or MAXID-1 @@ -332,11 +320,7 @@ int hashstr(const void *t) { // Slimey cheap hash function; no guaranteed performance. Better than the // default for pointers, especially on MS-DOS machines. int hashptr(const void *key) { -#ifdef __TURBOC__ - return ((intptr_t)key >> 16); -#else // __TURBOC__ - return ((intptr_t)key >> 2); -#endif + return ((intptr_t)key >> 2); } // Slimey cheap hash function; no guaranteed performance. @@ -345,12 +329,12 @@ int hashkey(const void *key) { } //------------------------------Key Comparator Functions--------------------- -int32 cmpstr(const void *k1, const void *k2) { +int32_t cmpstr(const void *k1, const void *k2) { return strcmp((const char *)k1,(const char *)k2); } // Cheap key comparator. -int32 cmpkey(const void *key1, const void *key2) { +int32_t cmpkey(const void *key1, const void *key2) { if (key1 == key2) return 0; intptr_t delta = (intptr_t)key1 - (intptr_t)key2; if (delta > 0) return 1; diff --git a/hotspot/src/share/vm/libadt/dict.hpp b/hotspot/src/share/vm/libadt/dict.hpp index dad45832de7..e3098dcc66c 100644 --- a/hotspot/src/share/vm/libadt/dict.hpp +++ b/hotspot/src/share/vm/libadt/dict.hpp @@ -25,11 +25,12 @@ #ifndef SHARE_VM_LIBADT_DICT_HPP #define SHARE_VM_LIBADT_DICT_HPP -#include "libadt/port.hpp" - // Dictionaries - An Abstract Data Type -//INTERFACE -class ostream; + +#include "memory/allocation.inline.hpp" +#include "memory/resourceArea.hpp" +#include "runtime/thread.hpp" + class Dict; // These dictionaries define a key-value mapping. They can be inserted to, @@ -38,7 +39,7 @@ class Dict; // key comparison routine determines if two keys are equal or not. A hash // function can be provided; if it's not provided the key itself is used // instead. A nice string hash function is included. -typedef int32 (*CmpKey)(const void *key1, const void *key2); +typedef int32_t (*CmpKey)(const void *key1, const void *key2); typedef int (*Hash)(const void *key); typedef void (*FuncDict)(const void *key, const void *val, Dict *d); @@ -47,7 +48,7 @@ class Dict : public ResourceObj { // Dictionary structure class Arena *_arena; // Where to draw storage from class bucket *_bin; // Hash table is array of buckets uint _size; // Size (# of slots) in hash table - uint32 _cnt; // Number of key-value pairs in hash table + uint32_t _cnt; // Number of key-value pairs in hash table const Hash _hash; // Hashing function const CmpKey _cmp; // Key comparison function void doubhash( void ); // Double hash table size @@ -67,7 +68,7 @@ class Dict : public ResourceObj { // Dictionary structure void Clear(); // Return # of key-value pairs in dict - uint32 Size(void) const { return _cnt; } + uint32_t Size(void) const { return _cnt; } // Insert inserts the given key-value pair into the dictionary. The prior // value of the key is returned; NULL if the key was not previously defined. @@ -81,7 +82,7 @@ class Dict : public ResourceObj { // Dictionary structure // == compares two dictionaries; they must have the same keys (their keys // must match using CmpKey) and they must have the same values (pointer // comparison). If so 1 is returned, if not 0 is returned. - int32 operator ==(const Dict &d) const; // Compare dictionaries for equal + int32_t operator ==(const Dict &d) const; // Compare dictionaries for equal // Print out the dictionary contents as key-value pairs void print(); @@ -96,9 +97,9 @@ int hashptr(const void *key); int hashkey(const void *key); // Key comparators -int32 cmpstr(const void *k1, const void *k2); +int32_t cmpstr(const void *k1, const void *k2); // Slimey cheap key comparator. -int32 cmpkey(const void *key1, const void *key2); +int32_t cmpkey(const void *key1, const void *key2); //------------------------------Iteration-------------------------------------- // The class of dictionary iterators. Fails in the presences of modifications diff --git a/hotspot/src/share/vm/libadt/port.cpp b/hotspot/src/share/vm/libadt/port.cpp deleted file mode 100644 index 165b301846d..00000000000 --- a/hotspot/src/share/vm/libadt/port.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 1997, 2010, 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. - * - */ - -#include "precompiled.hpp" -#include "libadt/port.hpp" - -// Code for portable compiling - -#ifdef __GNUC__ -#pragma implementation -#endif - -// %%%%% includes not needed with AVM framework - Ungar -// #include "port.hpp" - -// This is only used if turboc is used and it causes problems with -// gcc. -#ifdef __TURBOC__ -#include <iostream.h> -#endif - -#include <stdio.h> - -//------------------------------gcd-------------------------------------------- -// Greatest common divisor -uint32 gcd( register uint32 x, register uint32 y ) -{ - register uint32 tmp; - while( x ) { // While not zero - tmp = x; // Hold onto smaller x value - x = y % x; // Compute modulus; since y>=x, 0 <= mod < x - y = tmp; // y = old x - } - return y; -} - -//----------------------------------------------------------------------------- -// Find first 1, or return 32 if empty -int ff1( uint32 mask ) -{ - unsigned i, n = 0; - - for( i=1, n=0; i; i<<=1, n++) - if( mask&i ) return n; - return 32; -} - -//----------------------------------------------------------------------------- -// Find highest 1, or return 32 if empty -int fh1( uint32 mask ) -{ - unsigned i, n = 0; - - for( i=((uint32)1<<31), n=31; i; i>>=1, n--) - if( mask&i ) return n; - return 32; -} - -//------------------------------rotate32--------------------------------------- -// Rotate 32bits. Postive rotates left (bits move toward high-order bit), -// negative rotates right. -uint32 rotate32( register uint32 x, register int32 cnt ) -{ - if( cnt >= 0 ) { // Positive rotates left - cnt &= 31; // Mask off extra shift bits - } else { // Negative rotates right - cnt = (-cnt)&31; // Flip sign; mask extra shift bits - cnt = 32-cnt; // Rotate right by big left rotation - } - return (x << cnt) | (x >> (32-cnt)); -} - -/* Disabled - we have another log2 in the system. - This function doesn't work if used as substitute - for the existing log2. Keep around until we have - verified all uses of log2 do the correct thing! -//------------------------------log2------------------------------------------- -// Log base 2. Might also be called 'count leading zeros'. Log2(x) returns -// an l such that (1L<<l) <= x < (2L<<l). log2(x) returns 32. -uint log2( uint32 x ) -{ - register uint l = 32; // Log bits - register int32 sx = x; // Treat as signed number - while( sx >= 0 ) // While high bit is clear - sx <<= 1, l--; // Shift bits left, count down log2 - return l; -} -*/ - -//------------------------------print------------------------------------------ -// Print a pointer without modifying the contents -#ifdef __TURBOC__ -ostream &ostream::operator << (const void *ptr) -{ - return (*this) << "0x" << hex << (uint)ptr << dec; -} -#else -/*ostream &operator << (ostream &os, const void *ptr) -{ - return os << "0x" << hex << (uint)ptr << dec; -}*/ -#endif diff --git a/hotspot/src/share/vm/libadt/port.hpp b/hotspot/src/share/vm/libadt/port.hpp deleted file mode 100644 index 358ab3021c1..00000000000 --- a/hotspot/src/share/vm/libadt/port.hpp +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 1997, 2013, 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. - * - */ - -#ifndef SHARE_VM_LIBADT_PORT_HPP -#define SHARE_VM_LIBADT_PORT_HPP - -#include "utilities/top.hpp" - -// Typedefs for portable compiling - -#if defined(__GNUC__) - -#define INTERFACE #pragma interface -#define IMPLEMENTATION #pragma implementation -//INTERFACE -#include <stddef.h> -#include <stdlib.h> -#include <string.h> - -// Access to the C++ class virtual function pointer -// Put the class in the macro -typedef void *VPTR; -// G++ puts it at the end of the base class -#define ACCESS_VPTR(class) VPTR&vptr(){return*(VPTR*)((char*)this+sizeof(class)-sizeof(void*));} - -#elif defined(__TURBOC__) - -#include <mem.h> -#include <string.h> -extern "C" int stricmp(const char *, const char *); -inline void bcopy(const void *s, void *d, int l) { memmove(d,s,l); } -inline void bzero(void *p, int l) { memset(p,0,l); } -inline int bcmp(const void *s, const void *d, int l) { return memcmp(s,d,l); } -inline int min( int a, int b) { return a < b ? a : b; } -inline int max( int a, int b) { return a > b ? a : b; } -//strcasecmp moved to globalDefinitions_visCPP.hpp -//inline int strcasecmp(const char *s1, const char *s2) { return stricmp(s1,s2); } -inline long abs( long x ) { return x < 0 ? -x : x; } -// Access to the C++ class virtual function pointer -// Put the class in the macro -typedef void near *VPTR; -// BorlandC puts it up front -#define ACCESS_VPTR(class) VPTR&vptr(){return*(VPTR*)this;} - -#elif defined(__hpux) - -#define INTERFACE -#define IMPLEMENTATION -#define signed -#include <strings.h> -#include <stdlib.h> -inline long min( long a, long b) { return a < b ? a : b; } -inline long max( long a, long b) { return a > b ? a : b; } -inline int min( int a, int b) { return a < b ? a : b; } -inline int max( int a, int b) { return a > b ? a : b; } -inline long abs( long x ) { return x < 0 ? -x : x; } - -#elif defined(__MOTO__) -// Motorola's mcc -#define INTERFACE -#define IMPLEMENTATION -#include <stdlib.h> -#include <memory.h> -inline int min( int a, int b) { return a < b ? a : b; } -inline int max( int a, int b) { return a > b ? a : b; } - -#elif defined(_AIX) -// IBM's xlC compiler -#define INTERFACE -#define IMPLEMENTATION -#include <stdlib.h> -#include <memory.h> - -#elif defined(_MSC_VER) -// Microsoft Visual C++ -//#define INTERFACE -#define IMPLEMENTATION -#include <stdlib.h> -#undef small -//strcasecmp moved to globalDefinitions_visCPP.hpp -//inline int strcasecmp(const char *s1, const char *s2) { return stricmp(s1,s2); } - - -#elif defined(SPARC_WORKS) - -#define INTERFACE -#define IMPLEMENTATION - -#include <stddef.h> -#include <stdlib.h> -#include <string.h> - -#elif defined(SOLARIS) - -#define INTERFACE -#define IMPLEMENTATION - -#include <stddef.h> -#include <stdlib.h> -#include <string.h> - - -#elif defined(__TANDEM) - -// This case is for the Tandem Business Unit of Compaq Computer Corporation. -// The Tandem case must precede the AT&T case, -// because the Tandem c89 compiler also defines __cplusplus. - -#include "port_tandem.hpp" - -#elif defined(__cplusplus) -// AT&Ts cfront -#define INTERFACE -#define IMPLEMENTATION -#include <unistd.h> -#define signed -// #include <bstring.h> -inline int min( int a, int b) { return a < b ? a : b; } -inline int max( int a, int b) { return a > b ? a : b; } - -#else // All other machines - -#define signed -extern "C" void bcopy(void *b1, void *b2, int len); -inline int min( int a, int b) { return a < b ? a : b; } -inline int max( int a, int b) { return a > b ? a : b; } - -#endif - -//----------------------------------------------------------------------------- -// Safer memory allocations -#ifdef SAFE_MEMORY -#define malloc(size) safe_malloc(__FILE__,__LINE__,size) -#define free(ptr) safe_free(__FILE__,__LINE__,ptr) -#define realloc(ptr,size) safe_realloc(__FILE__,__LINE__,ptr,size) -#define calloc(nitems,size) safe_calloc(__FILE__,__LINE__,nitems,size) -#define strdup(ptr) safe_strdup(__FILE__,__LINE__,ptr) -extern void *safe_malloc (const char *file, unsigned line, unsigned size); -extern void safe_free (const char *file, unsigned line, void *ptr); -extern void *safe_calloc (const char *file, unsigned line, unsigned nitems, unsigned size); -extern void *safe_realloc(const char *file, unsigned line, void *ptr, unsigned size); -extern char *safe_strdup (const char *file, unsigned line, const char *src); -inline void *operator new( size_t size ) throw() { return malloc(size); } -inline void operator delete( void *ptr ) { free(ptr); } -#endif - -//----------------------------------------------------------------------------- -// And now, the bit-size-specified integer sizes -typedef signed char int8; -typedef unsigned char uint8; -typedef unsigned char byte; - -// All uses of *int16 changed to 32-bit to speed up compiler on Intel -//typedef signed short int16; // Exactly 16bits signed -//typedef unsigned short uint16; // Exactly 16bits unsigned -//const unsigned int min_uint16 = 0x0000; // smallest uint16 -//const unsigned int max_uint16 = 0xFFFF; // largest uint16 - -typedef unsigned int uint; // When you need a fast >=16bit unsigned value -/*typedef int int; */ // When you need a fast >=16bit value -const unsigned int max_uint = (uint)-1; -typedef int32_t int32; // Exactly 32bits signed -typedef uint32_t uint32; // Exactly 32bits unsigned - -// Bit-sized floating point and long thingies -#ifndef __TANDEM -// Do not define these for Tandem, because they conflict with typedefs in softieee.h. -typedef float float32; // 32-bit float -typedef double float64; // 64-bit float -#endif // __TANDEM - -typedef jlong int64; // Java long for my 64-bit type -typedef julong uint64; // Java long for my 64-bit type - -//----------------------------------------------------------------------------- -// Nice constants -uint32 gcd( uint32 x, uint32 y ); -int ff1( uint32 mask ); -int fh1( uint32 mask ); -uint32 rotate32( uint32 x, int32 cnt ); - - -//----------------------------------------------------------------------------- -extern uint32 heap_totalmem; // Current total memory allocation -extern uint32 heap_highwater; // Highwater mark to date for memory usage - -#endif // SHARE_VM_LIBADT_PORT_HPP diff --git a/hotspot/src/share/vm/libadt/set.cpp b/hotspot/src/share/vm/libadt/set.cpp index 7364795ed70..d52f5c7fb76 100644 --- a/hotspot/src/share/vm/libadt/set.cpp +++ b/hotspot/src/share/vm/libadt/set.cpp @@ -28,20 +28,11 @@ // Sets - An Abstract Data Type -// %%%%% includes not needed with AVM framework - Ungar -// #include "port.hpp" -//IMPLEMENTATION -// #include "set.hpp" - #include <stdio.h> #include <assert.h> #include <string.h> #include <stdlib.h> -// Not needed and it causes terouble for gcc. -// -// #include <iostream.h> - //-------------------------Virtual Functions----------------------------------- // These functions MUST be implemented by the inheriting class. class SparseSet; diff --git a/hotspot/src/share/vm/libadt/set.hpp b/hotspot/src/share/vm/libadt/set.hpp index f3b3533eb87..3c66e561566 100644 --- a/hotspot/src/share/vm/libadt/set.hpp +++ b/hotspot/src/share/vm/libadt/set.hpp @@ -25,13 +25,10 @@ #ifndef SHARE_VM_LIBADT_SET_HPP #define SHARE_VM_LIBADT_SET_HPP -#include "libadt/port.hpp" #include "memory/allocation.hpp" // Sets - An Abstract Data Type -//INTERFACE - class SparseSet; class VectorSet; class ListSet; diff --git a/hotspot/src/share/vm/libadt/vectset.cpp b/hotspot/src/share/vm/libadt/vectset.cpp index ab80afef681..256b0a9a1a9 100644 --- a/hotspot/src/share/vm/libadt/vectset.cpp +++ b/hotspot/src/share/vm/libadt/vectset.cpp @@ -28,15 +28,10 @@ // Vector Sets - An Abstract Data Type -// %%%%% includes not needed with AVM framework - Ungar -// #include "port.hpp" -//IMPLEMENTATION -// #include "vectset.hpp" - // BitsInByte is a lookup table which tells the number of bits that // are in the looked-up number. It is very useful in VectorSet_Size. -uint8 bitsInByte[256] = { +uint8_t bitsInByte[256] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, @@ -59,7 +54,7 @@ uint8 bitsInByte[256] = { // Create a new, empty Set. VectorSet::VectorSet(Arena *arena) : Set(arena) { size = 2; // Small initial size - data = (uint32 *)_set_arena->Amalloc(size*sizeof(uint32)); + data = (uint32_t *)_set_arena->Amalloc(size*sizeof(uint32_t)); data[0] = 0; // No elements data[1] = 0; } @@ -85,8 +80,8 @@ Set &VectorSet::operator = (const Set &set) void VectorSet::slamin(const VectorSet& s) { size = s.size; // Use new size - data = (uint32*)s._set_arena->Amalloc(size*sizeof(uint32)); // Make array of required size - memcpy( data, s.data, size*sizeof(uint32) ); // Fill the array + data = (uint32_t*)s._set_arena->Amalloc(size*sizeof(uint32_t)); // Make array of required size + memcpy( data, s.data, size*sizeof(uint32_t) ); // Fill the array } //------------------------------grow------------------------------------------- @@ -96,8 +91,8 @@ void VectorSet::grow( uint newsize ) newsize = (newsize+31) >> 5; // Convert to longwords uint x = size; while( x < newsize ) x <<= 1; - data = (uint32 *)_set_arena->Arealloc(data, size*sizeof(uint32), x*sizeof(uint32)); - memset((char *)(data + size), 0, (x - size)*sizeof(uint32)); + data = (uint32_t *)_set_arena->Arealloc(data, size*sizeof(uint32_t), x*sizeof(uint32_t)); + memset((char *)(data + size), 0, (x - size)*sizeof(uint32_t)); size = x; } @@ -106,7 +101,7 @@ void VectorSet::grow( uint newsize ) Set &VectorSet::operator <<= (uint elem) { register uint word = elem >> 5; // Get the longword offset - register uint32 mask = 1L << (elem & 31); // Get bit mask + register uint32_t mask = 1L << (elem & 31); // Get bit mask if( word >= size ) // Need to grow set? grow(elem+1); // Then grow it @@ -121,7 +116,7 @@ Set &VectorSet::operator >>= (uint elem) register uint word = elem >> 5; // Get the longword offset if( word >= size ) // Beyond the last? return *this; // Then it's clear & return clear - register uint32 mask = 1L << (elem & 31); // Get bit mask + register uint32_t mask = 1L << (elem & 31); // Get bit mask data[word] &= ~mask; // Clear bit return *this; } @@ -132,8 +127,8 @@ VectorSet &VectorSet::operator &= (const VectorSet &s) { // NOTE: The intersection is never any larger than the smallest set. if( s.size < size ) size = s.size; // Get smaller size - register uint32 *u1 = data; // Pointer to the destination data - register uint32 *u2 = s.data; // Pointer to the source data + register uint32_t *u1 = data; // Pointer to the destination data + register uint32_t *u2 = s.data; // Pointer to the source data for( uint i=0; i<size; i++) // For data in set *u1++ &= *u2++; // Copy and AND longwords return *this; // Return set @@ -152,14 +147,14 @@ VectorSet &VectorSet::operator |= (const VectorSet &s) { // This many words must be unioned register uint cnt = ((size<s.size)?size:s.size); - register uint32 *u1 = data; // Pointer to the destination data - register uint32 *u2 = s.data; // Pointer to the source data + register uint32_t *u1 = data; // Pointer to the destination data + register uint32_t *u2 = s.data; // Pointer to the source data for( uint i=0; i<cnt; i++) // Copy and OR the two sets *u1++ |= *u2++; if( size < s.size ) { // Is set 2 larger than set 1? // Extend result by larger set - grow(s.size*sizeof(uint32)*8); - memcpy(&data[cnt], u2, (s.size - cnt)*sizeof(uint32)); + grow(s.size*sizeof(uint32_t)*8); + memcpy(&data[cnt], u2, (s.size - cnt)*sizeof(uint32_t)); } return *this; // Return result set } @@ -177,8 +172,8 @@ VectorSet &VectorSet::operator -= (const VectorSet &s) { // This many words must be unioned register uint cnt = ((size<s.size)?size:s.size); - register uint32 *u1 = data; // Pointer to the destination data - register uint32 *u2 = s.data; // Pointer to the source data + register uint32_t *u1 = data; // Pointer to the destination data + register uint32_t *u2 = s.data; // Pointer to the source data for( uint i=0; i<cnt; i++ ) // For data in set *u1++ &= ~(*u2++); // A <-- A & ~B with longwords return *this; // Return new set @@ -199,17 +194,17 @@ Set &VectorSet::operator -= (const Set &set) // 1X -- B is a subset of A int VectorSet::compare (const VectorSet &s) const { - register uint32 *u1 = data; // Pointer to the destination data - register uint32 *u2 = s.data; // Pointer to the source data - register uint32 AnotB = 0, BnotA = 0; + register uint32_t *u1 = data; // Pointer to the destination data + register uint32_t *u2 = s.data; // Pointer to the source data + register uint32_t AnotB = 0, BnotA = 0; // This many words must be unioned register uint cnt = ((size<s.size)?size:s.size); // Get bits for both sets uint i; // Exit value of loop for( i=0; i<cnt; i++ ) { // For data in BOTH sets - register uint32 A = *u1++; // Data from one guy - register uint32 B = *u2++; // Data from other guy + register uint32_t A = *u1++; // Data from one guy + register uint32_t B = *u2++; // Data from other guy AnotB |= (A & ~B); // Compute bits in A not B BnotA |= (B & ~A); // Compute bits in B not A } @@ -250,8 +245,8 @@ int VectorSet::disjoint(const Set &set) const // NOTE: The intersection is never any larger than the smallest set. register uint small_size = ((size<s.size)?size:s.size); - register uint32 *u1 = data; // Pointer to the destination data - register uint32 *u2 = s.data; // Pointer to the source data + register uint32_t *u1 = data; // Pointer to the destination data + register uint32_t *u2 = s.data; // Pointer to the source data for( uint i=0; i<small_size; i++) // For data in set if( *u1++ & *u2++ ) // If any elements in common return 0; // Then not disjoint @@ -293,7 +288,7 @@ int VectorSet::operator[](uint elem) const register uint word = elem >> 5; // Get the longword offset if( word >= size ) // Beyond the last? return 0; // Then it's clear - register uint32 mask = 1L << (elem & 31); // Get bit mask + register uint32_t mask = 1L << (elem & 31); // Get bit mask return ((data[word] & mask))!=0; // Return the sense of the bit } @@ -305,7 +300,7 @@ uint VectorSet::getelem(void) const for( i=0; i<size; i++ ) if( data[i] ) break; - uint32 word = data[i]; + uint32_t word = data[i]; int j; // Exit value of loop for( j= -1; word; j++, word>>=1 ); return (i<<5)+j; @@ -316,11 +311,11 @@ uint VectorSet::getelem(void) const void VectorSet::Clear(void) { if( size > 100 ) { // Reclaim storage only if huge - FREE_RESOURCE_ARRAY(uint32,data,size); + FREE_RESOURCE_ARRAY(uint32_t,data,size); size = 2; // Small initial size - data = NEW_RESOURCE_ARRAY(uint32,size); + data = NEW_RESOURCE_ARRAY(uint32_t,size); } - memset( data, 0, size*sizeof(uint32) ); + memset( data, 0, size*sizeof(uint32_t) ); } //------------------------------Size------------------------------------------- @@ -328,8 +323,8 @@ void VectorSet::Clear(void) uint VectorSet::Size(void) const { uint sum = 0; // Cumulative size so far. - uint8 *currByte = (uint8*)data; - for( uint32 i = 0; i < (size<<2); i++) // While have bytes to process + uint8_t* currByte = (uint8_t*) data; + for( uint32_t i = 0; i < (size<<2); i++) // While have bytes to process sum += bitsInByte[*currByte++]; // Add bits in current byte to size. return sum; } @@ -343,7 +338,7 @@ void VectorSet::Sort(void) //------------------------------hash------------------------------------------- int VectorSet::hash() const { - uint32 _xor = 0; + uint32_t _xor = 0; uint lim = ((size<4)?size:4); for( uint i = 0; i < lim; i++ ) _xor ^= data[i]; diff --git a/hotspot/src/share/vm/libadt/vectset.hpp b/hotspot/src/share/vm/libadt/vectset.hpp index 552fdd17bee..d94ce44d35f 100644 --- a/hotspot/src/share/vm/libadt/vectset.hpp +++ b/hotspot/src/share/vm/libadt/vectset.hpp @@ -47,7 +47,7 @@ class VectorSet : public Set { friend class VectorSetI; // Friendly iterator class protected: uint size; // Size of data IN LONGWORDS (32bits) - uint32 *data; // The data, bit packed + uint32_t* data; // The data, bit packed void slamin( const VectorSet& s ); // Initialize one set with another int compare(const VectorSet &s) const; // Compare set contents @@ -99,7 +99,7 @@ public: void Sort(void); // Sort before iterating int hash() const; // Hash function void Reset(void) { // Reset a set - memset( data, 0, size*sizeof(uint32) ); + memset( data, 0, size*sizeof(uint32_t) ); } /* Removed for MCC BUG @@ -108,7 +108,7 @@ public: // Expose internals for speed-critical fast iterators uint word_size() const { return size; } - uint32 *EXPOSE() const { return data; } + uint32_t* EXPOSE() const { return data; } // Fast inlined "test and set". Replaces the idiom: // if( visited[idx] ) return; @@ -120,8 +120,8 @@ public: uint word = elem >> 5; // Get the longword offset if( word >= size ) // Beyond the last? return test_set_grow(elem); // Then grow; set; return 0; - uint32 mask = 1L << (elem & 31); // Get bit mask - uint32 datum = data[word] & mask;// Get bit + uint32_t mask = 1L << (elem & 31); // Get bit mask + uint32_t datum = data[word] & mask;// Get bit data[word] |= mask; // Set bit return datum; // Return bit } @@ -134,7 +134,7 @@ public: int test( uint elem ) const { uint word = elem >> 5; // Get the longword offset if( word >= size ) return 0; // Beyond the last? - uint32 mask = 1L << (elem & 31); // Get bit mask + uint32_t mask = 1L << (elem & 31); // Get bit mask return data[word] & mask; // Get bit } @@ -144,7 +144,7 @@ public: if( word >= size ) { // Beyond the last? test_set_grow(elem); // Then grow and set } else { - uint32 mask = 1L << (elem & 31); // Get bit mask + uint32_t mask = 1L << (elem & 31); // Get bit mask data[word] |= mask; // Set bit } } @@ -164,7 +164,7 @@ class VectorSetI : public StackObj { friend class VectorSet; const VectorSet *s; uint i, j; - uint32 mask; + uint32_t mask; uint next(void); public: diff --git a/hotspot/src/share/vm/opto/block.cpp b/hotspot/src/share/vm/opto/block.cpp index 3eaa2abcb7c..6b621f02c05 100644 --- a/hotspot/src/share/vm/opto/block.cpp +++ b/hotspot/src/share/vm/opto/block.cpp @@ -1268,7 +1268,6 @@ void UnionFind::extend( uint from_idx, uint to_idx ) { } void UnionFind::reset( uint max ) { - assert( max <= max_uint, "Must fit within uint" ); // Force the Union-Find mapping to be at least this large extend(max,0); // Initialize to be the ID mapping. diff --git a/hotspot/src/share/vm/opto/chaitin.hpp b/hotspot/src/share/vm/opto/chaitin.hpp index f11b5b1f416..99194cfe925 100644 --- a/hotspot/src/share/vm/opto/chaitin.hpp +++ b/hotspot/src/share/vm/opto/chaitin.hpp @@ -26,7 +26,6 @@ #define SHARE_VM_OPTO_CHAITIN_HPP #include "code/vmreg.hpp" -#include "libadt/port.hpp" #include "memory/resourceArea.hpp" #include "opto/connode.hpp" #include "opto/live.hpp" @@ -142,7 +141,7 @@ public: // Number of registers this live range uses when it colors private: - uint8 _num_regs; // 2 for Longs and Doubles, 1 for all else + uint8_t _num_regs; // 2 for Longs and Doubles, 1 for all else // except _num_regs is kill count for fat_proj public: int num_regs() const { return _num_regs; } @@ -151,7 +150,7 @@ public: private: // Number of physical registers this live range uses when it colors // Architecture and register-set dependent - uint8 _reg_pressure; + uint8_t _reg_pressure; public: void set_reg_pressure(int i) { _reg_pressure = i; } int reg_pressure() const { return _reg_pressure; } diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp index 76ff09226ea..5c74e931ae5 100644 --- a/hotspot/src/share/vm/opto/compile.hpp +++ b/hotspot/src/share/vm/opto/compile.hpp @@ -32,7 +32,6 @@ #include "compiler/compilerOracle.hpp" #include "compiler/compileBroker.hpp" #include "libadt/dict.hpp" -#include "libadt/port.hpp" #include "libadt/vectset.hpp" #include "memory/resourceArea.hpp" #include "opto/idealGraphPrinter.hpp" diff --git a/hotspot/src/share/vm/opto/divnode.cpp b/hotspot/src/share/vm/opto/divnode.cpp index f577c8b5125..40bd21fbc4c 100644 --- a/hotspot/src/share/vm/opto/divnode.cpp +++ b/hotspot/src/share/vm/opto/divnode.cpp @@ -514,7 +514,7 @@ const Type *DivINode::Value( PhaseTransform *phase ) const { int widen = MAX2(i1->_widen, i2->_widen); if( i2->is_con() && i2->get_con() != 0 ) { - int32 d = i2->get_con(); // Divisor + int32_t d = i2->get_con(); // Divisor jint lo, hi; if( d >= 0 ) { lo = i1->_lo/d; @@ -536,7 +536,7 @@ const Type *DivINode::Value( PhaseTransform *phase ) const { // If the dividend is a constant if( i1->is_con() ) { - int32 d = i1->get_con(); + int32_t d = i1->get_con(); if( d < 0 ) { if( d == min_jint ) { // (-min_jint) == min_jint == (min_jint / -1) diff --git a/hotspot/src/share/vm/opto/domgraph.cpp b/hotspot/src/share/vm/opto/domgraph.cpp index a7fa0532763..0be96ad7f71 100644 --- a/hotspot/src/share/vm/opto/domgraph.cpp +++ b/hotspot/src/share/vm/opto/domgraph.cpp @@ -397,8 +397,9 @@ void PhaseIdealLoop::Dominators() { ntarjan[i]._control = NULL; // Store the DFS order for the main loop + const uint fill_value = max_juint; uint *dfsorder = NEW_RESOURCE_ARRAY(uint,C->unique()+1); - memset(dfsorder, max_uint, (C->unique()+1) * sizeof(uint)); + memset(dfsorder, fill_value, (C->unique()+1) * sizeof(uint)); // Tarjan's algorithm, almost verbatim: // Step 1: @@ -419,7 +420,7 @@ void PhaseIdealLoop::Dominators() { if( whead->in(j) == NULL || !whead->in(j)->is_CFG() ) continue; // Only process control nodes uint b = dfsorder[whead->in(j)->_idx]; - if(b == max_uint) continue; + if(b == fill_value) continue; NTarjan *vx = &ntarjan[b]; NTarjan *u = vx->EVAL(); if( u->_semi < w->_semi ) diff --git a/hotspot/src/share/vm/opto/indexSet.cpp b/hotspot/src/share/vm/opto/indexSet.cpp index 4ba99e72783..d2172d157b3 100644 --- a/hotspot/src/share/vm/opto/indexSet.cpp +++ b/hotspot/src/share/vm/opto/indexSet.cpp @@ -51,7 +51,7 @@ int IndexSet::_serial_count = 1; #endif // What is the first set bit in a 5 bit integer? -const byte IndexSetIterator::_first_bit[32] = { +const uint8_t IndexSetIterator::_first_bit[32] = { 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, @@ -63,7 +63,7 @@ const byte IndexSetIterator::_first_bit[32] = { }; // What is the second set bit in a 5 bit integer? -const byte IndexSetIterator::_second_bit[32] = { +const uint8_t IndexSetIterator::_second_bit[32] = { 5, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, @@ -298,7 +298,7 @@ IndexSet::IndexSet (IndexSet *set) { set_block(i, &_empty_block); } else { BitBlock *new_block = alloc_block(); - memcpy(new_block->words(), block->words(), sizeof(uint32) * words_per_block); + memcpy(new_block->words(), block->words(), sizeof(uint32_t) * words_per_block); set_block(i, new_block); } } diff --git a/hotspot/src/share/vm/opto/indexSet.hpp b/hotspot/src/share/vm/opto/indexSet.hpp index ef5aed18b67..366c9d5843b 100644 --- a/hotspot/src/share/vm/opto/indexSet.hpp +++ b/hotspot/src/share/vm/opto/indexSet.hpp @@ -106,12 +106,12 @@ class IndexSet : public ResourceObj { // is used by IndexSet to mainting this free list. union { - uint32 _words[words_per_block]; + uint32_t _words[words_per_block]; BitBlock *_next; } _data; // accessors - uint32 *words() { return _data._words; } + uint32_t* words() { return _data._words; } void set_next(BitBlock *next) { _data._next = next; } BitBlock *next() { return _data._next; } @@ -120,22 +120,22 @@ class IndexSet : public ResourceObj { // not assume that the block index has been masked out. void clear() { - memset(words(), 0, sizeof(uint32) * words_per_block); + memset(words(), 0, sizeof(uint32_t) * words_per_block); } bool member(uint element) { uint word_index = IndexSet::get_word_index(element); uint bit_index = IndexSet::get_bit_index(element); - return ((words()[word_index] & (uint32)(0x1 << bit_index)) != 0); + return ((words()[word_index] & (uint32_t)(0x1 << bit_index)) != 0); } bool insert(uint element) { uint word_index = IndexSet::get_word_index(element); uint bit_index = IndexSet::get_bit_index(element); - uint32 bit = (0x1 << bit_index); - uint32 before = words()[word_index]; + uint32_t bit = (0x1 << bit_index); + uint32_t before = words()[word_index]; words()[word_index] = before | bit; return ((before & bit) != 0); } @@ -144,8 +144,8 @@ class IndexSet : public ResourceObj { uint word_index = IndexSet::get_word_index(element); uint bit_index = IndexSet::get_bit_index(element); - uint32 bit = (0x1 << bit_index); - uint32 before = words()[word_index]; + uint32_t bit = (0x1 << bit_index); + uint32_t before = words()[word_index]; words()[word_index] = before & ~bit; return ((before & bit) != 0); } @@ -404,14 +404,14 @@ class IndexSetIterator VALUE_OBJ_CLASS_SPEC { table_size = (1 << window_size) }; // For an integer of length window_size, what is the first set bit? - static const byte _first_bit[table_size]; + static const uint8_t _first_bit[table_size]; // For an integer of length window_size, what is the second set bit? - static const byte _second_bit[table_size]; + static const uint8_t _second_bit[table_size]; private: // The current word we are inspecting - uint32 _current; + uint32_t _current; // What element number are we currently on? uint _value; @@ -420,7 +420,7 @@ class IndexSetIterator VALUE_OBJ_CLASS_SPEC { uint _next_word; // A pointer to the contents of the current block - uint32 *_words; + uint32_t *_words; // The index of the next block we will inspect uint _next_block; diff --git a/hotspot/src/share/vm/opto/live.hpp b/hotspot/src/share/vm/opto/live.hpp index 343c5c6f727..9c779b2c2f0 100644 --- a/hotspot/src/share/vm/opto/live.hpp +++ b/hotspot/src/share/vm/opto/live.hpp @@ -25,7 +25,6 @@ #ifndef SHARE_VM_OPTO_LIVE_HPP #define SHARE_VM_OPTO_LIVE_HPP -#include "libadt/port.hpp" #include "libadt/vectset.hpp" #include "opto/block.hpp" #include "opto/indexSet.hpp" diff --git a/hotspot/src/share/vm/opto/loopnode.hpp b/hotspot/src/share/vm/opto/loopnode.hpp index 59915ffed6f..5c962ae9981 100644 --- a/hotspot/src/share/vm/opto/loopnode.hpp +++ b/hotspot/src/share/vm/opto/loopnode.hpp @@ -339,11 +339,11 @@ public: Node_List _body; // Loop body for inner loops - uint8 _nest; // Nesting depth - uint8 _irreducible:1, // True if irreducible - _has_call:1, // True if has call safepoint - _has_sfpt:1, // True if has non-call safepoint - _rce_candidate:1; // True if candidate for range check elimination + uint8_t _nest; // Nesting depth + uint8_t _irreducible:1, // True if irreducible + _has_call:1, // True if has call safepoint + _has_sfpt:1, // True if has non-call safepoint + _rce_candidate:1; // True if candidate for range check elimination Node_List* _safepts; // List of safepoints in this loop Node_List* _required_safept; // A inner loop cannot delete these safepts; diff --git a/hotspot/src/share/vm/opto/mulnode.cpp b/hotspot/src/share/vm/opto/mulnode.cpp index 861149afca5..056d8c5043a 100644 --- a/hotspot/src/share/vm/opto/mulnode.cpp +++ b/hotspot/src/share/vm/opto/mulnode.cpp @@ -235,23 +235,23 @@ const Type *MulINode::mul_ring(const Type *t0, const Type *t1) const { const TypeInt *r1 = t1->is_int(); // Fetch endpoints of all ranges - int32 lo0 = r0->_lo; + int32_t lo0 = r0->_lo; double a = (double)lo0; - int32 hi0 = r0->_hi; + int32_t hi0 = r0->_hi; double b = (double)hi0; - int32 lo1 = r1->_lo; + int32_t lo1 = r1->_lo; double c = (double)lo1; - int32 hi1 = r1->_hi; + int32_t hi1 = r1->_hi; double d = (double)hi1; // Compute all endpoints & check for overflow - int32 A = lo0*lo1; + int32_t A = lo0*lo1; if( (double)A != a*c ) return TypeInt::INT; // Overflow? - int32 B = lo0*hi1; + int32_t B = lo0*hi1; if( (double)B != a*d ) return TypeInt::INT; // Overflow? - int32 C = hi0*lo1; + int32_t C = hi0*lo1; if( (double)C != b*c ) return TypeInt::INT; // Overflow? - int32 D = hi0*hi1; + int32_t D = hi0*hi1; if( (double)D != b*d ) return TypeInt::INT; // Overflow? if( A < B ) { lo0 = A; hi0 = B; } // Sort range endpoints @@ -1228,12 +1228,12 @@ const Type *URShiftINode::Value( PhaseTransform *phase ) const { // // const TypeInstPtr *o = t1->is_instptr(); // if( t1->singleton() ) - // return TypeInt::make( ((uint32)o->const_oop() + o->_offset) >> shift ); + // return TypeInt::make( ((uint32_t)o->const_oop() + o->_offset) >> shift ); // } // else if( t1->base() == Type::KlassPtr ) { // const TypeKlassPtr *o = t1->is_klassptr(); // if( t1->singleton() ) - // return TypeInt::make( ((uint32)o->const_oop() + o->_offset) >> shift ); + // return TypeInt::make( ((uint32_t)o->const_oop() + o->_offset) >> shift ); // } return TypeInt::INT; diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp index 0b51d04875d..67db16f154b 100644 --- a/hotspot/src/share/vm/opto/node.hpp +++ b/hotspot/src/share/vm/opto/node.hpp @@ -25,7 +25,6 @@ #ifndef SHARE_VM_OPTO_NODE_HPP #define SHARE_VM_OPTO_NODE_HPP -#include "libadt/port.hpp" #include "libadt/vectset.hpp" #include "opto/compile.hpp" #include "opto/type.hpp" diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp index ede7534642d..d47912f208c 100644 --- a/hotspot/src/share/vm/opto/output.cpp +++ b/hotspot/src/share/vm/opto/output.cpp @@ -366,8 +366,8 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size // third inserts nops where needed. // Step one, perform a pessimistic sizing pass. - uint last_call_adr = max_uint; - uint last_avoid_back_to_back_adr = max_uint; + uint last_call_adr = max_juint; + uint last_avoid_back_to_back_adr = max_juint; uint nop_size = (new (this) MachNopNode())->size(_regalloc); for (uint i = 0; i < nblocks; i++) { // For all blocks Block* block = _cfg->get_block(i); @@ -479,7 +479,7 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size // Step two, replace eligible long jumps. bool progress = true; - uint last_may_be_short_branch_adr = max_uint; + uint last_may_be_short_branch_adr = max_juint; while (has_short_branch_candidate && progress) { progress = false; has_short_branch_candidate = false; diff --git a/hotspot/src/share/vm/opto/parse2.cpp b/hotspot/src/share/vm/opto/parse2.cpp index cce96328b9b..49396bc7dd1 100644 --- a/hotspot/src/share/vm/opto/parse2.cpp +++ b/hotspot/src/share/vm/opto/parse2.cpp @@ -405,9 +405,9 @@ bool Parse::create_jump_tables(Node* key_val, SwitchRange* lo, SwitchRange* hi) bool needs_guard = false; int default_dest; - int64 total_outlier_size = 0; - int64 hi_size = ((int64)hi->hi()) - ((int64)hi->lo()) + 1; - int64 lo_size = ((int64)lo->hi()) - ((int64)lo->lo()) + 1; + int64_t total_outlier_size = 0; + int64_t hi_size = ((int64_t)hi->hi()) - ((int64_t)hi->lo()) + 1; + int64_t lo_size = ((int64_t)lo->hi()) - ((int64_t)lo->lo()) + 1; if (lo->dest() == hi->dest()) { total_outlier_size = hi_size + lo_size; @@ -429,7 +429,7 @@ bool Parse::create_jump_tables(Node* key_val, SwitchRange* lo, SwitchRange* hi) } // Find the total number of cases and ranges - int64 num_cases = ((int64)hi->hi()) - ((int64)lo->lo()) + 1; + int64_t num_cases = ((int64_t)hi->hi()) - ((int64_t)lo->lo()) + 1; int num_range = hi - lo + 1; // Don't create table if: too large, too small, or too sparse. @@ -473,7 +473,7 @@ bool Parse::create_jump_tables(Node* key_val, SwitchRange* lo, SwitchRange* hi) // These are the switch destinations hanging off the jumpnode int i = 0; for (SwitchRange* r = lo; r <= hi; r++) { - for (int64 j = r->lo(); j <= r->hi(); j++, i++) { + for (int64_t j = r->lo(); j <= r->hi(); j++, i++) { Node* input = _gvn.transform(new (C) JumpProjNode(jtn, i, r->dest(), (int)(j - lowval))); { PreserveJVMState pjvms(this); diff --git a/hotspot/src/share/vm/opto/phase.hpp b/hotspot/src/share/vm/opto/phase.hpp index 08e9575640e..b06e3470df4 100644 --- a/hotspot/src/share/vm/opto/phase.hpp +++ b/hotspot/src/share/vm/opto/phase.hpp @@ -25,7 +25,6 @@ #ifndef SHARE_VM_OPTO_PHASE_HPP #define SHARE_VM_OPTO_PHASE_HPP -#include "libadt/port.hpp" #include "runtime/timer.hpp" class Compile; diff --git a/hotspot/src/share/vm/opto/regmask.cpp b/hotspot/src/share/vm/opto/regmask.cpp index 07fddd151c3..45432398909 100644 --- a/hotspot/src/share/vm/opto/regmask.cpp +++ b/hotspot/src/share/vm/opto/regmask.cpp @@ -51,7 +51,7 @@ //-------------Non-zero bit search methods used by RegMask--------------------- // Find lowest 1, or return 32 if empty -int find_lowest_bit( uint32 mask ) { +int find_lowest_bit( uint32_t mask ) { int n = 0; if( (mask & 0xffff) == 0 ) { mask >>= 16; @@ -80,7 +80,7 @@ int find_lowest_bit( uint32 mask ) { } // Find highest 1, or return 32 if empty -int find_hihghest_bit( uint32 mask ) { +int find_hihghest_bit( uint32_t mask ) { int n = 0; if( mask > 0xffff ) { mask >>= 16; @@ -395,7 +395,7 @@ bool RegMask::is_UP() const { //------------------------------Size------------------------------------------- // Compute size of register mask in bits uint RegMask::Size() const { - extern uint8 bitsInByte[256]; + extern uint8_t bitsInByte[256]; uint sum = 0; for( int i = 0; i < RM_SIZE; i++ ) sum += diff --git a/hotspot/src/share/vm/opto/regmask.hpp b/hotspot/src/share/vm/opto/regmask.hpp index 2ea6dfffdd3..ff0d0b96dc2 100644 --- a/hotspot/src/share/vm/opto/regmask.hpp +++ b/hotspot/src/share/vm/opto/regmask.hpp @@ -26,7 +26,6 @@ #define SHARE_VM_OPTO_REGMASK_HPP #include "code/vmreg.hpp" -#include "libadt/port.hpp" #include "opto/optoreg.hpp" #ifdef TARGET_ARCH_MODEL_x86_32 # include "adfiles/adGlobals_x86_32.hpp" @@ -68,9 +67,9 @@ //-------------Non-zero bit search methods used by RegMask--------------------- // Find lowest 1, or return 32 if empty -int find_lowest_bit( uint32 mask ); +int find_lowest_bit( uint32_t mask ); // Find highest 1, or return 32 if empty -int find_hihghest_bit( uint32 mask ); +int find_hihghest_bit( uint32_t mask ); //------------------------------RegMask---------------------------------------- // The ADL file describes how to print the machine-specific registers, as well diff --git a/hotspot/src/share/vm/opto/runtime.cpp b/hotspot/src/share/vm/opto/runtime.cpp index 877090e087a..ea277c04b85 100644 --- a/hotspot/src/share/vm/opto/runtime.cpp +++ b/hotspot/src/share/vm/opto/runtime.cpp @@ -960,7 +960,7 @@ JRT_LEAF(void, OptoRuntime::profile_receiver_type_C(DataLayout* data, oopDesc* r } else { // Receiver did not match any saved receiver and there is no empty row for it. // Increment total counter to indicate polymorphic case. - intptr_t* count_p = (intptr_t*)(((byte*)(data)) + in_bytes(CounterData::count_offset())); + intptr_t* count_p = (intptr_t*)(((uint8_t*)(data)) + in_bytes(CounterData::count_offset())); *count_p += DataLayout::counter_increment; } JRT_END diff --git a/hotspot/src/share/vm/opto/subnode.cpp b/hotspot/src/share/vm/opto/subnode.cpp index 469d4141e32..fd7fe8b2a2f 100644 --- a/hotspot/src/share/vm/opto/subnode.cpp +++ b/hotspot/src/share/vm/opto/subnode.cpp @@ -242,8 +242,8 @@ Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){ const Type *SubINode::sub( const Type *t1, const Type *t2 ) const { const TypeInt *r0 = t1->is_int(); // Handy access const TypeInt *r1 = t2->is_int(); - int32 lo = r0->_lo - r1->_hi; - int32 hi = r0->_hi - r1->_lo; + int32_t lo = r0->_lo - r1->_hi; + int32_t hi = r0->_hi - r1->_lo; // We next check for 32-bit overflow. // If that happens, we just assume all integers are possible. diff --git a/hotspot/src/share/vm/opto/type.hpp b/hotspot/src/share/vm/opto/type.hpp index 071c12bf0b6..e4340df4f9a 100644 --- a/hotspot/src/share/vm/opto/type.hpp +++ b/hotspot/src/share/vm/opto/type.hpp @@ -25,7 +25,6 @@ #ifndef SHARE_VM_OPTO_TYPE_HPP #define SHARE_VM_OPTO_TYPE_HPP -#include "libadt/port.hpp" #include "opto/adlcVMDeps.hpp" #include "runtime/handles.hpp" diff --git a/hotspot/src/share/vm/precompiled/precompiled.hpp b/hotspot/src/share/vm/precompiled/precompiled.hpp index 5118a398f13..cd1e279b27a 100644 --- a/hotspot/src/share/vm/precompiled/precompiled.hpp +++ b/hotspot/src/share/vm/precompiled/precompiled.hpp @@ -246,7 +246,6 @@ # include "utilities/yieldingWorkgroup.hpp" #ifdef COMPILER2 # include "libadt/dict.hpp" -# include "libadt/port.hpp" # include "libadt/set.hpp" # include "libadt/vectset.hpp" # include "opto/addnode.hpp" From ed9c096396c826886603284e5139760c90d26157 Mon Sep 17 00:00:00 2001 From: Gerard Ziemski <gziemski@openjdk.org> Date: Wed, 7 May 2014 14:16:45 -0500 Subject: [PATCH 043/157] 8038654: Separate SymbolTable and StringTable code Refactor stringTable class out of symbolTable, making sure all includes are minimal set and are sorted. Reviewed-by: coleenp, stefank --- .../src/share/vm/classfile/javaClasses.cpp | 2 +- .../src/share/vm/classfile/stringTable.cpp | 531 ++++++++++++++++++ .../src/share/vm/classfile/stringTable.hpp | 162 ++++++ .../src/share/vm/classfile/symbolTable.cpp | 495 ---------------- .../src/share/vm/classfile/symbolTable.hpp | 131 ----- .../share/vm/classfile/systemDictionary.cpp | 1 + .../concurrentMarkSweepGeneration.cpp | 2 +- .../gc_implementation/g1/g1CollectedHeap.cpp | 1 + .../parallelScavenge/psMarkSweep.cpp | 3 +- .../parallelScavenge/psParallelCompact.cpp | 2 +- .../parallelScavenge/psScavenge.cpp | 3 +- hotspot/src/share/vm/memory/genMarkSweep.cpp | 2 +- hotspot/src/share/vm/memory/sharedHeap.cpp | 2 +- hotspot/src/share/vm/memory/universe.cpp | 2 +- hotspot/src/share/vm/oops/constantPool.cpp | 2 +- hotspot/src/share/vm/prims/jvm.cpp | 2 +- hotspot/src/share/vm/prims/methodHandles.cpp | 2 +- hotspot/src/share/vm/prims/whitebox.cpp | 2 +- hotspot/src/share/vm/runtime/arguments.cpp | 1 + hotspot/src/share/vm/runtime/init.cpp | 2 +- hotspot/src/share/vm/runtime/java.cpp | 2 +- hotspot/src/share/vm/runtime/reflection.cpp | 2 +- hotspot/src/share/vm/runtime/safepoint.cpp | 2 +- hotspot/src/share/vm/runtime/vmStructs.cpp | 1 + hotspot/src/share/vm/utilities/hashtable.cpp | 1 + 25 files changed, 716 insertions(+), 642 deletions(-) create mode 100644 hotspot/src/share/vm/classfile/stringTable.cpp create mode 100644 hotspot/src/share/vm/classfile/stringTable.hpp diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index 9e17d77a55c..0a5e2d92c96 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -25,7 +25,7 @@ #include "precompiled.hpp" #include "classfile/altHashing.hpp" #include "classfile/javaClasses.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/vmSymbols.hpp" #include "code/debugInfo.hpp" #include "code/pcDesc.hpp" diff --git a/hotspot/src/share/vm/classfile/stringTable.cpp b/hotspot/src/share/vm/classfile/stringTable.cpp new file mode 100644 index 00000000000..c870d99e5e1 --- /dev/null +++ b/hotspot/src/share/vm/classfile/stringTable.cpp @@ -0,0 +1,531 @@ +/* + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + * + */ + +#include "precompiled.hpp" +#include "classfile/altHashing.hpp" +#include "classfile/javaClasses.hpp" +#include "classfile/stringTable.hpp" +#include "classfile/systemDictionary.hpp" +#include "gc_interface/collectedHeap.inline.hpp" +#include "memory/allocation.inline.hpp" +#include "memory/filemap.hpp" +#include "memory/gcLocker.inline.hpp" +#include "oops/oop.inline.hpp" +#include "oops/oop.inline2.hpp" +#include "runtime/mutexLocker.hpp" +#include "utilities/hashtable.inline.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/g1/g1StringDedup.hpp" +#endif + +// the number of buckets a thread claims +const int ClaimChunkSize = 32; + +#ifdef ASSERT +class StableMemoryChecker : public StackObj { + enum { _bufsize = wordSize*4 }; + + address _region; + jint _size; + u1 _save_buf[_bufsize]; + + int sample(u1* save_buf) { + if (_size <= _bufsize) { + memcpy(save_buf, _region, _size); + return _size; + } else { + // copy head and tail + memcpy(&save_buf[0], _region, _bufsize/2); + memcpy(&save_buf[_bufsize/2], _region + _size - _bufsize/2, _bufsize/2); + return (_bufsize/2)*2; + } + } + + public: + StableMemoryChecker(const void* region, jint size) { + _region = (address) region; + _size = size; + sample(_save_buf); + } + + bool verify() { + u1 check_buf[sizeof(_save_buf)]; + int check_size = sample(check_buf); + return (0 == memcmp(_save_buf, check_buf, check_size)); + } + + void set_region(const void* region) { _region = (address) region; } +}; +#endif + + +// -------------------------------------------------------------------------- +StringTable* StringTable::_the_table = NULL; + +bool StringTable::_needs_rehashing = false; + +volatile int StringTable::_parallel_claimed_idx = 0; + +// Pick hashing algorithm +unsigned int StringTable::hash_string(const jchar* s, int len) { + return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) : + java_lang_String::hash_code(s, len); +} + +oop StringTable::lookup(int index, jchar* name, + int len, unsigned int hash) { + int count = 0; + for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) { + count++; + if (l->hash() == hash) { + if (java_lang_String::equals(l->literal(), name, len)) { + return l->literal(); + } + } + } + // If the bucket size is too deep check if this hash code is insufficient. + if (count >= BasicHashtable<mtSymbol>::rehash_count && !needs_rehashing()) { + _needs_rehashing = check_rehash_table(count); + } + return NULL; +} + + +oop StringTable::basic_add(int index_arg, Handle string, jchar* name, + int len, unsigned int hashValue_arg, TRAPS) { + + assert(java_lang_String::equals(string(), name, len), + "string must be properly initialized"); + // Cannot hit a safepoint in this function because the "this" pointer can move. + No_Safepoint_Verifier nsv; + + // Check if the symbol table has been rehashed, if so, need to recalculate + // the hash value and index before second lookup. + unsigned int hashValue; + int index; + if (use_alternate_hashcode()) { + hashValue = hash_string(name, len); + index = hash_to_index(hashValue); + } else { + hashValue = hashValue_arg; + index = index_arg; + } + + // Since look-up was done lock-free, we need to check if another + // thread beat us in the race to insert the symbol. + + oop test = lookup(index, name, len, hashValue); // calls lookup(u1*, int) + if (test != NULL) { + // Entry already added + return test; + } + + HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string()); + add_entry(index, entry); + return string(); +} + + +oop StringTable::lookup(Symbol* symbol) { + ResourceMark rm; + int length; + jchar* chars = symbol->as_unicode(length); + return lookup(chars, length); +} + + +oop StringTable::lookup(jchar* name, int len) { + unsigned int hash = hash_string(name, len); + int index = the_table()->hash_to_index(hash); + return the_table()->lookup(index, name, len, hash); +} + + +oop StringTable::intern(Handle string_or_null, jchar* name, + int len, TRAPS) { + unsigned int hashValue = hash_string(name, len); + int index = the_table()->hash_to_index(hashValue); + oop found_string = the_table()->lookup(index, name, len, hashValue); + + // Found + if (found_string != NULL) return found_string; + + debug_only(StableMemoryChecker smc(name, len * sizeof(name[0]))); + assert(!Universe::heap()->is_in_reserved(name), + "proposed name of symbol must be stable"); + + Handle string; + // try to reuse the string if possible + if (!string_or_null.is_null()) { + string = string_or_null; + } else { + string = java_lang_String::create_from_unicode(name, len, CHECK_NULL); + } + +#if INCLUDE_ALL_GCS + if (G1StringDedup::is_enabled()) { + // Deduplicate the string before it is interned. Note that we should never + // deduplicate a string after it has been interned. Doing so will counteract + // compiler optimizations done on e.g. interned string literals. + G1StringDedup::deduplicate(string()); + } +#endif + + // Grab the StringTable_lock before getting the_table() because it could + // change at safepoint. + MutexLocker ml(StringTable_lock, THREAD); + + // Otherwise, add to symbol to table + return the_table()->basic_add(index, string, name, len, + hashValue, CHECK_NULL); +} + +oop StringTable::intern(Symbol* symbol, TRAPS) { + if (symbol == NULL) return NULL; + ResourceMark rm(THREAD); + int length; + jchar* chars = symbol->as_unicode(length); + Handle string; + oop result = intern(string, chars, length, CHECK_NULL); + return result; +} + + +oop StringTable::intern(oop string, TRAPS) +{ + if (string == NULL) return NULL; + ResourceMark rm(THREAD); + int length; + Handle h_string (THREAD, string); + jchar* chars = java_lang_String::as_unicode_string(string, length, CHECK_NULL); + oop result = intern(h_string, chars, length, CHECK_NULL); + return result; +} + + +oop StringTable::intern(const char* utf8_string, TRAPS) { + if (utf8_string == NULL) return NULL; + ResourceMark rm(THREAD); + int length = UTF8::unicode_length(utf8_string); + jchar* chars = NEW_RESOURCE_ARRAY(jchar, length); + UTF8::convert_to_unicode(utf8_string, chars, length); + Handle string; + oop result = intern(string, chars, length, CHECK_NULL); + return result; +} + +void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) { + buckets_unlink_or_oops_do(is_alive, f, 0, the_table()->table_size(), processed, removed); +} + +void StringTable::possibly_parallel_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) { + // Readers of the table are unlocked, so we should only be removing + // entries at a safepoint. + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); + const int limit = the_table()->table_size(); + + for (;;) { + // Grab next set of buckets to scan + int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize; + if (start_idx >= limit) { + // End of table + break; + } + + int end_idx = MIN2(limit, start_idx + ClaimChunkSize); + buckets_unlink_or_oops_do(is_alive, f, start_idx, end_idx, processed, removed); + } +} + +void StringTable::buckets_oops_do(OopClosure* f, int start_idx, int end_idx) { + const int limit = the_table()->table_size(); + + assert(0 <= start_idx && start_idx <= limit, + err_msg("start_idx (%d) is out of bounds", start_idx)); + assert(0 <= end_idx && end_idx <= limit, + err_msg("end_idx (%d) is out of bounds", end_idx)); + assert(start_idx <= end_idx, + err_msg("Index ordering: start_idx=%d, end_idx=%d", + start_idx, end_idx)); + + for (int i = start_idx; i < end_idx; i += 1) { + HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i); + while (entry != NULL) { + assert(!entry->is_shared(), "CDS not used for the StringTable"); + + f->do_oop((oop*)entry->literal_addr()); + + entry = entry->next(); + } + } +} + +void StringTable::buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed) { + const int limit = the_table()->table_size(); + + assert(0 <= start_idx && start_idx <= limit, + err_msg("start_idx (%d) is out of bounds", start_idx)); + assert(0 <= end_idx && end_idx <= limit, + err_msg("end_idx (%d) is out of bounds", end_idx)); + assert(start_idx <= end_idx, + err_msg("Index ordering: start_idx=%d, end_idx=%d", + start_idx, end_idx)); + + for (int i = start_idx; i < end_idx; ++i) { + HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i); + HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i); + while (entry != NULL) { + assert(!entry->is_shared(), "CDS not used for the StringTable"); + + if (is_alive->do_object_b(entry->literal())) { + if (f != NULL) { + f->do_oop((oop*)entry->literal_addr()); + } + p = entry->next_addr(); + } else { + *p = entry->next(); + the_table()->free_entry(entry); + (*removed)++; + } + (*processed)++; + entry = *p; + } + } +} + +void StringTable::oops_do(OopClosure* f) { + buckets_oops_do(f, 0, the_table()->table_size()); +} + +void StringTable::possibly_parallel_oops_do(OopClosure* f) { + const int limit = the_table()->table_size(); + + for (;;) { + // Grab next set of buckets to scan + int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize; + if (start_idx >= limit) { + // End of table + break; + } + + int end_idx = MIN2(limit, start_idx + ClaimChunkSize); + buckets_oops_do(f, start_idx, end_idx); + } +} + +// This verification is part of Universe::verify() and needs to be quick. +// See StringTable::verify_and_compare() below for exhaustive verification. +void StringTable::verify() { + for (int i = 0; i < the_table()->table_size(); ++i) { + HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i); + for ( ; p != NULL; p = p->next()) { + oop s = p->literal(); + guarantee(s != NULL, "interned string is NULL"); + unsigned int h = java_lang_String::hash_string(s); + guarantee(p->hash() == h, "broken hash in string table entry"); + guarantee(the_table()->hash_to_index(h) == i, + "wrong index in string table"); + } + } +} + +void StringTable::dump(outputStream* st) { + the_table()->dump_table(st, "StringTable"); +} + +StringTable::VerifyRetTypes StringTable::compare_entries( + int bkt1, int e_cnt1, + HashtableEntry<oop, mtSymbol>* e_ptr1, + int bkt2, int e_cnt2, + HashtableEntry<oop, mtSymbol>* e_ptr2) { + // These entries are sanity checked by verify_and_compare_entries() + // before this function is called. + oop str1 = e_ptr1->literal(); + oop str2 = e_ptr2->literal(); + + if (str1 == str2) { + tty->print_cr("ERROR: identical oop values (0x" PTR_FORMAT ") " + "in entry @ bucket[%d][%d] and entry @ bucket[%d][%d]", + (void *)str1, bkt1, e_cnt1, bkt2, e_cnt2); + return _verify_fail_continue; + } + + if (java_lang_String::equals(str1, str2)) { + tty->print_cr("ERROR: identical String values in entry @ " + "bucket[%d][%d] and entry @ bucket[%d][%d]", + bkt1, e_cnt1, bkt2, e_cnt2); + return _verify_fail_continue; + } + + return _verify_pass; +} + +StringTable::VerifyRetTypes StringTable::verify_entry(int bkt, int e_cnt, + HashtableEntry<oop, mtSymbol>* e_ptr, + StringTable::VerifyMesgModes mesg_mode) { + + VerifyRetTypes ret = _verify_pass; // be optimistic + + oop str = e_ptr->literal(); + if (str == NULL) { + if (mesg_mode == _verify_with_mesgs) { + tty->print_cr("ERROR: NULL oop value in entry @ bucket[%d][%d]", bkt, + e_cnt); + } + // NULL oop means no more verifications are possible + return _verify_fail_done; + } + + if (str->klass() != SystemDictionary::String_klass()) { + if (mesg_mode == _verify_with_mesgs) { + tty->print_cr("ERROR: oop is not a String in entry @ bucket[%d][%d]", + bkt, e_cnt); + } + // not a String means no more verifications are possible + return _verify_fail_done; + } + + unsigned int h = java_lang_String::hash_string(str); + if (e_ptr->hash() != h) { + if (mesg_mode == _verify_with_mesgs) { + tty->print_cr("ERROR: broken hash value in entry @ bucket[%d][%d], " + "bkt_hash=%d, str_hash=%d", bkt, e_cnt, e_ptr->hash(), h); + } + ret = _verify_fail_continue; + } + + if (the_table()->hash_to_index(h) != bkt) { + if (mesg_mode == _verify_with_mesgs) { + tty->print_cr("ERROR: wrong index value for entry @ bucket[%d][%d], " + "str_hash=%d, hash_to_index=%d", bkt, e_cnt, h, + the_table()->hash_to_index(h)); + } + ret = _verify_fail_continue; + } + + return ret; +} + +// See StringTable::verify() above for the quick verification that is +// part of Universe::verify(). This verification is exhaustive and +// reports on every issue that is found. StringTable::verify() only +// reports on the first issue that is found. +// +// StringTable::verify_entry() checks: +// - oop value != NULL (same as verify()) +// - oop value is a String +// - hash(String) == hash in entry (same as verify()) +// - index for hash == index of entry (same as verify()) +// +// StringTable::compare_entries() checks: +// - oops are unique across all entries +// - String values are unique across all entries +// +int StringTable::verify_and_compare_entries() { + assert(StringTable_lock->is_locked(), "sanity check"); + + int fail_cnt = 0; + + // first, verify all the entries individually: + for (int bkt = 0; bkt < the_table()->table_size(); bkt++) { + HashtableEntry<oop, mtSymbol>* e_ptr = the_table()->bucket(bkt); + for (int e_cnt = 0; e_ptr != NULL; e_ptr = e_ptr->next(), e_cnt++) { + VerifyRetTypes ret = verify_entry(bkt, e_cnt, e_ptr, _verify_with_mesgs); + if (ret != _verify_pass) { + fail_cnt++; + } + } + } + + // Optimization: if the above check did not find any failures, then + // the comparison loop below does not need to call verify_entry() + // before calling compare_entries(). If there were failures, then we + // have to call verify_entry() to see if the entry can be passed to + // compare_entries() safely. When we call verify_entry() in the loop + // below, we do so quietly to void duplicate messages and we don't + // increment fail_cnt because the failures have already been counted. + bool need_entry_verify = (fail_cnt != 0); + + // second, verify all entries relative to each other: + for (int bkt1 = 0; bkt1 < the_table()->table_size(); bkt1++) { + HashtableEntry<oop, mtSymbol>* e_ptr1 = the_table()->bucket(bkt1); + for (int e_cnt1 = 0; e_ptr1 != NULL; e_ptr1 = e_ptr1->next(), e_cnt1++) { + if (need_entry_verify) { + VerifyRetTypes ret = verify_entry(bkt1, e_cnt1, e_ptr1, + _verify_quietly); + if (ret == _verify_fail_done) { + // cannot use the current entry to compare against other entries + continue; + } + } + + for (int bkt2 = bkt1; bkt2 < the_table()->table_size(); bkt2++) { + HashtableEntry<oop, mtSymbol>* e_ptr2 = the_table()->bucket(bkt2); + int e_cnt2; + for (e_cnt2 = 0; e_ptr2 != NULL; e_ptr2 = e_ptr2->next(), e_cnt2++) { + if (bkt1 == bkt2 && e_cnt2 <= e_cnt1) { + // skip the entries up to and including the one that + // we're comparing against + continue; + } + + if (need_entry_verify) { + VerifyRetTypes ret = verify_entry(bkt2, e_cnt2, e_ptr2, + _verify_quietly); + if (ret == _verify_fail_done) { + // cannot compare against this entry + continue; + } + } + + // compare two entries, report and count any failures: + if (compare_entries(bkt1, e_cnt1, e_ptr1, bkt2, e_cnt2, e_ptr2) + != _verify_pass) { + fail_cnt++; + } + } + } + } + } + return fail_cnt; +} + +// Create a new table and using alternate hash code, populate the new table +// with the existing strings. Set flag to use the alternate hash code afterwards. +void StringTable::rehash_table() { + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); + // This should never happen with -Xshare:dump but it might in testing mode. + if (DumpSharedSpaces) return; + StringTable* new_table = new StringTable(); + + // Rehash the table + the_table()->move_to(new_table); + + // Delete the table and buckets (entries are reused in new table). + delete _the_table; + // Don't check if we need rehashing until the table gets unbalanced again. + // Then rehash with a new global seed. + _needs_rehashing = false; + _the_table = new_table; +} diff --git a/hotspot/src/share/vm/classfile/stringTable.hpp b/hotspot/src/share/vm/classfile/stringTable.hpp new file mode 100644 index 00000000000..af6f909f200 --- /dev/null +++ b/hotspot/src/share/vm/classfile/stringTable.hpp @@ -0,0 +1,162 @@ +/* + * Copyright (c) 1997, 2013, 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. + * + */ + +#ifndef SHARE_VM_CLASSFILE_STRINGTABLE_HPP +#define SHARE_VM_CLASSFILE_STRINGTABLE_HPP + +#include "memory/allocation.inline.hpp" +#include "utilities/hashtable.hpp" + +class StringTable : public Hashtable<oop, mtSymbol> { + friend class VMStructs; + friend class Symbol; + +private: + // The string table + static StringTable* _the_table; + + // Set if one bucket is out of balance due to hash algorithm deficiency + static bool _needs_rehashing; + + // Claimed high water mark for parallel chunked scanning + static volatile int _parallel_claimed_idx; + + static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS); + oop basic_add(int index, Handle string_or_null, jchar* name, int len, + unsigned int hashValue, TRAPS); + + oop lookup(int index, jchar* chars, int length, unsigned int hashValue); + + // Apply the give oop closure to the entries to the buckets + // in the range [start_idx, end_idx). + static void buckets_oops_do(OopClosure* f, int start_idx, int end_idx); + // Unlink or apply the give oop closure to the entries to the buckets + // in the range [start_idx, end_idx). + static void buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed); + + StringTable() : Hashtable<oop, mtSymbol>((int)StringTableSize, + sizeof (HashtableEntry<oop, mtSymbol>)) {} + + StringTable(HashtableBucket<mtSymbol>* t, int number_of_entries) + : Hashtable<oop, mtSymbol>((int)StringTableSize, sizeof (HashtableEntry<oop, mtSymbol>), t, + number_of_entries) {} +public: + // The string table + static StringTable* the_table() { return _the_table; } + + // Size of one bucket in the string table. Used when checking for rollover. + static uint bucket_size() { return sizeof(HashtableBucket<mtSymbol>); } + + static void create_table() { + assert(_the_table == NULL, "One string table allowed."); + _the_table = new StringTable(); + } + + // GC support + // Delete pointers to otherwise-unreachable objects. + static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f) { + int processed = 0; + int removed = 0; + unlink_or_oops_do(cl, f, &processed, &removed); + } + static void unlink(BoolObjectClosure* cl) { + int processed = 0; + int removed = 0; + unlink_or_oops_do(cl, NULL, &processed, &removed); + } + static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed); + static void unlink(BoolObjectClosure* cl, int* processed, int* removed) { + unlink_or_oops_do(cl, NULL, processed, removed); + } + // Serially invoke "f->do_oop" on the locations of all oops in the table. + static void oops_do(OopClosure* f); + + // Possibly parallel versions of the above + static void possibly_parallel_unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed); + static void possibly_parallel_unlink(BoolObjectClosure* cl, int* processed, int* removed) { + possibly_parallel_unlink_or_oops_do(cl, NULL, processed, removed); + } + static void possibly_parallel_oops_do(OopClosure* f); + + // Hashing algorithm, used as the hash value used by the + // StringTable for bucket selection and comparison (stored in the + // HashtableEntry structures). This is used in the String.intern() method. + static unsigned int hash_string(const jchar* s, int len); + + // Internal test. + static void test_alt_hash() PRODUCT_RETURN; + + // Probing + static oop lookup(Symbol* symbol); + static oop lookup(jchar* chars, int length); + + // Interning + static oop intern(Symbol* symbol, TRAPS); + static oop intern(oop string, TRAPS); + static oop intern(const char *utf8_string, TRAPS); + + // Debugging + static void verify(); + static void dump(outputStream* st); + + enum VerifyMesgModes { + _verify_quietly = 0, + _verify_with_mesgs = 1 + }; + + enum VerifyRetTypes { + _verify_pass = 0, + _verify_fail_continue = 1, + _verify_fail_done = 2 + }; + + static VerifyRetTypes compare_entries(int bkt1, int e_cnt1, + HashtableEntry<oop, mtSymbol>* e_ptr1, + int bkt2, int e_cnt2, + HashtableEntry<oop, mtSymbol>* e_ptr2); + static VerifyRetTypes verify_entry(int bkt, int e_cnt, + HashtableEntry<oop, mtSymbol>* e_ptr, + VerifyMesgModes mesg_mode); + static int verify_and_compare_entries(); + + // Sharing + static void copy_buckets(char** top, char*end) { + the_table()->Hashtable<oop, mtSymbol>::copy_buckets(top, end); + } + static void copy_table(char** top, char*end) { + the_table()->Hashtable<oop, mtSymbol>::copy_table(top, end); + } + static void reverse() { + the_table()->Hashtable<oop, mtSymbol>::reverse(); + } + + // Rehash the symbol table if it gets out of balance + static void rehash_table(); + static bool needs_rehashing() { return _needs_rehashing; } + + // Parallel chunked scanning + static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; } + static int parallel_claimed_index() { return _parallel_claimed_idx; } +}; +#endif // SHARE_VM_CLASSFILE_STRINGTABLE_HPP diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp index 40a06da9b34..5867c18790c 100644 --- a/hotspot/src/share/vm/classfile/symbolTable.cpp +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp @@ -35,11 +35,6 @@ #include "oops/oop.inline2.hpp" #include "runtime/mutexLocker.hpp" #include "utilities/hashtable.inline.hpp" -#if INCLUDE_ALL_GCS -#include "gc_implementation/g1/g1StringDedup.hpp" -#endif - -// -------------------------------------------------------------------------- // the number of buckets a thread claims const int ClaimChunkSize = 32; @@ -587,493 +582,3 @@ void SymbolTable::print() { } } #endif // PRODUCT - -// -------------------------------------------------------------------------- - -#ifdef ASSERT -class StableMemoryChecker : public StackObj { - enum { _bufsize = wordSize*4 }; - - address _region; - jint _size; - u1 _save_buf[_bufsize]; - - int sample(u1* save_buf) { - if (_size <= _bufsize) { - memcpy(save_buf, _region, _size); - return _size; - } else { - // copy head and tail - memcpy(&save_buf[0], _region, _bufsize/2); - memcpy(&save_buf[_bufsize/2], _region + _size - _bufsize/2, _bufsize/2); - return (_bufsize/2)*2; - } - } - - public: - StableMemoryChecker(const void* region, jint size) { - _region = (address) region; - _size = size; - sample(_save_buf); - } - - bool verify() { - u1 check_buf[sizeof(_save_buf)]; - int check_size = sample(check_buf); - return (0 == memcmp(_save_buf, check_buf, check_size)); - } - - void set_region(const void* region) { _region = (address) region; } -}; -#endif - - -// -------------------------------------------------------------------------- -StringTable* StringTable::_the_table = NULL; - -bool StringTable::_needs_rehashing = false; - -volatile int StringTable::_parallel_claimed_idx = 0; - -// Pick hashing algorithm -unsigned int StringTable::hash_string(const jchar* s, int len) { - return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) : - java_lang_String::hash_code(s, len); -} - -oop StringTable::lookup(int index, jchar* name, - int len, unsigned int hash) { - int count = 0; - for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) { - count++; - if (l->hash() == hash) { - if (java_lang_String::equals(l->literal(), name, len)) { - return l->literal(); - } - } - } - // If the bucket size is too deep check if this hash code is insufficient. - if (count >= BasicHashtable<mtSymbol>::rehash_count && !needs_rehashing()) { - _needs_rehashing = check_rehash_table(count); - } - return NULL; -} - - -oop StringTable::basic_add(int index_arg, Handle string, jchar* name, - int len, unsigned int hashValue_arg, TRAPS) { - - assert(java_lang_String::equals(string(), name, len), - "string must be properly initialized"); - // Cannot hit a safepoint in this function because the "this" pointer can move. - No_Safepoint_Verifier nsv; - - // Check if the symbol table has been rehashed, if so, need to recalculate - // the hash value and index before second lookup. - unsigned int hashValue; - int index; - if (use_alternate_hashcode()) { - hashValue = hash_string(name, len); - index = hash_to_index(hashValue); - } else { - hashValue = hashValue_arg; - index = index_arg; - } - - // Since look-up was done lock-free, we need to check if another - // thread beat us in the race to insert the symbol. - - oop test = lookup(index, name, len, hashValue); // calls lookup(u1*, int) - if (test != NULL) { - // Entry already added - return test; - } - - HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string()); - add_entry(index, entry); - return string(); -} - - -oop StringTable::lookup(Symbol* symbol) { - ResourceMark rm; - int length; - jchar* chars = symbol->as_unicode(length); - return lookup(chars, length); -} - - -oop StringTable::lookup(jchar* name, int len) { - unsigned int hash = hash_string(name, len); - int index = the_table()->hash_to_index(hash); - return the_table()->lookup(index, name, len, hash); -} - - -oop StringTable::intern(Handle string_or_null, jchar* name, - int len, TRAPS) { - unsigned int hashValue = hash_string(name, len); - int index = the_table()->hash_to_index(hashValue); - oop found_string = the_table()->lookup(index, name, len, hashValue); - - // Found - if (found_string != NULL) return found_string; - - debug_only(StableMemoryChecker smc(name, len * sizeof(name[0]))); - assert(!Universe::heap()->is_in_reserved(name), - "proposed name of symbol must be stable"); - - Handle string; - // try to reuse the string if possible - if (!string_or_null.is_null()) { - string = string_or_null; - } else { - string = java_lang_String::create_from_unicode(name, len, CHECK_NULL); - } - -#if INCLUDE_ALL_GCS - if (G1StringDedup::is_enabled()) { - // Deduplicate the string before it is interned. Note that we should never - // deduplicate a string after it has been interned. Doing so will counteract - // compiler optimizations done on e.g. interned string literals. - G1StringDedup::deduplicate(string()); - } -#endif - - // Grab the StringTable_lock before getting the_table() because it could - // change at safepoint. - MutexLocker ml(StringTable_lock, THREAD); - - // Otherwise, add to symbol to table - return the_table()->basic_add(index, string, name, len, - hashValue, CHECK_NULL); -} - -oop StringTable::intern(Symbol* symbol, TRAPS) { - if (symbol == NULL) return NULL; - ResourceMark rm(THREAD); - int length; - jchar* chars = symbol->as_unicode(length); - Handle string; - oop result = intern(string, chars, length, CHECK_NULL); - return result; -} - - -oop StringTable::intern(oop string, TRAPS) -{ - if (string == NULL) return NULL; - ResourceMark rm(THREAD); - int length; - Handle h_string (THREAD, string); - jchar* chars = java_lang_String::as_unicode_string(string, length, CHECK_NULL); - oop result = intern(h_string, chars, length, CHECK_NULL); - return result; -} - - -oop StringTable::intern(const char* utf8_string, TRAPS) { - if (utf8_string == NULL) return NULL; - ResourceMark rm(THREAD); - int length = UTF8::unicode_length(utf8_string); - jchar* chars = NEW_RESOURCE_ARRAY(jchar, length); - UTF8::convert_to_unicode(utf8_string, chars, length); - Handle string; - oop result = intern(string, chars, length, CHECK_NULL); - return result; -} - -void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) { - buckets_unlink_or_oops_do(is_alive, f, 0, the_table()->table_size(), processed, removed); -} - -void StringTable::possibly_parallel_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) { - // Readers of the table are unlocked, so we should only be removing - // entries at a safepoint. - assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); - const int limit = the_table()->table_size(); - - for (;;) { - // Grab next set of buckets to scan - int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize; - if (start_idx >= limit) { - // End of table - break; - } - - int end_idx = MIN2(limit, start_idx + ClaimChunkSize); - buckets_unlink_or_oops_do(is_alive, f, start_idx, end_idx, processed, removed); - } -} - -void StringTable::buckets_oops_do(OopClosure* f, int start_idx, int end_idx) { - const int limit = the_table()->table_size(); - - assert(0 <= start_idx && start_idx <= limit, - err_msg("start_idx (%d) is out of bounds", start_idx)); - assert(0 <= end_idx && end_idx <= limit, - err_msg("end_idx (%d) is out of bounds", end_idx)); - assert(start_idx <= end_idx, - err_msg("Index ordering: start_idx=%d, end_idx=%d", - start_idx, end_idx)); - - for (int i = start_idx; i < end_idx; i += 1) { - HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i); - while (entry != NULL) { - assert(!entry->is_shared(), "CDS not used for the StringTable"); - - f->do_oop((oop*)entry->literal_addr()); - - entry = entry->next(); - } - } -} - -void StringTable::buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed) { - const int limit = the_table()->table_size(); - - assert(0 <= start_idx && start_idx <= limit, - err_msg("start_idx (%d) is out of bounds", start_idx)); - assert(0 <= end_idx && end_idx <= limit, - err_msg("end_idx (%d) is out of bounds", end_idx)); - assert(start_idx <= end_idx, - err_msg("Index ordering: start_idx=%d, end_idx=%d", - start_idx, end_idx)); - - for (int i = start_idx; i < end_idx; ++i) { - HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i); - HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i); - while (entry != NULL) { - assert(!entry->is_shared(), "CDS not used for the StringTable"); - - if (is_alive->do_object_b(entry->literal())) { - if (f != NULL) { - f->do_oop((oop*)entry->literal_addr()); - } - p = entry->next_addr(); - } else { - *p = entry->next(); - the_table()->free_entry(entry); - (*removed)++; - } - (*processed)++; - entry = *p; - } - } -} - -void StringTable::oops_do(OopClosure* f) { - buckets_oops_do(f, 0, the_table()->table_size()); -} - -void StringTable::possibly_parallel_oops_do(OopClosure* f) { - const int limit = the_table()->table_size(); - - for (;;) { - // Grab next set of buckets to scan - int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize; - if (start_idx >= limit) { - // End of table - break; - } - - int end_idx = MIN2(limit, start_idx + ClaimChunkSize); - buckets_oops_do(f, start_idx, end_idx); - } -} - -// This verification is part of Universe::verify() and needs to be quick. -// See StringTable::verify_and_compare() below for exhaustive verification. -void StringTable::verify() { - for (int i = 0; i < the_table()->table_size(); ++i) { - HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i); - for ( ; p != NULL; p = p->next()) { - oop s = p->literal(); - guarantee(s != NULL, "interned string is NULL"); - unsigned int h = java_lang_String::hash_string(s); - guarantee(p->hash() == h, "broken hash in string table entry"); - guarantee(the_table()->hash_to_index(h) == i, - "wrong index in string table"); - } - } -} - -void StringTable::dump(outputStream* st) { - the_table()->dump_table(st, "StringTable"); -} - -StringTable::VerifyRetTypes StringTable::compare_entries( - int bkt1, int e_cnt1, - HashtableEntry<oop, mtSymbol>* e_ptr1, - int bkt2, int e_cnt2, - HashtableEntry<oop, mtSymbol>* e_ptr2) { - // These entries are sanity checked by verify_and_compare_entries() - // before this function is called. - oop str1 = e_ptr1->literal(); - oop str2 = e_ptr2->literal(); - - if (str1 == str2) { - tty->print_cr("ERROR: identical oop values (0x" PTR_FORMAT ") " - "in entry @ bucket[%d][%d] and entry @ bucket[%d][%d]", - (void *)str1, bkt1, e_cnt1, bkt2, e_cnt2); - return _verify_fail_continue; - } - - if (java_lang_String::equals(str1, str2)) { - tty->print_cr("ERROR: identical String values in entry @ " - "bucket[%d][%d] and entry @ bucket[%d][%d]", - bkt1, e_cnt1, bkt2, e_cnt2); - return _verify_fail_continue; - } - - return _verify_pass; -} - -StringTable::VerifyRetTypes StringTable::verify_entry(int bkt, int e_cnt, - HashtableEntry<oop, mtSymbol>* e_ptr, - StringTable::VerifyMesgModes mesg_mode) { - - VerifyRetTypes ret = _verify_pass; // be optimistic - - oop str = e_ptr->literal(); - if (str == NULL) { - if (mesg_mode == _verify_with_mesgs) { - tty->print_cr("ERROR: NULL oop value in entry @ bucket[%d][%d]", bkt, - e_cnt); - } - // NULL oop means no more verifications are possible - return _verify_fail_done; - } - - if (str->klass() != SystemDictionary::String_klass()) { - if (mesg_mode == _verify_with_mesgs) { - tty->print_cr("ERROR: oop is not a String in entry @ bucket[%d][%d]", - bkt, e_cnt); - } - // not a String means no more verifications are possible - return _verify_fail_done; - } - - unsigned int h = java_lang_String::hash_string(str); - if (e_ptr->hash() != h) { - if (mesg_mode == _verify_with_mesgs) { - tty->print_cr("ERROR: broken hash value in entry @ bucket[%d][%d], " - "bkt_hash=%d, str_hash=%d", bkt, e_cnt, e_ptr->hash(), h); - } - ret = _verify_fail_continue; - } - - if (the_table()->hash_to_index(h) != bkt) { - if (mesg_mode == _verify_with_mesgs) { - tty->print_cr("ERROR: wrong index value for entry @ bucket[%d][%d], " - "str_hash=%d, hash_to_index=%d", bkt, e_cnt, h, - the_table()->hash_to_index(h)); - } - ret = _verify_fail_continue; - } - - return ret; -} - -// See StringTable::verify() above for the quick verification that is -// part of Universe::verify(). This verification is exhaustive and -// reports on every issue that is found. StringTable::verify() only -// reports on the first issue that is found. -// -// StringTable::verify_entry() checks: -// - oop value != NULL (same as verify()) -// - oop value is a String -// - hash(String) == hash in entry (same as verify()) -// - index for hash == index of entry (same as verify()) -// -// StringTable::compare_entries() checks: -// - oops are unique across all entries -// - String values are unique across all entries -// -int StringTable::verify_and_compare_entries() { - assert(StringTable_lock->is_locked(), "sanity check"); - - int fail_cnt = 0; - - // first, verify all the entries individually: - for (int bkt = 0; bkt < the_table()->table_size(); bkt++) { - HashtableEntry<oop, mtSymbol>* e_ptr = the_table()->bucket(bkt); - for (int e_cnt = 0; e_ptr != NULL; e_ptr = e_ptr->next(), e_cnt++) { - VerifyRetTypes ret = verify_entry(bkt, e_cnt, e_ptr, _verify_with_mesgs); - if (ret != _verify_pass) { - fail_cnt++; - } - } - } - - // Optimization: if the above check did not find any failures, then - // the comparison loop below does not need to call verify_entry() - // before calling compare_entries(). If there were failures, then we - // have to call verify_entry() to see if the entry can be passed to - // compare_entries() safely. When we call verify_entry() in the loop - // below, we do so quietly to void duplicate messages and we don't - // increment fail_cnt because the failures have already been counted. - bool need_entry_verify = (fail_cnt != 0); - - // second, verify all entries relative to each other: - for (int bkt1 = 0; bkt1 < the_table()->table_size(); bkt1++) { - HashtableEntry<oop, mtSymbol>* e_ptr1 = the_table()->bucket(bkt1); - for (int e_cnt1 = 0; e_ptr1 != NULL; e_ptr1 = e_ptr1->next(), e_cnt1++) { - if (need_entry_verify) { - VerifyRetTypes ret = verify_entry(bkt1, e_cnt1, e_ptr1, - _verify_quietly); - if (ret == _verify_fail_done) { - // cannot use the current entry to compare against other entries - continue; - } - } - - for (int bkt2 = bkt1; bkt2 < the_table()->table_size(); bkt2++) { - HashtableEntry<oop, mtSymbol>* e_ptr2 = the_table()->bucket(bkt2); - int e_cnt2; - for (e_cnt2 = 0; e_ptr2 != NULL; e_ptr2 = e_ptr2->next(), e_cnt2++) { - if (bkt1 == bkt2 && e_cnt2 <= e_cnt1) { - // skip the entries up to and including the one that - // we're comparing against - continue; - } - - if (need_entry_verify) { - VerifyRetTypes ret = verify_entry(bkt2, e_cnt2, e_ptr2, - _verify_quietly); - if (ret == _verify_fail_done) { - // cannot compare against this entry - continue; - } - } - - // compare two entries, report and count any failures: - if (compare_entries(bkt1, e_cnt1, e_ptr1, bkt2, e_cnt2, e_ptr2) - != _verify_pass) { - fail_cnt++; - } - } - } - } - } - return fail_cnt; -} - -// Create a new table and using alternate hash code, populate the new table -// with the existing strings. Set flag to use the alternate hash code afterwards. -void StringTable::rehash_table() { - assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); - // This should never happen with -Xshare:dump but it might in testing mode. - if (DumpSharedSpaces) return; - StringTable* new_table = new StringTable(); - - // Rehash the table - the_table()->move_to(new_table); - - // Delete the table and buckets (entries are reused in new table). - delete _the_table; - // Don't check if we need rehashing until the table gets unbalanced again. - // Then rehash with a new global seed. - _needs_rehashing = false; - _the_table = new_table; -} diff --git a/hotspot/src/share/vm/classfile/symbolTable.hpp b/hotspot/src/share/vm/classfile/symbolTable.hpp index b0a2fcb38b8..c5dd75b82ea 100644 --- a/hotspot/src/share/vm/classfile/symbolTable.hpp +++ b/hotspot/src/share/vm/classfile/symbolTable.hpp @@ -42,7 +42,6 @@ class BoolObjectClosure; class outputStream; - // Class to hold a newly created or referenced Symbol* temporarily in scope. // new_symbol() and lookup() will create a Symbol* if not already in the // symbol table and add to the symbol's reference count. @@ -252,134 +251,4 @@ public: static int parallel_claimed_index() { return _parallel_claimed_idx; } }; -class StringTable : public Hashtable<oop, mtSymbol> { - friend class VMStructs; - -private: - // The string table - static StringTable* _the_table; - - // Set if one bucket is out of balance due to hash algorithm deficiency - static bool _needs_rehashing; - - // Claimed high water mark for parallel chunked scanning - static volatile int _parallel_claimed_idx; - - static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS); - oop basic_add(int index, Handle string_or_null, jchar* name, int len, - unsigned int hashValue, TRAPS); - - oop lookup(int index, jchar* chars, int length, unsigned int hashValue); - - // Apply the give oop closure to the entries to the buckets - // in the range [start_idx, end_idx). - static void buckets_oops_do(OopClosure* f, int start_idx, int end_idx); - // Unlink or apply the give oop closure to the entries to the buckets - // in the range [start_idx, end_idx). - static void buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed); - - StringTable() : Hashtable<oop, mtSymbol>((int)StringTableSize, - sizeof (HashtableEntry<oop, mtSymbol>)) {} - - StringTable(HashtableBucket<mtSymbol>* t, int number_of_entries) - : Hashtable<oop, mtSymbol>((int)StringTableSize, sizeof (HashtableEntry<oop, mtSymbol>), t, - number_of_entries) {} -public: - // The string table - static StringTable* the_table() { return _the_table; } - - // Size of one bucket in the string table. Used when checking for rollover. - static uint bucket_size() { return sizeof(HashtableBucket<mtSymbol>); } - - static void create_table() { - assert(_the_table == NULL, "One string table allowed."); - _the_table = new StringTable(); - } - - // GC support - // Delete pointers to otherwise-unreachable objects. - static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f) { - int processed = 0; - int removed = 0; - unlink_or_oops_do(cl, f, &processed, &removed); - } - static void unlink(BoolObjectClosure* cl) { - int processed = 0; - int removed = 0; - unlink_or_oops_do(cl, NULL, &processed, &removed); - } - static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed); - static void unlink(BoolObjectClosure* cl, int* processed, int* removed) { - unlink_or_oops_do(cl, NULL, processed, removed); - } - // Serially invoke "f->do_oop" on the locations of all oops in the table. - static void oops_do(OopClosure* f); - - // Possibly parallel versions of the above - static void possibly_parallel_unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed); - static void possibly_parallel_unlink(BoolObjectClosure* cl, int* processed, int* removed) { - possibly_parallel_unlink_or_oops_do(cl, NULL, processed, removed); - } - static void possibly_parallel_oops_do(OopClosure* f); - - // Hashing algorithm, used as the hash value used by the - // StringTable for bucket selection and comparison (stored in the - // HashtableEntry structures). This is used in the String.intern() method. - static unsigned int hash_string(const jchar* s, int len); - - // Internal test. - static void test_alt_hash() PRODUCT_RETURN; - - // Probing - static oop lookup(Symbol* symbol); - static oop lookup(jchar* chars, int length); - - // Interning - static oop intern(Symbol* symbol, TRAPS); - static oop intern(oop string, TRAPS); - static oop intern(const char *utf8_string, TRAPS); - - // Debugging - static void verify(); - static void dump(outputStream* st); - - enum VerifyMesgModes { - _verify_quietly = 0, - _verify_with_mesgs = 1 - }; - - enum VerifyRetTypes { - _verify_pass = 0, - _verify_fail_continue = 1, - _verify_fail_done = 2 - }; - - static VerifyRetTypes compare_entries(int bkt1, int e_cnt1, - HashtableEntry<oop, mtSymbol>* e_ptr1, - int bkt2, int e_cnt2, - HashtableEntry<oop, mtSymbol>* e_ptr2); - static VerifyRetTypes verify_entry(int bkt, int e_cnt, - HashtableEntry<oop, mtSymbol>* e_ptr, - VerifyMesgModes mesg_mode); - static int verify_and_compare_entries(); - - // Sharing - static void copy_buckets(char** top, char*end) { - the_table()->Hashtable<oop, mtSymbol>::copy_buckets(top, end); - } - static void copy_table(char** top, char*end) { - the_table()->Hashtable<oop, mtSymbol>::copy_table(top, end); - } - static void reverse() { - the_table()->Hashtable<oop, mtSymbol>::reverse(); - } - - // Rehash the symbol table if it gets out of balance - static void rehash_table(); - static bool needs_rehashing() { return _needs_rehashing; } - - // Parallel chunked scanning - static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; } - static int parallel_claimed_index() { return _parallel_claimed_idx; } -}; #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp index 304a88f54e7..6d816427c82 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp @@ -29,6 +29,7 @@ #include "classfile/loaderConstraints.hpp" #include "classfile/placeholders.hpp" #include "classfile/resolutionErrors.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "compiler/compileBroker.hpp" diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index 40ff7b30e40..dc87162d864 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "classfile/classLoaderData.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp" diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 79a19976658..b6a53a40b4f 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "classfile/stringTable.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" #include "gc_implementation/g1/bufferingOopClosure.hpp" diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp index cdfc31911ee..c5819a93877 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp @@ -1,3 +1,4 @@ + /* * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -23,7 +24,7 @@ */ #include "precompiled.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp index e93f612e4bd..4654c35d98e 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp index de18bd00d05..3ec667d1037 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp @@ -1,3 +1,4 @@ + /* * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -23,7 +24,7 @@ */ #include "precompiled.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "code/codeCache.hpp" #include "gc_implementation/parallelScavenge/cardTableExtension.hpp" #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" diff --git a/hotspot/src/share/vm/memory/genMarkSweep.cpp b/hotspot/src/share/vm/memory/genMarkSweep.cpp index 80a35d10e2c..64d7c3eaa61 100644 --- a/hotspot/src/share/vm/memory/genMarkSweep.cpp +++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "classfile/javaClasses.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" diff --git a/hotspot/src/share/vm/memory/sharedHeap.cpp b/hotspot/src/share/vm/memory/sharedHeap.cpp index b59635c9f33..d58c21b2d90 100644 --- a/hotspot/src/share/vm/memory/sharedHeap.cpp +++ b/hotspot/src/share/vm/memory/sharedHeap.cpp @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "gc_interface/collectedHeap.inline.hpp" diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index 63c7c005d44..7573d94b3f6 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -26,7 +26,7 @@ #include "classfile/classLoader.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/javaClasses.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index 5f005dcb12e..2a84181a3ce 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -26,7 +26,7 @@ #include "classfile/classLoaderData.hpp" #include "classfile/javaClasses.hpp" #include "classfile/metadataOnStackMark.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "interpreter/linkResolver.hpp" diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index e6c059c0d30..e7d1d64da71 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -26,7 +26,7 @@ #include "classfile/classLoader.hpp" #include "classfile/javaAssertions.hpp" #include "classfile/javaClasses.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "gc_interface/collectedHeap.inline.hpp" diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp index e1fafabf54d..6af676abb97 100644 --- a/hotspot/src/share/vm/prims/methodHandles.cpp +++ b/hotspot/src/share/vm/prims/methodHandles.cpp @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "compiler/compileBroker.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/oopMapCache.hpp" diff --git a/hotspot/src/share/vm/prims/whitebox.cpp b/hotspot/src/share/vm/prims/whitebox.cpp index 2289618ff6d..bb09c7000c1 100644 --- a/hotspot/src/share/vm/prims/whitebox.cpp +++ b/hotspot/src/share/vm/prims/whitebox.cpp @@ -27,7 +27,7 @@ #include "memory/universe.hpp" #include "oops/oop.inline.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/classLoaderData.hpp" #include "prims/whitebox.hpp" diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 0d1655c7997..bc64080dd14 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/javaAssertions.hpp" +#include "classfile/stringTable.hpp" #include "classfile/symbolTable.hpp" #include "compiler/compilerOracle.hpp" #include "memory/allocation.inline.hpp" diff --git a/hotspot/src/share/vm/runtime/init.cpp b/hotspot/src/share/vm/runtime/init.cpp index 4533c7e8127..6c654d280e2 100644 --- a/hotspot/src/share/vm/runtime/init.cpp +++ b/hotspot/src/share/vm/runtime/init.cpp @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "code/icBuffer.hpp" #include "gc_interface/collectedHeap.hpp" #include "interpreter/bytecodes.hpp" diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp index cddfd3d1ffc..6bdfb20e152 100644 --- a/hotspot/src/share/vm/runtime/java.cpp +++ b/hotspot/src/share/vm/runtime/java.cpp @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "classfile/classLoader.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "compiler/compileBroker.hpp" diff --git a/hotspot/src/share/vm/runtime/reflection.cpp b/hotspot/src/share/vm/runtime/reflection.cpp index de707164d03..c692687a3a3 100644 --- a/hotspot/src/share/vm/runtime/reflection.cpp +++ b/hotspot/src/share/vm/runtime/reflection.cpp @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "classfile/javaClasses.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/verifier.hpp" #include "classfile/vmSymbols.hpp" diff --git a/hotspot/src/share/vm/runtime/safepoint.cpp b/hotspot/src/share/vm/runtime/safepoint.cpp index 7e7f36788f1..d32dbed4518 100644 --- a/hotspot/src/share/vm/runtime/safepoint.cpp +++ b/hotspot/src/share/vm/runtime/safepoint.cpp @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 2bffd9b33db..5d8fb2e3ba3 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -27,6 +27,7 @@ #include "classfile/javaClasses.hpp" #include "classfile/loaderConstraints.hpp" #include "classfile/placeholders.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "ci/ciField.hpp" #include "ci/ciInstance.hpp" diff --git a/hotspot/src/share/vm/utilities/hashtable.cpp b/hotspot/src/share/vm/utilities/hashtable.cpp index 8698cca914a..c0c73c425fc 100644 --- a/hotspot/src/share/vm/utilities/hashtable.cpp +++ b/hotspot/src/share/vm/utilities/hashtable.cpp @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "classfile/altHashing.hpp" #include "classfile/javaClasses.hpp" +#include "classfile/stringTable.hpp" #include "memory/allocation.inline.hpp" #include "memory/filemap.hpp" #include "memory/resourceArea.hpp" From 09c2deeb5aa8544896c26f2d6e60d78287fa43a7 Mon Sep 17 00:00:00 2001 From: Andreas Sjoberg <andreas.sjoberg@oracle.com> Date: Thu, 8 May 2014 10:29:17 +0200 Subject: [PATCH 044/157] 8042474: Clean up duplicated code in RSHashTable Removed duplicate code in RSHashTable to fetch SparsePRTEntries Reviewed-by: tschatzl, brutisso --- .../vm/gc_implementation/g1/sparsePRT.cpp | 42 ++++--------------- .../vm/gc_implementation/g1/sparsePRT.hpp | 10 +---- 2 files changed, 10 insertions(+), 42 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp index 11f30c36283..fe33cef7d28 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -194,23 +194,16 @@ bool RSHashTable::add_card(RegionIdx_t region_ind, CardIdx_t card_index) { } bool RSHashTable::get_cards(RegionIdx_t region_ind, CardIdx_t* cards) { - int ind = (int) (region_ind & capacity_mask()); - int cur_ind = _buckets[ind]; - SparsePRTEntry* cur; - while (cur_ind != NullEntry && - (cur = entry(cur_ind))->r_ind() != region_ind) { - cur_ind = cur->next_index(); + SparsePRTEntry* entry = get_entry(region_ind); + if (entry == NULL) { + return false; } - - if (cur_ind == NullEntry) return false; // Otherwise... - assert(cur->r_ind() == region_ind, "Postcondition of loop + test above."); - assert(cur->num_valid_cards() > 0, "Inv"); - cur->copy_cards(cards); + entry->copy_cards(cards); return true; } -SparsePRTEntry* RSHashTable::get_entry(RegionIdx_t region_ind) { +SparsePRTEntry* RSHashTable::get_entry(RegionIdx_t region_ind) const { int ind = (int) (region_ind & capacity_mask()); int cur_ind = _buckets[ind]; SparsePRTEntry* cur; @@ -246,28 +239,9 @@ bool RSHashTable::delete_entry(RegionIdx_t region_ind) { return true; } -SparsePRTEntry* -RSHashTable::entry_for_region_ind(RegionIdx_t region_ind) const { - assert(occupied_entries() < capacity(), "Precondition"); - int ind = (int) (region_ind & capacity_mask()); - int cur_ind = _buckets[ind]; - SparsePRTEntry* cur; - while (cur_ind != NullEntry && - (cur = entry(cur_ind))->r_ind() != region_ind) { - cur_ind = cur->next_index(); - } - - if (cur_ind != NullEntry) { - assert(cur->r_ind() == region_ind, "Loop postcondition + test"); - return cur; - } else { - return NULL; - } -} - SparsePRTEntry* RSHashTable::entry_for_region_ind_create(RegionIdx_t region_ind) { - SparsePRTEntry* res = entry_for_region_ind(region_ind); + SparsePRTEntry* res = get_entry(region_ind); if (res == NULL) { int new_ind = alloc_entry(); assert(0 <= new_ind && (size_t)new_ind < capacity(), "There should be room."); @@ -365,7 +339,7 @@ bool RSHashTableIter::has_next(size_t& card_index) { } bool RSHashTable::contains_card(RegionIdx_t region_index, CardIdx_t card_index) const { - SparsePRTEntry* e = entry_for_region_ind(region_index); + SparsePRTEntry* e = get_entry(region_index); return (e != NULL && e->contains_card(card_index)); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp index 6094837d35a..a534ceca5f1 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,12 +119,6 @@ class RSHashTable : public CHeapObj<mtGC> { int _free_region; int _free_list; - // Requires that the caller hold a lock preventing parallel modifying - // operations, and that the the table be less than completely full. If - // an entry for "region_ind" is already in the table, finds it and - // returns its address; otherwise returns "NULL." - SparsePRTEntry* entry_for_region_ind(RegionIdx_t region_ind) const; - // Requires that the caller hold a lock preventing parallel modifying // operations, and that the the table be less than completely full. If // an entry for "region_ind" is already in the table, finds it and @@ -158,7 +152,7 @@ public: void add_entry(SparsePRTEntry* e); - SparsePRTEntry* get_entry(RegionIdx_t region_id); + SparsePRTEntry* get_entry(RegionIdx_t region_id) const; void clear(); From 535c74a38e4e5b6f46e0749cc7926c313f713ca0 Mon Sep 17 00:00:00 2001 From: Matthias Braun <matthia.braun@sap.com> Date: Thu, 8 May 2014 11:46:03 +0200 Subject: [PATCH 045/157] 8042416: X11GraphicsEnvironment.isDisplayLocal() throws NoSuchElementException if DISPLAY host has more IP addresses than a local interface Reviewed-by: anthony, azvegint --- jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java b/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java index 02f491d6707..cfa6e516dfe 100644 --- a/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java +++ b/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java @@ -277,8 +277,9 @@ public class X11GraphicsEnvironment for (; interfaces.hasMoreElements();) { locals = interfaces.nextElement().getInetAddresses(); for (; locals.hasMoreElements();) { + final InetAddress localAddr = locals.nextElement(); for (int i = 0; i < remAddr.length; i++) { - if (locals.nextElement().equals(remAddr[i])) { + if (localAddr.equals(remAddr[i])) { return Boolean.TRUE; } } From 1ec8e7aa8a6ee79c58d5c9fb5e28579cbff2a1cd Mon Sep 17 00:00:00 2001 From: Petr Pchelko <pchelko@openjdk.org> Date: Thu, 8 May 2014 16:50:42 +0400 Subject: [PATCH 046/157] 8036917: [macosx] Native memory leaks Reviewed-by: serb, azvegint --- jdk/src/macosx/native/sun/awt/CImage.m | 33 +++++++++++++------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/jdk/src/macosx/native/sun/awt/CImage.m b/jdk/src/macosx/native/sun/awt/CImage.m index b6db3458047..e4ef6306031 100644 --- a/jdk/src/macosx/native/sun/awt/CImage.m +++ b/jdk/src/macosx/native/sun/awt/CImage.m @@ -76,17 +76,17 @@ static void CImage_CopyNSImageIntoArray static NSBitmapImageRep* CImage_CreateImageRep(JNIEnv *env, jintArray buffer, jint width, jint height) { - NSBitmapImageRep* imageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL - pixelsWide:width - pixelsHigh:height - bitsPerSample:8 - samplesPerPixel:4 - hasAlpha:YES - isPlanar:NO - colorSpaceName:NSDeviceRGBColorSpace - bitmapFormat:NSAlphaFirstBitmapFormat - bytesPerRow:width*4 // TODO: use explicit scanStride - bitsPerPixel:32]; + NSBitmapImageRep* imageRep = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL + pixelsWide:width + pixelsHigh:height + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bitmapFormat:NSAlphaFirstBitmapFormat + bytesPerRow:width*4 // TODO: use explicit scanStride + bitsPerPixel:32] autorelease]; jint *imgData = (jint *)[imageRep bitmapData]; if (imgData == NULL) return 0L; @@ -115,9 +115,8 @@ JNF_COCOA_ENTER(env); NSBitmapImageRep* imageRep = CImage_CreateImageRep(env, buffer, width, height); if (imageRep) { - NSImage *nsImage = [[[NSImage alloc] initWithSize:NSMakeSize(width, height)] retain]; + NSImage *nsImage = [[NSImage alloc] initWithSize:NSMakeSize(width, height)]; [nsImage addRepresentation:imageRep]; - [imageRep release]; result = ptr_to_jlong(nsImage); } @@ -160,7 +159,7 @@ JNF_COCOA_ENTER(env); (*env)->ReleaseIntArrayElements(env, widths, ws, JNI_ABORT); } if ([reps count]) { - NSImage *nsImage = [[[NSImage alloc] initWithSize:NSMakeSize(0, 0)] retain]; + NSImage *nsImage = [[NSImage alloc] initWithSize:NSMakeSize(0, 0)]; [nsImage addRepresentations: reps]; result = ptr_to_jlong(nsImage); } @@ -184,7 +183,7 @@ JNF_COCOA_ENTER(env); IconRef iconRef; if (noErr == GetIconRef(kOnSystemDisk, kSystemIconsCreator, selector, &iconRef)) { - image = [[[NSImage alloc] initWithIconRef:iconRef] retain]; + image = [[NSImage alloc] initWithIconRef:iconRef]; ReleaseIconRef(iconRef); } @@ -206,7 +205,7 @@ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromFile JNF_COCOA_ENTER(env); NSString *path = JNFNormalizedNSStringForPath(env, file); - image = [[[NSImage alloc] initByReferencingFile:path] retain]; + image = [[NSImage alloc] initByReferencingFile:path]; JNF_COCOA_EXIT(env); @@ -435,7 +434,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_lwawt_macosx_CImage_nativeGetPlatformImage JNF_COCOA_ENTER(env); - NSBitmapImageRep* imageRep = [CImage_CreateImageRep(env, buffer, width, height) autorelease]; + NSBitmapImageRep* imageRep = CImage_CreateImageRep(env, buffer, width, height); if (imageRep) { NSData *tiffImage = [imageRep TIFFRepresentation]; jsize tiffSize = (jsize)[tiffImage length]; From 7ef690b2c7dfd63a5b053aa84ee44b450f72507e Mon Sep 17 00:00:00 2001 From: Roland Westrelin <roland@openjdk.org> Date: Thu, 15 May 2014 09:09:28 +0200 Subject: [PATCH 047/157] 8026694: New type profiling points break compilation replay Fixes compilation replay with new profiling points Reviewed-by: kvn, twisti --- .../classes/sun/jvm/hotspot/ci/ciEnv.java | 11 +- .../classes/sun/jvm/hotspot/ci/ciKlass.java | 5 + .../classes/sun/jvm/hotspot/ci/ciMethod.java | 30 ++- .../sun/jvm/hotspot/ci/ciMethodData.java | 185 ++++++++++++--- .../ArgInfoData.java} | 34 +-- .../sun/jvm/hotspot/oops/CallTypeData.java | 108 +++++++++ .../hotspot/oops/CallTypeDataInterface.java | 35 +++ .../sun/jvm/hotspot/oops/DataLayout.java | 17 +- .../classes/sun/jvm/hotspot/oops/Method.java | 10 +- .../sun/jvm/hotspot/oops/MethodData.java | 220 +++++++++++++++--- .../jvm/hotspot/oops/MethodDataInterface.java | 39 ++++ .../jvm/hotspot/oops/ParametersTypeData.java | 74 ++++++ .../jvm/hotspot/oops/ReceiverTypeData.java | 16 +- .../ReturnTypeEntry.java} | 39 ++-- .../jvm/hotspot/oops/SpeculativeTrapData.java | 70 ++++++ .../sun/jvm/hotspot/oops/TypeEntries.java | 97 ++++++++ .../jvm/hotspot/oops/TypeEntriesAtCall.java | 54 +++++ .../hotspot/oops/TypeStackSlotEntries.java | 91 ++++++++ .../sun/jvm/hotspot/oops/VirtualCallData.java | 6 +- .../jvm/hotspot/oops/VirtualCallTypeData.java | 108 +++++++++ hotspot/src/share/vm/ci/ciMethodData.cpp | 121 +++++++--- hotspot/src/share/vm/ci/ciMethodData.hpp | 27 ++- hotspot/src/share/vm/ci/ciReplay.cpp | 58 +++-- hotspot/src/share/vm/oops/methodData.hpp | 43 +++- hotspot/src/share/vm/runtime/vmStructs.cpp | 5 + 25 files changed, 1306 insertions(+), 197 deletions(-) rename hotspot/agent/src/share/classes/sun/jvm/hotspot/{ci/ciVirtualCallData.java => oops/ArgInfoData.java} (62%) create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/CallTypeData.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/CallTypeDataInterface.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodDataInterface.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ParametersTypeData.java rename hotspot/agent/src/share/classes/sun/jvm/hotspot/{ci/ciReceiverTypeData.java => oops/ReturnTypeEntry.java} (62%) create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/SpeculativeTrapData.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeEntries.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeEntriesAtCall.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeStackSlotEntries.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallTypeData.java diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciEnv.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciEnv.java index c0db13d1365..ca4b2f5aa34 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciEnv.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciEnv.java @@ -64,7 +64,11 @@ public class ciEnv extends VMObject { } public Compile compilerData() { - return new Compile(compilerDataField.getValue(this.getAddress())); + Address addr = compilerDataField.getValue(this.getAddress()); + if (addr == null) { + return null; + } + return new Compile(addr); } public ciObjectFactory factory() { @@ -94,10 +98,7 @@ public class ciEnv extends VMObject { Method method = task.method(); int entryBci = task.osrBci(); int compLevel = task.compLevel(); - Klass holder = method.getMethodHolder(); - out.print("compile " + holder.getName().asString() + " " + - OopUtilities.escapeString(method.getName().asString()) + " " + - method.getSignature().asString() + " " + + out.print("compile " + method.nameAsAscii() + " " + entryBci + " " + compLevel); Compile compiler = compilerData(); if (compiler != null) { diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciKlass.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciKlass.java index aba64a5015e..2e03c5481aa 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciKlass.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciKlass.java @@ -55,4 +55,9 @@ public class ciKlass extends ciType { public ciKlass(Address addr) { super(addr); } + + public void printValueOn(PrintStream tty) { + Klass k = (Klass)getMetadata(); + k.printValueOn(tty); + } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java index cdf21c946ac..ac972e97ce6 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java @@ -90,17 +90,23 @@ public class ciMethod extends ciMetadata { } public void dumpReplayData(PrintStream out) { - Method method = (Method)getMetadata(); - NMethod nm = method.getNativeMethod(); - Klass holder = method.getMethodHolder(); - out.println("ciMethod " + - holder.getName().asString() + " " + - OopUtilities.escapeString(method.getName().asString()) + " " + - method.getSignature().asString() + " " + - method.getInvocationCount() + " " + - method.getBackedgeCount() + " " + - interpreterInvocationCount() + " " + - interpreterThrowoutCount() + " " + - instructionsSize()); + Method method = (Method)getMetadata(); + NMethod nm = method.getNativeMethod(); + out.println("ciMethod " + + nameAsAscii() + " " + + method.getInvocationCount() + " " + + method.getBackedgeCount() + " " + + interpreterInvocationCount() + " " + + interpreterThrowoutCount() + " " + + instructionsSize()); + } + + public void printValueOn(PrintStream tty) { + tty.print("ciMethod " + method().getName().asString() + method().getSignature().asString() + "@" + getAddress()); + } + + public String nameAsAscii() { + Method method = (Method)getMetadata(); + return method.nameAsAscii(); } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethodData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethodData.java index 117a9488cf7..13ad04a9d30 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethodData.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethodData.java @@ -31,7 +31,7 @@ import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.oops.*; import sun.jvm.hotspot.types.*; -public class ciMethodData extends ciMetadata { +public class ciMethodData extends ciMetadata implements MethodDataInterface<ciKlass,ciMethod> { static { VM.registerVMInitializedObserver(new Observer() { public void update(Observable o, Object data) { @@ -54,7 +54,9 @@ public class ciMethodData extends ciMetadata { extraDataSizeField = new CIntField(type.getCIntegerField("_extra_data_size"), 0); dataSizeField = new CIntField(type.getCIntegerField("_data_size"), 0); stateField = new CIntField(type.getCIntegerField("_state"), 0); - sizeofMethodDataOopDesc = (int)db.lookupType("MethodData").getSize();; + Type typeMethodData = db.lookupType("MethodData"); + sizeofMethodDataOopDesc = (int)typeMethodData.getSize(); + parametersTypeDataDi = new CIntField(typeMethodData.getCIntegerField("_parameters_type_data_di"), 0); } private static AddressField origField; @@ -69,11 +71,28 @@ public class ciMethodData extends ciMetadata { private static CIntField dataSizeField; private static CIntField stateField; private static int sizeofMethodDataOopDesc; + private static CIntField parametersTypeDataDi; public ciMethodData(Address addr) { super(addr); } + public ciKlass getKlassAtAddress(Address addr) { + return (ciKlass)ciObjectFactory.getMetadata(addr); + } + + public ciMethod getMethodAtAddress(Address addr) { + return (ciMethod)ciObjectFactory.getMetadata(addr); + } + + public void printKlassValueOn(ciKlass klass, PrintStream st) { + klass.printValueOn(st); + } + + public void printMethodValueOn(ciMethod method, PrintStream st) { + method.printValueOn(st); + } + private byte[] fetchDataAt(Address base, long size) { byte[] result = new byte[(int)size]; for (int i = 0; i < size; i++) { @@ -110,6 +129,10 @@ public class ciMethodData extends ciMetadata { return (int)dataSizeField.getValue(getAddress()); } + int extraDataSize() { + return (int)extraDataSizeField.getValue(getAddress()); + } + int state() { return (int)stateField.getValue(getAddress()); } @@ -122,6 +145,16 @@ public class ciMethodData extends ciMetadata { return dataIndex >= dataSize(); } + ParametersTypeData<ciKlass,ciMethod> parametersTypeData() { + Address base = getAddress().addOffsetTo(origField.getOffset()); + int di = (int)parametersTypeDataDi.getValue(base); + if (di == -1) { + return null; + } + DataLayout dataLayout = new DataLayout(dataField.getValue(getAddress()), di); + return new ParametersTypeData<ciKlass,ciMethod>(this, dataLayout); + } + ProfileData dataAt(int dataIndex) { if (outOfBounds(dataIndex)) { return null; @@ -139,15 +172,21 @@ public class ciMethodData extends ciMetadata { case DataLayout.jumpDataTag: return new JumpData(dataLayout); case DataLayout.receiverTypeDataTag: - return new ciReceiverTypeData(dataLayout); + return new ReceiverTypeData<ciKlass,ciMethod>(this, dataLayout); case DataLayout.virtualCallDataTag: - return new ciVirtualCallData(dataLayout); + return new VirtualCallData<ciKlass,ciMethod>(this, dataLayout); case DataLayout.retDataTag: return new RetData(dataLayout); case DataLayout.branchDataTag: return new BranchData(dataLayout); case DataLayout.multiBranchDataTag: return new MultiBranchData(dataLayout); + case DataLayout.callTypeDataTag: + return new CallTypeData<ciKlass,ciMethod>(this, dataLayout); + case DataLayout.virtualCallTypeDataTag: + return new VirtualCallTypeData<ciKlass,ciMethod>(this, dataLayout); + case DataLayout.parametersTypeDataTag: + return new ParametersTypeData<ciKlass,ciMethod>(this, dataLayout); } } @@ -164,7 +203,23 @@ public class ciMethodData extends ciMetadata { } boolean isValid(ProfileData current) { return current != null; } + DataLayout limitDataPosition() { + return new DataLayout(dataField.getValue(getAddress()), dataSize()); + } + DataLayout extraDataBase() { + return limitDataPosition(); + } + DataLayout extraDataLimit() { + return new DataLayout(dataField.getValue(getAddress()), dataSize() + extraDataSize()); + } + DataLayout nextExtra(DataLayout dataLayout) { + return new DataLayout(dataField.getValue(getAddress()), dataLayout.dp() + DataLayout.computeSizeInBytes(MethodData.extraNbCells(dataLayout))); + } + public void printDataOn(PrintStream st) { + if (parametersTypeData() != null) { + parametersTypeData().printDataOn(st); + } ProfileData data = firstData(); for ( ; isValid(data); data = nextData(data)) { st.print(dpToDi(data.dp())); @@ -172,16 +227,96 @@ public class ciMethodData extends ciMetadata { // st->fillTo(6); data.printDataOn(st); } + st.println("--- Extra data:"); + DataLayout dp = extraDataBase(); + DataLayout end = extraDataLimit(); + for (;; dp = nextExtra(dp)) { + switch(dp.tag()) { + case DataLayout.noTag: + continue; + case DataLayout.bitDataTag: + data = new BitData(dp); + break; + case DataLayout.speculativeTrapDataTag: + data = new SpeculativeTrapData<ciKlass,ciMethod>(this, dp); + break; + case DataLayout.argInfoDataTag: + data = new ArgInfoData(dp); + dp = end; // ArgInfoData is at the end of extra data section. + break; + default: + throw new InternalError("unexpected tag " + dp.tag()); + } + st.print(dpToDi(data.dp())); + st.print(" "); + data.printDataOn(st); + if (dp == end) return; + } + } + + int dumpReplayDataTypeHelper(PrintStream out, int round, int count, int index, ProfileData pdata, ciKlass k) { + if (k != null) { + if (round == 0) count++; + else out.print(" " + ((pdata.dp() + pdata.cellOffset(index)) / MethodData.cellSize) + " " + k.name()); + } + return count; + } + + int dumpReplayDataReceiverTypeHelper(PrintStream out, int round, int count, ReceiverTypeData<ciKlass,ciMethod> vdata) { + for (int i = 0; i < vdata.rowLimit(); i++) { + ciKlass k = vdata.receiver(i); + count = dumpReplayDataTypeHelper(out, round, count, vdata.receiverCellIndex(i), vdata, k); + } + return count; + } + + int dumpReplayDataCallTypeHelper(PrintStream out, int round, int count, CallTypeDataInterface<ciKlass> callTypeData) { + if (callTypeData.hasArguments()) { + for (int i = 0; i < callTypeData.numberOfArguments(); i++) { + count = dumpReplayDataTypeHelper(out, round, count, callTypeData.argumentTypeIndex(i), (ProfileData)callTypeData, callTypeData.argumentType(i)); + } + } + if (callTypeData.hasReturn()) { + count = dumpReplayDataTypeHelper(out, round, count, callTypeData.returnTypeIndex(), (ProfileData)callTypeData, callTypeData.returnType()); + } + return count; + } + + int dumpReplayDataExtraDataHelper(PrintStream out, int round, int count) { + DataLayout dp = extraDataBase(); + DataLayout end = extraDataLimit(); + + for (;dp != end; dp = nextExtra(dp)) { + switch(dp.tag()) { + case DataLayout.noTag: + case DataLayout.argInfoDataTag: + return count; + case DataLayout.bitDataTag: + break; + case DataLayout.speculativeTrapDataTag: { + SpeculativeTrapData<ciKlass,ciMethod> data = new SpeculativeTrapData<ciKlass,ciMethod>(this, dp); + ciMethod m = data.method(); + if (m != null) { + if (round == 0) { + count++; + } else { + out.print(" " + (dpToDi(data.dp() + data.cellOffset(SpeculativeTrapData.methodIndex())) / MethodData.cellSize) + " " + m.nameAsAscii()); + } + } + break; + } + default: + throw new InternalError("bad tag " + dp.tag()); + } + } + return count; } public void dumpReplayData(PrintStream out) { MethodData mdo = (MethodData)getMetadata(); Method method = mdo.getMethod(); - Klass holder = method.getMethodHolder(); out.print("ciMethodData " + - holder.getName().asString() + " " + - OopUtilities.escapeString(method.getName().asString()) + " " + - method.getSignature().asString() + " " + + method.nameAsAscii() + " " + state() + " " + currentMileage()); byte[] orig = orig(); out.print(" orig " + orig.length); @@ -195,30 +330,28 @@ public class ciMethodData extends ciMetadata { out.print(" 0x" + Long.toHexString(data[i])); } int count = 0; + ParametersTypeData<ciKlass,ciMethod> parameters = parametersTypeData(); for (int round = 0; round < 2; round++) { if (round == 1) out.print(" oops " + count); ProfileData pdata = firstData(); for ( ; isValid(pdata); pdata = nextData(pdata)) { - if (pdata instanceof ciReceiverTypeData) { - ciReceiverTypeData vdata = (ciReceiverTypeData)pdata; - for (int i = 0; i < vdata.rowLimit(); i++) { - ciKlass k = vdata.receiverAt(i); - if (k != null) { - if (round == 0) count++; - else out.print(" " + ((vdata.dp() + vdata.cellOffset(vdata.receiverCellIndex(i))) / MethodData.cellSize) + " " + k.name()); - } - } - } else if (pdata instanceof ciVirtualCallData) { - ciVirtualCallData vdata = (ciVirtualCallData)pdata; - for (int i = 0; i < vdata.rowLimit(); i++) { - ciKlass k = vdata.receiverAt(i); - if (k != null) { - if (round == 0) count++; - else out.print(" " + ((vdata.dp() + vdata.cellOffset(vdata.receiverCellIndex(i))) / MethodData.cellSize + " " + k.name())); - } - } + if (pdata instanceof ReceiverTypeData) { + count = dumpReplayDataReceiverTypeHelper(out, round, count, (ReceiverTypeData<ciKlass,ciMethod>)pdata); + } + if (pdata instanceof CallTypeDataInterface) { + count = dumpReplayDataCallTypeHelper(out, round, count, (CallTypeDataInterface<ciKlass>)pdata); } } + if (parameters != null) { + for (int i = 0; i < parameters.numberOfParameters(); i++) { + count = dumpReplayDataTypeHelper(out, round, count, ParametersTypeData.typeIndex(i), parameters, parameters.type(i)); + } + } + } + count = 0; + for (int round = 0; round < 2; round++) { + if (round == 1) out.print(" methods " + count); + count = dumpReplayDataExtraDataHelper(out, round, count); } out.println(); } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciVirtualCallData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ArgInfoData.java similarity index 62% rename from hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciVirtualCallData.java rename to hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ArgInfoData.java index 231ab844e3e..992d86a02ec 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciVirtualCallData.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ArgInfoData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,31 +22,35 @@ * */ -package sun.jvm.hotspot.ci; +package sun.jvm.hotspot.oops; import java.io.*; import java.util.*; import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.runtime.*; -import sun.jvm.hotspot.oops.*; import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; -public class ciVirtualCallData extends VirtualCallData { - public ciVirtualCallData(DataLayout data) { - super(data); +public class ArgInfoData extends ArrayData { + + public ArgInfoData(DataLayout layout) { + super(layout); } - public Klass receiver(int row) { - throw new InternalError("should not call"); + int numberOfArgs() { + return arrayLen(); } - public ciKlass receiverAt(int row) { - //assert((uint)row < rowLimit(), "oob"); - ciMetadata recv = ciObjectFactory.getMetadata(addressAt(receiverCellIndex(row))); - if (recv != null && !(recv instanceof ciKlass)) { - System.err.println(recv); + int argModified(int arg) { + return arrayUintAt(arg); + } + + public void printDataOn(PrintStream st) { + printShared(st, "ArgInfoData"); + int nargs = numberOfArgs(); + for (int i = 0; i < nargs; i++) { + st.print(" 0x" + Integer.toHexString(argModified(i))); } - //assert(recv == NULL || recv->isKlass(), "wrong type"); - return (ciKlass)recv; + st.println(); } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/CallTypeData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/CallTypeData.java new file mode 100644 index 00000000000..a0eb02946b3 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/CallTypeData.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 sun.jvm.hotspot.oops; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +// CallTypeData +// +// A CallTypeData is used to access profiling information about a non +// virtual call for which we collect type information about arguments +// and return value. +public class CallTypeData<K,M> extends CounterData implements CallTypeDataInterface<K> { + final TypeStackSlotEntries<K,M> args; + final ReturnTypeEntry<K,M> ret; + + int cellCountGlobalOffset() { + return CounterData.staticCellCount() + TypeEntriesAtCall.cellCountLocalOffset(); + } + + int cellCountNoHeader() { + return uintAt(cellCountGlobalOffset()); + } + + public CallTypeData(MethodDataInterface<K,M> methodData, DataLayout layout) { + super(layout); + args = new TypeStackSlotEntries<K,M>(methodData, this, CounterData.staticCellCount()+TypeEntriesAtCall.headerCellCount(), numberOfArguments()); + ret = new ReturnTypeEntry<K,M>(methodData, this, cellCount() - ReturnTypeEntry.staticCellCount()); + } + + static int staticCellCount() { + return -1; + } + + public int cellCount() { + return CounterData.staticCellCount() + + TypeEntriesAtCall.headerCellCount() + + intAt(cellCountGlobalOffset()); + } + + public int numberOfArguments() { + return cellCountNoHeader() / TypeStackSlotEntries.perArgCount(); + } + + public boolean hasArguments() { + return cellCountNoHeader() >= TypeStackSlotEntries.perArgCount(); + } + + public K argumentType(int i) { + return args.type(i); + } + + public boolean hasReturn() { + return (cellCountNoHeader() % TypeStackSlotEntries.perArgCount()) != 0; + } + + public K returnType() { + return ret.type(); + } + + public int argumentTypeIndex(int i) { + return args.typeIndex(i); + } + + public int returnTypeIndex() { + return ret.typeIndex(); + } + + public void printDataOn(PrintStream st) { + super.printDataOn(st); + if (hasArguments()) { + tab(st); + st.print("argument types"); + args.printDataOn(st); + } + if (hasReturn()) { + tab(st); + st.print("return type"); + ret.printDataOn(st); + } + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/CallTypeDataInterface.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/CallTypeDataInterface.java new file mode 100644 index 00000000000..0a8bf4721e4 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/CallTypeDataInterface.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 sun.jvm.hotspot.oops; + +public interface CallTypeDataInterface<K> { + int numberOfArguments(); + boolean hasArguments(); + K argumentType(int i); + boolean hasReturn(); + K returnType(); + int argumentTypeIndex(int i); + int returnTypeIndex(); +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/DataLayout.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/DataLayout.java index d9348507a96..4c992f176a8 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/DataLayout.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/DataLayout.java @@ -41,6 +41,11 @@ public class DataLayout { public static final int retDataTag = 6; public static final int branchDataTag = 7; public static final int multiBranchDataTag = 8; + public static final int argInfoDataTag = 9; + public static final int callTypeDataTag = 10; + public static final int virtualCallTypeDataTag = 11; + public static final int parametersTypeDataTag = 12; + public static final int speculativeTrapDataTag = 13; // The _struct._flags word is formatted as [trapState:4 | flags:4]. // The trap state breaks down further as [recompile:1 | reason:3]. @@ -61,8 +66,6 @@ public class DataLayout { private int offset; - private boolean handlized; - public DataLayout(MethodData d, int o) { data = d.getAddress(); offset = o; @@ -71,7 +74,6 @@ public class DataLayout { public DataLayout(Address d, int o) { data = d; offset = o; - handlized = true; } public int dp() { return offset; } @@ -90,12 +92,7 @@ public class DataLayout { } public Address addressAt(int index) { - OopHandle handle; - if (handlized) { - return data.getAddressAt(offset + cellOffset(index)); - } else { - return data.getOopHandleAt(offset + cellOffset(index)); - } + return data.getAddressAt(offset + cellOffset(index)); } // Every data layout begins with a header. This header @@ -128,7 +125,7 @@ public class DataLayout { return 1; } - static int computeSizeInBytes(int cellCount) { + static public int computeSizeInBytes(int cellCount) { return headerSizeInBytes() + cellCount * MethodData.cellSize; } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java index e039470f801..2bde98074ff 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java @@ -354,9 +354,7 @@ public class Method extends Metadata { } Klass holder = getMethodHolder(); out.println("ciMethod " + - holder.getName().asString() + " " + - OopUtilities.escapeString(getName().asString()) + " " + - getSignature().asString() + " " + + nameAsAscii() + " " + getInvocationCount() + " " + getBackedgeCount() + " " + interpreterInvocationCount() + " " + @@ -371,4 +369,10 @@ public class Method extends Metadata { public int interpreterInvocationCount() { return getMethodCounters().interpreterInvocationCount(); } + + public String nameAsAscii() { + return getMethodHolder().getName().asString() + " " + + OopUtilities.escapeString(getName().asString()) + " " + + getSignature().asString(); + } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java index 41c121468ea..f07b8268873 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java @@ -33,7 +33,7 @@ import sun.jvm.hotspot.utilities.*; // A MethodData provides interpreter profiling information -public class MethodData extends Metadata { +public class MethodData extends Metadata implements MethodDataInterface<Klass,Method> { static int TypeProfileWidth = 2; static int BciProfileWidth = 2; static int CompileThreshold; @@ -152,6 +152,8 @@ public class MethodData extends Metadata { dataSize = new CIntField(type.getCIntegerField("_data_size"), 0); data = type.getAddressField("_data[0]"); + parametersTypeDataDi = new CIntField(type.getCIntegerField("_parameters_type_data_di"), 0); + sizeofMethodDataOopDesc = (int)type.getSize();; Reason_many = db.lookupIntConstant("Deoptimization::Reason_many").intValue(); @@ -191,6 +193,22 @@ public class MethodData extends Metadata { super(addr); } + public Klass getKlassAtAddress(Address addr) { + return (Klass)Metadata.instantiateWrapperFor(addr); + } + + public Method getMethodAtAddress(Address addr) { + return (Method)Metadata.instantiateWrapperFor(addr); + } + + public void printKlassValueOn(Klass klass, PrintStream st) { + klass.printValueOn(st); + } + + public void printMethodValueOn(Method method, PrintStream st) { + method.printValueOn(st); + } + public boolean isMethodData() { return true; } private static long baseOffset; @@ -198,7 +216,7 @@ public class MethodData extends Metadata { private static MetadataField method; private static CIntField dataSize; private static AddressField data; - + private static CIntField parametersTypeDataDi; public static int sizeofMethodDataOopDesc; public static int cellSize; @@ -225,6 +243,27 @@ public class MethodData extends Metadata { } } + int sizeInBytes() { + if (size == null) { + return 0; + } else { + return (int)size.getValue(getAddress()); + } + } + + int size() { + return (int)Oop.alignObjectSize(VM.getVM().alignUp(sizeInBytes(), VM.getVM().getBytesPerWord())/VM.getVM().getBytesPerWord()); + } + + ParametersTypeData<Klass,Method> parametersTypeData() { + int di = (int)parametersTypeDataDi.getValue(getAddress()); + if (di == -1) { + return null; + } + DataLayout dataLayout = new DataLayout(this, di + (int)data.getOffset()); + return new ParametersTypeData<Klass,Method>(this, dataLayout); + } + boolean outOfBounds(int dataIndex) { return dataIndex >= dataSize(); } @@ -246,15 +285,21 @@ public class MethodData extends Metadata { case DataLayout.jumpDataTag: return new JumpData(dataLayout); case DataLayout.receiverTypeDataTag: - return new ReceiverTypeData(dataLayout); + return new ReceiverTypeData<Klass,Method>(this, dataLayout); case DataLayout.virtualCallDataTag: - return new VirtualCallData(dataLayout); + return new VirtualCallData<Klass,Method>(this, dataLayout); case DataLayout.retDataTag: return new RetData(dataLayout); case DataLayout.branchDataTag: return new BranchData(dataLayout); case DataLayout.multiBranchDataTag: return new MultiBranchData(dataLayout); + case DataLayout.callTypeDataTag: + return new CallTypeData<Klass,Method>(this, dataLayout); + case DataLayout.virtualCallTypeDataTag: + return new VirtualCallTypeData<Klass,Method>(this, dataLayout); + case DataLayout.parametersTypeDataTag: + return new ParametersTypeData<Klass,Method>(this, dataLayout); } } @@ -272,7 +317,42 @@ public class MethodData extends Metadata { } boolean isValid(ProfileData current) { return current != null; } + DataLayout limitDataPosition() { + return new DataLayout(this, dataSize() + (int)data.getOffset()); + } + + DataLayout extraDataBase() { + return limitDataPosition(); + } + + DataLayout extraDataLimit() { + return new DataLayout(this, sizeInBytes()); + } + + static public int extraNbCells(DataLayout dataLayout) { + int nbCells = 0; + switch(dataLayout.tag()) { + case DataLayout.bitDataTag: + case DataLayout.noTag: + nbCells = BitData.staticCellCount(); + break; + case DataLayout.speculativeTrapDataTag: + nbCells = SpeculativeTrapData.staticCellCount(); + break; + default: + throw new InternalError("unexpected tag " + dataLayout.tag()); + } + return nbCells; + } + + DataLayout nextExtra(DataLayout dataLayout) { + return new DataLayout(this, dataLayout.dp() + DataLayout.computeSizeInBytes(extraNbCells(dataLayout))); + } + public void printDataOn(PrintStream st) { + if (parametersTypeData() != null) { + parametersTypeData().printDataOn(st); + } ProfileData data = firstData(); for ( ; isValid(data); data = nextData(data)) { st.print(dpToDi(data.dp())); @@ -280,6 +360,31 @@ public class MethodData extends Metadata { // st->fillTo(6); data.printDataOn(st); } + st.println("--- Extra data:"); + DataLayout dp = extraDataBase(); + DataLayout end = extraDataLimit(); + for (;; dp = nextExtra(dp)) { + switch(dp.tag()) { + case DataLayout.noTag: + continue; + case DataLayout.bitDataTag: + data = new BitData(dp); + break; + case DataLayout.speculativeTrapDataTag: + data = new SpeculativeTrapData<Klass,Method>(this, dp); + break; + case DataLayout.argInfoDataTag: + data = new ArgInfoData(dp); + dp = end; // ArgInfoData is at the end of extra data section. + break; + default: + throw new InternalError("unexpected tag " + dp.tag()); + } + st.print(dpToDi(data.dp())); + st.print(" "); + data.printDataOn(st); + if (dp == end) return; + } } private byte[] fetchDataAt(Address base, long offset, long size) { @@ -332,14 +437,71 @@ public class MethodData extends Metadata { return 20000; } + int dumpReplayDataTypeHelper(PrintStream out, int round, int count, int index, ProfileData pdata, Klass k) { + if (k != null) { + if (round == 0) count++; + else out.print(" " + + (dpToDi(pdata.dp() + + pdata.cellOffset(index)) / cellSize) + " " + + k.getName().asString()); + } + return count; + } + + int dumpReplayDataReceiverTypeHelper(PrintStream out, int round, int count, ReceiverTypeData<Klass,Method> vdata) { + for (int i = 0; i < vdata.rowLimit(); i++) { + Klass k = vdata.receiver(i); + count = dumpReplayDataTypeHelper(out, round, count, vdata.receiverCellIndex(i), vdata, k); + } + return count; + } + + int dumpReplayDataCallTypeHelper(PrintStream out, int round, int count, CallTypeDataInterface<Klass> callTypeData) { + if (callTypeData.hasArguments()) { + for (int i = 0; i < callTypeData.numberOfArguments(); i++) { + count = dumpReplayDataTypeHelper(out, round, count, callTypeData.argumentTypeIndex(i), (ProfileData)callTypeData, callTypeData.argumentType(i)); + } + } + if (callTypeData.hasReturn()) { + count = dumpReplayDataTypeHelper(out, round, count, callTypeData.returnTypeIndex(), (ProfileData)callTypeData, callTypeData.returnType()); + } + return count; + } + + int dumpReplayDataExtraDataHelper(PrintStream out, int round, int count) { + DataLayout dp = extraDataBase(); + DataLayout end = extraDataLimit(); + + for (;dp != end; dp = nextExtra(dp)) { + switch(dp.tag()) { + case DataLayout.noTag: + case DataLayout.argInfoDataTag: + return count; + case DataLayout.bitDataTag: + break; + case DataLayout.speculativeTrapDataTag: { + SpeculativeTrapData<Klass,Method> data = new SpeculativeTrapData<Klass,Method>(this, dp); + Method m = data.method(); + if (m != null) { + if (round == 0) { + count++; + } else { + out.print(" " + (dpToDi(data.dp() + data.cellOffset(SpeculativeTrapData.methodIndex())) / cellSize) + " " + m.nameAsAscii()); + } + } + break; + } + default: + throw new InternalError("bad tag " + dp.tag()); + } + } + return count; + } + public void dumpReplayData(PrintStream out) { Method method = getMethod(); - Klass holder = method.getMethodHolder(); - out.print("ciMethodData " + - holder.getName().asString() + " " + - OopUtilities.escapeString(method.getName().asString()) + " " + - method.getSignature().asString() + " " + - "2" + " " + + out.print("ciMethodData " + method.nameAsAscii() + + " " + "2" + " " + currentMileage()); byte[] orig = orig(); out.print(" orig " + orig.length); @@ -353,36 +515,28 @@ public class MethodData extends Metadata { out.print(" 0x" + Long.toHexString(data[i])); } int count = 0; + ParametersTypeData<Klass,Method> parameters = parametersTypeData(); for (int round = 0; round < 2; round++) { if (round == 1) out.print(" oops " + count); ProfileData pdata = firstData(); for ( ; isValid(pdata); pdata = nextData(pdata)) { if (pdata instanceof ReceiverTypeData) { - ReceiverTypeData vdata = (ReceiverTypeData)pdata; - for (int i = 0; i < vdata.rowLimit(); i++) { - Klass k = vdata.receiver(i); - if (k != null) { - if (round == 0) count++; - else out.print(" " + - (dpToDi(vdata.dp() + - vdata.cellOffset(vdata.receiverCellIndex(i))) / cellSize) + " " + - k.getName().asString()); - } - } - } else if (pdata instanceof VirtualCallData) { - VirtualCallData vdata = (VirtualCallData)pdata; - for (int i = 0; i < vdata.rowLimit(); i++) { - Klass k = vdata.receiver(i); - if (k != null) { - if (round == 0) count++; - else out.print(" " + - (dpToDi(vdata.dp() + - vdata.cellOffset(vdata.receiverCellIndex(i))) / cellSize) + " " + - k.getName().asString()); - } - } + count = dumpReplayDataReceiverTypeHelper(out, round, count, (ReceiverTypeData<Klass,Method>)pdata); + } + if (pdata instanceof CallTypeDataInterface) { + count = dumpReplayDataCallTypeHelper(out, round, count, (CallTypeDataInterface<Klass>)pdata); } } + if (parameters != null) { + for (int i = 0; i < parameters.numberOfParameters(); i++) { + count = dumpReplayDataTypeHelper(out, round, count, ParametersTypeData.typeIndex(i), parameters, parameters.type(i)); + } + } + } + count = 0; + for (int round = 0; round < 2; round++) { + if (round == 1) out.print(" methods " + count); + count = dumpReplayDataExtraDataHelper(out, round, count); } out.println(); } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodDataInterface.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodDataInterface.java new file mode 100644 index 00000000000..8e6b131ee9d --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodDataInterface.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 sun.jvm.hotspot.oops; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +public interface MethodDataInterface<K, M> { + K getKlassAtAddress(Address addr); + M getMethodAtAddress(Address addr); + void printKlassValueOn(K klass, PrintStream st); + void printMethodValueOn(M klass, PrintStream st); +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ParametersTypeData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ParametersTypeData.java new file mode 100644 index 00000000000..d1a1fea6914 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ParametersTypeData.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 sun.jvm.hotspot.oops; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +// ParametersTypeData +// +// A ParametersTypeData is used to access profiling information about +// types of parameters to a method +public class ParametersTypeData<K,M> extends ArrayData { + final TypeStackSlotEntries<K,M> parameters; + + static int stackSlotLocalOffset(int i) { + return arrayStartOffSet + TypeStackSlotEntries.stackSlotLocalOffset(i); + } + + static int typeLocalOffset(int i) { + return arrayStartOffSet + TypeStackSlotEntries.typeLocalOffset(i); + } + + public ParametersTypeData(MethodDataInterface<K,M> methodData, DataLayout layout) { + super(layout); + parameters = new TypeStackSlotEntries<K,M>(methodData, this, 1, numberOfParameters()); + } + + public int numberOfParameters() { + return arrayLen() / TypeStackSlotEntries.perArgCount(); + } + + int stackSlot(int i) { + return parameters.stackSlot(i); + } + + public K type(int i) { + return parameters.type(i); + } + + static public int typeIndex(int i) { + return typeLocalOffset(i); + } + + public void printDataOn(PrintStream st) { + st.print("parameter types"); + parameters.printDataOn(st); + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ReceiverTypeData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ReceiverTypeData.java index 155035eea18..7ac053fe0c5 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ReceiverTypeData.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ReceiverTypeData.java @@ -37,13 +37,15 @@ import sun.jvm.hotspot.utilities.*; // dynamic type check. It consists of a counter which counts the total times // that the check is reached, and a series of (Klass, count) pairs // which are used to store a type profile for the receiver of the check. -public class ReceiverTypeData extends CounterData { +public class ReceiverTypeData<K,M> extends CounterData { static final int receiver0Offset = counterCellCount; static final int count0Offset = receiver0Offset + 1; static final int receiverTypeRowCellCount = (count0Offset + 1) - receiver0Offset; + final MethodDataInterface<K,M> methodData; - public ReceiverTypeData(DataLayout layout) { + public ReceiverTypeData(MethodDataInterface<K,M> methodData, DataLayout layout) { super(layout); + this.methodData = methodData; //assert(layout.tag() == DataLayout.receiverTypeDataTag || // layout.tag() == DataLayout.virtualCallDataTag, "wrong type"); } @@ -73,14 +75,14 @@ public class ReceiverTypeData extends CounterData { // gc; it does not assert the receiver is a klass. During compaction of the // perm gen, the klass may already have moved, so the isKlass() predicate // would fail. The 'normal' version should be used whenever possible. - Klass receiverUnchecked(int row) { + K receiverUnchecked(int row) { //assert(row < rowLimit(), "oob"); Address recv = addressAt(receiverCellIndex(row)); - return (Klass)Metadata.instantiateWrapperFor(recv); + return methodData.getKlassAtAddress(recv); } - public Klass receiver(int row) { - Klass recv = receiverUnchecked(row); + public K receiver(int row) { + K recv = receiverUnchecked(row); //assert(recv == NULL || ((oop)recv).isKlass(), "wrong type"); return recv; } @@ -111,7 +113,7 @@ public class ReceiverTypeData extends CounterData { for (row = 0; row < rowLimit(); row++) { if (receiver(row) != null) { tab(st); - receiver(row).printValueOn(st); + methodData.printKlassValueOn(receiver(row), st); st.println("(" + receiverCount(row) + ")"); } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciReceiverTypeData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ReturnTypeEntry.java similarity index 62% rename from hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciReceiverTypeData.java rename to hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ReturnTypeEntry.java index e568b3f7cec..667e4cd4a94 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciReceiverTypeData.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ReturnTypeEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,32 +22,39 @@ * */ -package sun.jvm.hotspot.ci; +package sun.jvm.hotspot.oops; import java.io.*; import java.util.*; import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.runtime.*; -import sun.jvm.hotspot.oops.*; import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; -public class ciReceiverTypeData extends ReceiverTypeData { - public ciReceiverTypeData(DataLayout data) { - super(data); +// Type entry used for return from a call. A single cell to record the +// type. +public class ReturnTypeEntry<K,M> extends TypeEntries<K,M> { + static final int cellCount = 1; + + ReturnTypeEntry(MethodDataInterface<K,M> methodData, ProfileData pd, int baseOff) { + super(methodData, pd, baseOff); } - public Klass receiver(int row) { - throw new InternalError("should not call"); + K type() { + return validKlass(baseOff); } - public ciKlass receiverAt(int row) { - //assert((uint)row < rowLimit(), "oob"); - ciMetadata recv = ciObjectFactory.getMetadata(addressAt(receiverCellIndex(row))); - if (recv != null && !(recv instanceof ciKlass)) { - System.err.println(recv); - } - //assert(recv == NULL || recv->isKlass(), "wrong type"); - return (ciKlass)recv; + static int staticCellCount() { + return cellCount; } + int typeIndex() { + return baseOff; + } + + void printDataOn(PrintStream st) { + pd.tab(st); + printKlass(st, baseOff); + st.println(); + } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/SpeculativeTrapData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/SpeculativeTrapData.java new file mode 100644 index 00000000000..16a33f932b9 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/SpeculativeTrapData.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 sun.jvm.hotspot.oops; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +// SpeculativeTrapData +// +// A SpeculativeTrapData is used to record traps due to type +// speculation. It records the root of the compilation. +public class SpeculativeTrapData<K, M> extends ProfileData { + static final int speculativeTrapMethod = 0; + static final int speculativeTrapCellCount = 1; + final MethodDataInterface<K, M> methodData; + + public SpeculativeTrapData(MethodDataInterface<K,M> methodData, DataLayout layout) { + super(layout); + this.methodData = methodData; + } + + static int staticCellCount() { + return speculativeTrapCellCount; + } + + public int cellCount() { + return staticCellCount(); + } + + public M method() { + return methodData.getMethodAtAddress(addressAt(speculativeTrapMethod)); + } + + static public int methodIndex() { + return speculativeTrapMethod; + } + + public void printDataOn(PrintStream st) { + printShared(st, "SpeculativeTrapData"); + tab(st); + methodData.printMethodValueOn(method(), st); + st.println(); + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeEntries.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeEntries.java new file mode 100644 index 00000000000..8b791b5f938 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeEntries.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 sun.jvm.hotspot.oops; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +// Entries in a ProfileData object to record types: it can either be +// none (no profile), unknown (conflicting profile data) or a klass if +// a single one is seen. Whether a null reference was seen is also +// recorded. No counter is associated with the type and a single type +// is tracked (unlike VirtualCallData). +public abstract class TypeEntries<K,M> { + static final int nullSeen = 1; + static final int typeMask = ~nullSeen; + static final int typeUnknown = 2; + static final int statusBits = nullSeen | typeUnknown; + static final int typeKlassMask = ~statusBits; + + final ProfileData pd; + final int baseOff; + final MethodDataInterface<K,M> methodData; + + boolean wasNullSeen(int index) { + int v = pd.intptrAt(index); + return (v & nullSeen) != 0; + } + + boolean isTypeUnknown(int index) { + int v = pd.intptrAt(index); + return (v & typeUnknown) != 0; + } + + boolean isTypeNone(int index) { + int v = pd.intptrAt(index); + return (v & typeMask) == 0; + } + + K validKlass(int index) { + if (!isTypeNone(index) && + !isTypeUnknown(index)) { + return methodData.getKlassAtAddress(pd.addressAt(index).andWithMask(typeKlassMask)); + } else { + return null; + } + } + + void printKlass(PrintStream st, int index) { + if (isTypeNone(index)) { + st.print("none"); + } else if (isTypeUnknown(index)) { + st.print("unknown"); + } else { + methodData.printKlassValueOn(validKlass(index), st); + } + if (wasNullSeen(index)) { + st.print(" (null seen)"); + } + } + + TypeEntries(MethodDataInterface<K,M> methodData, ProfileData pd, int baseOff) { + this.pd = pd; + this.baseOff = baseOff; + this.methodData = methodData; + } + + long intptrAt(int index) { + return pd.intptrAt(index); + } + +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeEntriesAtCall.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeEntriesAtCall.java new file mode 100644 index 00000000000..2891f91c69e --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeEntriesAtCall.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 sun.jvm.hotspot.oops; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +// Entries to collect type information at a call: contains arguments +// (TypeStackSlotEntries), a return type (ReturnTypeEntry) and a +// number of cells. +public abstract class TypeEntriesAtCall { + + static int stackSlotLocalOffset(int i) { + return headerCellCount() + TypeStackSlotEntries.stackSlotLocalOffset(i); + } + + static int argumentTypeLocalOffset(int i) { + return headerCellCount() + TypeStackSlotEntries.typeLocalOffset(i); + } + + static int headerCellCount() { + return 1; + } + + static int cellCountLocalOffset() { + return 0; + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeStackSlotEntries.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeStackSlotEntries.java new file mode 100644 index 00000000000..9efff34a4c3 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeStackSlotEntries.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 sun.jvm.hotspot.oops; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +// Type entries used for arguments passed at a call and parameters on +// method entry. 2 cells per entry: one for the type encoded as in +// TypeEntries and one initialized with the stack slot where the +// profiled object is to be found so that the interpreter can locate +// it quickly. +public class TypeStackSlotEntries<K,M> extends TypeEntries<K,M> { + static final int stackSlotEntry = 0; + static final int typeEntry = 1; + static final int perArgCellCount = 2; + + int stackSlotOffset(int i) { + return baseOff + stackSlotLocalOffset(i); + } + + final int numberOfEntries; + + int typeOffsetInCells(int i) { + return baseOff + typeLocalOffset(i); + } + + TypeStackSlotEntries(MethodDataInterface<K,M> methodData, ProfileData pd, int baseOff, int nbEntries) { + super(methodData, pd, baseOff); + numberOfEntries = nbEntries; + } + + static int stackSlotLocalOffset(int i) { + return i * perArgCellCount + stackSlotEntry; + } + + static int typeLocalOffset(int i) { + return i * perArgCellCount + typeEntry; + } + + int stackSlot(int i) { + return pd.uintAt(stackSlotOffset(i)); + } + + K type(int i) { + return validKlass(typeOffsetInCells(i)); + } + + static int perArgCount() { + return perArgCellCount; + } + + int typeIndex(int i) { + return typeOffsetInCells(i); + } + + void printDataOn(PrintStream st) { + for (int i = 0; i < numberOfEntries; i++) { + pd.tab(st); + st.print(i + ": stack(" + stackSlot(i)+ ") "); + printKlass(st, typeOffsetInCells(i)); + st.println(); + } + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallData.java index 21b715f343c..eec5000a6a4 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallData.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallData.java @@ -35,9 +35,9 @@ import sun.jvm.hotspot.utilities.*; // // A VirtualCallData is used to access profiling information about a // call. For now, it has nothing more than a ReceiverTypeData. -public class VirtualCallData extends ReceiverTypeData { - public VirtualCallData(DataLayout layout) { - super(layout); +public class VirtualCallData<K,M> extends ReceiverTypeData<K,M> { + public VirtualCallData(MethodDataInterface<K,M> methodData, DataLayout layout) { + super(methodData, layout); //assert(layout.tag() == DataLayout.virtualCallDataTag, "wrong type"); } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallTypeData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallTypeData.java new file mode 100644 index 00000000000..d7ad5d993ec --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallTypeData.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 sun.jvm.hotspot.oops; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +// VirtualCallTypeData +// +// A VirtualCallTypeData is used to access profiling information about +// a virtual call for which we collect type information about +// arguments and return value. +public class VirtualCallTypeData<K,M> extends VirtualCallData implements CallTypeDataInterface<K> { + final TypeStackSlotEntries<K,M> args; + final ReturnTypeEntry<K,M> ret; + + int cellCountGlobalOffset() { + return VirtualCallData.staticCellCount() + TypeEntriesAtCall.cellCountLocalOffset(); + } + + int cellCountNoHeader() { + return uintAt(cellCountGlobalOffset()); + } + + public VirtualCallTypeData(MethodDataInterface<K,M> methodData, DataLayout layout) { + super(methodData, layout); + args = new TypeStackSlotEntries<K,M>(methodData, this, VirtualCallData.staticCellCount()+TypeEntriesAtCall.headerCellCount(), numberOfArguments()); + ret = new ReturnTypeEntry<K,M>(methodData, this, cellCount() - ReturnTypeEntry.staticCellCount()); + } + + static int staticCellCount() { + return -1; + } + + public int cellCount() { + return VirtualCallData.staticCellCount() + + TypeEntriesAtCall.headerCellCount() + + intAt(cellCountGlobalOffset()); + } + + public int numberOfArguments() { + return cellCountNoHeader() / TypeStackSlotEntries.perArgCount(); + } + + public boolean hasArguments() { + return cellCountNoHeader() >= TypeStackSlotEntries.perArgCount(); + } + + public K argumentType(int i) { + return args.type(i); + } + + public boolean hasReturn() { + return (cellCountNoHeader() % TypeStackSlotEntries.perArgCount()) != 0; + } + + public K returnType() { + return ret.type(); + } + + public int argumentTypeIndex(int i) { + return args.typeIndex(i); + } + + public int returnTypeIndex() { + return ret.typeIndex(); + } + + public void printDataOn(PrintStream st) { + super.printDataOn(st); + if (hasArguments()) { + tab(st); + st.print("argument types"); + args.printDataOn(st); + } + if (hasReturn()) { + tab(st); + st.print("return type"); + ret.printDataOn(st); + } + } +}; diff --git a/hotspot/src/share/vm/ci/ciMethodData.cpp b/hotspot/src/share/vm/ci/ciMethodData.cpp index 1b604ba4e4d..9a7c405a2d8 100644 --- a/hotspot/src/share/vm/ci/ciMethodData.cpp +++ b/hotspot/src/share/vm/ci/ciMethodData.cpp @@ -177,7 +177,7 @@ void ciReceiverTypeData::translate_receiver_data_from(const ProfileData* data) { void ciTypeStackSlotEntries::translate_type_data_from(const TypeStackSlotEntries* entries) { - for (int i = 0; i < _number_of_entries; i++) { + for (int i = 0; i < number_of_entries(); i++) { intptr_t k = entries->type(i); TypeStackSlotEntries::set_type(i, translate_klass(k)); } @@ -242,7 +242,6 @@ ciProfileData* ciMethodData::next_data(ciProfileData* current) { } ciProfileData* ciMethodData::bci_to_extra_data(int bci, ciMethod* m, bool& two_free_slots) { - // bci_to_extra_data(bci) ... DataLayout* dp = data_layout_at(data_size()); DataLayout* end = data_layout_at(data_size() + extra_data_size()); two_free_slots = false; @@ -506,6 +505,63 @@ void ciMethodData::print_impl(outputStream* st) { ciMetadata::print_impl(st); } +void ciMethodData::dump_replay_data_type_helper(outputStream* out, int round, int& count, ProfileData* pdata, ByteSize offset, ciKlass* k) { + if (k != NULL) { + if (round == 0) { + count++; + } else { + out->print(" %d %s", (int)(dp_to_di(pdata->dp() + in_bytes(offset)) / sizeof(intptr_t)), k->name()->as_quoted_ascii()); + } + } +} + +template<class T> void ciMethodData::dump_replay_data_receiver_type_helper(outputStream* out, int round, int& count, T* vdata) { + for (uint i = 0; i < vdata->row_limit(); i++) { + dump_replay_data_type_helper(out, round, count, vdata, vdata->receiver_offset(i), vdata->receiver(i)); + } +} + +template<class T> void ciMethodData::dump_replay_data_call_type_helper(outputStream* out, int round, int& count, T* call_type_data) { + if (call_type_data->has_arguments()) { + for (int i = 0; i < call_type_data->number_of_arguments(); i++) { + dump_replay_data_type_helper(out, round, count, call_type_data, call_type_data->argument_type_offset(i), call_type_data->valid_argument_type(i)); + } + } + if (call_type_data->has_return()) { + dump_replay_data_type_helper(out, round, count, call_type_data, call_type_data->return_type_offset(), call_type_data->valid_return_type()); + } +} + +void ciMethodData::dump_replay_data_extra_data_helper(outputStream* out, int round, int& count) { + DataLayout* dp = data_layout_at(data_size()); + DataLayout* end = data_layout_at(data_size() + extra_data_size()); + + for (;dp < end; dp = MethodData::next_extra(dp)) { + switch(dp->tag()) { + case DataLayout::no_tag: + case DataLayout::arg_info_data_tag: + return; + case DataLayout::bit_data_tag: + break; + case DataLayout::speculative_trap_data_tag: { + ciSpeculativeTrapData* data = new ciSpeculativeTrapData(dp); + ciMethod* m = data->method(); + if (m != NULL) { + if (round == 0) { + count++; + } else { + out->print(" %d ", (int)(dp_to_di(((address)dp) + in_bytes(ciSpeculativeTrapData::method_offset())) / sizeof(intptr_t))); + m->dump_name_as_ascii(out); + } + } + break; + } + default: + fatal(err_msg("bad tag = %d", dp->tag())); + } + } +} + void ciMethodData::dump_replay_data(outputStream* out) { ResourceMark rm; MethodData* mdo = get_MethodData(); @@ -527,7 +583,7 @@ void ciMethodData::dump_replay_data(outputStream* out) { } // dump the MDO data as raw data - int elements = data_size() / sizeof(intptr_t); + int elements = (data_size() + extra_data_size()) / sizeof(intptr_t); out->print(" data %d", elements); for (int i = 0; i < elements; i++) { // We could use INTPTR_FORMAT here but that's a zero justified @@ -544,37 +600,35 @@ void ciMethodData::dump_replay_data(outputStream* out) { // and emit pairs of offset and klass name so that they can be // reconstructed at runtime. The first round counts the number of // oop references and the second actually emits them. - int count = 0; - for (int round = 0; round < 2; round++) { + ciParametersTypeData* parameters = parameters_type_data(); + for (int count = 0, round = 0; round < 2; round++) { if (round == 1) out->print(" oops %d", count); ProfileData* pdata = first_data(); for ( ; is_valid(pdata); pdata = next_data(pdata)) { - if (pdata->is_ReceiverTypeData()) { - ciReceiverTypeData* vdata = (ciReceiverTypeData*)pdata; - for (uint i = 0; i < vdata->row_limit(); i++) { - ciKlass* k = vdata->receiver(i); - if (k != NULL) { - if (round == 0) { - count++; - } else { - out->print(" %d %s", (int)(dp_to_di(vdata->dp() + in_bytes(vdata->receiver_offset(i))) / sizeof(intptr_t)), k->name()->as_quoted_ascii()); - } - } - } - } else if (pdata->is_VirtualCallData()) { + if (pdata->is_VirtualCallData()) { ciVirtualCallData* vdata = (ciVirtualCallData*)pdata; - for (uint i = 0; i < vdata->row_limit(); i++) { - ciKlass* k = vdata->receiver(i); - if (k != NULL) { - if (round == 0) { - count++; - } else { - out->print(" %d %s", (int)(dp_to_di(vdata->dp() + in_bytes(vdata->receiver_offset(i))) / sizeof(intptr_t)), k->name()->as_quoted_ascii()); - } - } + dump_replay_data_receiver_type_helper<ciVirtualCallData>(out, round, count, vdata); + if (pdata->is_VirtualCallTypeData()) { + ciVirtualCallTypeData* call_type_data = (ciVirtualCallTypeData*)pdata; + dump_replay_data_call_type_helper<ciVirtualCallTypeData>(out, round, count, call_type_data); } + } else if (pdata->is_ReceiverTypeData()) { + ciReceiverTypeData* vdata = (ciReceiverTypeData*)pdata; + dump_replay_data_receiver_type_helper<ciReceiverTypeData>(out, round, count, vdata); + } else if (pdata->is_CallTypeData()) { + ciCallTypeData* call_type_data = (ciCallTypeData*)pdata; + dump_replay_data_call_type_helper<ciCallTypeData>(out, round, count, call_type_data); } } + if (parameters != NULL) { + for (int i = 0; i < parameters->number_of_parameters(); i++) { + dump_replay_data_type_helper(out, round, count, parameters, ParametersTypeData::type_offset(i), parameters->valid_parameter_type(i)); + } + } + } + for (int count = 0, round = 0; round < 2; round++) { + if (round == 1) out->print(" methods %d", count); + dump_replay_data_extra_data_helper(out, round, count); } out->cr(); } @@ -586,6 +640,10 @@ void ciMethodData::print() { void ciMethodData::print_data_on(outputStream* st) { ResourceMark rm; + ciParametersTypeData* parameters = parameters_type_data(); + if (parameters != NULL) { + parameters->print_data_on(st); + } ciProfileData* data; for (data = first_data(); is_valid(data); data = next_data(data)) { st->print("%d", dp_to_di(data->dp())); @@ -607,6 +665,9 @@ void ciMethodData::print_data_on(outputStream* st) { data = new ciArgInfoData(dp); dp = end; // ArgInfoData is at the end of extra data section. break; + case DataLayout::speculative_trap_data_tag: + data = new ciSpeculativeTrapData(dp); + break; default: fatal(err_msg("unexpected tag %d", dp->tag())); } @@ -631,7 +692,7 @@ void ciTypeEntries::print_ciklass(outputStream* st, intptr_t k) { } void ciTypeStackSlotEntries::print_data_on(outputStream* st) const { - for (int i = 0; i < _number_of_entries; i++) { + for (int i = 0; i < number_of_entries(); i++) { _pd->tab(st); st->print("%d: stack (%u) ", i, stack_slot(i)); print_ciklass(st, type(i)); @@ -650,12 +711,12 @@ void ciCallTypeData::print_data_on(outputStream* st, const char* extra) const { print_shared(st, "ciCallTypeData", extra); if (has_arguments()) { tab(st, true); - st->print("argument types"); + st->print_cr("argument types"); args()->print_data_on(st); } if (has_return()) { tab(st, true); - st->print("return type"); + st->print_cr("return type"); ret()->print_data_on(st); } } diff --git a/hotspot/src/share/vm/ci/ciMethodData.hpp b/hotspot/src/share/vm/ci/ciMethodData.hpp index b1809a19d10..9b9f67c446a 100644 --- a/hotspot/src/share/vm/ci/ciMethodData.hpp +++ b/hotspot/src/share/vm/ci/ciMethodData.hpp @@ -45,7 +45,7 @@ class ciArgInfoData; class ciCallTypeData; class ciVirtualCallTypeData; class ciParametersTypeData; -class ciSpeculativeTrapData;; +class ciSpeculativeTrapData; typedef ProfileData ciProfileData; @@ -175,7 +175,7 @@ public: } #ifndef PRODUCT - void print_data_on(outputStream* st, const char* extra) const; + void print_data_on(outputStream* st, const char* extra = NULL) const; #endif }; @@ -202,7 +202,7 @@ public: } void translate_receiver_data_from(const ProfileData* data); #ifndef PRODUCT - void print_data_on(outputStream* st, const char* extra) const; + void print_data_on(outputStream* st, const char* extra = NULL) const; void print_receiver_data_on(outputStream* st) const; #endif }; @@ -227,7 +227,7 @@ public: rtd_super()->translate_receiver_data_from(data); } #ifndef PRODUCT - void print_data_on(outputStream* st, const char* extra) const; + void print_data_on(outputStream* st, const char* extra = NULL) const; #endif }; @@ -289,7 +289,7 @@ public: } #ifndef PRODUCT - void print_data_on(outputStream* st, const char* extra) const; + void print_data_on(outputStream* st, const char* extra = NULL) const; #endif }; @@ -338,7 +338,7 @@ public: } #ifndef PRODUCT - void print_data_on(outputStream* st, const char* extra) const; + void print_data_on(outputStream* st, const char* extra = NULL) const; #endif }; @@ -349,15 +349,15 @@ public: virtual void translate_from(const ProfileData* data); ciMethod* method() const { - return (ciMethod*)intptr_at(method_offset); + return (ciMethod*)intptr_at(speculative_trap_method); } void set_method(ciMethod* m) { - set_intptr_at(method_offset, (intptr_t)m); + set_intptr_at(speculative_trap_method, (intptr_t)m); } #ifndef PRODUCT - void print_data_on(outputStream* st, const char* extra) const; + void print_data_on(outputStream* st, const char* extra = NULL) const; #endif }; @@ -406,8 +406,8 @@ private: // Coherent snapshot of original header. MethodData _orig; - // Dedicated area dedicated to parameters. Null if no parameter - // profiling for this method. + // Area dedicated to parameters. NULL if no parameter profiling for + // this method. DataLayout* _parameters; ciMethodData(MethodData* md); @@ -467,6 +467,11 @@ private: void load_extra_data(); ciProfileData* bci_to_extra_data(int bci, ciMethod* m, bool& two_free_slots); + void dump_replay_data_type_helper(outputStream* out, int round, int& count, ProfileData* pdata, ByteSize offset, ciKlass* k); + template<class T> void dump_replay_data_call_type_helper(outputStream* out, int round, int& count, T* call_type_data); + template<class T> void dump_replay_data_receiver_type_helper(outputStream* out, int round, int& count, T* call_type_data); + void dump_replay_data_extra_data_helper(outputStream* out, int round, int& count); + public: bool is_method_data() const { return true; } diff --git a/hotspot/src/share/vm/ci/ciReplay.cpp b/hotspot/src/share/vm/ci/ciReplay.cpp index 6acde213d57..51897b26300 100644 --- a/hotspot/src/share/vm/ci/ciReplay.cpp +++ b/hotspot/src/share/vm/ci/ciReplay.cpp @@ -48,11 +48,14 @@ typedef struct _ciMethodDataRecord { intptr_t* _data; char* _orig_data; - jobject* _oops_handles; - int* _oops_offsets; + Klass** _classes; + Method** _methods; + int* _classes_offsets; + int* _methods_offsets; int _data_length; int _orig_data_length; - int _oops_length; + int _classes_length; + int _methods_length; } ciMethodDataRecord; typedef struct _ciMethodRecord { @@ -565,7 +568,7 @@ class CompileReplay : public StackObj { rec->_instructions_size = parse_int("instructions_size"); } - // ciMethodData <klass> <name> <signature> <state> <current mileage> orig <length> # # ... data <length> # # ... oops <length> + // ciMethodData <klass> <name> <signature> <state> <current mileage> orig <length> # # ... data <length> # # ... oops <length> # ... methods <length> void process_ciMethodData(TRAPS) { Method* method = parse_method(CHECK); if (had_error()) return; @@ -602,21 +605,34 @@ class CompileReplay : public StackObj { if (rec->_data == NULL) { return; } - if (!parse_tag_and_count("oops", rec->_oops_length)) { + if (!parse_tag_and_count("oops", rec->_classes_length)) { return; } - rec->_oops_handles = NEW_RESOURCE_ARRAY(jobject, rec->_oops_length); - rec->_oops_offsets = NEW_RESOURCE_ARRAY(int, rec->_oops_length); - for (int i = 0; i < rec->_oops_length; i++) { + rec->_classes = NEW_RESOURCE_ARRAY(Klass*, rec->_classes_length); + rec->_classes_offsets = NEW_RESOURCE_ARRAY(int, rec->_classes_length); + for (int i = 0; i < rec->_classes_length; i++) { int offset = parse_int("offset"); if (had_error()) { return; } Klass* k = parse_klass(CHECK); - rec->_oops_offsets[i] = offset; - KlassHandle *kh = NEW_C_HEAP_OBJ(KlassHandle, mtCompiler); - ::new ((void*)kh) KlassHandle(THREAD, k); - rec->_oops_handles[i] = (jobject)kh; + rec->_classes_offsets[i] = offset; + rec->_classes[i] = k; + } + + if (!parse_tag_and_count("methods", rec->_methods_length)) { + return; + } + rec->_methods = NEW_RESOURCE_ARRAY(Method*, rec->_methods_length); + rec->_methods_offsets = NEW_RESOURCE_ARRAY(int, rec->_methods_length); + for (int i = 0; i < rec->_methods_length; i++) { + int offset = parse_int("offset"); + if (had_error()) { + return; + } + Method* m = parse_method(CHECK); + rec->_methods_offsets[i] = offset; + rec->_methods[i] = m; } } @@ -1105,14 +1121,22 @@ void ciReplay::initialize(ciMethodData* m) { m->_state = rec->_state; m->_current_mileage = rec->_current_mileage; if (rec->_data_length != 0) { - assert(m->_data_size == rec->_data_length * (int)sizeof(rec->_data[0]), "must agree"); + assert(m->_data_size + m->_extra_data_size == rec->_data_length * (int)sizeof(rec->_data[0]) || + m->_data_size == rec->_data_length * (int)sizeof(rec->_data[0]), "must agree"); // Write the correct ciObjects back into the profile data ciEnv* env = ciEnv::current(); - for (int i = 0; i < rec->_oops_length; i++) { - KlassHandle *h = (KlassHandle *)rec->_oops_handles[i]; - *(ciMetadata**)(rec->_data + rec->_oops_offsets[i]) = - env->get_metadata((*h)()); + for (int i = 0; i < rec->_classes_length; i++) { + Klass *k = rec->_classes[i]; + // In case this class pointer is is tagged, preserve the tag + // bits + rec->_data[rec->_classes_offsets[i]] = + ciTypeEntries::with_status(env->get_metadata(k)->as_klass(), rec->_data[rec->_classes_offsets[i]]); + } + for (int i = 0; i < rec->_methods_length; i++) { + Method *m = rec->_methods[i]; + *(ciMetadata**)(rec->_data + rec->_methods_offsets[i]) = + env->get_metadata(m); } // Copy the updated profile data into place as intptr_ts #ifdef _LP64 diff --git a/hotspot/src/share/vm/oops/methodData.hpp b/hotspot/src/share/vm/oops/methodData.hpp index 32a48a97a5a..be40bad175d 100644 --- a/hotspot/src/share/vm/oops/methodData.hpp +++ b/hotspot/src/share/vm/oops/methodData.hpp @@ -851,11 +851,10 @@ private: return _base_off + stack_slot_local_offset(i); } -protected: const int _number_of_entries; // offset of cell for type for entry i within ProfileData object - int type_offset(int i) const { + int type_offset_in_cells(int i) const { return _base_off + type_local_offset(i); } @@ -868,6 +867,8 @@ public: void post_initialize(Symbol* signature, bool has_receiver, bool include_receiver); + int number_of_entries() const { return _number_of_entries; } + // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries static int stack_slot_local_offset(int i) { return i * per_arg_cell_count + stack_slot_entry; @@ -893,13 +894,13 @@ public: // type for entry i intptr_t type(int i) const { assert(i >= 0 && i < _number_of_entries, "oob"); - return _pd->intptr_at(type_offset(i)); + return _pd->intptr_at(type_offset_in_cells(i)); } // set type for entry i void set_type(int i, intptr_t k) { assert(i >= 0 && i < _number_of_entries, "oob"); - _pd->set_intptr_at(type_offset(i), k); + _pd->set_intptr_at(type_offset_in_cells(i), k); } static ByteSize per_arg_size() { @@ -907,7 +908,11 @@ public: } static int per_arg_count() { - return per_arg_cell_count ; + return per_arg_cell_count; + } + + ByteSize type_offset(int i) const { + return DataLayout::cell_offset(type_offset_in_cells(i)); } // GC support @@ -973,7 +978,7 @@ private: } static int argument_type_local_offset(int i) { - return header_cell_count() + TypeStackSlotEntries::type_local_offset(i);; + return header_cell_count() + TypeStackSlotEntries::type_local_offset(i); } public: @@ -1129,6 +1134,14 @@ public: return cell_offset(CounterData::static_cell_count()) + TypeEntriesAtCall::args_data_offset(); } + ByteSize argument_type_offset(int i) { + return _args.type_offset(i); + } + + ByteSize return_type_offset() { + return _ret.type_offset(); + } + // GC support virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { if (has_arguments()) { @@ -1436,6 +1449,14 @@ public: return cell_offset(VirtualCallData::static_cell_count()) + TypeEntriesAtCall::args_data_offset(); } + ByteSize argument_type_offset(int i) { + return _args.type_offset(i); + } + + ByteSize return_type_offset() { + return _ret.type_offset(); + } + // GC support virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { ReceiverTypeData::clean_weak_klass_links(is_alive_closure); @@ -1926,7 +1947,7 @@ public: class SpeculativeTrapData : public ProfileData { protected: enum { - method_offset, + speculative_trap_method, speculative_trap_cell_count }; public: @@ -1946,11 +1967,15 @@ public: // Direct accessor Method* method() const { - return (Method*)intptr_at(method_offset); + return (Method*)intptr_at(speculative_trap_method); } void set_method(Method* m) { - set_intptr_at(method_offset, (intptr_t)m); + set_intptr_at(speculative_trap_method, (intptr_t)m); + } + + static ByteSize method_offset() { + return cell_offset(speculative_trap_method); } virtual void print_data_on(outputStream* st, const char* extra = NULL) const; diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index f169c3b2ef0..66bc5a8fab6 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -353,6 +353,7 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable; nonstatic_field(MethodData, _method, Method*) \ nonstatic_field(MethodData, _data_size, int) \ nonstatic_field(MethodData, _data[0], intptr_t) \ + nonstatic_field(MethodData, _parameters_type_data_di, int) \ nonstatic_field(MethodData, _nof_decompiles, uint) \ nonstatic_field(MethodData, _nof_overflow_recompiles, uint) \ nonstatic_field(MethodData, _nof_overflow_traps, uint) \ @@ -2499,6 +2500,10 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable; declare_constant(Deoptimization::Reason_age) \ declare_constant(Deoptimization::Reason_predicate) \ declare_constant(Deoptimization::Reason_loop_limit_check) \ + declare_constant(Deoptimization::Reason_speculate_class_check) \ + declare_constant(Deoptimization::Reason_speculate_null_check) \ + declare_constant(Deoptimization::Reason_rtm_state_change) \ + declare_constant(Deoptimization::Reason_tenured) \ declare_constant(Deoptimization::Reason_LIMIT) \ declare_constant(Deoptimization::Reason_RECORDED_LIMIT) \ \ From a2eea4770afb5e6b384402ccaac8dcced8c4dfdb Mon Sep 17 00:00:00 2001 From: Igor Veresov <iveresov@openjdk.org> Date: Thu, 15 May 2014 10:37:52 -0700 Subject: [PATCH 048/157] 8043180: SIGSEGV in Events::log_deopt_message Added missing deopt reason name Reason_tenured Reviewed-by: kvn, twisti --- hotspot/src/share/vm/runtime/deoptimization.cpp | 15 +++++++++++---- hotspot/src/share/vm/runtime/deoptimization.hpp | 4 ++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/runtime/deoptimization.cpp b/hotspot/src/share/vm/runtime/deoptimization.cpp index eec441873c3..e4b1292c6b6 100644 --- a/hotspot/src/share/vm/runtime/deoptimization.cpp +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp @@ -1340,7 +1340,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra if (xtty != NULL) xtty->name(class_name); } - if (xtty != NULL && trap_mdo != NULL) { + if (xtty != NULL && trap_mdo != NULL && (int)reason < (int)MethodData::_trap_hist_limit) { // Dump the relevant MDO state. // This is the deopt count for the current reason, any previous // reasons or recompiles seen at this point. @@ -1818,7 +1818,7 @@ const char* Deoptimization::format_trap_state(char* buf, size_t buflen, //--------------------------------statics-------------------------------------- -const char* Deoptimization::_trap_reason_name[Reason_LIMIT] = { +const char* Deoptimization::_trap_reason_name[] = { // Note: Keep this in sync. with enum DeoptReason. "none", "null_check", @@ -1839,9 +1839,10 @@ const char* Deoptimization::_trap_reason_name[Reason_LIMIT] = { "loop_limit_check", "speculate_class_check", "speculate_null_check", - "rtm_state_change" + "rtm_state_change", + "tenured" }; -const char* Deoptimization::_trap_action_name[Action_LIMIT] = { +const char* Deoptimization::_trap_action_name[] = { // Note: Keep this in sync. with enum DeoptAction. "none", "maybe_recompile", @@ -1851,6 +1852,9 @@ const char* Deoptimization::_trap_action_name[Action_LIMIT] = { }; const char* Deoptimization::trap_reason_name(int reason) { + // Check that every reason has a name + STATIC_ASSERT(sizeof(_trap_reason_name)/sizeof(const char*) == Reason_LIMIT); + if (reason == Reason_many) return "many"; if ((uint)reason < Reason_LIMIT) return _trap_reason_name[reason]; @@ -1859,6 +1863,9 @@ const char* Deoptimization::trap_reason_name(int reason) { return buf; } const char* Deoptimization::trap_action_name(int action) { + // Check that every action has a name + STATIC_ASSERT(sizeof(_trap_action_name)/sizeof(const char*) == Action_LIMIT); + if ((uint)action < Action_LIMIT) return _trap_action_name[action]; static char buf[20]; diff --git a/hotspot/src/share/vm/runtime/deoptimization.hpp b/hotspot/src/share/vm/runtime/deoptimization.hpp index d0af1823248..02daabccb98 100644 --- a/hotspot/src/share/vm/runtime/deoptimization.hpp +++ b/hotspot/src/share/vm/runtime/deoptimization.hpp @@ -376,8 +376,8 @@ class Deoptimization : AllStatic { static UnrollBlock* fetch_unroll_info_helper(JavaThread* thread); static DeoptAction _unloaded_action; // == Action_reinterpret; - static const char* _trap_reason_name[Reason_LIMIT]; - static const char* _trap_action_name[Action_LIMIT]; + static const char* _trap_reason_name[]; + static const char* _trap_action_name[]; static juint _deoptimization_hist[Reason_LIMIT][1+Action_LIMIT][BC_CASE_LIMIT]; // Note: Histogram array size is 1-2 Kb. From 6bfc0288f34379a294f10bcf2bdefbee02378823 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov <kvn@openjdk.org> Date: Fri, 16 May 2014 12:05:14 -0700 Subject: [PATCH 049/157] 8042786: Proper fix for 8032566 Check for overflow cases in range checks and collapse it if we can. Reviewed-by: jrose, iveresov --- hotspot/src/share/vm/opto/c2_globals.hpp | 2 +- hotspot/src/share/vm/opto/callGenerator.cpp | 2 +- hotspot/src/share/vm/opto/doCall.cpp | 2 +- hotspot/src/share/vm/opto/ifnode.cpp | 2 +- hotspot/src/share/vm/opto/phaseX.cpp | 9 +++ hotspot/src/share/vm/opto/subnode.cpp | 87 ++++++++++++++++++++- hotspot/src/share/vm/opto/subnode.hpp | 2 + 7 files changed, 101 insertions(+), 5 deletions(-) diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp index 093344bb32d..4f45d28666b 100644 --- a/hotspot/src/share/vm/opto/c2_globals.hpp +++ b/hotspot/src/share/vm/opto/c2_globals.hpp @@ -452,7 +452,7 @@ notproduct(bool, PrintEliminateLocks, false, \ "Print out when locks are eliminated") \ \ - product(bool, EliminateAutoBox, false, \ + product(bool, EliminateAutoBox, true, \ "Control optimizations for autobox elimination") \ \ diagnostic(bool, UseImplicitStableValues, true, \ diff --git a/hotspot/src/share/vm/opto/callGenerator.cpp b/hotspot/src/share/vm/opto/callGenerator.cpp index ef1921a0077..249e0215c60 100644 --- a/hotspot/src/share/vm/opto/callGenerator.cpp +++ b/hotspot/src/share/vm/opto/callGenerator.cpp @@ -391,7 +391,7 @@ void LateInlineCallGenerator::do_late_inline() { } // Setup default node notes to be picked up by the inlining - Node_Notes* old_nn = C->default_node_notes(); + Node_Notes* old_nn = C->node_notes_at(call->_idx); if (old_nn != NULL) { Node_Notes* entry_nn = old_nn->clone(C); entry_nn->set_jvms(jvms); diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp index e3a95c079f3..2c48e604497 100644 --- a/hotspot/src/share/vm/opto/doCall.cpp +++ b/hotspot/src/share/vm/opto/doCall.cpp @@ -364,7 +364,7 @@ bool Compile::should_delay_string_inlining(ciMethod* call_method, JVMState* jvms bool Compile::should_delay_boxing_inlining(ciMethod* call_method, JVMState* jvms) { if (eliminate_boxing() && call_method->is_boxing_method()) { set_has_boxed_value(true); - return true; + return aggressive_unboxing(); } return false; } diff --git a/hotspot/src/share/vm/opto/ifnode.cpp b/hotspot/src/share/vm/opto/ifnode.cpp index 1c9dbb70839..587c3b8c864 100644 --- a/hotspot/src/share/vm/opto/ifnode.cpp +++ b/hotspot/src/share/vm/opto/ifnode.cpp @@ -673,7 +673,7 @@ const TypeInt* IfNode::filtered_int_type(PhaseGVN* gvn, Node *val, Node* if_proj // / Region // Node* IfNode::fold_compares(PhaseGVN* phase) { - if (!phase->C->eliminate_boxing() || Opcode() != Op_If) return NULL; + if (Opcode() != Op_If) return NULL; Node* this_cmp = in(1)->in(1); if (this_cmp != NULL && this_cmp->Opcode() == Op_CmpI && diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp index 8cc008f8f56..4635342e678 100644 --- a/hotspot/src/share/vm/opto/phaseX.cpp +++ b/hotspot/src/share/vm/opto/phaseX.cpp @@ -1393,6 +1393,15 @@ void PhaseIterGVN::add_users_to_worklist( Node *n ) { _worklist.push(u); } } + // If changed AddI/SubI inputs, check CmpU for range check optimization. + if (use_op == Op_AddI || use_op == Op_SubI) { + for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) { + Node* u = use->fast_out(i2); + if (u->is_Cmp() && (u->Opcode() == Op_CmpU)) { + _worklist.push(u); + } + } + } // If changed AddP inputs, check Stores for loop invariant if( use_op == Op_AddP ) { for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) { diff --git a/hotspot/src/share/vm/opto/subnode.cpp b/hotspot/src/share/vm/opto/subnode.cpp index 31bb9f6d133..102e8ece6e4 100644 --- a/hotspot/src/share/vm/opto/subnode.cpp +++ b/hotspot/src/share/vm/opto/subnode.cpp @@ -80,7 +80,7 @@ Node *SubNode::Identity( PhaseTransform *phase ) { //------------------------------Value------------------------------------------ // A subtract node differences it's two inputs. -const Type *SubNode::Value( PhaseTransform *phase ) const { +const Type* SubNode::Value_common(PhaseTransform *phase) const { const Node* in1 = in(1); const Node* in2 = in(2); // Either input is TOP ==> the result is TOP @@ -97,6 +97,16 @@ const Type *SubNode::Value( PhaseTransform *phase ) const { if( t1 == Type::BOTTOM || t2 == Type::BOTTOM ) return bottom_type(); + return NULL; +} + +const Type* SubNode::Value(PhaseTransform *phase) const { + const Type* t = Value_common(phase); + if (t != NULL) { + return t; + } + const Type* t1 = phase->type(in(1)); + const Type* t2 = phase->type(in(2)); return sub(t1,t2); // Local flavor of type subtraction } @@ -570,6 +580,81 @@ const Type *CmpUNode::sub( const Type *t1, const Type *t2 ) const { return TypeInt::CC; // else use worst case results } +const Type* CmpUNode::Value(PhaseTransform *phase) const { + const Type* t = SubNode::Value_common(phase); + if (t != NULL) { + return t; + } + const Node* in1 = in(1); + const Node* in2 = in(2); + const Type* t1 = phase->type(in1); + const Type* t2 = phase->type(in2); + assert(t1->isa_int(), "CmpU has only Int type inputs"); + if (t2 == TypeInt::INT) { // Compare to bottom? + return bottom_type(); + } + uint in1_op = in1->Opcode(); + if (in1_op == Op_AddI || in1_op == Op_SubI) { + // The problem rise when result of AddI(SubI) may overflow + // signed integer value. Let say the input type is + // [256, maxint] then +128 will create 2 ranges due to + // overflow: [minint, minint+127] and [384, maxint]. + // But C2 type system keep only 1 type range and as result + // it use general [minint, maxint] for this case which we + // can't optimize. + // + // Make 2 separate type ranges based on types of AddI(SubI) inputs + // and compare results of their compare. If results are the same + // CmpU node can be optimized. + const Node* in11 = in1->in(1); + const Node* in12 = in1->in(2); + const Type* t11 = (in11 == in1) ? Type::TOP : phase->type(in11); + const Type* t12 = (in12 == in1) ? Type::TOP : phase->type(in12); + // Skip cases when input types are top or bottom. + if ((t11 != Type::TOP) && (t11 != TypeInt::INT) && + (t12 != Type::TOP) && (t12 != TypeInt::INT)) { + const TypeInt *r0 = t11->is_int(); + const TypeInt *r1 = t12->is_int(); + jlong lo_r0 = r0->_lo; + jlong hi_r0 = r0->_hi; + jlong lo_r1 = r1->_lo; + jlong hi_r1 = r1->_hi; + if (in1_op == Op_SubI) { + jlong tmp = hi_r1; + hi_r1 = -lo_r1; + lo_r1 = -tmp; + // Note, for substructing [minint,x] type range + // long arithmetic provides correct overflow answer. + // The confusion come from the fact that in 32-bit + // -minint == minint but in 64-bit -minint == maxint+1. + } + jlong lo_long = lo_r0 + lo_r1; + jlong hi_long = hi_r0 + hi_r1; + int lo_tr1 = min_jint; + int hi_tr1 = (int)hi_long; + int lo_tr2 = (int)lo_long; + int hi_tr2 = max_jint; + bool underflow = lo_long != (jlong)lo_tr2; + bool overflow = hi_long != (jlong)hi_tr1; + // Use sub(t1, t2) when there is no overflow (one type range) + // or when both overflow and underflow (too complex). + if ((underflow != overflow) && (hi_tr1 < lo_tr2)) { + // Overflow only on one boundary, compare 2 separate type ranges. + int w = MAX2(r0->_widen, r1->_widen); // _widen does not matter here + const TypeInt* tr1 = TypeInt::make(lo_tr1, hi_tr1, w); + const TypeInt* tr2 = TypeInt::make(lo_tr2, hi_tr2, w); + const Type* cmp1 = sub(tr1, t2); + const Type* cmp2 = sub(tr2, t2); + if (cmp1 == cmp2) { + return cmp1; // Hit! + } + } + } + } + + return sub(t1, t2); // Local flavor of type subtraction +} + bool CmpUNode::is_index_range_check() const { // Check for the "(X ModI Y) CmpU Y" shape return (in(1)->Opcode() == Op_ModI && diff --git a/hotspot/src/share/vm/opto/subnode.hpp b/hotspot/src/share/vm/opto/subnode.hpp index 56ee308d982..da5d7e378cd 100644 --- a/hotspot/src/share/vm/opto/subnode.hpp +++ b/hotspot/src/share/vm/opto/subnode.hpp @@ -50,6 +50,7 @@ public: // Compute a new Type for this node. Basically we just do the pre-check, // then call the virtual add() to set the type. virtual const Type *Value( PhaseTransform *phase ) const; + const Type* Value_common( PhaseTransform *phase ) const; // Supplied function returns the subtractend of the inputs. // This also type-checks the inputs for sanity. Guaranteed never to @@ -158,6 +159,7 @@ public: CmpUNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {} virtual int Opcode() const; virtual const Type *sub( const Type *, const Type * ) const; + const Type *Value( PhaseTransform *phase ) const; bool is_index_range_check() const; }; From 1af450a3cbd06fb55bd4f9e802d43dce2721eb72 Mon Sep 17 00:00:00 2001 From: Igor Ignatyev <iignatyev@openjdk.org> Date: Mon, 19 May 2014 23:52:23 +0400 Subject: [PATCH 050/157] 8032498: compiler/ciReplay tests fail with StatusError: failed to clean up files after test.. Reviewed-by: kvn --- hotspot/test/compiler/ciReplay/TestVM.sh | 1 - hotspot/test/compiler/ciReplay/TestVM_no_comp_level.sh | 1 - hotspot/test/compiler/ciReplay/common.sh | 6 ++++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/hotspot/test/compiler/ciReplay/TestVM.sh b/hotspot/test/compiler/ciReplay/TestVM.sh index bdb38748504..e58d63e16fa 100644 --- a/hotspot/test/compiler/ciReplay/TestVM.sh +++ b/hotspot/test/compiler/ciReplay/TestVM.sh @@ -26,7 +26,6 @@ ## ## @test ## @bug 8011675 -## @ignore 8032498 ## @summary testing of ciReplay with using generated by VM replay.txt ## @author igor.ignatyev@oracle.com ## @run shell TestVM.sh diff --git a/hotspot/test/compiler/ciReplay/TestVM_no_comp_level.sh b/hotspot/test/compiler/ciReplay/TestVM_no_comp_level.sh index 19f23583e6d..d961d42541d 100644 --- a/hotspot/test/compiler/ciReplay/TestVM_no_comp_level.sh +++ b/hotspot/test/compiler/ciReplay/TestVM_no_comp_level.sh @@ -26,7 +26,6 @@ ## ## @test ## @bug 8011675 -## @ignore 8032498 ## @summary testing of ciReplay with using generated by VM replay.txt w/o comp_level ## @author igor.ignatyev@oracle.com ## @run shell TestVM_no_comp_level.sh diff --git a/hotspot/test/compiler/ciReplay/common.sh b/hotspot/test/compiler/ciReplay/common.sh index f992ff39fc2..cf17febc4f7 100644 --- a/hotspot/test/compiler/ciReplay/common.sh +++ b/hotspot/test/compiler/ciReplay/common.sh @@ -234,6 +234,12 @@ generate_replay() { sed -e 's/.*location: //'` echo CRASH OUTPUT: cat crash.out + + if [ "${core_locations}" = "" ] + then + test_fail 2 "CHECK :: CORE_LOCATION" "output doesn't contain the location of core file, see crash.out" + fi + rm crash.out # processing core locations for *nix From c66bd8445cb4cad36e6e59ec83f5b7a3cfe86b94 Mon Sep 17 00:00:00 2001 From: Bharadwaj Yadavalli <bharadwaj@openjdk.org> Date: Mon, 19 May 2014 20:28:35 +0000 Subject: [PATCH 051/157] 6563994: assert(wf.check_method_context(ctxk, m), "proper context") failed Check for redefined method before finding unique concrete method Reviewed-by: twisti, kvn --- hotspot/src/share/vm/code/dependencies.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hotspot/src/share/vm/code/dependencies.cpp b/hotspot/src/share/vm/code/dependencies.cpp index 21e0f816d83..0f50425bcdd 100644 --- a/hotspot/src/share/vm/code/dependencies.cpp +++ b/hotspot/src/share/vm/code/dependencies.cpp @@ -1429,6 +1429,10 @@ Klass* Dependencies::check_unique_concrete_method(Klass* ctxk, Method* uniqm, // Include m itself in the set, unless it is abstract. // If this set has exactly one element, return that element. Method* Dependencies::find_unique_concrete_method(Klass* ctxk, Method* m) { + // Return NULL if m is marked old; must have been a redefined method. + if (m->is_old()) { + return NULL; + } ClassHierarchyWalker wf(m); assert(wf.check_method_context(ctxk, m), "proper context"); wf.record_witnesses(1); From 5ec44ad8e9a20ce41cf16ce3000331e550f11e41 Mon Sep 17 00:00:00 2001 From: Yuri Gaevsky <ygaevsky@azulsystems.com> Date: Tue, 20 May 2014 09:35:05 +0200 Subject: [PATCH 052/157] 6883953: java -client -XX:ValueMapInitialSize=0 crashes Added lower bound check for ValueMapInitialSize Reviewed-by: kvn --- hotspot/src/share/vm/runtime/arguments.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 0239d8817d3..7e67292092b 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -2363,6 +2363,9 @@ bool Arguments::check_vm_args_consistency() { status = status && verify_percentage(MarkSweepDeadRatio, "MarkSweepDeadRatio"); status = status && verify_min_value(MarkSweepAlwaysCompactCount, 1, "MarkSweepAlwaysCompactCount"); +#ifdef COMPILER1 + status = status && verify_min_value(ValueMapInitialSize, 1, "ValueMapInitialSize"); +#endif if (PrintNMTStatistics) { #if INCLUDE_NMT From fb62773268082fd73fb93bd3c58821c05db06a56 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier <goetz@openjdk.org> Date: Thu, 8 May 2014 15:37:17 +0200 Subject: [PATCH 053/157] 8042737: Introduce umbrella header prefetch.inline.hpp Reviewed-by: twisti, stefank --- hotspot/src/os/aix/vm/thread_aix.inline.hpp | 3 - hotspot/src/os/bsd/vm/thread_bsd.inline.hpp | 6 - .../src/os/linux/vm/thread_linux.inline.hpp | 16 - .../os/solaris/vm/thread_solaris.inline.hpp | 7 - .../os/windows/vm/thread_windows.inline.hpp | 4 - .../compactibleFreeListSpace.cpp | 1 + .../gc_implementation/g1/concurrentMark.cpp | 1 + .../gc_implementation/g1/g1CollectedHeap.cpp | 1 + .../g1/g1OopClosures.inline.hpp | 1 + .../vm/gc_implementation/g1/heapRegion.cpp | 1 + .../parallelScavenge/cardTableExtension.cpp | 1 + .../parallelScavenge/psMarkSweepDecorator.cpp | 1 + .../src/share/vm/memory/defNewGeneration.cpp | 1 + hotspot/src/share/vm/memory/space.cpp | 1 + hotspot/src/share/vm/memory/space.hpp | 282 ------------------ hotspot/src/share/vm/memory/space.inline.hpp | 267 +++++++++++++++++ hotspot/src/share/vm/oops/klass.hpp | 30 -- .../src/share/vm/precompiled/precompiled.hpp | 1 + hotspot/src/share/vm/prims/unsafe.cpp | 1 + .../src/share/vm/runtime/prefetch.inline.hpp | 73 +++++ 20 files changed, 351 insertions(+), 348 deletions(-) create mode 100644 hotspot/src/share/vm/runtime/prefetch.inline.hpp diff --git a/hotspot/src/os/aix/vm/thread_aix.inline.hpp b/hotspot/src/os/aix/vm/thread_aix.inline.hpp index 034f6b4e2e0..04623516049 100644 --- a/hotspot/src/os/aix/vm/thread_aix.inline.hpp +++ b/hotspot/src/os/aix/vm/thread_aix.inline.hpp @@ -26,12 +26,9 @@ #ifndef OS_AIX_VM_THREAD_AIX_INLINE_HPP #define OS_AIX_VM_THREAD_AIX_INLINE_HPP -#include "runtime/prefetch.hpp" #include "runtime/thread.hpp" #include "runtime/threadLocalStorage.hpp" -#include "prefetch_aix_ppc.inline.hpp" - // Contains inlined functions for class Thread and ThreadLocalStorage inline void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do diff --git a/hotspot/src/os/bsd/vm/thread_bsd.inline.hpp b/hotspot/src/os/bsd/vm/thread_bsd.inline.hpp index 622707d4f5d..86f125dc5b4 100644 --- a/hotspot/src/os/bsd/vm/thread_bsd.inline.hpp +++ b/hotspot/src/os/bsd/vm/thread_bsd.inline.hpp @@ -31,12 +31,6 @@ #include "runtime/thread.hpp" #include "runtime/threadLocalStorage.hpp" -#ifdef TARGET_OS_ARCH_bsd_x86 -# include "prefetch_bsd_x86.inline.hpp" -#endif -#ifdef TARGET_OS_ARCH_bsd_zero -# include "prefetch_bsd_zero.inline.hpp" -#endif // Contains inlined functions for class Thread and ThreadLocalStorage diff --git a/hotspot/src/os/linux/vm/thread_linux.inline.hpp b/hotspot/src/os/linux/vm/thread_linux.inline.hpp index 76bdd223449..b58dc078948 100644 --- a/hotspot/src/os/linux/vm/thread_linux.inline.hpp +++ b/hotspot/src/os/linux/vm/thread_linux.inline.hpp @@ -29,24 +29,8 @@ #error "This file should only be included from thread.inline.hpp" #endif -#include "runtime/prefetch.hpp" #include "runtime/thread.hpp" #include "runtime/threadLocalStorage.hpp" -#ifdef TARGET_OS_ARCH_linux_x86 -# include "prefetch_linux_x86.inline.hpp" -#endif -#ifdef TARGET_OS_ARCH_linux_sparc -# include "prefetch_linux_sparc.inline.hpp" -#endif -#ifdef TARGET_OS_ARCH_linux_zero -# include "prefetch_linux_zero.inline.hpp" -#endif -#ifdef TARGET_OS_ARCH_linux_arm -# include "prefetch_linux_arm.inline.hpp" -#endif -#ifdef TARGET_OS_ARCH_linux_ppc -# include "prefetch_linux_ppc.inline.hpp" -#endif // Contains inlined functions for class Thread and ThreadLocalStorage diff --git a/hotspot/src/os/solaris/vm/thread_solaris.inline.hpp b/hotspot/src/os/solaris/vm/thread_solaris.inline.hpp index affc2c824c6..d7d6d378f1a 100644 --- a/hotspot/src/os/solaris/vm/thread_solaris.inline.hpp +++ b/hotspot/src/os/solaris/vm/thread_solaris.inline.hpp @@ -30,15 +30,8 @@ #endif #include "runtime/atomic.inline.hpp" -#include "runtime/prefetch.hpp" #include "runtime/thread.hpp" #include "runtime/threadLocalStorage.hpp" -#ifdef TARGET_OS_ARCH_solaris_x86 -# include "prefetch_solaris_x86.inline.hpp" -#endif -#ifdef TARGET_OS_ARCH_solaris_sparc -# include "prefetch_solaris_sparc.inline.hpp" -#endif // Thread::current is "hot" it's called > 128K times in the 1st 500 msecs of // startup. diff --git a/hotspot/src/os/windows/vm/thread_windows.inline.hpp b/hotspot/src/os/windows/vm/thread_windows.inline.hpp index a7af8776325..95dd17cecc7 100644 --- a/hotspot/src/os/windows/vm/thread_windows.inline.hpp +++ b/hotspot/src/os/windows/vm/thread_windows.inline.hpp @@ -29,12 +29,8 @@ #error "This file should only be included from thread.inline.hpp" #endif -#include "runtime/prefetch.hpp" #include "runtime/thread.hpp" #include "runtime/threadLocalStorage.hpp" -#ifdef TARGET_OS_ARCH_windows_x86 -# include "prefetch_windows_x86.inline.hpp" -#endif // Contains inlined functions for class Thread and ThreadLocalStorage diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp index da4bf278299..640265fbf56 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @@ -33,6 +33,7 @@ #include "memory/allocation.inline.hpp" #include "memory/blockOffsetTable.inline.hpp" #include "memory/resourceArea.hpp" +#include "memory/space.inline.hpp" #include "memory/universe.inline.hpp" #include "oops/oop.inline.hpp" #include "runtime/globals.hpp" diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index ad21b8ed7b6..ed28c85f22c 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -45,6 +45,7 @@ #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" +#include "runtime/prefetch.inline.hpp" #include "services/memTracker.hpp" // Concurrent marking bit map wrapper diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 575d3db9239..001673a1cdb 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -62,6 +62,7 @@ #include "memory/referenceProcessor.hpp" #include "oops/oop.inline.hpp" #include "oops/oop.pcgc.inline.hpp" +#include "runtime/prefetch.inline.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/vmThread.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp index 0c9f0cf2d49..48c024d7470 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp @@ -31,6 +31,7 @@ #include "gc_implementation/g1/g1RemSet.hpp" #include "gc_implementation/g1/g1RemSet.inline.hpp" #include "gc_implementation/g1/heapRegionRemSet.hpp" +#include "runtime/prefetch.inline.hpp" /* * This really ought to be an inline function, but apparently the C++ diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp index 24afeba238f..c12e3fe840c 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp @@ -32,6 +32,7 @@ #include "gc_implementation/g1/heapRegionSeq.inline.hpp" #include "memory/genOopClosures.inline.hpp" #include "memory/iterator.hpp" +#include "memory/space.inline.hpp" #include "oops/oop.inline.hpp" #include "runtime/orderAccess.inline.hpp" diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp index 502371f0169..a2a6b55a27c 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp @@ -30,6 +30,7 @@ #include "gc_implementation/parallelScavenge/psYoungGen.hpp" #include "oops/oop.inline.hpp" #include "oops/oop.psgc.inline.hpp" +#include "runtime/prefetch.inline.hpp" // Checks an individual oop for missing precise marks. Mark // may be either dirty or newgen. diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp index ee43825614b..dc79821cb37 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp @@ -32,6 +32,7 @@ #include "gc_implementation/shared/markSweep.inline.hpp" #include "gc_implementation/shared/spaceDecorator.hpp" #include "oops/oop.inline.hpp" +#include "runtime/prefetch.inline.hpp" PSMarkSweepDecorator* PSMarkSweepDecorator::_destination_decorator = NULL; diff --git a/hotspot/src/share/vm/memory/defNewGeneration.cpp b/hotspot/src/share/vm/memory/defNewGeneration.cpp index 32c2e28bee6..bf51090df12 100644 --- a/hotspot/src/share/vm/memory/defNewGeneration.cpp +++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp @@ -42,6 +42,7 @@ #include "oops/instanceRefKlass.hpp" #include "oops/oop.inline.hpp" #include "runtime/java.hpp" +#include "runtime/prefetch.inline.hpp" #include "runtime/thread.inline.hpp" #include "utilities/copy.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/hotspot/src/share/vm/memory/space.cpp b/hotspot/src/share/vm/memory/space.cpp index 68e2631d115..ae29692a62b 100644 --- a/hotspot/src/share/vm/memory/space.cpp +++ b/hotspot/src/share/vm/memory/space.cpp @@ -37,6 +37,7 @@ #include "oops/oop.inline.hpp" #include "oops/oop.inline2.hpp" #include "runtime/java.hpp" +#include "runtime/prefetch.inline.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/safepoint.hpp" #include "utilities/copy.hpp" diff --git a/hotspot/src/share/vm/memory/space.hpp b/hotspot/src/share/vm/memory/space.hpp index 2e0ebcb09b4..4c2974dcdab 100644 --- a/hotspot/src/share/vm/memory/space.hpp +++ b/hotspot/src/share/vm/memory/space.hpp @@ -33,24 +33,8 @@ #include "memory/watermark.hpp" #include "oops/markOop.hpp" #include "runtime/mutexLocker.hpp" -#include "runtime/prefetch.hpp" #include "utilities/macros.hpp" #include "utilities/workgroup.hpp" -#ifdef TARGET_OS_FAMILY_linux -# include "os_linux.inline.hpp" -#endif -#ifdef TARGET_OS_FAMILY_solaris -# include "os_solaris.inline.hpp" -#endif -#ifdef TARGET_OS_FAMILY_windows -# include "os_windows.inline.hpp" -#endif -#ifdef TARGET_OS_FAMILY_aix -# include "os_aix.inline.hpp" -#endif -#ifdef TARGET_OS_FAMILY_bsd -# include "os_bsd.inline.hpp" -#endif // A space is an abstraction for the "storage units" backing // up the generation abstraction. It includes specific @@ -468,272 +452,6 @@ protected: size_t word_len); }; -#define SCAN_AND_FORWARD(cp,scan_limit,block_is_obj,block_size) { \ - /* Compute the new addresses for the live objects and store it in the mark \ - * Used by universe::mark_sweep_phase2() \ - */ \ - HeapWord* compact_top; /* This is where we are currently compacting to. */ \ - \ - /* We're sure to be here before any objects are compacted into this \ - * space, so this is a good time to initialize this: \ - */ \ - set_compaction_top(bottom()); \ - \ - if (cp->space == NULL) { \ - assert(cp->gen != NULL, "need a generation"); \ - assert(cp->threshold == NULL, "just checking"); \ - assert(cp->gen->first_compaction_space() == this, "just checking"); \ - cp->space = cp->gen->first_compaction_space(); \ - compact_top = cp->space->bottom(); \ - cp->space->set_compaction_top(compact_top); \ - cp->threshold = cp->space->initialize_threshold(); \ - } else { \ - compact_top = cp->space->compaction_top(); \ - } \ - \ - /* We allow some amount of garbage towards the bottom of the space, so \ - * we don't start compacting before there is a significant gain to be made.\ - * Occasionally, we want to ensure a full compaction, which is determined \ - * by the MarkSweepAlwaysCompactCount parameter. \ - */ \ - uint invocations = MarkSweep::total_invocations(); \ - bool skip_dead = ((invocations % MarkSweepAlwaysCompactCount) != 0); \ - \ - size_t allowed_deadspace = 0; \ - if (skip_dead) { \ - const size_t ratio = allowed_dead_ratio(); \ - allowed_deadspace = (capacity() * ratio / 100) / HeapWordSize; \ - } \ - \ - HeapWord* q = bottom(); \ - HeapWord* t = scan_limit(); \ - \ - HeapWord* end_of_live= q; /* One byte beyond the last byte of the last \ - live object. */ \ - HeapWord* first_dead = end();/* The first dead object. */ \ - LiveRange* liveRange = NULL; /* The current live range, recorded in the \ - first header of preceding free area. */ \ - _first_dead = first_dead; \ - \ - const intx interval = PrefetchScanIntervalInBytes; \ - \ - while (q < t) { \ - assert(!block_is_obj(q) || \ - oop(q)->mark()->is_marked() || oop(q)->mark()->is_unlocked() || \ - oop(q)->mark()->has_bias_pattern(), \ - "these are the only valid states during a mark sweep"); \ - if (block_is_obj(q) && oop(q)->is_gc_marked()) { \ - /* prefetch beyond q */ \ - Prefetch::write(q, interval); \ - size_t size = block_size(q); \ - compact_top = cp->space->forward(oop(q), size, cp, compact_top); \ - q += size; \ - end_of_live = q; \ - } else { \ - /* run over all the contiguous dead objects */ \ - HeapWord* end = q; \ - do { \ - /* prefetch beyond end */ \ - Prefetch::write(end, interval); \ - end += block_size(end); \ - } while (end < t && (!block_is_obj(end) || !oop(end)->is_gc_marked()));\ - \ - /* see if we might want to pretend this object is alive so that \ - * we don't have to compact quite as often. \ - */ \ - if (allowed_deadspace > 0 && q == compact_top) { \ - size_t sz = pointer_delta(end, q); \ - if (insert_deadspace(allowed_deadspace, q, sz)) { \ - compact_top = cp->space->forward(oop(q), sz, cp, compact_top); \ - q = end; \ - end_of_live = end; \ - continue; \ - } \ - } \ - \ - /* otherwise, it really is a free region. */ \ - \ - /* for the previous LiveRange, record the end of the live objects. */ \ - if (liveRange) { \ - liveRange->set_end(q); \ - } \ - \ - /* record the current LiveRange object. \ - * liveRange->start() is overlaid on the mark word. \ - */ \ - liveRange = (LiveRange*)q; \ - liveRange->set_start(end); \ - liveRange->set_end(end); \ - \ - /* see if this is the first dead region. */ \ - if (q < first_dead) { \ - first_dead = q; \ - } \ - \ - /* move on to the next object */ \ - q = end; \ - } \ - } \ - \ - assert(q == t, "just checking"); \ - if (liveRange != NULL) { \ - liveRange->set_end(q); \ - } \ - _end_of_live = end_of_live; \ - if (end_of_live < first_dead) { \ - first_dead = end_of_live; \ - } \ - _first_dead = first_dead; \ - \ - /* save the compaction_top of the compaction space. */ \ - cp->space->set_compaction_top(compact_top); \ -} - -#define SCAN_AND_ADJUST_POINTERS(adjust_obj_size) { \ - /* adjust all the interior pointers to point at the new locations of objects \ - * Used by MarkSweep::mark_sweep_phase3() */ \ - \ - HeapWord* q = bottom(); \ - HeapWord* t = _end_of_live; /* Established by "prepare_for_compaction". */ \ - \ - assert(_first_dead <= _end_of_live, "Stands to reason, no?"); \ - \ - if (q < t && _first_dead > q && \ - !oop(q)->is_gc_marked()) { \ - /* we have a chunk of the space which hasn't moved and we've \ - * reinitialized the mark word during the previous pass, so we can't \ - * use is_gc_marked for the traversal. */ \ - HeapWord* end = _first_dead; \ - \ - while (q < end) { \ - /* I originally tried to conjoin "block_start(q) == q" to the \ - * assertion below, but that doesn't work, because you can't \ - * accurately traverse previous objects to get to the current one \ - * after their pointers have been \ - * updated, until the actual compaction is done. dld, 4/00 */ \ - assert(block_is_obj(q), \ - "should be at block boundaries, and should be looking at objs"); \ - \ - /* point all the oops to the new location */ \ - size_t size = oop(q)->adjust_pointers(); \ - size = adjust_obj_size(size); \ - \ - q += size; \ - } \ - \ - if (_first_dead == t) { \ - q = t; \ - } else { \ - /* $$$ This is funky. Using this to read the previously written \ - * LiveRange. See also use below. */ \ - q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer(); \ - } \ - } \ - \ - const intx interval = PrefetchScanIntervalInBytes; \ - \ - debug_only(HeapWord* prev_q = NULL); \ - while (q < t) { \ - /* prefetch beyond q */ \ - Prefetch::write(q, interval); \ - if (oop(q)->is_gc_marked()) { \ - /* q is alive */ \ - /* point all the oops to the new location */ \ - size_t size = oop(q)->adjust_pointers(); \ - size = adjust_obj_size(size); \ - debug_only(prev_q = q); \ - q += size; \ - } else { \ - /* q is not a live object, so its mark should point at the next \ - * live object */ \ - debug_only(prev_q = q); \ - q = (HeapWord*) oop(q)->mark()->decode_pointer(); \ - assert(q > prev_q, "we should be moving forward through memory"); \ - } \ - } \ - \ - assert(q == t, "just checking"); \ -} - -#define SCAN_AND_COMPACT(obj_size) { \ - /* Copy all live objects to their new location \ - * Used by MarkSweep::mark_sweep_phase4() */ \ - \ - HeapWord* q = bottom(); \ - HeapWord* const t = _end_of_live; \ - debug_only(HeapWord* prev_q = NULL); \ - \ - if (q < t && _first_dead > q && \ - !oop(q)->is_gc_marked()) { \ - debug_only( \ - /* we have a chunk of the space which hasn't moved and we've reinitialized \ - * the mark word during the previous pass, so we can't use is_gc_marked for \ - * the traversal. */ \ - HeapWord* const end = _first_dead; \ - \ - while (q < end) { \ - size_t size = obj_size(q); \ - assert(!oop(q)->is_gc_marked(), \ - "should be unmarked (special dense prefix handling)"); \ - debug_only(prev_q = q); \ - q += size; \ - } \ - ) /* debug_only */ \ - \ - if (_first_dead == t) { \ - q = t; \ - } else { \ - /* $$$ Funky */ \ - q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer(); \ - } \ - } \ - \ - const intx scan_interval = PrefetchScanIntervalInBytes; \ - const intx copy_interval = PrefetchCopyIntervalInBytes; \ - while (q < t) { \ - if (!oop(q)->is_gc_marked()) { \ - /* mark is pointer to next marked oop */ \ - debug_only(prev_q = q); \ - q = (HeapWord*) oop(q)->mark()->decode_pointer(); \ - assert(q > prev_q, "we should be moving forward through memory"); \ - } else { \ - /* prefetch beyond q */ \ - Prefetch::read(q, scan_interval); \ - \ - /* size and destination */ \ - size_t size = obj_size(q); \ - HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee(); \ - \ - /* prefetch beyond compaction_top */ \ - Prefetch::write(compaction_top, copy_interval); \ - \ - /* copy object and reinit its mark */ \ - assert(q != compaction_top, "everything in this pass should be moving"); \ - Copy::aligned_conjoint_words(q, compaction_top, size); \ - oop(compaction_top)->init_mark(); \ - assert(oop(compaction_top)->klass() != NULL, "should have a class"); \ - \ - debug_only(prev_q = q); \ - q += size; \ - } \ - } \ - \ - /* Let's remember if we were empty before we did the compaction. */ \ - bool was_empty = used_region().is_empty(); \ - /* Reset space after compaction is complete */ \ - reset_after_compaction(); \ - /* We do this clear, below, since it has overloaded meanings for some */ \ - /* space subtypes. For example, OffsetTableContigSpace's that were */ \ - /* compacted into will have had their offset table thresholds updated */ \ - /* continuously, but those that weren't need to have their thresholds */ \ - /* re-initialized. Also mangles unused area for debugging. */ \ - if (used_region().is_empty()) { \ - if (!was_empty) clear(SpaceDecorator::Mangle); \ - } else { \ - if (ZapUnusedHeapArea) mangle_unused_area(); \ - } \ -} - class GenSpaceMangler; // A space in which the free area is contiguous. It therefore supports diff --git a/hotspot/src/share/vm/memory/space.inline.hpp b/hotspot/src/share/vm/memory/space.inline.hpp index 1d600e2a1aa..007cebd16e6 100644 --- a/hotspot/src/share/vm/memory/space.inline.hpp +++ b/hotspot/src/share/vm/memory/space.inline.hpp @@ -28,12 +28,279 @@ #include "gc_interface/collectedHeap.hpp" #include "memory/space.hpp" #include "memory/universe.hpp" +#include "runtime/prefetch.inline.hpp" #include "runtime/safepoint.hpp" inline HeapWord* Space::block_start(const void* p) { return block_start_const(p); } +#define SCAN_AND_FORWARD(cp,scan_limit,block_is_obj,block_size) { \ + /* Compute the new addresses for the live objects and store it in the mark \ + * Used by universe::mark_sweep_phase2() \ + */ \ + HeapWord* compact_top; /* This is where we are currently compacting to. */ \ + \ + /* We're sure to be here before any objects are compacted into this \ + * space, so this is a good time to initialize this: \ + */ \ + set_compaction_top(bottom()); \ + \ + if (cp->space == NULL) { \ + assert(cp->gen != NULL, "need a generation"); \ + assert(cp->threshold == NULL, "just checking"); \ + assert(cp->gen->first_compaction_space() == this, "just checking"); \ + cp->space = cp->gen->first_compaction_space(); \ + compact_top = cp->space->bottom(); \ + cp->space->set_compaction_top(compact_top); \ + cp->threshold = cp->space->initialize_threshold(); \ + } else { \ + compact_top = cp->space->compaction_top(); \ + } \ + \ + /* We allow some amount of garbage towards the bottom of the space, so \ + * we don't start compacting before there is a significant gain to be made.\ + * Occasionally, we want to ensure a full compaction, which is determined \ + * by the MarkSweepAlwaysCompactCount parameter. \ + */ \ + uint invocations = MarkSweep::total_invocations(); \ + bool skip_dead = ((invocations % MarkSweepAlwaysCompactCount) != 0); \ + \ + size_t allowed_deadspace = 0; \ + if (skip_dead) { \ + const size_t ratio = allowed_dead_ratio(); \ + allowed_deadspace = (capacity() * ratio / 100) / HeapWordSize; \ + } \ + \ + HeapWord* q = bottom(); \ + HeapWord* t = scan_limit(); \ + \ + HeapWord* end_of_live= q; /* One byte beyond the last byte of the last \ + live object. */ \ + HeapWord* first_dead = end();/* The first dead object. */ \ + LiveRange* liveRange = NULL; /* The current live range, recorded in the \ + first header of preceding free area. */ \ + _first_dead = first_dead; \ + \ + const intx interval = PrefetchScanIntervalInBytes; \ + \ + while (q < t) { \ + assert(!block_is_obj(q) || \ + oop(q)->mark()->is_marked() || oop(q)->mark()->is_unlocked() || \ + oop(q)->mark()->has_bias_pattern(), \ + "these are the only valid states during a mark sweep"); \ + if (block_is_obj(q) && oop(q)->is_gc_marked()) { \ + /* prefetch beyond q */ \ + Prefetch::write(q, interval); \ + size_t size = block_size(q); \ + compact_top = cp->space->forward(oop(q), size, cp, compact_top); \ + q += size; \ + end_of_live = q; \ + } else { \ + /* run over all the contiguous dead objects */ \ + HeapWord* end = q; \ + do { \ + /* prefetch beyond end */ \ + Prefetch::write(end, interval); \ + end += block_size(end); \ + } while (end < t && (!block_is_obj(end) || !oop(end)->is_gc_marked()));\ + \ + /* see if we might want to pretend this object is alive so that \ + * we don't have to compact quite as often. \ + */ \ + if (allowed_deadspace > 0 && q == compact_top) { \ + size_t sz = pointer_delta(end, q); \ + if (insert_deadspace(allowed_deadspace, q, sz)) { \ + compact_top = cp->space->forward(oop(q), sz, cp, compact_top); \ + q = end; \ + end_of_live = end; \ + continue; \ + } \ + } \ + \ + /* otherwise, it really is a free region. */ \ + \ + /* for the previous LiveRange, record the end of the live objects. */ \ + if (liveRange) { \ + liveRange->set_end(q); \ + } \ + \ + /* record the current LiveRange object. \ + * liveRange->start() is overlaid on the mark word. \ + */ \ + liveRange = (LiveRange*)q; \ + liveRange->set_start(end); \ + liveRange->set_end(end); \ + \ + /* see if this is the first dead region. */ \ + if (q < first_dead) { \ + first_dead = q; \ + } \ + \ + /* move on to the next object */ \ + q = end; \ + } \ + } \ + \ + assert(q == t, "just checking"); \ + if (liveRange != NULL) { \ + liveRange->set_end(q); \ + } \ + _end_of_live = end_of_live; \ + if (end_of_live < first_dead) { \ + first_dead = end_of_live; \ + } \ + _first_dead = first_dead; \ + \ + /* save the compaction_top of the compaction space. */ \ + cp->space->set_compaction_top(compact_top); \ +} + +#define SCAN_AND_ADJUST_POINTERS(adjust_obj_size) { \ + /* adjust all the interior pointers to point at the new locations of objects \ + * Used by MarkSweep::mark_sweep_phase3() */ \ + \ + HeapWord* q = bottom(); \ + HeapWord* t = _end_of_live; /* Established by "prepare_for_compaction". */ \ + \ + assert(_first_dead <= _end_of_live, "Stands to reason, no?"); \ + \ + if (q < t && _first_dead > q && \ + !oop(q)->is_gc_marked()) { \ + /* we have a chunk of the space which hasn't moved and we've \ + * reinitialized the mark word during the previous pass, so we can't \ + * use is_gc_marked for the traversal. */ \ + HeapWord* end = _first_dead; \ + \ + while (q < end) { \ + /* I originally tried to conjoin "block_start(q) == q" to the \ + * assertion below, but that doesn't work, because you can't \ + * accurately traverse previous objects to get to the current one \ + * after their pointers have been \ + * updated, until the actual compaction is done. dld, 4/00 */ \ + assert(block_is_obj(q), \ + "should be at block boundaries, and should be looking at objs"); \ + \ + /* point all the oops to the new location */ \ + size_t size = oop(q)->adjust_pointers(); \ + size = adjust_obj_size(size); \ + \ + q += size; \ + } \ + \ + if (_first_dead == t) { \ + q = t; \ + } else { \ + /* $$$ This is funky. Using this to read the previously written \ + * LiveRange. See also use below. */ \ + q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer(); \ + } \ + } \ + \ + const intx interval = PrefetchScanIntervalInBytes; \ + \ + debug_only(HeapWord* prev_q = NULL); \ + while (q < t) { \ + /* prefetch beyond q */ \ + Prefetch::write(q, interval); \ + if (oop(q)->is_gc_marked()) { \ + /* q is alive */ \ + /* point all the oops to the new location */ \ + size_t size = oop(q)->adjust_pointers(); \ + size = adjust_obj_size(size); \ + debug_only(prev_q = q); \ + q += size; \ + } else { \ + /* q is not a live object, so its mark should point at the next \ + * live object */ \ + debug_only(prev_q = q); \ + q = (HeapWord*) oop(q)->mark()->decode_pointer(); \ + assert(q > prev_q, "we should be moving forward through memory"); \ + } \ + } \ + \ + assert(q == t, "just checking"); \ +} + +#define SCAN_AND_COMPACT(obj_size) { \ + /* Copy all live objects to their new location \ + * Used by MarkSweep::mark_sweep_phase4() */ \ + \ + HeapWord* q = bottom(); \ + HeapWord* const t = _end_of_live; \ + debug_only(HeapWord* prev_q = NULL); \ + \ + if (q < t && _first_dead > q && \ + !oop(q)->is_gc_marked()) { \ + debug_only( \ + /* we have a chunk of the space which hasn't moved and we've reinitialized \ + * the mark word during the previous pass, so we can't use is_gc_marked for \ + * the traversal. */ \ + HeapWord* const end = _first_dead; \ + \ + while (q < end) { \ + size_t size = obj_size(q); \ + assert(!oop(q)->is_gc_marked(), \ + "should be unmarked (special dense prefix handling)"); \ + debug_only(prev_q = q); \ + q += size; \ + } \ + ) /* debug_only */ \ + \ + if (_first_dead == t) { \ + q = t; \ + } else { \ + /* $$$ Funky */ \ + q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer(); \ + } \ + } \ + \ + const intx scan_interval = PrefetchScanIntervalInBytes; \ + const intx copy_interval = PrefetchCopyIntervalInBytes; \ + while (q < t) { \ + if (!oop(q)->is_gc_marked()) { \ + /* mark is pointer to next marked oop */ \ + debug_only(prev_q = q); \ + q = (HeapWord*) oop(q)->mark()->decode_pointer(); \ + assert(q > prev_q, "we should be moving forward through memory"); \ + } else { \ + /* prefetch beyond q */ \ + Prefetch::read(q, scan_interval); \ + \ + /* size and destination */ \ + size_t size = obj_size(q); \ + HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee(); \ + \ + /* prefetch beyond compaction_top */ \ + Prefetch::write(compaction_top, copy_interval); \ + \ + /* copy object and reinit its mark */ \ + assert(q != compaction_top, "everything in this pass should be moving"); \ + Copy::aligned_conjoint_words(q, compaction_top, size); \ + oop(compaction_top)->init_mark(); \ + assert(oop(compaction_top)->klass() != NULL, "should have a class"); \ + \ + debug_only(prev_q = q); \ + q += size; \ + } \ + } \ + \ + /* Let's remember if we were empty before we did the compaction. */ \ + bool was_empty = used_region().is_empty(); \ + /* Reset space after compaction is complete */ \ + reset_after_compaction(); \ + /* We do this clear, below, since it has overloaded meanings for some */ \ + /* space subtypes. For example, OffsetTableContigSpace's that were */ \ + /* compacted into will have had their offset table thresholds updated */ \ + /* continuously, but those that weren't need to have their thresholds */ \ + /* re-initialized. Also mangles unused area for debugging. */ \ + if (used_region().is_empty()) { \ + if (!was_empty) clear(SpaceDecorator::Mangle); \ + } else { \ + if (ZapUnusedHeapArea) mangle_unused_area(); \ + } \ +} + inline HeapWord* OffsetTableContigSpace::allocate(size_t size) { HeapWord* res = ContiguousSpace::allocate(size); if (res != NULL) { diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp index 6aac575cf11..06198fbb11c 100644 --- a/hotspot/src/share/vm/oops/klass.hpp +++ b/hotspot/src/share/vm/oops/klass.hpp @@ -555,36 +555,6 @@ class Klass : public Metadata { static void clean_weak_klass_links(BoolObjectClosure* is_alive); - // Prefetch within oop iterators. This is a macro because we - // can't guarantee that the compiler will inline it. In 64-bit - // it generally doesn't. Signature is - // - // static void prefetch_beyond(oop* const start, - // oop* const end, - // const intx foffset, - // const Prefetch::style pstyle); -#define prefetch_beyond(start, end, foffset, pstyle) { \ - const intx foffset_ = (foffset); \ - const Prefetch::style pstyle_ = (pstyle); \ - assert(foffset_ > 0, "prefetch beyond, not behind"); \ - if (pstyle_ != Prefetch::do_none) { \ - oop* ref = (start); \ - if (ref < (end)) { \ - switch (pstyle_) { \ - case Prefetch::do_read: \ - Prefetch::read(*ref, foffset_); \ - break; \ - case Prefetch::do_write: \ - Prefetch::write(*ref, foffset_); \ - break; \ - default: \ - ShouldNotReachHere(); \ - break; \ - } \ - } \ - } \ - } - // iterators virtual int oop_oop_iterate(oop obj, ExtendedOopClosure* blk) = 0; virtual int oop_oop_iterate_v(oop obj, ExtendedOopClosure* blk) { diff --git a/hotspot/src/share/vm/precompiled/precompiled.hpp b/hotspot/src/share/vm/precompiled/precompiled.hpp index 6d532de6aad..e8d014430df 100644 --- a/hotspot/src/share/vm/precompiled/precompiled.hpp +++ b/hotspot/src/share/vm/precompiled/precompiled.hpp @@ -199,6 +199,7 @@ # include "runtime/perfData.hpp" # include "runtime/perfMemory.hpp" # include "runtime/prefetch.hpp" +# include "runtime/prefetch.inline.hpp" # include "runtime/reflection.hpp" # include "runtime/reflectionUtils.hpp" # include "runtime/registerMap.hpp" diff --git a/hotspot/src/share/vm/prims/unsafe.cpp b/hotspot/src/share/vm/prims/unsafe.cpp index b3160771aed..4dd10cfca57 100644 --- a/hotspot/src/share/vm/prims/unsafe.cpp +++ b/hotspot/src/share/vm/prims/unsafe.cpp @@ -33,6 +33,7 @@ #include "prims/jvm.h" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.hpp" +#include "runtime/prefetch.inline.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/reflection.hpp" #include "runtime/synchronizer.hpp" diff --git a/hotspot/src/share/vm/runtime/prefetch.inline.hpp b/hotspot/src/share/vm/runtime/prefetch.inline.hpp new file mode 100644 index 00000000000..e147a211aea --- /dev/null +++ b/hotspot/src/share/vm/runtime/prefetch.inline.hpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + * + */ + +#ifndef SHARE_VM_RUNTIME_PREFETCH_INLINE_HPP +#define SHARE_VM_RUNTIME_PREFETCH_INLINE_HPP + +#include "runtime/prefetch.hpp" + +// Linux +#ifdef TARGET_OS_ARCH_linux_x86 +# include "prefetch_linux_x86.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_sparc +# include "prefetch_linux_sparc.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_zero +# include "prefetch_linux_zero.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_arm +# include "prefetch_linux_arm.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_ppc +# include "prefetch_linux_ppc.inline.hpp" +#endif + +// Solaris +#ifdef TARGET_OS_ARCH_solaris_x86 +# include "prefetch_solaris_x86.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_solaris_sparc +# include "prefetch_solaris_sparc.inline.hpp" +#endif + +// Windows +#ifdef TARGET_OS_ARCH_windows_x86 +# include "prefetch_windows_x86.inline.hpp" +#endif + +// AIX +#ifdef TARGET_OS_ARCH_aix_ppc +# include "prefetch_aix_ppc.inline.hpp" +#endif + +// BSD +#ifdef TARGET_OS_ARCH_bsd_x86 +# include "prefetch_bsd_x86.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_bsd_zero +# include "prefetch_bsd_zero.inline.hpp" +#endif + +#endif // SHARE_VM_RUNTIME_PREFETCH_INLINE_HPP From 358e8a04ee83ac9aec3c9a743e8bf6619df98173 Mon Sep 17 00:00:00 2001 From: Petr Pchelko <pchelko@openjdk.org> Date: Thu, 8 May 2014 18:37:34 +0400 Subject: [PATCH 054/157] 8042752: [macosx] NSEvent instances leak throw JNI local references Reviewed-by: serb, azvegint --- jdk/src/macosx/native/sun/awt/AWTView.m | 13 +++++++------ jdk/src/macosx/native/sun/awt/CTrayIcon.m | 7 +++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/jdk/src/macosx/native/sun/awt/AWTView.m b/jdk/src/macosx/native/sun/awt/AWTView.m index bcc832190f4..830fb77e82b 100644 --- a/jdk/src/macosx/native/sun/awt/AWTView.m +++ b/jdk/src/macosx/native/sun/awt/AWTView.m @@ -27,6 +27,7 @@ #import <JavaNativeFoundation/JavaNativeFoundation.h> #import <JavaRuntimeSupport/JavaRuntimeSupport.h> +#import "jni_util.h" #import "ThreadUtilities.h" #import "AWTView.h" @@ -391,14 +392,12 @@ AWT_ASSERT_APPKIT_THREAD; (jint)absP.x, (jint)absP.y, [event deltaY], [event deltaX]); - if (jEvent == nil) { - // Unable to create event by some reason. - return; - } + CHECK_NULL(jEvent); static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_MEMBER_CACHE(jm_deliverMouseEvent, jc_PlatformView, "deliverMouseEvent", "(Lsun/lwawt/macosx/NSEvent;)V"); JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent); + (*env)->DeleteLocalRef(env, jEvent); } - (void) resetTrackingArea { @@ -447,20 +446,22 @@ AWT_ASSERT_APPKIT_THREAD; static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/NSEvent"); static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IISLjava/lang/String;)V"); - jobject jevent = JNFNewObject(env, jctor_NSEvent, + jobject jEvent = JNFNewObject(env, jctor_NSEvent, [event type], [event modifierFlags], [event keyCode], characters); + CHECK_NULL(jEvent); static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_MEMBER_CACHE(jm_deliverKeyEvent, jc_PlatformView, "deliverKeyEvent", "(Lsun/lwawt/macosx/NSEvent;)V"); - JNFCallVoidMethod(env, m_cPlatformView, jm_deliverKeyEvent, jevent); + JNFCallVoidMethod(env, m_cPlatformView, jm_deliverKeyEvent, jEvent); if (characters != NULL) { (*env)->DeleteLocalRef(env, characters); } + (*env)->DeleteLocalRef(env, jEvent); } -(void) deliverResize: (NSRect) rect { diff --git a/jdk/src/macosx/native/sun/awt/CTrayIcon.m b/jdk/src/macosx/native/sun/awt/CTrayIcon.m index 79ae024f76f..35adf3b866d 100644 --- a/jdk/src/macosx/native/sun/awt/CTrayIcon.m +++ b/jdk/src/macosx/native/sun/awt/CTrayIcon.m @@ -25,6 +25,7 @@ #import <AppKit/AppKit.h> #import <JavaNativeFoundation/JavaNativeFoundation.h> +#import "jni_util.h" #import "CTrayIcon.h" #import "ThreadUtilities.h" @@ -146,14 +147,12 @@ static NSSize ScaledImageSizeForStatusBar(NSSize imageSize) { (jint)absP.x, (jint)absP.y, [event deltaY], [event deltaX]); - if (jEvent == nil) { - // Unable to create event by some reason. - return; - } + CHECK_NULL(jEvent); static JNF_CLASS_CACHE(jc_TrayIcon, "sun/lwawt/macosx/CTrayIcon"); static JNF_MEMBER_CACHE(jm_handleMouseEvent, jc_TrayIcon, "handleMouseEvent", "(Lsun/lwawt/macosx/NSEvent;)V"); JNFCallVoidMethod(env, peer, jm_handleMouseEvent, jEvent); + (*env)->DeleteLocalRef(env, jEvent); } @end //AWTTrayIcon From 4c217914c2965a26f38a85379b007f16061e7aad Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Thu, 8 May 2014 15:17:02 -0700 Subject: [PATCH 055/157] 8038875: Remove use of ServiceLoader in finding class implementing sun.java2d.pipe. RenderingEngine Reviewed-by: flar, mchung --- jdk/make/CopyIntoClasses.gmk | 2 - jdk/make/profile-rtjar-includes.txt | 3 +- .../services/sun.java2d.pipe.RenderingEngine | 2 - .../sun/java2d/pipe/RenderingEngine.java | 60 +++++++------------ .../services/sun.java2d.pipe.RenderingEngine | 2 - .../services/sun.java2d.pipe.RenderingEngine | 5 -- 6 files changed, 23 insertions(+), 51 deletions(-) delete mode 100644 jdk/src/share/classes/sun/dc/META-INF/services/sun.java2d.pipe.RenderingEngine delete mode 100644 jdk/src/share/classes/sun/java2d/pisces/META-INF/services/sun.java2d.pipe.RenderingEngine delete mode 100644 jdk/src/solaris/classes/sun/java2d/pisces/META-INF/services/sun.java2d.pipe.RenderingEngine diff --git a/jdk/make/CopyIntoClasses.gmk b/jdk/make/CopyIntoClasses.gmk index 36b0919fa2f..322901603a3 100644 --- a/jdk/make/CopyIntoClasses.gmk +++ b/jdk/make/CopyIntoClasses.gmk @@ -118,10 +118,8 @@ endif SRC_SERVICES_FILES := $(wildcard $(addsuffix /services/*, $(ALL_META-INF_DIRS))) ifdef OPENJDK - SRC_SERVICES_FILES := $(filter-out %sun/dc/META-INF/services/sun.java2d.pipe.RenderingEngine, $(SRC_SERVICES_FILES)) SRC_SERVICES_FILES := $(filter-out %sun/java2d/cmm/kcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider, $(SRC_SERVICES_FILES)) else - SRC_SERVICES_FILES := $(filter-out %sun/java2d/pisces/META-INF/services/sun.java2d.pipe.RenderingEngine, $(SRC_SERVICES_FILES)) SRC_SERVICES_FILES := $(filter-out %sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider, $(SRC_SERVICES_FILES)) endif diff --git a/jdk/make/profile-rtjar-includes.txt b/jdk/make/profile-rtjar-includes.txt index 231b1583ae0..6cce159e400 100644 --- a/jdk/make/profile-rtjar-includes.txt +++ b/jdk/make/profile-rtjar-includes.txt @@ -242,5 +242,4 @@ FULL_JRE_INCLUDE_METAINF_SERVICES := \ META-INF/services/javax.sound.sampled.spi.AudioFileWriter \ META-INF/services/javax.sound.sampled.spi.FormatConversionProvider \ META-INF/services/javax.sound.sampled.spi.MixerProvider \ - META-INF/services/sun.java2d.cmm.PCMM \ - META-INF/services/sun.java2d.pipe.RenderingEngine + META-INF/services/sun.java2d.cmm.PCMM diff --git a/jdk/src/share/classes/sun/dc/META-INF/services/sun.java2d.pipe.RenderingEngine b/jdk/src/share/classes/sun/dc/META-INF/services/sun.java2d.pipe.RenderingEngine deleted file mode 100644 index 45f0ddfa772..00000000000 --- a/jdk/src/share/classes/sun/dc/META-INF/services/sun.java2d.pipe.RenderingEngine +++ /dev/null @@ -1,2 +0,0 @@ -# Ductus Rendering Engine module -sun.dc.DuctusRenderingEngine diff --git a/jdk/src/share/classes/sun/java2d/pipe/RenderingEngine.java b/jdk/src/share/classes/sun/java2d/pipe/RenderingEngine.java index 3c2a77ca73b..034a6e8b218 100644 --- a/jdk/src/share/classes/sun/java2d/pipe/RenderingEngine.java +++ b/jdk/src/share/classes/sun/java2d/pipe/RenderingEngine.java @@ -32,7 +32,6 @@ import java.awt.geom.AffineTransform; import java.security.PrivilegedAction; import java.security.AccessController; -import java.util.ServiceLoader; import sun.security.action.GetPropertyAction; import sun.awt.geom.PathConsumer2D; @@ -97,12 +96,9 @@ public abstract class RenderingEngine { * </pre> * * If no specific {@code RenderingEngine} is specified on the command - * or Ductus renderer is specified, it will attempt loading the - * sun.dc.DuctusRenderingEngine class using Class.forName as a fastpath; - * if not found, use the ServiceLoader. - * If no specific {@code RenderingEngine} is specified on the command - * line then the last one returned by enumerating all subclasses of - * {@code RenderingEngine} known to the ServiceLoader is used. + * or Ductus renderer is specified, it will first attempt loading the + * sun.dc.DuctusRenderingEngine class using Class.forName, if that + * is not found, then it will look for Pisces. * <p> * Runtime tracing of the actions of the {@code RenderingEngine} * can be enabled by specifying the runtime flag: @@ -117,42 +113,30 @@ public abstract class RenderingEngine { return reImpl; } - reImpl = - AccessController.doPrivileged(new PrivilegedAction<RenderingEngine>() { - public RenderingEngine run() { - final String ductusREClass = "sun.dc.DuctusRenderingEngine"; - String reClass = - System.getProperty("sun.java2d.renderer", ductusREClass); - if (reClass.equals(ductusREClass)) { - try { - Class<?> cls = Class.forName(ductusREClass); - return (RenderingEngine) cls.newInstance(); - } catch (ReflectiveOperationException ignored) { - // not found - } - } - - ServiceLoader<RenderingEngine> reLoader = - ServiceLoader.loadInstalled(RenderingEngine.class); - - RenderingEngine service = null; - - for (RenderingEngine re : reLoader) { - service = re; - if (re.getClass().getName().equals(reClass)) { - break; - } - } - return service; - } - }); + /* Look first for ductus or an app-override renderer, + * if not specified or present, then look for pisces. + */ + final String ductusREClass = "sun.dc.DuctusRenderingEngine"; + final String piscesREClass = "sun.java2d.pisces.PiscesRenderingEngine"; + GetPropertyAction gpa = + new GetPropertyAction("sun.java2d.renderer", ductusREClass); + String reClass = AccessController.doPrivileged(gpa); + try { + Class<?> cls = Class.forName(reClass); + reImpl = (RenderingEngine) cls.newInstance(); + } catch (ReflectiveOperationException ignored0) { + try { + Class<?> cls = Class.forName(piscesREClass); + reImpl = (RenderingEngine) cls.newInstance(); + } catch (ReflectiveOperationException ignored1) { + } + } if (reImpl == null) { throw new InternalError("No RenderingEngine module found"); } - GetPropertyAction gpa = - new GetPropertyAction("sun.java2d.renderer.trace"); + gpa = new GetPropertyAction("sun.java2d.renderer.trace"); String reTrace = AccessController.doPrivileged(gpa); if (reTrace != null) { reImpl = new Tracer(reImpl); diff --git a/jdk/src/share/classes/sun/java2d/pisces/META-INF/services/sun.java2d.pipe.RenderingEngine b/jdk/src/share/classes/sun/java2d/pisces/META-INF/services/sun.java2d.pipe.RenderingEngine deleted file mode 100644 index 607ff59051a..00000000000 --- a/jdk/src/share/classes/sun/java2d/pisces/META-INF/services/sun.java2d.pipe.RenderingEngine +++ /dev/null @@ -1,2 +0,0 @@ -# Pisces Rendering Engine module -sun.java2d.pisces.PiscesRenderingEngine diff --git a/jdk/src/solaris/classes/sun/java2d/pisces/META-INF/services/sun.java2d.pipe.RenderingEngine b/jdk/src/solaris/classes/sun/java2d/pisces/META-INF/services/sun.java2d.pipe.RenderingEngine deleted file mode 100644 index c79fdbde9c8..00000000000 --- a/jdk/src/solaris/classes/sun/java2d/pisces/META-INF/services/sun.java2d.pipe.RenderingEngine +++ /dev/null @@ -1,5 +0,0 @@ -# Jules Rendering Engine module -sun.java2d.jules.JulesRenderingEngine - -# Pisces Rendering Engine module -sun.java2d.pisces.PiscesRenderingEngine From a9f93ddc32c6fc158b449c3bc4b4865a147762fd Mon Sep 17 00:00:00 2001 From: Omair Majid <omajid@openjdk.org> Date: Thu, 8 May 2014 19:27:24 -0400 Subject: [PATCH 056/157] 8042806: Splashscreen uses libjpeg-internal macros Reviewed-by: anthony, prr --- .../share/native/sun/awt/splashscreen/splashscreen_jpeg.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c b/jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c index f9cb8995c86..8d41c9207d8 100644 --- a/jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c +++ b/jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c @@ -25,7 +25,6 @@ #include "splashscreen_impl.h" -#include "jinclude.h" #include "jpeglib.h" #include "jerror.h" @@ -107,11 +106,11 @@ set_stream_src(j_decompress_ptr cinfo, SplashStream * stream) if (cinfo->src == NULL) { /* first time for this JPEG object? */ cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, - JPOOL_PERMANENT, SIZEOF(stream_source_mgr)); + JPOOL_PERMANENT, sizeof(stream_source_mgr)); src = (stream_src_ptr) cinfo->src; src->buffer = (JOCTET *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, - JPOOL_PERMANENT, INPUT_BUF_SIZE * SIZEOF(JOCTET)); + JPOOL_PERMANENT, INPUT_BUF_SIZE * sizeof(JOCTET)); } src = (stream_src_ptr) cinfo->src; From 8629eeb403467b26502a71d8656fd57f163a8885 Mon Sep 17 00:00:00 2001 From: Erik Helin <ehelin@openjdk.org> Date: Fri, 9 May 2014 09:59:39 +0200 Subject: [PATCH 057/157] 8034852: Shrinking of Metaspace high-water-mark causes incorrect OutOfMemoryErrors or back-to-back GCs Reviewed-by: jmasa, pliden, stefank --- hotspot/src/share/vm/memory/metaspace.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 10b95973192..70207ca3ad1 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -1431,10 +1431,9 @@ size_t MetaspaceGC::allowed_expansion() { } size_t capacity_until_gc = capacity_until_GC(); - - if (capacity_until_gc <= committed_bytes) { - return 0; - } + assert(capacity_until_gc >= committed_bytes, + err_msg("capacity_until_gc: " SIZE_FORMAT " < committed_bytes: " SIZE_FORMAT, + capacity_until_gc, committed_bytes)); size_t left_until_GC = capacity_until_gc - committed_bytes; size_t left_to_commit = MIN2(left_until_GC, left_until_max); @@ -1447,7 +1446,15 @@ void MetaspaceGC::compute_new_size() { uint current_shrink_factor = _shrink_factor; _shrink_factor = 0; - const size_t used_after_gc = MetaspaceAux::capacity_bytes(); + // Using committed_bytes() for used_after_gc is an overestimation, since the + // chunk free lists are included in committed_bytes() and the memory in an + // un-fragmented chunk free list is available for future allocations. + // However, if the chunk free lists becomes fragmented, then the memory may + // not be available for future allocations and the memory is therefore "in use". + // Including the chunk free lists in the definition of "in use" is therefore + // necessary. Not including the chunk free lists can cause capacity_until_GC to + // shrink below committed_bytes() and this has caused serious bugs in the past. + const size_t used_after_gc = MetaspaceAux::committed_bytes(); const size_t capacity_until_GC = MetaspaceGC::capacity_until_GC(); const double minimum_free_percentage = MinMetaspaceFreeRatio / 100.0; From 20e8dfef5327f5c32a9d3501cb18ae8a99bb7921 Mon Sep 17 00:00:00 2001 From: Christian Tornqvist <ctornqvi@openjdk.org> Date: Fri, 9 May 2014 17:06:17 +0200 Subject: [PATCH 058/157] 8042471: Unable to build JDK 9 Hotspot within VS2010 Fixed quoting issue and passing on defines to project file Reviewed-by: mgronlun, sla --- hotspot/make/windows/projectfiles/common/Makefile | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/hotspot/make/windows/projectfiles/common/Makefile b/hotspot/make/windows/projectfiles/common/Makefile index 4a527ef68c3..51d4e6f1f11 100644 --- a/hotspot/make/windows/projectfiles/common/Makefile +++ b/hotspot/make/windows/projectfiles/common/Makefile @@ -93,7 +93,7 @@ JRE_RELEASE_VERSION="\\\"$(JDK_MAJOR_VER).$(JDK_MINOR_VER).$(JDK_MICRO_VER)\\\"" !if "$(HOTSPOT_RELEASE_VERSION)" != "" HOTSPOT_RELEASE_VERSION="\\\"$(HOTSPOT_RELEASE_VERSION)\\\"" !else -HOTSPOT_RELEASE_VERSION="\\\"$(JRE_RELEASE_VERSION)\\\"" +HOTSPOT_RELEASE_VERSION=$(JRE_RELEASE_VERSION) !endif # Define HOTSPOT_VM_DISTRO if HOTSPOT_VM_DISTRO is set, # and if it is not see if we have the src/closed directory @@ -105,9 +105,18 @@ HOTSPOT_VM_DISTRO="\\\"Java HotSpot(TM)\\\"" !else HOTSPOT_VM_DISTRO="\\\"OpenJDK\\\"" !endif +!if "$(JDK_BUILD_NUMBER)" != "" +JDK_BUILD_NUMBER="\\\"$(JDK_BUILD_NUMBER)\\\"" +!else +JDK_BUILD_NUMBER="\\\"00\\\"" +!endif !endif -ReleaseOptions = -define HOTSPOT_RELEASE_VERSION=$(HOTSPOT_RELEASE_VERSION) -define JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION) -define HOTSPOT_VM_DISTRO=$(HOTSPOT_VM_DISTRO) +JDK_MAJOR_VERSION="\\\"$(JDK_MAJOR_VER)\\\"" +JDK_MINOR_VERSION="\\\"$(JDK_MINOR_VER)\\\"" +JDK_MICRO_VERSION="\\\"$(JDK_MICRO_VER)\\\"" + +ReleaseOptions = -define HOTSPOT_RELEASE_VERSION=$(HOTSPOT_RELEASE_VERSION) -define JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION) -define HOTSPOT_VM_DISTRO=$(HOTSPOT_VM_DISTRO) -define JDK_MAJOR_VERSION=$(JDK_MAJOR_VERSION) -define JDK_MINOR_VERSION=$(JDK_MINOR_VERSION) -define JDK_MICRO_VERSION=$(JDK_MICRO_VERSION) -define JDK_BUILD_NUMBER=$(JDK_BUILD_NUMBER) ProjectCreatorIDEOptions = $(ProjectCreatorIDEOptions) $(ReleaseOptions) $(HOTSPOTBUILDSPACE)/$(ProjectFile): $(HOTSPOTBUILDSPACE)/classes/ProjectCreator.class From 3e6986fb58400193cf02ce4566afcf8bd24b92de Mon Sep 17 00:00:00 2001 From: Christian Tornqvist <ctornqvi@openjdk.org> Date: Fri, 9 May 2014 17:06:52 +0200 Subject: [PATCH 059/157] 8042726: [TESTBUG] TEST.groups file was not updated after runtime/6925573/SortMethodsTest.java removal Removed runtime/6925573/SortMethodsTest.java from TEST.groups Reviewed-by: gtriantafill, lfoltan, coleenp, dholmes --- hotspot/test/TEST.groups | 1 - 1 file changed, 1 deletion(-) diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index 1053faa7f16..e470171dc21 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -66,7 +66,6 @@ needs_jdk = \ gc/metaspace/TestMetaspacePerfCounters.java \ gc/metaspace/TestPerfCountersAndMemoryPools.java \ runtime/6819213/TestBootNativeLibraryPath.java \ - runtime/6925573/SortMethodsTest.java \ runtime/7158988/FieldMonitor.java \ runtime/7194254/Test7194254.java \ runtime/Metaspace/FragmentMetaspace.java \ From 305ec3bd3f3fd4abb55a992f418bcf88a2694925 Mon Sep 17 00:00:00 2001 From: David Chase <drchase@openjdk.org> Date: Fri, 9 May 2014 16:50:54 -0400 Subject: [PATCH 060/157] 8037816: Fix for 8036122 breaks build with Xcode5/clang Repaired or selectively disabled offending formats; future-proofed with additional checking Reviewed-by: kvn, jrose, stefank --- hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp | 4 +- hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp | 12 ++-- hotspot/src/cpu/x86/vm/assembler_x86.cpp | 6 +- hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp | 4 +- hotspot/src/cpu/x86/vm/compiledIC_x86.cpp | 4 +- hotspot/src/cpu/x86/vm/frame_x86.cpp | 3 +- hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp | 3 +- hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp | 3 +- hotspot/src/cpu/x86/vm/methodHandles_x86.cpp | 4 +- hotspot/src/cpu/x86/vm/nativeInst_x86.cpp | 4 +- hotspot/src/cpu/x86/vm/vm_version_x86.cpp | 20 +++--- hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp | 6 +- hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp | 4 +- hotspot/src/os/bsd/vm/decoder_machO.cpp | 4 +- hotspot/src/os/bsd/vm/os_bsd.cpp | 11 +-- hotspot/src/os/bsd/vm/perfMemory_bsd.cpp | 4 +- hotspot/src/os/linux/vm/os_linux.cpp | 14 ++-- hotspot/src/os/linux/vm/perfMemory_linux.cpp | 2 +- hotspot/src/os/posix/vm/os_posix.cpp | 14 ++-- hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp | 4 +- .../src/os_cpu/linux_x86/vm/os_linux_x86.cpp | 4 +- hotspot/src/share/vm/adlc/formssel.cpp | 6 +- hotspot/src/share/vm/adlc/output_h.cpp | 34 ++++----- hotspot/src/share/vm/asm/codeBuffer.cpp | 10 +-- hotspot/src/share/vm/asm/codeBuffer.hpp | 4 +- hotspot/src/share/vm/asm/register.hpp | 46 +++++++----- hotspot/src/share/vm/c1/c1_CFGPrinter.cpp | 6 +- .../src/share/vm/c1/c1_InstructionPrinter.cpp | 16 ++--- hotspot/src/share/vm/c1/c1_LIR.cpp | 44 ++++++------ .../share/vm/c1/c1_RangeCheckElimination.cpp | 12 ++-- hotspot/src/share/vm/c1/c1_Runtime1.cpp | 14 ++-- hotspot/src/share/vm/c1/c1_ValueType.hpp | 4 +- hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp | 8 +-- hotspot/src/share/vm/ci/ciConstant.cpp | 4 +- hotspot/src/share/vm/ci/ciEnv.cpp | 7 +- hotspot/src/share/vm/ci/ciInstanceKlass.cpp | 10 +-- hotspot/src/share/vm/ci/ciMetadata.cpp | 4 +- hotspot/src/share/vm/ci/ciMethodData.cpp | 6 +- hotspot/src/share/vm/ci/ciObject.cpp | 6 +- hotspot/src/share/vm/ci/ciSignature.cpp | 4 +- hotspot/src/share/vm/ci/ciType.cpp | 4 +- .../src/share/vm/classfile/classFileError.cpp | 7 +- .../share/vm/classfile/classFileParser.hpp | 7 +- .../src/share/vm/classfile/classLoader.cpp | 6 +- .../share/vm/classfile/classLoaderData.cpp | 26 +++---- .../src/share/vm/classfile/defaultMethods.cpp | 12 ++-- hotspot/src/share/vm/classfile/dictionary.cpp | 1 + hotspot/src/share/vm/classfile/dictionary.hpp | 4 +- .../src/share/vm/classfile/javaClasses.cpp | 4 +- .../src/share/vm/classfile/symbolTable.cpp | 2 + .../share/vm/classfile/systemDictionary.cpp | 2 +- hotspot/src/share/vm/classfile/verifier.cpp | 17 +++-- hotspot/src/share/vm/classfile/verifier.hpp | 8 +-- hotspot/src/share/vm/classfile/vmSymbols.cpp | 4 +- hotspot/src/share/vm/code/codeBlob.cpp | 16 ++--- hotspot/src/share/vm/code/codeCache.cpp | 26 +++---- hotspot/src/share/vm/code/compiledIC.cpp | 24 +++---- .../src/share/vm/code/compressedStream.cpp | 5 +- hotspot/src/share/vm/code/debugInfo.cpp | 6 +- .../share/vm/code/exceptionHandlerTable.cpp | 4 +- hotspot/src/share/vm/code/icBuffer.cpp | 3 +- hotspot/src/share/vm/code/nmethod.cpp | 4 +- hotspot/src/share/vm/code/pcDesc.cpp | 4 +- hotspot/src/share/vm/code/relocInfo.cpp | 3 +- hotspot/src/share/vm/code/scopeDesc.cpp | 3 +- hotspot/src/share/vm/code/vtableStubs.cpp | 4 +- .../src/share/vm/compiler/compileBroker.cpp | 12 ++-- hotspot/src/share/vm/compiler/compileLog.cpp | 12 ++-- hotspot/src/share/vm/compiler/compileLog.hpp | 6 +- .../src/share/vm/compiler/compilerOracle.cpp | 6 +- .../src/share/vm/compiler/disassembler.cpp | 5 +- .../src/share/vm/compiler/methodLiveness.cpp | 4 +- hotspot/src/share/vm/compiler/oopMap.cpp | 10 +-- .../concurrentMarkSweep/adaptiveFreeList.cpp | 4 +- .../compactibleFreeListSpace.cpp | 18 ++--- .../compactibleFreeListSpace.hpp | 4 +- .../concurrentMarkSweepGeneration.cpp | 14 ++-- .../concurrentMarkSweepThread.cpp | 4 +- .../concurrentMarkSweepThread.hpp | 6 +- .../concurrentMarkSweep/freeChunk.cpp | 4 +- .../concurrentMarkSweep/promotionInfo.cpp | 4 +- .../concurrentMarkSweep/vmCMSOperations.cpp | 3 +- .../gc_implementation/g1/concurrentMark.cpp | 72 +++++++++---------- .../g1/concurrentMark.inline.hpp | 14 ++-- .../vm/gc_implementation/g1/g1AllocRegion.cpp | 4 +- .../vm/gc_implementation/g1/g1AllocRegion.hpp | 4 +- .../vm/gc_implementation/g1/g1BiasedArray.cpp | 4 +- .../vm/gc_implementation/g1/g1BiasedArray.hpp | 8 +-- .../g1/g1BlockOffsetTable.cpp | 4 +- .../g1/g1BlockOffsetTable.hpp | 4 +- .../g1/g1BlockOffsetTable.inline.hpp | 6 +- .../vm/gc_implementation/g1/g1CardCounts.cpp | 4 +- .../vm/gc_implementation/g1/g1CardCounts.hpp | 6 +- .../g1/g1CodeCacheRemSet.cpp | 2 + .../gc_implementation/g1/g1CollectedHeap.cpp | 11 ++- .../g1/g1CollectedHeap.inline.hpp | 4 +- .../g1/g1CollectorPolicy.cpp | 17 +++-- .../gc_implementation/g1/g1GCPhaseTimes.cpp | 11 +-- .../vm/gc_implementation/g1/g1HRPrinter.cpp | 4 +- .../g1/g1OopClosures.inline.hpp | 4 +- .../vm/gc_implementation/g1/g1RemSet.cpp | 4 +- .../vm/gc_implementation/g1/heapRegion.cpp | 6 +- .../vm/gc_implementation/g1/heapRegion.hpp | 6 +- .../gc_implementation/g1/heapRegionRemSet.cpp | 4 +- .../vm/gc_implementation/g1/heapRegionSeq.cpp | 4 +- .../g1/heapRegionSeq.inline.hpp | 6 +- .../vm/gc_implementation/g1/heapRegionSet.cpp | 2 + .../vm/gc_implementation/g1/heapRegionSet.hpp | 2 +- .../vm/gc_implementation/g1/satbQueue.cpp | 4 +- .../vm/gc_implementation/g1/survRateGroup.cpp | 6 +- .../parNew/asParNewGeneration.cpp | 38 +++++----- .../parNew/parCardTableModRefBS.cpp | 4 +- .../parNew/parNewGeneration.cpp | 4 +- .../parNew/parOopClosures.inline.hpp | 8 +-- .../parallelScavenge/asPSYoungGen.cpp | 38 +++++----- .../parallelScavenge/cardTableExtension.cpp | 18 ++--- .../parallelScavenge/gcTaskManager.cpp | 4 +- .../parallelScavenge/gcTaskThread.cpp | 4 +- .../parallelScavenge/parMarkBitMap.hpp | 8 +-- .../parallelScavenge/parallelScavengeHeap.cpp | 4 +- .../parallelScavengeHeap.inline.hpp | 4 +- .../parallelScavenge/pcTasks.cpp | 4 +- .../parallelScavenge/psAdaptiveSizePolicy.cpp | 6 +- .../parallelScavenge/psMarkSweep.cpp | 4 +- .../parallelScavenge/psOldGen.cpp | 4 +- .../parallelScavenge/psParallelCompact.cpp | 4 +- .../parallelScavenge/psPromotionManager.cpp | 6 +- .../psPromotionManager.inline.hpp | 4 +- .../parallelScavenge/psScavenge.cpp | 3 +- .../parallelScavenge/psScavenge.inline.hpp | 6 +- .../parallelScavenge/psVirtualspace.cpp | 4 +- .../parallelScavenge/psYoungGen.cpp | 4 +- .../vm/gc_implementation/shared/ageTable.cpp | 8 +-- .../shared/allocationStats.hpp | 4 +- .../shared/immutableSpace.cpp | 4 +- .../vm/gc_implementation/shared/markSweep.cpp | 4 +- .../shared/mutableNUMASpace.cpp | 4 +- .../gc_implementation/shared/mutableSpace.cpp | 4 +- .../shared/parGCAllocBuffer.cpp | 4 +- .../shared/spaceDecorator.cpp | 4 +- .../share/vm/gc_interface/collectedHeap.cpp | 4 +- .../share/vm/interpreter/bytecodeTracer.cpp | 19 +++-- .../src/share/vm/interpreter/interpreter.cpp | 4 +- .../vm/interpreter/interpreterRuntime.cpp | 4 +- .../src/share/vm/interpreter/linkResolver.cpp | 2 +- .../src/share/vm/interpreter/oopMapCache.cpp | 4 +- .../vm/interpreter/templateInterpreter.cpp | 4 +- hotspot/src/share/vm/libadt/dict.cpp | 4 +- hotspot/src/share/vm/libadt/set.cpp | 4 +- hotspot/src/share/vm/memory/allocation.cpp | 20 +++--- .../share/vm/memory/binaryTreeDictionary.cpp | 2 +- .../src/share/vm/memory/blockOffsetTable.cpp | 22 +++--- .../src/share/vm/memory/cardTableModRefBS.cpp | 32 ++++----- .../src/share/vm/memory/cardTableModRefBS.hpp | 8 +-- hotspot/src/share/vm/memory/cardTableRS.cpp | 14 ++-- .../src/share/vm/memory/collectorPolicy.cpp | 6 +- .../src/share/vm/memory/defNewGeneration.cpp | 4 +- hotspot/src/share/vm/memory/filemap.cpp | 3 +- hotspot/src/share/vm/memory/gcLocker.cpp | 4 +- .../src/share/vm/memory/genCollectedHeap.cpp | 8 +-- .../src/share/vm/memory/genOopClosures.hpp | 4 +- hotspot/src/share/vm/memory/generation.cpp | 4 +- hotspot/src/share/vm/memory/generation.hpp | 4 +- .../src/share/vm/memory/heapInspection.cpp | 14 +++- .../src/share/vm/memory/heapInspection.hpp | 6 +- hotspot/src/share/vm/memory/metachunk.cpp | 4 +- hotspot/src/share/vm/memory/metaspace.cpp | 8 ++- .../src/share/vm/memory/metaspaceShared.cpp | 29 ++++---- .../share/vm/memory/referenceProcessor.cpp | 4 +- hotspot/src/share/vm/memory/sharedHeap.cpp | 4 +- hotspot/src/share/vm/memory/space.cpp | 4 +- .../vm/memory/threadLocalAllocBuffer.cpp | 4 +- .../memory/threadLocalAllocBuffer.inline.hpp | 4 +- hotspot/src/share/vm/memory/universe.cpp | 6 +- hotspot/src/share/vm/oops/annotations.cpp | 4 +- hotspot/src/share/vm/oops/constMethod.cpp | 6 +- hotspot/src/share/vm/oops/constantPool.cpp | 4 +- hotspot/src/share/vm/oops/cpCache.cpp | 5 +- hotspot/src/share/vm/oops/generateOopMap.hpp | 8 +-- hotspot/src/share/vm/oops/instanceKlass.cpp | 4 +- .../src/share/vm/oops/instanceRefKlass.cpp | 4 +- hotspot/src/share/vm/oops/klass.inline.hpp | 4 +- hotspot/src/share/vm/oops/klassVtable.cpp | 2 + hotspot/src/share/vm/oops/markOop.cpp | 6 +- hotspot/src/share/vm/oops/method.cpp | 7 +- hotspot/src/share/vm/oops/methodData.cpp | 8 ++- hotspot/src/share/vm/oops/oop.cpp | 2 + hotspot/src/share/vm/oops/oop.inline.hpp | 4 +- hotspot/src/share/vm/opto/block.cpp | 4 +- hotspot/src/share/vm/opto/callnode.cpp | 24 +++---- hotspot/src/share/vm/opto/chaitin.cpp | 22 +++--- hotspot/src/share/vm/opto/compile.cpp | 15 ++-- hotspot/src/share/vm/opto/compile.hpp | 4 +- hotspot/src/share/vm/opto/doCall.cpp | 4 +- hotspot/src/share/vm/opto/gcm.cpp | 4 +- .../src/share/vm/opto/idealGraphPrinter.cpp | 14 ++-- hotspot/src/share/vm/opto/ifg.cpp | 4 +- hotspot/src/share/vm/opto/loopPredicate.cpp | 4 +- hotspot/src/share/vm/opto/loopnode.cpp | 4 +- hotspot/src/share/vm/opto/matcher.cpp | 4 +- hotspot/src/share/vm/opto/memnode.cpp | 4 +- hotspot/src/share/vm/opto/node.cpp | 4 +- hotspot/src/share/vm/opto/parse1.cpp | 6 +- hotspot/src/share/vm/opto/parse2.cpp | 6 +- hotspot/src/share/vm/opto/phaseX.cpp | 6 +- hotspot/src/share/vm/opto/regmask.cpp | 4 +- hotspot/src/share/vm/opto/runtime.cpp | 2 +- hotspot/src/share/vm/opto/subnode.cpp | 4 +- hotspot/src/share/vm/opto/type.cpp | 6 +- hotspot/src/share/vm/prims/jni.cpp | 2 +- hotspot/src/share/vm/prims/jniCheck.cpp | 8 +-- hotspot/src/share/vm/prims/jvm.cpp | 17 ++--- hotspot/src/share/vm/prims/jvmtiEnter.xsl | 5 +- .../share/vm/prims/jvmtiEnvThreadState.cpp | 2 +- .../share/vm/prims/jvmtiEventController.cpp | 2 + hotspot/src/share/vm/prims/jvmtiExport.cpp | 2 + hotspot/src/share/vm/prims/jvmtiImpl.cpp | 4 +- .../share/vm/prims/jvmtiRedefineClasses.cpp | 6 +- hotspot/src/share/vm/prims/methodHandles.cpp | 4 +- .../src/share/vm/prims/privilegedStack.cpp | 3 +- hotspot/src/share/vm/prims/unsafe.cpp | 4 +- hotspot/src/share/vm/prims/whitebox.cpp | 2 + hotspot/src/share/vm/runtime/arguments.cpp | 18 ++--- hotspot/src/share/vm/runtime/arguments.hpp | 4 +- .../src/share/vm/runtime/biasedLocking.cpp | 14 ++-- .../share/vm/runtime/compilationPolicy.cpp | 14 ++-- .../src/share/vm/runtime/deoptimization.cpp | 4 +- hotspot/src/share/vm/runtime/fprofiler.cpp | 6 +- hotspot/src/share/vm/runtime/frame.cpp | 4 +- hotspot/src/share/vm/runtime/globals.cpp | 10 ++- hotspot/src/share/vm/runtime/handles.cpp | 4 +- .../src/share/vm/runtime/interfaceSupport.cpp | 3 +- hotspot/src/share/vm/runtime/java.cpp | 7 +- hotspot/src/share/vm/runtime/jniHandles.cpp | 1 + hotspot/src/share/vm/runtime/mutex.cpp | 4 +- hotspot/src/share/vm/runtime/os.cpp | 8 ++- hotspot/src/share/vm/runtime/osThread.cpp | 3 +- hotspot/src/share/vm/runtime/perfData.cpp | 4 +- hotspot/src/share/vm/runtime/perfMemory.cpp | 2 + hotspot/src/share/vm/runtime/safepoint.cpp | 10 +-- hotspot/src/share/vm/runtime/safepoint.hpp | 6 +- .../src/share/vm/runtime/sharedRuntime.cpp | 2 + hotspot/src/share/vm/runtime/signature.cpp | 3 +- hotspot/src/share/vm/runtime/stackValue.cpp | 4 +- .../share/vm/runtime/stackValueCollection.cpp | 4 +- .../share/vm/runtime/stubCodeGenerator.cpp | 8 +-- hotspot/src/share/vm/runtime/sweeper.cpp | 8 ++- hotspot/src/share/vm/runtime/sweeper.hpp | 4 +- hotspot/src/share/vm/runtime/synchronizer.cpp | 2 + hotspot/src/share/vm/runtime/thread.cpp | 4 +- hotspot/src/share/vm/runtime/thread.hpp | 2 +- hotspot/src/share/vm/runtime/timer.cpp | 4 +- .../src/share/vm/runtime/unhandledOops.cpp | 4 +- hotspot/src/share/vm/runtime/vframe.cpp | 4 +- hotspot/src/share/vm/runtime/vframe.hpp | 4 +- hotspot/src/share/vm/runtime/vframeArray.cpp | 3 +- hotspot/src/share/vm/runtime/virtualspace.cpp | 3 +- hotspot/src/share/vm/runtime/vmThread.cpp | 4 +- .../src/share/vm/runtime/vm_operations.cpp | 4 +- hotspot/src/share/vm/runtime/vm_version.cpp | 4 +- .../src/share/vm/services/attachListener.cpp | 12 ++-- .../share/vm/services/classLoadingService.cpp | 4 +- .../share/vm/services/diagnosticCommand.cpp | 6 +- .../share/vm/services/diagnosticFramework.cpp | 8 +-- hotspot/src/share/vm/services/heapDumper.cpp | 6 +- .../share/vm/services/lowMemoryDetector.cpp | 4 +- hotspot/src/share/vm/services/management.cpp | 8 ++- hotspot/src/share/vm/services/memReporter.cpp | 4 +- hotspot/src/share/vm/services/memSnapshot.cpp | 6 +- .../src/share/vm/services/memTrackWorker.cpp | 4 +- hotspot/src/share/vm/services/nmtDCmd.cpp | 4 +- .../src/share/vm/services/threadService.cpp | 4 +- hotspot/src/share/vm/trace/traceStream.hpp | 4 +- hotspot/src/share/vm/utilities/array.hpp | 2 +- hotspot/src/share/vm/utilities/bitMap.cpp | 6 +- .../src/share/vm/utilities/constantTag.cpp | 2 +- hotspot/src/share/vm/utilities/debug.cpp | 5 +- hotspot/src/share/vm/utilities/debug.hpp | 12 ++-- hotspot/src/share/vm/utilities/events.cpp | 6 +- hotspot/src/share/vm/utilities/events.hpp | 17 +++-- hotspot/src/share/vm/utilities/exceptions.cpp | 4 +- hotspot/src/share/vm/utilities/exceptions.hpp | 2 +- .../share/vm/utilities/globalDefinitions.hpp | 37 +++++++++- .../vm/utilities/globalDefinitions_gcc.hpp | 31 +++++++- hotspot/src/share/vm/utilities/numberSeq.cpp | 4 +- hotspot/src/share/vm/utilities/ostream.cpp | 16 ++--- hotspot/src/share/vm/utilities/ostream.hpp | 20 +++--- hotspot/src/share/vm/utilities/quickSort.cpp | 4 +- hotspot/src/share/vm/utilities/taskqueue.cpp | 4 +- hotspot/src/share/vm/utilities/vmError.cpp | 12 ++-- hotspot/src/share/vm/utilities/workgroup.cpp | 4 +- hotspot/src/share/vm/utilities/xmlstream.cpp | 7 +- hotspot/src/share/vm/utilities/xmlstream.hpp | 32 ++++----- 293 files changed, 1285 insertions(+), 913 deletions(-) diff --git a/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp index 0a6261a21e8..32fb22ce229 100644 --- a/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright 2012, 2014 SAP AG. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -149,7 +149,7 @@ void VM_Version::initialize() { } void VM_Version::print_features() { - tty->print_cr("Version: %s cache_line_size = %d", cpu_features(), get_cache_line_size()); + tty->print_cr("Version: %s cache_line_size = %d", cpu_features(), (int) get_cache_line_size()); } #ifdef COMPILER2 diff --git a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp index 129bcd8b6c3..1943705a558 100644 --- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp @@ -318,22 +318,22 @@ void VM_Version::initialize() { tty->print("BIS"); } if (AllocatePrefetchLines > 1) { - tty->print_cr(" at distance %d, %d lines of %d bytes", AllocatePrefetchDistance, AllocatePrefetchLines, AllocatePrefetchStepSize); + tty->print_cr(" at distance %d, %d lines of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchLines, (int) AllocatePrefetchStepSize); } else { - tty->print_cr(" at distance %d, one line of %d bytes", AllocatePrefetchDistance, AllocatePrefetchStepSize); + tty->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize); } } if (PrefetchCopyIntervalInBytes > 0) { - tty->print_cr("PrefetchCopyIntervalInBytes %d", PrefetchCopyIntervalInBytes); + tty->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes); } if (PrefetchScanIntervalInBytes > 0) { - tty->print_cr("PrefetchScanIntervalInBytes %d", PrefetchScanIntervalInBytes); + tty->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes); } if (PrefetchFieldsAhead > 0) { - tty->print_cr("PrefetchFieldsAhead %d", PrefetchFieldsAhead); + tty->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead); } if (ContendedPaddingWidth > 0) { - tty->print_cr("ContendedPaddingWidth %d", ContendedPaddingWidth); + tty->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth); } } #endif // PRODUCT diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.cpp b/hotspot/src/cpu/x86/vm/assembler_x86.cpp index a89e50b650e..64b8ce731a5 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -522,11 +522,11 @@ address Assembler::locate_operand(address inst, WhichOperand which) { // these asserts are somewhat nonsensical #ifndef _LP64 assert(which == imm_operand || which == disp32_operand, - err_msg("which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, ip)); + err_msg("which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, p2i(ip))); #else assert((which == call32_operand || which == imm_operand) && is_64bit || which == narrow_oop_operand && !is_64bit, - err_msg("which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, ip)); + err_msg("which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, p2i(ip))); #endif // _LP64 return ip; diff --git a/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp index 12b01bfab42..ba5dc48623d 100644 --- a/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -95,7 +95,7 @@ void LinearScan::allocate_fpu_stack() { #ifndef PRODUCT if (TraceFPURegisterUsage) { - tty->print("FPU regs for block %d, LIR instr %d): ", b->block_id(), id); regs.print_on(tty); tty->print_cr(""); + tty->print("FPU regs for block %d, LIR instr %d): ", b->block_id(), id); regs.print_on(tty); tty->cr(); } #endif } diff --git a/hotspot/src/cpu/x86/vm/compiledIC_x86.cpp b/hotspot/src/cpu/x86/vm/compiledIC_x86.cpp index 957695fdc32..26d56b86ab3 100644 --- a/hotspot/src/cpu/x86/vm/compiledIC_x86.cpp +++ b/hotspot/src/cpu/x86/vm/compiledIC_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -122,7 +122,7 @@ void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry) if (TraceICs) { ResourceMark rm; tty->print_cr("CompiledStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s", - instruction_address(), + p2i(instruction_address()), callee->name_and_sig_as_C_string()); } diff --git a/hotspot/src/cpu/x86/vm/frame_x86.cpp b/hotspot/src/cpu/x86/vm/frame_x86.cpp index deeb48a44bb..7a31e0800c4 100644 --- a/hotspot/src/cpu/x86/vm/frame_x86.cpp +++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,6 +48,7 @@ void RegisterMap::check_location_valid() { } #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC // Profiling/safepoint support diff --git a/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp b/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp index 02ee74506bb..e9c1ef782d8 100644 --- a/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,6 +51,7 @@ #define __ _masm-> +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC #ifdef _WIN64 address AbstractInterpreterGenerator::generate_slow_signature_handler() { diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp index 3a14d975927..5b324124138 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,6 +55,7 @@ #define BIND(label) bind(label); BLOCK_COMMENT(#label ":") +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC #ifdef ASSERT bool AbstractAssembler::pd_check_instruction_mark() { return true; } diff --git a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp index 3c12385fdbb..42c690f5e07 100644 --- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp +++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ #include "memory/allocation.inline.hpp" #include "prims/methodHandles.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #define __ _masm-> #ifdef PRODUCT diff --git a/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp b/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp index dccd7e0b7cd..cc1573e720a 100644 --- a/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp +++ b/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ #include "c1/c1_Runtime1.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + void NativeInstruction::wrote(int offset) { ICache::invalidate_word(addr_at(offset)); } diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp index 1fc0e614b6d..e09dba38b0d 100644 --- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp +++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -925,16 +925,16 @@ void VM_Version::get_processor_features() { if (PrintMiscellaneous && Verbose) { tty->print_cr("Logical CPUs per core: %u", logical_processors_per_package()); - tty->print("UseSSE=%d",UseSSE); + tty->print("UseSSE=%d", (int) UseSSE); if (UseAVX > 0) { - tty->print(" UseAVX=%d",UseAVX); + tty->print(" UseAVX=%d", (int) UseAVX); } if (UseAES) { tty->print(" UseAES=1"); } #ifdef COMPILER2 if (MaxVectorSize > 0) { - tty->print(" MaxVectorSize=%d", MaxVectorSize); + tty->print(" MaxVectorSize=%d", (int) MaxVectorSize); } #endif tty->cr(); @@ -957,23 +957,23 @@ void VM_Version::get_processor_features() { } } if (AllocatePrefetchLines > 1) { - tty->print_cr(" at distance %d, %d lines of %d bytes", AllocatePrefetchDistance, AllocatePrefetchLines, AllocatePrefetchStepSize); + tty->print_cr(" at distance %d, %d lines of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchLines, (int) AllocatePrefetchStepSize); } else { - tty->print_cr(" at distance %d, one line of %d bytes", AllocatePrefetchDistance, AllocatePrefetchStepSize); + tty->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize); } } if (PrefetchCopyIntervalInBytes > 0) { - tty->print_cr("PrefetchCopyIntervalInBytes %d", PrefetchCopyIntervalInBytes); + tty->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes); } if (PrefetchScanIntervalInBytes > 0) { - tty->print_cr("PrefetchScanIntervalInBytes %d", PrefetchScanIntervalInBytes); + tty->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes); } if (PrefetchFieldsAhead > 0) { - tty->print_cr("PrefetchFieldsAhead %d", PrefetchFieldsAhead); + tty->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead); } if (ContendedPaddingWidth > 0) { - tty->print_cr("ContendedPaddingWidth %d", ContendedPaddingWidth); + tty->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth); } } #endif // !PRODUCT diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp index 73c2f3ca20d..8d0353eff64 100644 --- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,7 +118,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { if (PrintMiscellaneous && (WizardMode || Verbose)) { tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d", - vtable_index, s->entry_point(), + vtable_index, p2i(s->entry_point()), (int)(s->code_end() - s->entry_point()), (int)(s->code_end() - __ pc())); } @@ -199,7 +199,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) { if (PrintMiscellaneous && (WizardMode || Verbose)) { tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d", - itable_index, s->entry_point(), + itable_index, p2i(s->entry_point()), (int)(s->code_end() - s->entry_point()), (int)(s->code_end() - __ pc())); } diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp index 089b368d015..b6dd1b33645 100644 --- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ #include "opto/runtime.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // machine-dependent part of VtableStubs: create VtableStub of correct size and // initialize its code diff --git a/hotspot/src/os/bsd/vm/decoder_machO.cpp b/hotspot/src/os/bsd/vm/decoder_machO.cpp index b475f23ff94..6ef6314a1d1 100644 --- a/hotspot/src/os/bsd/vm/decoder_machO.cpp +++ b/hotspot/src/os/bsd/vm/decoder_machO.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ bool MachODecoder::decode(address addr, char *buf, struct symtab_command * symt = (struct symtab_command *) mach_find_command((struct mach_header_64 *)mach_base, LC_SYMTAB); if (symt == NULL) { - DEBUG_ONLY(tty->print_cr("no symtab in mach file at 0x%lx", mach_base)); + DEBUG_ONLY(tty->print_cr("no symtab in mach file at 0x%lx", p2i(mach_base))); return false; } uint32_t off = symt->symoff; /* symbol table offset (within this mach file) */ diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp index 9d3ec5ffd2d..c8313235d0c 100644 --- a/hotspot/src/os/bsd/vm/os_bsd.cpp +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp @@ -124,6 +124,9 @@ #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) #define LARGEPAGES_BIT (1 << 6) + +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + //////////////////////////////////////////////////////////////////////////////// // global variables julong os::Bsd::_physical_memory = 0; @@ -2394,7 +2397,6 @@ char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, (!FLAG_IS_DEFAULT(UseLargePages) || !FLAG_IS_DEFAULT(LargePageSizeInBytes) ); - char msg[128]; // Create a large shared memory region to attach to based on size. // Currently, size is the total size of the heap @@ -2415,8 +2417,7 @@ char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, // coalesce into large pages. Try to reserve large pages when // the system is still "fresh". if (warn_on_failure) { - jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno); - warning(msg); + warning("Failed to reserve shared memory (errno = %d).", errno); } return NULL; } @@ -2433,8 +2434,7 @@ char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, if ((intptr_t)addr == -1) { if (warn_on_failure) { - jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err); - warning(msg); + warning("Failed to attach shared memory (errno = %d).", err); } return NULL; } @@ -3810,6 +3810,7 @@ bool os::check_heap(bool force) { return true; } +ATTRIBUTE_PRINTF(3, 0) int local_vsnprintf(char* buf, size_t count, const char* format, va_list args) { return ::vsnprintf(buf, count, format, args); } diff --git a/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp b/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp index f59b763b325..e812a76f51b 100644 --- a/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp +++ b/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -925,7 +925,7 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor if (PerfTraceMemOps) { tty->print("mapped " SIZE_FORMAT " bytes for vmid %d at " - INTPTR_FORMAT "\n", size, vmid, (void*)mapAddress); + INTPTR_FORMAT "\n", size, vmid, p2i((void*)mapAddress)); } } diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index ce771028a3b..7941edf59ce 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -102,6 +102,8 @@ # include <inttypes.h> # include <sys/ioctl.h> +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling // getrusage() is prepared to handle the associated failure. #ifndef RUSAGE_THREAD @@ -2138,7 +2140,7 @@ void os::print_os_info(outputStream* st) { // Print warning if unsafe chroot environment detected if (unsafe_chroot_detected) { st->print("WARNING!! "); - st->print_cr(unstable_chroot_error); + st->print_cr("%s", unstable_chroot_error); } os::Linux::print_libversion_info(st); @@ -2199,8 +2201,8 @@ void os::Linux::print_distro_info(outputStream* st) { void os::Linux::print_libversion_info(outputStream* st) { // libc, pthread st->print("libc:"); - st->print(os::Linux::glibc_version()); st->print(" "); - st->print(os::Linux::libpthread_version()); st->print(" "); + st->print("%s ", os::Linux::glibc_version()); + st->print("%s ", os::Linux::libpthread_version()); if (os::Linux::is_LinuxThreads()) { st->print("(%s stack)", os::Linux::is_floating_stack() ? "floating" : "fixed"); } @@ -3417,7 +3419,7 @@ char* os::Linux::reserve_memory_special_shm(size_t bytes, size_t alignment, char // the system is still "fresh". if (warn_on_failure) { jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno); - warning(msg); + warning("%s", msg); } return NULL; } @@ -3435,7 +3437,7 @@ char* os::Linux::reserve_memory_special_shm(size_t bytes, size_t alignment, char if ((intptr_t)addr == -1) { if (warn_on_failure) { jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err); - warning(msg); + warning("%s", msg); } return NULL; } @@ -3455,7 +3457,7 @@ static void warn_on_large_pages_failure(char* req_addr, size_t bytes, int error) char msg[128]; jio_snprintf(msg, sizeof(msg), "Failed to reserve large pages memory req_addr: " PTR_FORMAT " bytes: " SIZE_FORMAT " (errno = %d).", req_addr, bytes, error); - warning(msg); + warning("%s", msg); } } diff --git a/hotspot/src/os/linux/vm/perfMemory_linux.cpp b/hotspot/src/os/linux/vm/perfMemory_linux.cpp index d95d33107e6..9708734295f 100644 --- a/hotspot/src/os/linux/vm/perfMemory_linux.cpp +++ b/hotspot/src/os/linux/vm/perfMemory_linux.cpp @@ -931,7 +931,7 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor if (PerfTraceMemOps) { tty->print("mapped " SIZE_FORMAT " bytes for vmid %d at " - INTPTR_FORMAT "\n", size, vmid, (void*)mapAddress); + INTPTR_FORMAT "\n", size, vmid, p2i((void*)mapAddress)); } } diff --git a/hotspot/src/os/posix/vm/os_posix.cpp b/hotspot/src/os/posix/vm/os_posix.cpp index 41e9b6ccfe9..d17bc15cbae 100644 --- a/hotspot/src/os/posix/vm/os_posix.cpp +++ b/hotspot/src/os/posix/vm/os_posix.cpp @@ -36,6 +36,8 @@ #include <pthread.h> #include <signal.h> +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Todo: provide a os::get_max_process_id() or similar. Number of processes // may have been configured, can be read more accurately from proc fs etc. #ifndef MAX_PID @@ -192,10 +194,10 @@ void os::Posix::print_uname_info(outputStream* st) { st->print("uname:"); struct utsname name; uname(&name); - st->print(name.sysname); st->print(" "); - st->print(name.release); st->print(" "); - st->print(name.version); st->print(" "); - st->print(name.machine); + st->print("%s ", name.sysname); + st->print("%s ", name.release); + st->print("%s ", name.version); + st->print("%s", name.machine); st->cr(); } @@ -682,7 +684,7 @@ const char* os::Posix::describe_signal_set_short(const sigset_t* set, char* buff void os::Posix::print_signal_set_short(outputStream* st, const sigset_t* set) { char buf[NUM_IMPORTANT_SIGS + 1]; os::Posix::describe_signal_set_short(set, buf, sizeof(buf)); - st->print(buf); + st->print("%s", buf); } // Writes one-line description of a combination of sigaction.sa_flags into a user @@ -742,7 +744,7 @@ const char* os::Posix::describe_sa_flags(int flags, char* buffer, size_t size) { void os::Posix::print_sa_flags(outputStream* st, int flags) { char buffer[0x100]; os::Posix::describe_sa_flags(flags, buffer, sizeof(buffer)); - st->print(buffer); + st->print("%s", buffer); } // Helper function for os::Posix::print_siginfo_...(): diff --git a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp index 5718a791959..50051d7c699 100644 --- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp +++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -276,6 +276,8 @@ # endif #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + address os::current_stack_pointer() { #if defined(__clang__) || defined(__llvm__) register void *esp; diff --git a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp index d269d38ac59..3c8e18eef48 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -89,6 +89,8 @@ #define SPELL_REG_FP "ebp" #endif // AMD64 +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + address os::current_stack_pointer() { #ifdef SPARC_WORKS register void *esp; diff --git a/hotspot/src/share/vm/adlc/formssel.cpp b/hotspot/src/share/vm/adlc/formssel.cpp index df58c5746de..ffb13e759a4 100644 --- a/hotspot/src/share/vm/adlc/formssel.cpp +++ b/hotspot/src/share/vm/adlc/formssel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1322,7 +1322,7 @@ void InstructForm::rep_var_format(FILE *fp, const char *rep_var) { OperandForm* oper = form->is_operand(); if (oper != NULL && oper->is_bound_register()) { const RegDef* first = oper->get_RegClass()->find_first_elem(); - fprintf(fp, " st->print(\"%s\");\n", first->_regname); + fprintf(fp, " st->print_raw(\"%s\");\n", first->_regname); } else { globalAD->syntax_err(_linenum, "In %s can't find format for %s %s", _ident, opc->_ident, rep_var); } @@ -2530,7 +2530,7 @@ void OperandForm::format_constant(FILE *fp, uint const_index, uint const_type) { case Form::idealP: fprintf(fp," if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break; case Form::idealNKlass: case Form::idealN: fprintf(fp," if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break; - case Form::idealL: fprintf(fp," st->print(\"#%%lld\", _c%d);\n", const_index); break; + case Form::idealL: fprintf(fp," st->print(\"#\" INT64_FORMAT, (int64_t)_c%d);\n", const_index); break; case Form::idealF: fprintf(fp," st->print(\"#%%f\", _c%d);\n", const_index); break; case Form::idealD: fprintf(fp," st->print(\"#%%f\", _c%d);\n", const_index); break; default: diff --git a/hotspot/src/share/vm/adlc/output_h.cpp b/hotspot/src/share/vm/adlc/output_h.cpp index 2279e75ecc5..4a5b5467687 100644 --- a/hotspot/src/share/vm/adlc/output_h.cpp +++ b/hotspot/src/share/vm/adlc/output_h.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -386,14 +386,14 @@ static void defineConstructor(FILE *fp, const char *name, uint num_consts, static void defineCCodeDump(OperandForm* oper, FILE *fp, int i) { assert(oper != NULL, "what"); CondInterface* cond = oper->_interface->is_CondInterface(); - fprintf(fp, " if( _c%d == BoolTest::eq ) st->print(\"%s\");\n",i,cond->_equal_format); - fprintf(fp, " else if( _c%d == BoolTest::ne ) st->print(\"%s\");\n",i,cond->_not_equal_format); - fprintf(fp, " else if( _c%d == BoolTest::le ) st->print(\"%s\");\n",i,cond->_less_equal_format); - fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format); - fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format); - fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format); - fprintf(fp, " else if( _c%d == BoolTest::overflow ) st->print(\"%s\");\n",i,cond->_overflow_format); - fprintf(fp, " else if( _c%d == BoolTest::no_overflow ) st->print(\"%s\");\n",i,cond->_no_overflow_format); + fprintf(fp, " if( _c%d == BoolTest::eq ) st->print_raw(\"%s\");\n",i,cond->_equal_format); + fprintf(fp, " else if( _c%d == BoolTest::ne ) st->print_raw(\"%s\");\n",i,cond->_not_equal_format); + fprintf(fp, " else if( _c%d == BoolTest::le ) st->print_raw(\"%s\");\n",i,cond->_less_equal_format); + fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print_raw(\"%s\");\n",i,cond->_greater_equal_format); + fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print_raw(\"%s\");\n",i,cond->_less_format); + fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print_raw(\"%s\");\n",i,cond->_greater_format); + fprintf(fp, " else if( _c%d == BoolTest::overflow ) st->print_raw(\"%s\");\n",i,cond->_overflow_format); + fprintf(fp, " else if( _c%d == BoolTest::no_overflow ) st->print_raw(\"%s\");\n",i,cond->_no_overflow_format); } // Output code that dumps constant values, increment "i" if type is constant @@ -416,8 +416,8 @@ static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i, Operand ++i; } else if (!strcmp(ideal_type, "ConL")) { - fprintf(fp," st->print(\"#\" INT64_FORMAT, _c%d);\n", i); - fprintf(fp," st->print(\"/\" PTR64_FORMAT, _c%d);\n", i); + fprintf(fp," st->print(\"#\" INT64_FORMAT, (int64_t)_c%d);\n", i); + fprintf(fp," st->print(\"/\" PTR64_FORMAT, (uint64_t)_c%d);\n", i); ++i; } else if (!strcmp(ideal_type, "ConF")) { @@ -429,7 +429,7 @@ static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i, Operand else if (!strcmp(ideal_type, "ConD")) { fprintf(fp," st->print(\"#%%f\", _c%d);\n", i); fprintf(fp," jlong _c%dl = JavaValue(_c%d).get_jlong();\n", i, i); - fprintf(fp," st->print(\"/\" PTR64_FORMAT, _c%dl);\n", i); + fprintf(fp," st->print(\"/\" PTR64_FORMAT, (uint64_t)_c%dl);\n", i); ++i; } else if (!strcmp(ideal_type, "Bool")) { @@ -471,7 +471,7 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_ if ( string != NameList::_signal ) { // Normal string // Pass through to st->print - fprintf(fp," st->print(\"%s\");\n", string); + fprintf(fp," st->print_raw(\"%s\");\n", string); } else { // Replacement variable const char *rep_var = oper._format->_rep_vars.iter(); @@ -542,7 +542,7 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_ if ( string != NameList::_signal ) { // Normal string // Pass through to st->print - fprintf(fp," st->print(\"%s\");\n", string); + fprintf(fp," st->print_raw(\"%s\");\n", string); } else { // Replacement variable const char *rep_var = oper._format->_rep_vars.iter(); @@ -669,7 +669,7 @@ void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &inst, bool for_c } else if( string == NameList::_signal2 ) // Raw program text fputs(inst._format->_strings.iter(), fp); else - fprintf(fp,"st->print(\"%s\");\n", string); + fprintf(fp,"st->print_raw(\"%s\");\n", string); } // Done with all format strings } // Done generating the user-defined portion of the format @@ -696,13 +696,13 @@ void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &inst, bool for_c default: assert(0,"ShouldNotReachHere"); } - fprintf(fp, " st->print_cr(\"\");\n" ); + fprintf(fp, " st->cr();\n" ); fprintf(fp, " if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\" No JVM State Info\");\n" ); fprintf(fp, " st->print(\" # \");\n" ); fprintf(fp, " if( _jvms && _oop_map ) _oop_map->print_on(st);\n"); } else if(inst.is_ideal_safepoint()) { - fprintf(fp, " st->print(\"\");\n" ); + fprintf(fp, " st->print_raw(\"\");\n" ); fprintf(fp, " if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\" No JVM State Info\");\n" ); fprintf(fp, " st->print(\" # \");\n" ); fprintf(fp, " if( _jvms && _oop_map ) _oop_map->print_on(st);\n"); diff --git a/hotspot/src/share/vm/asm/codeBuffer.cpp b/hotspot/src/share/vm/asm/codeBuffer.cpp index 0c10e1fdb9e..60d405b35f4 100644 --- a/hotspot/src/share/vm/asm/codeBuffer.cpp +++ b/hotspot/src/share/vm/asm/codeBuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -988,7 +988,7 @@ void CodeSection::dump() { for (csize_t step; ptr < end(); ptr += step) { step = end() - ptr; if (step > jintSize * 4) step = jintSize * 4; - tty->print(PTR_FORMAT ": ", ptr); + tty->print(INTPTR_FORMAT ": ", p2i(ptr)); while (step > 0) { tty->print(" " PTR32_FORMAT, *(jint*)ptr); ptr += jintSize; @@ -1098,7 +1098,7 @@ void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) con while (c && c->offset() == offset) { stream->bol(); stream->print(" ;; "); - stream->print_cr(c->string()); + stream->print_cr("%s", c->string()); c = c->next_comment(); } } @@ -1154,10 +1154,10 @@ void CodeBuffer::decode_all() { void CodeSection::print(const char* name) { csize_t locs_size = locs_end() - locs_start(); tty->print_cr(" %7s.code = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d)%s", - name, start(), end(), limit(), size(), capacity(), + name, p2i(start()), p2i(end()), p2i(limit()), size(), capacity(), is_frozen()? " [frozen]": ""); tty->print_cr(" %7s.locs = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d) point=%d", - name, locs_start(), locs_end(), locs_limit(), locs_size, locs_capacity(), locs_point_off()); + name, p2i(locs_start()), p2i(locs_end()), p2i(locs_limit()), locs_size, locs_capacity(), locs_point_off()); if (PrintRelocations) { RelocIterator iter(this); iter.print(); diff --git a/hotspot/src/share/vm/asm/codeBuffer.hpp b/hotspot/src/share/vm/asm/codeBuffer.hpp index bcc5d51e7ad..5572a39af7d 100644 --- a/hotspot/src/share/vm/asm/codeBuffer.hpp +++ b/hotspot/src/share/vm/asm/codeBuffer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -173,7 +173,7 @@ class CodeSection VALUE_OBJ_CLASS_SPEC { bool allocates(address pc) const { return pc >= _start && pc < _limit; } bool allocates2(address pc) const { return pc >= _start && pc <= _limit; } - void set_end(address pc) { assert(allocates2(pc), err_msg("not in CodeBuffer memory: " PTR_FORMAT " <= " PTR_FORMAT " <= " PTR_FORMAT, _start, pc, _limit)); _end = pc; } + void set_end(address pc) { assert(allocates2(pc), err_msg("not in CodeBuffer memory: " INTPTR_FORMAT " <= " INTPTR_FORMAT " <= " INTPTR_FORMAT, p2i(_start), p2i(pc), p2i(_limit))); _end = pc; } void set_mark(address pc) { assert(contains2(pc), "not in codeBuffer"); _mark = pc; } void set_mark_off(int offset) { assert(contains2(offset+_start),"not in codeBuffer"); diff --git a/hotspot/src/share/vm/asm/register.hpp b/hotspot/src/share/vm/asm/register.hpp index 5afecdeb116..d9918517dd9 100644 --- a/hotspot/src/share/vm/asm/register.hpp +++ b/hotspot/src/share/vm/asm/register.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,8 +118,8 @@ inline void assert_different_registers( ) { assert( a != b, - err_msg_res("registers must be different: a=%d, b=%d", - a, b) + err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT "", + p2i(a), p2i(b)) ); } @@ -132,8 +132,9 @@ inline void assert_different_registers( assert( a != b && a != c && b != c, - err_msg_res("registers must be different: a=%d, b=%d, c=%d", - a, b, c) + err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT + ", c=" INTPTR_FORMAT "", + p2i(a), p2i(b), p2i(c)) ); } @@ -148,8 +149,9 @@ inline void assert_different_registers( a != b && a != c && a != d && b != c && b != d && c != d, - err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d", - a, b, c, d) + err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT + ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT "", + p2i(a), p2i(b), p2i(c), p2i(d)) ); } @@ -166,8 +168,9 @@ inline void assert_different_registers( && b != c && b != d && b != e && c != d && c != e && d != e, - err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d", - a, b, c, d, e) + err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT + ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT "", + p2i(a), p2i(b), p2i(c), p2i(d), p2i(e)) ); } @@ -186,8 +189,10 @@ inline void assert_different_registers( && c != d && c != e && c != f && d != e && d != f && e != f, - err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d", - a, b, c, d, e, f) + err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT + ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT + ", f=" INTPTR_FORMAT "", + p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f)) ); } @@ -208,8 +213,10 @@ inline void assert_different_registers( && d != e && d != f && d != g && e != f && e != g && f != g, - err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d", - a, b, c, d, e, f, g) + err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT + ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT + ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT "", + p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g)) ); } @@ -232,8 +239,10 @@ inline void assert_different_registers( && e != f && e != g && e != h && f != g && f != h && g != h, - err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d", - a, b, c, d, e, f, g, h) + err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT + ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT + ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT "", + p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h)) ); } @@ -258,8 +267,11 @@ inline void assert_different_registers( && f != g && f != h && f != i && g != h && g != i && h != i, - err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d", - a, b, c, d, e, f, g, h, i) + err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT + ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT + ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT + ", i=" INTPTR_FORMAT "", + p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i)) ); } diff --git a/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp b/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp index 4eaa7d27f68..b0cb94629f4 100644 --- a/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp +++ b/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ class CFGPrinterOutput : public CHeapObj<mtCompiler> { void inc_indent(); void dec_indent(); - void print(const char* format, ...); + void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); void print_begin(const char* tag); void print_end(const char* tag); @@ -161,7 +161,7 @@ void CFGPrinterOutput::print_compilation() { print("name \"%s\"", method_name(_compilation->method(), true)); print("method \"%s\"", method_name(_compilation->method())); - print("date "INT64_FORMAT, os::javaTimeMillis()); + print("date "INT64_FORMAT, (int64_t) os::javaTimeMillis()); print_end("compilation"); } diff --git a/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp b/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp index 7f87e1183b0..842acec5be9 100644 --- a/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp +++ b/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -134,23 +134,23 @@ void InstructionPrinter::print_object(Value obj) { if (value->is_null_object()) { output()->print("null"); } else if (!value->is_loaded()) { - output()->print("<unloaded object " PTR_FORMAT ">", value); + output()->print("<unloaded object " INTPTR_FORMAT ">", p2i(value)); } else { - output()->print("<object " PTR_FORMAT " klass=", value->constant_encoding()); + output()->print("<object " INTPTR_FORMAT " klass=", p2i(value->constant_encoding())); print_klass(value->klass()); output()->print(">"); } } else if (type->as_InstanceConstant() != NULL) { ciInstance* value = type->as_InstanceConstant()->value(); if (value->is_loaded()) { - output()->print("<instance " PTR_FORMAT " klass=", value->constant_encoding()); + output()->print("<instance " INTPTR_FORMAT " klass=", p2i(value->constant_encoding())); print_klass(value->klass()); output()->print(">"); } else { - output()->print("<unloaded instance " PTR_FORMAT ">", value); + output()->print("<unloaded instance " INTPTR_FORMAT ">", p2i(value)); } } else if (type->as_ArrayConstant() != NULL) { - output()->print("<array " PTR_FORMAT ">", type->as_ArrayConstant()->value()->constant_encoding()); + output()->print("<array " INTPTR_FORMAT ">", p2i(type->as_ArrayConstant()->value()->constant_encoding())); } else if (type->as_ClassConstant() != NULL) { ciInstanceKlass* klass = type->as_ClassConstant()->value(); if (!klass->is_loaded()) { @@ -268,7 +268,7 @@ void InstructionPrinter::print_inline_level(BlockBegin* block) { void InstructionPrinter::print_unsafe_op(UnsafeOp* op, const char* name) { - output()->print(name); + output()->print("%s", name); output()->print(".("); } @@ -479,7 +479,7 @@ void InstructionPrinter::do_TypeCast(TypeCast* x) { if (x->declared_type()->is_klass()) print_klass(x->declared_type()->as_klass()); else - output()->print(type2name(x->declared_type()->basic_type())); + output()->print("%s", type2name(x->declared_type()->basic_type())); } diff --git a/hotspot/src/share/vm/c1/c1_LIR.cpp b/hotspot/src/share/vm/c1/c1_LIR.cpp index 2634f5f4105..fc176943ee8 100644 --- a/hotspot/src/share/vm/c1/c1_LIR.cpp +++ b/hotspot/src/share/vm/c1/c1_LIR.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1563,15 +1563,15 @@ void LIR_OprDesc::print(outputStream* out) const { } else if (is_virtual()) { out->print("R%d", vreg_number()); } else if (is_single_cpu()) { - out->print(as_register()->name()); + out->print("%s", as_register()->name()); } else if (is_double_cpu()) { - out->print(as_register_hi()->name()); - out->print(as_register_lo()->name()); + out->print("%s", as_register_hi()->name()); + out->print("%s", as_register_lo()->name()); #if defined(X86) } else if (is_single_xmm()) { - out->print(as_xmm_float_reg()->name()); + out->print("%s", as_xmm_float_reg()->name()); } else if (is_double_xmm()) { - out->print(as_xmm_double_reg()->name()); + out->print("%s", as_xmm_double_reg()->name()); } else if (is_single_fpu()) { out->print("fpu%d", fpu_regnr()); } else if (is_double_fpu()) { @@ -1583,9 +1583,9 @@ void LIR_OprDesc::print(outputStream* out) const { out->print("d%d", fpu_regnrLo() >> 1); #else } else if (is_single_fpu()) { - out->print(as_float_reg()->name()); + out->print("%s", as_float_reg()->name()); } else if (is_double_fpu()) { - out->print(as_double_reg()->name()); + out->print("%s", as_double_reg()->name()); #endif } else if (is_illegal()) { @@ -1611,9 +1611,9 @@ void LIR_Const::print_value_on(outputStream* out) const { case T_LONG: out->print("lng:" JLONG_FORMAT, as_jlong()); break; case T_FLOAT: out->print("flt:%f", as_jfloat()); break; case T_DOUBLE: out->print("dbl:%f", as_jdouble()); break; - case T_OBJECT: out->print("obj:0x%x", as_jobject()); break; - case T_METADATA: out->print("metadata:0x%x", as_metadata());break; - default: out->print("%3d:0x%x",type(), as_jdouble()); break; + case T_OBJECT: out->print("obj:" INTPTR_FORMAT, p2i(as_jobject())); break; + case T_METADATA: out->print("metadata:" INTPTR_FORMAT, p2i(as_metadata()));break; + default: out->print("%3d:0x" UINT64_FORMAT_X, type(), (uint64_t)as_jlong()); break; } } @@ -1629,7 +1629,7 @@ void LIR_Address::print_value_on(outputStream* out) const { case times_8: out->print(" * 8"); break; } } - out->print(" Disp: %d", _disp); + out->print(" Disp: " INTX_FORMAT, _disp); } // debug output of block header without InstructionPrinter @@ -1703,7 +1703,7 @@ void LIR_Op::print_on(outputStream* out) const { } else { out->print(" "); } - out->print(name()); out->print(" "); + out->print("%s ", name()); print_instr(out); if (info() != NULL) out->print(" [bci:%d]", info()->stack()->bci()); #ifdef ASSERT @@ -1833,7 +1833,7 @@ const char * LIR_Op::name() const { // LIR_OpJavaCall void LIR_OpJavaCall::print_instr(outputStream* out) const { out->print("call: "); - out->print("[addr: 0x%x]", address()); + out->print("[addr: " INTPTR_FORMAT "]", p2i(address())); if (receiver()->is_valid()) { out->print(" [recv: "); receiver()->print(out); out->print("]"); } @@ -1844,7 +1844,7 @@ void LIR_OpJavaCall::print_instr(outputStream* out) const { // LIR_OpLabel void LIR_OpLabel::print_instr(outputStream* out) const { - out->print("[label:0x%x]", _label); + out->print("[label:" INTPTR_FORMAT "]", p2i(_label)); } // LIR_OpArrayCopy @@ -1911,7 +1911,7 @@ void LIR_Op1::print_instr(outputStream* out) const { // LIR_Op1 void LIR_OpRTCall::print_instr(outputStream* out) const { intx a = (intx)addr(); - out->print(Runtime1::name_for_address(addr())); + out->print("%s", Runtime1::name_for_address(addr())); out->print(" "); tmp()->print(out); } @@ -1934,10 +1934,10 @@ void LIR_OpBranch::print_instr(outputStream* out) const { } else if (stub() != NULL) { out->print("["); stub()->print_name(out); - out->print(": 0x%x]", stub()); + out->print(": " INTPTR_FORMAT "]", p2i(stub())); if (stub()->info() != NULL) out->print(" [bci:%d]", stub()->info()->stack()->bci()); } else { - out->print("[label:0x%x] ", label()); + out->print("[label:" INTPTR_FORMAT "] ", p2i(label())); } if (ublock() != NULL) { out->print("unordered: [B%d] ", ublock()->block_id()); @@ -2004,7 +2004,7 @@ void LIR_OpAllocObj::print_instr(outputStream* out) const { tmp4()->print(out); out->print(" "); out->print("[hdr:%d]", header_size()); out->print(" "); out->print("[obj:%d]", object_size()); out->print(" "); - out->print("[lbl:0x%x]", stub()->entry()); + out->print("[lbl:" INTPTR_FORMAT "]", p2i(stub()->entry())); } void LIR_OpRoundFP::print_instr(outputStream* out) const { @@ -2037,7 +2037,7 @@ void LIR_OpAllocArray::print_instr(outputStream* out) const { tmp3()->print(out); out->print(" "); tmp4()->print(out); out->print(" "); out->print("[type:0x%x]", type()); out->print(" "); - out->print("[label:0x%x]", stub()->entry()); + out->print("[label:" INTPTR_FORMAT "]", p2i(stub()->entry())); } @@ -2074,7 +2074,7 @@ void LIR_OpLock::print_instr(outputStream* out) const { if (_scratch->is_valid()) { _scratch->print(out); out->print(" "); } - out->print("[lbl:0x%x]", stub()->entry()); + out->print("[lbl:" INTPTR_FORMAT "]", p2i(stub()->entry())); } #ifdef ASSERT @@ -2082,7 +2082,7 @@ void LIR_OpAssert::print_instr(outputStream* out) const { print_condition(out, condition()); out->print(" "); in_opr1()->print(out); out->print(" "); in_opr2()->print(out); out->print(", \""); - out->print(msg()); out->print("\""); + out->print("%s", msg()); out->print("\""); } #endif diff --git a/hotspot/src/share/vm/c1/c1_RangeCheckElimination.cpp b/hotspot/src/share/vm/c1/c1_RangeCheckElimination.cpp index 599cedb99d0..71e9de00b30 100644 --- a/hotspot/src/share/vm/c1/c1_RangeCheckElimination.cpp +++ b/hotspot/src/share/vm/c1/c1_RangeCheckElimination.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,10 +62,10 @@ RangeCheckEliminator::RangeCheckEliminator(IR *ir) : _optimistic = ir->compilation()->is_optimistic(); TRACE_RANGE_CHECK_ELIMINATION( - tty->print_cr(""); + tty->cr(); tty->print_cr("Range check elimination"); ir->method()->print_name(tty); - tty->print_cr(""); + tty->cr(); ); TRACE_RANGE_CHECK_ELIMINATION( @@ -1024,7 +1024,7 @@ void RangeCheckEliminator::dump_condition_stack(BlockBegin *block) { tty->print("i%d", phi->id()); tty->print(": "); bound->print(); - tty->print_cr(""); + tty->cr(); ); } }); @@ -1039,7 +1039,7 @@ void RangeCheckEliminator::dump_condition_stack(BlockBegin *block) { tty->print("i%d", instr->id()); tty->print(": "); bound->print(); - tty->print_cr(""); + tty->cr(); ); } } @@ -1400,7 +1400,7 @@ Value RangeCheckEliminator::Bound::lower_instr() { // print void RangeCheckEliminator::Bound::print() { - tty->print(""); + tty->print("%s", ""); if (this->_lower_instr || this->_lower != min_jint) { if (this->_lower_instr) { tty->print("i%d", this->_lower_instr->id()); diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp index 11542c4a50b..9942e44b842 100644 --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -532,8 +532,8 @@ JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* t if (TraceExceptions) { ttyLocker ttyl; ResourceMark rm; - tty->print_cr("Exception <%s> (0x%x) thrown in compiled method <%s> at PC " PTR_FORMAT " for thread 0x%x", - exception->print_value_string(), (address)exception(), nm->method()->print_value_string(), pc, thread); + tty->print_cr("Exception <%s> (" INTPTR_FORMAT ") thrown in compiled method <%s> at PC " INTPTR_FORMAT " for thread " INTPTR_FORMAT "", + exception->print_value_string(), p2i((address)exception()), nm->method()->print_value_string(), p2i(pc), p2i(thread)); } // for AbortVMOnException flag NOT_PRODUCT(Exceptions::debug_check_abort(exception)); @@ -563,7 +563,7 @@ JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* t ttyLocker ttyl; ResourceMark rm; tty->print_cr("Thread " PTR_FORMAT " continuing at PC " PTR_FORMAT " for exception thrown at PC " PTR_FORMAT, - thread, continuation, pc); + p2i(thread), p2i(continuation), p2i(pc)); } return continuation; @@ -988,8 +988,8 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i address copy_buff = stub_location - *byte_skip - *byte_count; address being_initialized_entry = stub_location - *being_initialized_entry_offset; if (TracePatching) { - tty->print_cr(" Patching %s at bci %d at address 0x%x (%s)", Bytecodes::name(code), bci, - instr_pc, (stub_id == Runtime1::access_field_patching_id) ? "field" : "klass"); + tty->print_cr(" Patching %s at bci %d at address " INTPTR_FORMAT " (%s)", Bytecodes::name(code), bci, + p2i(instr_pc), (stub_id == Runtime1::access_field_patching_id) ? "field" : "klass"); nmethod* caller_code = CodeCache::find_nmethod(caller_frame.pc()); assert(caller_code != NULL, "nmethod not found"); @@ -1448,7 +1448,7 @@ JRT_ENTRY(void, Runtime1::predicate_failed_trap(JavaThread* thread)) methodHandle inlinee = methodHandle(vfst.method()); inlinee->print_short_name(&ss1); m->print_short_name(&ss2); - tty->print_cr("Predicate failed trap in method %s at bci %d inlined in %s at pc %x", ss1.as_string(), vfst.bci(), ss2.as_string(), caller_frame.pc()); + tty->print_cr("Predicate failed trap in method %s at bci %d inlined in %s at pc " INTPTR_FORMAT, ss1.as_string(), vfst.bci(), ss2.as_string(), p2i(caller_frame.pc())); } diff --git a/hotspot/src/share/vm/c1/c1_ValueType.hpp b/hotspot/src/share/vm/c1/c1_ValueType.hpp index a0bb5647d76..291dd2386d3 100644 --- a/hotspot/src/share/vm/c1/c1_ValueType.hpp +++ b/hotspot/src/share/vm/c1/c1_ValueType.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -175,7 +175,7 @@ class ValueType: public CompilationResourceObj { ValueType* join(ValueType* y) const; // debugging - void print(outputStream* s = tty) { s->print(name()); } + void print(outputStream* s = tty) { s->print("%s", name()); } }; diff --git a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp index 24b2830ed83..c2943e98edb 100644 --- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp +++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1287,10 +1287,10 @@ void BCEscapeAnalyzer::compute_escape_info() { tty->print_cr("class of method is not initialized."); else if (_level > MaxBCEAEstimateLevel) tty->print_cr("level (%d) exceeds MaxBCEAEstimateLevel (%d).", - _level, MaxBCEAEstimateLevel); + _level, (int) MaxBCEAEstimateLevel); else if (method()->code_size() > MaxBCEAEstimateSize) - tty->print_cr("code size (%d) exceeds MaxBCEAEstimateSize.", - method()->code_size(), MaxBCEAEstimateSize); + tty->print_cr("code size (%d) exceeds MaxBCEAEstimateSize (%d).", + method()->code_size(), (int) MaxBCEAEstimateSize); else ShouldNotReachHere(); } diff --git a/hotspot/src/share/vm/ci/ciConstant.cpp b/hotspot/src/share/vm/ci/ciConstant.cpp index 4955a088ffa..a059f2c8a3e 100644 --- a/hotspot/src/share/vm/ci/ciConstant.cpp +++ b/hotspot/src/share/vm/ci/ciConstant.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ void ciConstant::print() { tty->print("%d", _value._int); break; case T_LONG: - tty->print(INT64_FORMAT, _value._long); + tty->print(INT64_FORMAT, (int64_t)(_value._long)); break; case T_FLOAT: tty->print("%f", _value._float); diff --git a/hotspot/src/share/vm/ci/ciEnv.cpp b/hotspot/src/share/vm/ci/ciEnv.cpp index df6017e0a4a..fbe7bbbd83c 100644 --- a/hotspot/src/share/vm/ci/ciEnv.cpp +++ b/hotspot/src/share/vm/ci/ciEnv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1250,8 +1250,7 @@ void ciEnv::dump_replay_data(int compile_id) { if (replay_data_file != NULL) { fileStream replay_data_stream(replay_data_file, /*need_close=*/true); dump_replay_data(&replay_data_stream); - tty->print("# Compiler replay data is saved as: "); - tty->print_cr(buffer); + tty->print_cr("# Compiler replay data is saved as: %s", buffer); } else { tty->print_cr("# Can't open file to dump replay data."); } @@ -1274,7 +1273,7 @@ void ciEnv::dump_inline_data(int compile_id) { ) replay_data_stream.flush(); tty->print("# Compiler inline data is saved as: "); - tty->print_cr(buffer); + tty->print_cr("%s", buffer); } else { tty->print_cr("# Can't open file to dump inline data."); } diff --git a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp index f4389da46a6..f8b39ed79c9 100644 --- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -292,7 +292,7 @@ bool ciInstanceKlass::is_in_package_impl(const char* packagename, int len) { // Implementation of the print method. void ciInstanceKlass::print_impl(outputStream* st) { ciKlass::print_impl(st); - GUARDED_VM_ENTRY(st->print(" loader=0x%x", (address)loader());) + GUARDED_VM_ENTRY(st->print(" loader=" INTPTR_FORMAT, p2i((address)loader()));) if (is_loaded()) { st->print(" loaded=true initialized=%s finalized=%s subklass=%s size=%d flags=", bool_to_str(is_initialized()), @@ -618,7 +618,7 @@ class StaticFinalFieldPrinter : public FieldClosure { case T_SHORT: _out->print_cr("%d", mirror->short_field(fd->offset())); break; case T_CHAR: _out->print_cr("%d", mirror->char_field(fd->offset())); break; case T_INT: _out->print_cr("%d", mirror->int_field(fd->offset())); break; - case T_LONG: _out->print_cr(INT64_FORMAT, mirror->long_field(fd->offset())); break; + case T_LONG: _out->print_cr(INT64_FORMAT, (int64_t)(mirror->long_field(fd->offset()))); break; case T_FLOAT: { float f = mirror->float_field(fd->offset()); _out->print_cr("%d", *(int*)&f); @@ -626,7 +626,7 @@ class StaticFinalFieldPrinter : public FieldClosure { } case T_DOUBLE: { double d = mirror->double_field(fd->offset()); - _out->print_cr(INT64_FORMAT, *(jlong*)&d); + _out->print_cr(INT64_FORMAT, *(int64_t*)&d); break; } case T_ARRAY: { @@ -656,7 +656,7 @@ class StaticFinalFieldPrinter : public FieldClosure { _out->print_cr("\""); } else { const char* klass_name = value->klass()->name()->as_quoted_ascii(); - _out->print_cr(klass_name); + _out->print_cr("%s", klass_name); } } else { ShouldNotReachHere(); diff --git a/hotspot/src/share/vm/ci/ciMetadata.cpp b/hotspot/src/share/vm/ci/ciMetadata.cpp index fb738798549..efb4f58aef2 100644 --- a/hotspot/src/share/vm/ci/ciMetadata.cpp +++ b/hotspot/src/share/vm/ci/ciMetadata.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ void ciMetadata::print(outputStream* st) { st->print("<%s", type_string()); GUARDED_VM_ENTRY(print_impl(st);) - st->print(" ident=%d address=0x%x>", ident(), (address)this); + st->print(" ident=%d address=" INTPTR_FORMAT ">", ident(), p2i((address)this)); } diff --git a/hotspot/src/share/vm/ci/ciMethodData.cpp b/hotspot/src/share/vm/ci/ciMethodData.cpp index bc8794063ad..1b604ba4e4d 100644 --- a/hotspot/src/share/vm/ci/ciMethodData.cpp +++ b/hotspot/src/share/vm/ci/ciMethodData.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -557,7 +557,7 @@ void ciMethodData::dump_replay_data(outputStream* out) { if (round == 0) { count++; } else { - out->print(" %d %s", dp_to_di(vdata->dp() + in_bytes(vdata->receiver_offset(i))) / sizeof(intptr_t), k->name()->as_quoted_ascii()); + out->print(" %d %s", (int)(dp_to_di(vdata->dp() + in_bytes(vdata->receiver_offset(i))) / sizeof(intptr_t)), k->name()->as_quoted_ascii()); } } } @@ -569,7 +569,7 @@ void ciMethodData::dump_replay_data(outputStream* out) { if (round == 0) { count++; } else { - out->print(" %d %s", dp_to_di(vdata->dp() + in_bytes(vdata->receiver_offset(i))) / sizeof(intptr_t), k->name()->as_quoted_ascii()); + out->print(" %d %s", (int)(dp_to_di(vdata->dp() + in_bytes(vdata->receiver_offset(i))) / sizeof(intptr_t)), k->name()->as_quoted_ascii()); } } } diff --git a/hotspot/src/share/vm/ci/ciObject.cpp b/hotspot/src/share/vm/ci/ciObject.cpp index 9685356754c..0fe31d54b13 100644 --- a/hotspot/src/share/vm/ci/ciObject.cpp +++ b/hotspot/src/share/vm/ci/ciObject.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -213,9 +213,9 @@ void ciObject::init_flags_from(oop x) { void ciObject::print(outputStream* st) { st->print("<%s", type_string()); GUARDED_VM_ENTRY(print_impl(st);) - st->print(" ident=%d %s address=0x%x>", ident(), + st->print(" ident=%d %s address=" INTPTR_FORMAT ">", ident(), is_scavengable() ? "SCAVENGABLE" : "", - (address)this); + p2i((address)this)); } // ------------------------------------------------------------------ diff --git a/hotspot/src/share/vm/ci/ciSignature.cpp b/hotspot/src/share/vm/ci/ciSignature.cpp index d09cc2fd2fe..634ca47981c 100644 --- a/hotspot/src/share/vm/ci/ciSignature.cpp +++ b/hotspot/src/share/vm/ci/ciSignature.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -148,5 +148,5 @@ void ciSignature::print() { print_signature(); tty->print(" accessing_klass="); _accessing_klass->print(); - tty->print(" address=0x%x>", (address)this); + tty->print(" address=" INTPTR_FORMAT ">", p2i((address)this)); } diff --git a/hotspot/src/share/vm/ci/ciType.cpp b/hotspot/src/share/vm/ci/ciType.cpp index 15c884213bb..43df753cb49 100644 --- a/hotspot/src/share/vm/ci/ciType.cpp +++ b/hotspot/src/share/vm/ci/ciType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,7 +87,7 @@ void ciType::print_impl(outputStream* st) { // Print the name of this type void ciType::print_name_on(outputStream* st) { ResourceMark rm; - st->print(name()); + st->print("%s", name()); } diff --git a/hotspot/src/share/vm/classfile/classFileError.cpp b/hotspot/src/share/vm/classfile/classFileError.cpp index a9c55fb73a5..3c3302fb29f 100644 --- a/hotspot/src/share/vm/classfile/classFileError.cpp +++ b/hotspot/src/share/vm/classfile/classFileError.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,9 @@ // Keep these in a separate file to prevent inlining +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED + void ClassFileParser::classfile_parse_error(const char* msg, TRAPS) { ResourceMark rm(THREAD); Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(), @@ -53,6 +56,8 @@ void ClassFileParser::classfile_parse_error(const char* msg, int index, const ch msg, index, name, _class_name->as_C_string()); } +PRAGMA_DIAG_POP + void StackMapStream::stackmap_format_error(const char* msg, TRAPS) { ResourceMark rm(THREAD); Exceptions::fthrow( diff --git a/hotspot/src/share/vm/classfile/classFileParser.hpp b/hotspot/src/share/vm/classfile/classFileParser.hpp index ba12f26fde0..10170eb49eb 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.hpp +++ b/hotspot/src/share/vm/classfile/classFileParser.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -312,7 +312,9 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { if (!b) { classfile_parse_error(msg, CHECK); } } - inline void assert_property(bool b, const char* msg, TRAPS) { +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED +inline void assert_property(bool b, const char* msg, TRAPS) { #ifdef ASSERT if (!b) { ResourceMark rm(THREAD); @@ -329,6 +331,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { } #endif } +PRAGMA_DIAG_POP inline void check_property(bool property, const char* msg, int index, TRAPS) { if (_need_verify) { diff --git a/hotspot/src/share/vm/classfile/classLoader.cpp b/hotspot/src/share/vm/classfile/classLoader.cpp index c1dcb36dba4..8366c8fc4ce 100644 --- a/hotspot/src/share/vm/classfile/classLoader.cpp +++ b/hotspot/src/share/vm/classfile/classLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -343,7 +343,7 @@ static void print_meta_index(LazyClassPathEntry* entry, tty->print("[Meta index for %s=", entry->name()); for (int i = 0; i < meta_packages.length(); i++) { if (i > 0) tty->print(" "); - tty->print(meta_packages.at(i)); + tty->print("%s", meta_packages.at(i)); } tty->print_cr("]"); } @@ -1299,7 +1299,7 @@ void ClassLoader::compile_the_world() { e = e->next(); } jlong end = os::javaTimeMillis(); - tty->print_cr("CompileTheWorld : Done (%d classes, %d methods, %d ms)", + tty->print_cr("CompileTheWorld : Done (%d classes, %d methods, " JLONG_FORMAT " ms)", _compile_the_world_class_counter, _compile_the_world_method_counter, (end - start)); { // Print statistics as if before normal exit: diff --git a/hotspot/src/share/vm/classfile/classLoaderData.cpp b/hotspot/src/share/vm/classfile/classLoaderData.cpp index efd141332dc..4d716b9f38a 100644 --- a/hotspot/src/share/vm/classfile/classLoaderData.cpp +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp @@ -281,10 +281,10 @@ void ClassLoaderData::add_class(Klass* k) { ResourceMark rm; tty->print_cr("[TraceClassLoaderData] Adding k: " PTR_FORMAT " %s to CLD: " PTR_FORMAT " loader: " PTR_FORMAT " %s", - k, + p2i(k), k->external_name(), - k->class_loader_data(), - (void *)k->class_loader(), + p2i(k->class_loader_data()), + p2i((void *)k->class_loader()), loader_name()); } } @@ -319,11 +319,11 @@ void ClassLoaderData::unload() { if (TraceClassLoaderData) { ResourceMark rm; - tty->print("[ClassLoaderData: unload loader data "PTR_FORMAT, this); - tty->print(" for instance "PTR_FORMAT" of %s", (void *)class_loader(), + tty->print("[ClassLoaderData: unload loader data " INTPTR_FORMAT, p2i(this)); + tty->print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)class_loader()), loader_name()); if (is_anonymous()) { - tty->print(" for anonymous class "PTR_FORMAT " ", _klasses); + tty->print(" for anonymous class " INTPTR_FORMAT " ", p2i(_klasses)); } tty->print_cr("]"); } @@ -485,14 +485,14 @@ const char* ClassLoaderData::loader_name() { void ClassLoaderData::dump(outputStream * const out) { ResourceMark rm; out->print("ClassLoaderData CLD: "PTR_FORMAT", loader: "PTR_FORMAT", loader_klass: "PTR_FORMAT" %s {", - this, (void *)class_loader(), - class_loader() != NULL ? class_loader()->klass() : NULL, loader_name()); + p2i(this), p2i((void *)class_loader()), + p2i(class_loader() != NULL ? class_loader()->klass() : NULL), loader_name()); if (claimed()) out->print(" claimed "); if (is_unloading()) out->print(" unloading "); - out->print(" handles " INTPTR_FORMAT, handles()); + out->print(" handles " INTPTR_FORMAT, p2i(handles())); out->cr(); if (metaspace_or_null() != NULL) { - out->print_cr("metaspace: " PTR_FORMAT, metaspace_or_null()); + out->print_cr("metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null())); metaspace_or_null()->dump(out); } else { out->print_cr("metaspace: NULL"); @@ -586,8 +586,8 @@ ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRA if (TraceClassLoaderData) { ResourceMark rm; tty->print("[ClassLoaderData: "); - tty->print("create class loader data "PTR_FORMAT, cld); - tty->print(" for instance "PTR_FORMAT" of %s", (void *)cld->class_loader(), + tty->print("create class loader data " INTPTR_FORMAT, p2i(cld)); + tty->print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)cld->class_loader()), cld->loader_name()); tty->print_cr("]"); } @@ -847,7 +847,7 @@ void ClassLoaderData::print_value_on(outputStream* out) const { if (class_loader() == NULL) { out->print("NULL class_loader"); } else { - out->print("class loader "PTR_FORMAT, this); + out->print("class loader " INTPTR_FORMAT, p2i(this)); class_loader()->print_value_on(out); } } diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp index b5e4da63f0f..1b56ff2fba4 100644 --- a/hotspot/src/share/vm/classfile/defaultMethods.cpp +++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp @@ -436,7 +436,7 @@ class MethodFamily : public ResourceObj { _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError(); if (TraceDefaultMethods) { _exception_message->print_value_on(tty); - tty->print_cr(""); + tty->cr(); } } } @@ -463,7 +463,7 @@ class MethodFamily : public ResourceObj { if (_members.at(i).second == DISQUALIFIED) { str->print(" (disqualified)"); } - str->print_cr(""); + str->cr(); } if (_selected_target != NULL) { @@ -480,7 +480,7 @@ class MethodFamily : public ResourceObj { if (!method_holder->is_interface()) { tty->print(" : in superclass"); } - str->print_cr(""); + str->cr(); } void print_exception(outputStream* str, int indent) { @@ -688,7 +688,7 @@ static GrowableArray<EmptyVtableSlot*>* find_empty_vtable_slots( for (int i = 0; i < slots->length(); ++i) { tty->indent(); slots->at(i)->print_on(tty); - tty->print_cr(""); + tty->cr(); } } #endif // ndef PRODUCT @@ -828,7 +828,7 @@ void DefaultMethods::generate_default_methods( streamIndentor si(tty, 2); tty->indent().print("Looking for default methods for slot "); slot->print_on(tty); - tty->print_cr(""); + tty->cr(); } #endif // ndef PRODUCT @@ -946,7 +946,7 @@ static void create_defaults_and_exceptions( if (TraceDefaultMethods) { tty->print("for slot: "); slot->print_on(tty); - tty->print_cr(""); + tty->cr(); if (method->has_target()) { method->print_selected(tty, 1); } else if (method->throws_exception()) { diff --git a/hotspot/src/share/vm/classfile/dictionary.cpp b/hotspot/src/share/vm/classfile/dictionary.cpp index ec64adc2476..b84475a8dbb 100644 --- a/hotspot/src/share/vm/classfile/dictionary.cpp +++ b/hotspot/src/share/vm/classfile/dictionary.cpp @@ -31,6 +31,7 @@ #include "runtime/orderAccess.inline.hpp" #include "utilities/hashtable.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC DictionaryEntry* Dictionary::_current_class_entry = NULL; int Dictionary::_current_class_index = 0; diff --git a/hotspot/src/share/vm/classfile/dictionary.hpp b/hotspot/src/share/vm/classfile/dictionary.hpp index 17d916f0629..bc25c811c52 100644 --- a/hotspot/src/share/vm/classfile/dictionary.hpp +++ b/hotspot/src/share/vm/classfile/dictionary.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -379,7 +379,7 @@ class SymbolPropertyEntry : public HashtableEntry<Symbol*, mtSymbol> { } if (method_type() != NULL) { if (printed) st->print(" and "); - st->print(INTPTR_FORMAT, (void *)method_type()); + st->print(INTPTR_FORMAT, p2i((void *)method_type())); printed = true; } st->print_cr(printed ? "" : "(empty)"); diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index a9d213948eb..d68c4e806cb 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -51,6 +51,8 @@ #include "runtime/vframe.hpp" #include "utilities/preserveException.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #define INJECTED_FIELD_COMPUTE_OFFSET(klass, name, signature, may_be_java) \ klass::_##name##_offset = JavaClasses::compute_injected_offset(JavaClasses::klass##_##name##_enum); @@ -1490,7 +1492,7 @@ void java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) { while (h_throwable.not_null()) { objArrayHandle result (THREAD, objArrayOop(backtrace(h_throwable()))); if (result.is_null()) { - st->print_cr(no_stack_trace_message()); + st->print_cr("%s", no_stack_trace_message()); return; } diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp index 40a06da9b34..3028e12dae9 100644 --- a/hotspot/src/share/vm/classfile/symbolTable.cpp +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp @@ -39,6 +39,8 @@ #include "gc_implementation/g1/g1StringDedup.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // -------------------------------------------------------------------------- // the number of buckets a thread claims diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp index 8d52bef7194..f4a933045d0 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp @@ -2269,7 +2269,7 @@ static methodHandle unpack_method_and_appendix(Handle mname, oop appendix = appendix_box->obj_at(0); if (TraceMethodHandles) { #ifndef PRODUCT - tty->print("Linked method="INTPTR_FORMAT": ", m); + tty->print("Linked method=" INTPTR_FORMAT ": ", p2i(m)); m->print(); if (appendix != NULL) { tty->print("appendix = "); appendix->print(); } tty->cr(); diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp index d1238f609fa..2c1edcb6278 100644 --- a/hotspot/src/share/vm/classfile/verifier.cpp +++ b/hotspot/src/share/vm/classfile/verifier.cpp @@ -364,7 +364,7 @@ void TypeOrigin::print_on(outputStream* str) const { void ErrorContext::details(outputStream* ss, const Method* method) const { if (is_valid()) { - ss->print_cr(""); + ss->cr(); ss->print_cr("Exception Details:"); location_details(ss, method); reason_details(ss); @@ -379,7 +379,7 @@ void ErrorContext::reason_details(outputStream* ss) const { streamIndentor si(ss); ss->indent().print_cr("Reason:"); streamIndentor si2(ss); - ss->indent().print(""); + ss->indent().print("%s", ""); switch (_fault) { case INVALID_BYTECODE: ss->print("Error exists in the bytecode"); @@ -432,7 +432,7 @@ void ErrorContext::reason_details(outputStream* ss) const { ShouldNotReachHere(); ss->print_cr("Unknown"); } - ss->print_cr(""); + ss->cr(); } void ErrorContext::location_details(outputStream* ss, const Method* method) const { @@ -507,7 +507,7 @@ void ErrorContext::stackmap_details(outputStream* ss, const Method* method) cons for (u2 i = 0; i < sm_table->number_of_entries(); ++i) { ss->indent(); sm_frame->print_on(ss, current_offset); - ss->print_cr(""); + ss->cr(); current_offset += sm_frame->offset_delta(); sm_frame = sm_frame->next(); } @@ -579,7 +579,8 @@ void ClassVerifier::verify_method(methodHandle m, TRAPS) { tty->print_cr("Verifying method %s", m->name_and_sig_as_C_string()); } - const char* bad_type_msg = "Bad type on operand stack in %s"; +// For clang, the only good constant format string is a literal constant format string. +#define bad_type_msg "Bad type on operand stack in %s" int32_t max_stack = m->verifier_max_stack(); int32_t max_locals = m->max_locals(); @@ -1676,6 +1677,8 @@ void ClassVerifier::verify_method(methodHandle m, TRAPS) { } } +#undef bad_type_message + char* ClassVerifier::generate_code_data(methodHandle m, u4 code_length, TRAPS) { char* code_data = NEW_RESOURCE_ARRAY(char, code_length); memset(code_data, 0, sizeof(char) * code_length); @@ -2363,8 +2366,8 @@ void ClassVerifier::verify_invoke_instructions( if (opcode == Bytecodes::_invokedynamic) { if (_klass->major_version() < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { class_format_error( - "invokedynamic instructions not supported by this class file version", - _klass->external_name()); + "invokedynamic instructions not supported by this class file version (%d), class %s", + _klass->major_version(), _klass->external_name()); return; } } else { diff --git a/hotspot/src/share/vm/classfile/verifier.hpp b/hotspot/src/share/vm/classfile/verifier.hpp index 74143a6e787..557f567bf78 100644 --- a/hotspot/src/share/vm/classfile/verifier.hpp +++ b/hotspot/src/share/vm/classfile/verifier.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -375,15 +375,15 @@ class ClassVerifier : public StackObj { bool has_error() const { return result() != NULL; } char* exception_message() { stringStream ss; - ss.print(_message); + ss.print("%s", _message); _error_context.details(&ss, _method()); return ss.as_string(); } // Called when verify or class format errors are encountered. // May throw an exception based upon the mode. - void verify_error(ErrorContext ctx, const char* fmt, ...); - void class_format_error(const char* fmt, ...); + void verify_error(ErrorContext ctx, const char* fmt, ...) ATTRIBUTE_PRINTF(3, 4); + void class_format_error(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3); Klass* load_class(Symbol* name, TRAPS); diff --git a/hotspot/src/share/vm/classfile/vmSymbols.cpp b/hotspot/src/share/vm/classfile/vmSymbols.cpp index 855c6bdd773..6d13995c588 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.cpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -533,7 +533,7 @@ void vmIntrinsics::verify_method(ID actual_id, Method* m) { xtty->begin_elem("intrinsic_misdeclared actual='%s' declared='%s'", actual_name, declared_name); xtty->method(mh); - xtty->end_elem(""); + xtty->end_elem("%s", ""); } if (PrintMiscellaneous && (WizardMode || Verbose)) { tty->print_cr("*** misidentified method; %s(%d) should be %s(%d):", diff --git a/hotspot/src/share/vm/code/codeBlob.cpp b/hotspot/src/share/vm/code/codeBlob.cpp index 141bbae007b..f9e78bfb9e2 100644 --- a/hotspot/src/share/vm/code/codeBlob.cpp +++ b/hotspot/src/share/vm/code/codeBlob.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -530,7 +530,7 @@ void CodeBlob::verify() { } void CodeBlob::print_on(outputStream* st) const { - st->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", this); + st->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", p2i(this)); st->print_cr("Framesize: %d", _frame_size); } @@ -548,7 +548,7 @@ void BufferBlob::print_on(outputStream* st) const { } void BufferBlob::print_value_on(outputStream* st) const { - st->print_cr("BufferBlob (" INTPTR_FORMAT ") used for %s", this, name()); + st->print_cr("BufferBlob (" INTPTR_FORMAT ") used for %s", p2i(this), name()); } void RuntimeStub::verify() { @@ -558,13 +558,13 @@ void RuntimeStub::verify() { void RuntimeStub::print_on(outputStream* st) const { ttyLocker ttyl; CodeBlob::print_on(st); - st->print("Runtime Stub (" INTPTR_FORMAT "): ", this); - st->print_cr(name()); + st->print("Runtime Stub (" INTPTR_FORMAT "): ", p2i(this)); + st->print_cr("%s", name()); Disassembler::decode((CodeBlob*)this, st); } void RuntimeStub::print_value_on(outputStream* st) const { - st->print("RuntimeStub (" INTPTR_FORMAT "): ", this); st->print(name()); + st->print("RuntimeStub (" INTPTR_FORMAT "): ", p2i(this)); st->print("%s", name()); } void SingletonBlob::verify() { @@ -574,12 +574,12 @@ void SingletonBlob::verify() { void SingletonBlob::print_on(outputStream* st) const { ttyLocker ttyl; CodeBlob::print_on(st); - st->print_cr(name()); + st->print_cr("%s", name()); Disassembler::decode((CodeBlob*)this, st); } void SingletonBlob::print_value_on(outputStream* st) const { - st->print_cr(name()); + st->print_cr("%s", name()); } void DeoptimizationBlob::print_value_on(outputStream* st) const { diff --git a/hotspot/src/share/vm/code/codeCache.cpp b/hotspot/src/share/vm/code/codeCache.cpp index b3a857c2062..07bcc202b76 100644 --- a/hotspot/src/share/vm/code/codeCache.cpp +++ b/hotspot/src/share/vm/code/codeCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -81,10 +81,10 @@ class CodeBlob_sizes { bool is_empty() { return count == 0; } void print(const char* title) { - tty->print_cr(" #%d %s = %dK (hdr %d%%, loc %d%%, code %d%%, stub %d%%, [oops %d%%, data %d%%, pcs %d%%])", + tty->print_cr(" #%d %s = %dK (hdr %d%%, loc %d%%, code %d%%, stub %d%%, [oops %d%%, metadata %d%%, data %d%%, pcs %d%%])", count, title, - total() / K, + (int)(total() / K), header_size * 100 / total_size, relocation_size * 100 / total_size, code_size * 100 / total_size, @@ -191,7 +191,7 @@ CodeBlob* CodeCache::allocate(int size, bool is_critical) { } if (PrintCodeCacheExtension) { ResourceMark rm; - tty->print_cr("code cache extended to [" INTPTR_FORMAT ", " INTPTR_FORMAT "] (%d bytes)", + tty->print_cr("code cache extended to [" INTPTR_FORMAT ", " INTPTR_FORMAT "] (" SSIZE_FORMAT " bytes)", (intptr_t)_heap->low_boundary(), (intptr_t)_heap->high(), (address)_heap->high() - (address)_heap->low_boundary()); } @@ -487,7 +487,7 @@ void CodeCache::gc_epilogue() { if (CompiledIC::is_icholder_call_site(iter.virtual_call_reloc())) { CompiledIC *ic = CompiledIC_at(iter.reloc()); if (TraceCompiledIC) { - tty->print("noticed icholder " INTPTR_FORMAT " ", ic->cached_icholder()); + tty->print("noticed icholder " INTPTR_FORMAT " ", p2i(ic->cached_icholder())); ic->print(); } assert(ic->cached_icholder() != NULL, "must be non-NULL"); @@ -741,10 +741,10 @@ void CodeCache::print_memory_overhead() { } // Print bytes that are allocated in the freelist ttyLocker ttl; - tty->print_cr("Number of elements in freelist: %d", freelist_length()); - tty->print_cr("Allocated in freelist: %dkB", bytes_allocated_in_freelist()/K); - tty->print_cr("Unused bytes in CodeBlobs: %dkB", (int)(wasted_bytes/K)); - tty->print_cr("Segment map size: %dkB", allocated_segments()/K); // 1 byte per segment + tty->print_cr("Number of elements in freelist: " SSIZE_FORMAT, freelist_length()); + tty->print_cr("Allocated in freelist: " SSIZE_FORMAT "kB", bytes_allocated_in_freelist()/K); + tty->print_cr("Unused bytes in CodeBlobs: " SSIZE_FORMAT "kB", (wasted_bytes/K)); + tty->print_cr("Segment map size: " SSIZE_FORMAT "kB", allocated_segments()/K); // 1 byte per segment } //------------------------------------------------------------------------------------------------ @@ -756,7 +756,7 @@ void CodeCache::print_trace(const char* event, CodeBlob* cb, int size) { if (PrintCodeCache2) { // Need to add a new flag ResourceMark rm; if (size == 0) size = cb->size(); - tty->print_cr("CodeCache %s: addr: " INTPTR_FORMAT ", size: 0x%x", event, cb, size); + tty->print_cr("CodeCache %s: addr: " INTPTR_FORMAT ", size: 0x%x", event, p2i(cb), size); } } @@ -926,9 +926,9 @@ void CodeCache::print_summary(outputStream* st, bool detailed) { if (detailed) { st->print_cr(" bounds [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT "]", - _heap->low_boundary(), - _heap->high(), - _heap->high_boundary()); + p2i(_heap->low_boundary()), + p2i(_heap->high()), + p2i(_heap->high_boundary())); st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT " adapters=" UINT32_FORMAT, nof_blobs(), nof_nmethods(), nof_adapters()); diff --git a/hotspot/src/share/vm/code/compiledIC.cpp b/hotspot/src/share/vm/code/compiledIC.cpp index 251a4c79c43..9a038164689 100644 --- a/hotspot/src/share/vm/code/compiledIC.cpp +++ b/hotspot/src/share/vm/code/compiledIC.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,9 +88,9 @@ void CompiledIC::internal_set_ic_destination(address entry_point, bool is_icstub if (TraceCompiledIC) { tty->print(" "); print_compiled_ic(); - tty->print(" changing destination to " INTPTR_FORMAT, entry_point); + tty->print(" changing destination to " INTPTR_FORMAT, p2i(entry_point)); if (!is_optimized()) { - tty->print(" changing cached %s to " INTPTR_FORMAT, is_icholder ? "icholder" : "metadata", (address)cache); + tty->print(" changing cached %s to " INTPTR_FORMAT, is_icholder ? "icholder" : "metadata", p2i((address)cache)); } if (is_icstub) { tty->print(" (icstub)"); @@ -195,7 +195,7 @@ bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecod if (TraceICs) { ResourceMark rm; tty->print_cr ("IC@" INTPTR_FORMAT ": to megamorphic %s entry: " INTPTR_FORMAT, - instruction_address(), call_info->selected_method()->print_value_string(), entry); + p2i(instruction_address()), call_info->selected_method()->print_value_string(), p2i(entry)); } // We can't check this anymore. With lazy deopt we could have already @@ -272,7 +272,7 @@ bool CompiledIC::is_call_to_interpreted() const { void CompiledIC::set_to_clean() { assert(SafepointSynchronize::is_at_safepoint() || CompiledIC_lock->is_locked() , "MT-unsafe call"); if (TraceInlineCacheClearing || TraceICs) { - tty->print_cr("IC@" INTPTR_FORMAT ": set to clean", instruction_address()); + tty->print_cr("IC@" INTPTR_FORMAT ": set to clean", p2i(instruction_address())); print(); } @@ -354,7 +354,7 @@ void CompiledIC::set_to_monomorphic(CompiledICInfo& info) { if (TraceICs) { ResourceMark rm(thread); tty->print_cr ("IC@" INTPTR_FORMAT ": monomorphic to interpreter: %s", - instruction_address(), + p2i(instruction_address()), method->print_value_string()); } } else { @@ -362,7 +362,7 @@ void CompiledIC::set_to_monomorphic(CompiledICInfo& info) { InlineCacheBuffer::create_transition_stub(this, info.claim_cached_icholder(), info.entry()); if (TraceICs) { ResourceMark rm(thread); - tty->print_cr ("IC@" INTPTR_FORMAT ": monomorphic to interpreter via icholder ", instruction_address()); + tty->print_cr ("IC@" INTPTR_FORMAT ": monomorphic to interpreter via icholder ", p2i(instruction_address())); } } } else { @@ -392,7 +392,7 @@ void CompiledIC::set_to_monomorphic(CompiledICInfo& info) { ResourceMark rm(thread); assert(info.cached_metadata() == NULL || info.cached_metadata()->is_klass(), "must be"); tty->print_cr ("IC@" INTPTR_FORMAT ": monomorphic to compiled (rcvr klass) %s: %s", - instruction_address(), + p2i(instruction_address()), ((Klass*)info.cached_metadata())->print_value_string(), (safe) ? "" : "via stub"); } @@ -530,8 +530,8 @@ void CompiledStaticCall::set(const StaticCallInfo& info) { if (TraceICs) { ResourceMark rm; tty->print_cr("CompiledStaticCall@" INTPTR_FORMAT ": set_to_compiled " INTPTR_FORMAT, - instruction_address(), - info.entry()); + p2i(instruction_address()), + p2i(info.entry())); } // Call to compiled code assert (CodeCache::contains(info.entry()), "wrong entry point"); @@ -600,11 +600,11 @@ void CompiledIC::print() { void CompiledIC::print_compiled_ic() { tty->print("Inline cache at " INTPTR_FORMAT ", calling %s " INTPTR_FORMAT " cached_value " INTPTR_FORMAT, - instruction_address(), is_call_to_interpreted() ? "interpreted " : "", ic_destination(), is_optimized() ? NULL : cached_value()); + p2i(instruction_address()), is_call_to_interpreted() ? "interpreted " : "", p2i(ic_destination()), p2i(is_optimized() ? NULL : cached_value())); } void CompiledStaticCall::print() { - tty->print("static call at " INTPTR_FORMAT " -> ", instruction_address()); + tty->print("static call at " INTPTR_FORMAT " -> ", p2i(instruction_address())); if (is_clean()) { tty->print("clean"); } else if (is_call_to_compiled()) { diff --git a/hotspot/src/share/vm/code/compressedStream.cpp b/hotspot/src/share/vm/code/compressedStream.cpp index 1716ffac651..4687372f833 100644 --- a/hotspot/src/share/vm/code/compressedStream.cpp +++ b/hotspot/src/share/vm/code/compressedStream.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -212,6 +212,8 @@ static jlong stretch(jint x, int bits) { return h ^ l; } +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_IGNORED // Someone needs to deal with this. void test_compressed_stream(int trace) { CompressedWriteStream bytes(stretch_limit * 100); jint n; @@ -275,6 +277,7 @@ void test_compressed_stream(int trace) { guarantee(length == length2, "bad length"); guarantee(fails == 0, "test failures"); } +PRAGMA_DIAG_POP #if defined(_MSC_VER) &&_MSC_VER >=1400 && !defined(_WIN64) #pragma warning(default: 4748) diff --git a/hotspot/src/share/vm/code/debugInfo.cpp b/hotspot/src/share/vm/code/debugInfo.cpp index ecdae461039..3b01884c6e4 100644 --- a/hotspot/src/share/vm/code/debugInfo.cpp +++ b/hotspot/src/share/vm/code/debugInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,9 @@ #include "code/nmethod.hpp" #include "runtime/handles.inline.hpp" -// Comstructors +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + +// Constructors DebugInfoWriteStream::DebugInfoWriteStream(DebugInformationRecorder* recorder, int initial_size) : CompressedWriteStream(initial_size) { diff --git a/hotspot/src/share/vm/code/exceptionHandlerTable.cpp b/hotspot/src/share/vm/code/exceptionHandlerTable.cpp index 9e259008287..511b84d220d 100644 --- a/hotspot/src/share/vm/code/exceptionHandlerTable.cpp +++ b/hotspot/src/share/vm/code/exceptionHandlerTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ #include "code/nmethod.hpp" #include "memory/allocation.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + void ExceptionHandlerTable::add_entry(HandlerTableEntry entry) { _nesting.check(); if (_length >= _size) { diff --git a/hotspot/src/share/vm/code/icBuffer.cpp b/hotspot/src/share/vm/code/icBuffer.cpp index 81ef87ce200..0fe6e0d1145 100644 --- a/hotspot/src/share/vm/code/icBuffer.cpp +++ b/hotspot/src/share/vm/code/icBuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,7 @@ #include "runtime/mutexLocker.hpp" #include "runtime/stubRoutines.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC DEF_STUB_INTERFACE(ICStub); diff --git a/hotspot/src/share/vm/code/nmethod.cpp b/hotspot/src/share/vm/code/nmethod.cpp index 89604e0caa8..86264436755 100644 --- a/hotspot/src/share/vm/code/nmethod.cpp +++ b/hotspot/src/share/vm/code/nmethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,6 +48,8 @@ #include "shark/sharkCompiler.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef DTRACE_ENABLED // Only bother with this argument setup if dtrace is available diff --git a/hotspot/src/share/vm/code/pcDesc.cpp b/hotspot/src/share/vm/code/pcDesc.cpp index 7ba25464f7d..7f27cc0c08c 100644 --- a/hotspot/src/share/vm/code/pcDesc.cpp +++ b/hotspot/src/share/vm/code/pcDesc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ #include "code/scopeDesc.hpp" #include "memory/resourceArea.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + PcDesc::PcDesc(int pc_offset, int scope_decode_offset, int obj_decode_offset) { _pc_offset = pc_offset; _scope_decode_offset = scope_decode_offset; diff --git a/hotspot/src/share/vm/code/relocInfo.cpp b/hotspot/src/share/vm/code/relocInfo.cpp index 7cff27f085e..aa0ef6b106e 100644 --- a/hotspot/src/share/vm/code/relocInfo.cpp +++ b/hotspot/src/share/vm/code/relocInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ #include "runtime/stubCodeGenerator.hpp" #include "utilities/copy.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC const RelocationHolder RelocationHolder::none; // its type is relocInfo::none diff --git a/hotspot/src/share/vm/code/scopeDesc.cpp b/hotspot/src/share/vm/code/scopeDesc.cpp index b1c3ccef764..7e557afcd35 100644 --- a/hotspot/src/share/vm/code/scopeDesc.cpp +++ b/hotspot/src/share/vm/code/scopeDesc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop) { _code = code; diff --git a/hotspot/src/share/vm/code/vtableStubs.cpp b/hotspot/src/share/vm/code/vtableStubs.cpp index b3bfc258f56..ac99da40e1c 100644 --- a/hotspot/src/share/vm/code/vtableStubs.cpp +++ b/hotspot/src/share/vm/code/vtableStubs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,8 @@ #include "opto/matcher.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // ----------------------------------------------------------------------------------------- // Implementation of VtableStub diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp index 8521806cd1f..b2320eac8bd 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.cpp +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -172,7 +172,7 @@ class CompilationLog : public StringEventLog { void log_nmethod(JavaThread* thread, nmethod* nm) { log(thread, "nmethod %d%s " INTPTR_FORMAT " code ["INTPTR_FORMAT ", " INTPTR_FORMAT "]", nm->compile_id(), nm->is_osr_method() ? "%" : "", - nm, nm->code_begin(), nm->code_end()); + p2i(nm), p2i(nm->code_begin()), p2i(nm->code_end())); } void log_failure(JavaThread* thread, CompileTask* task, const char* reason, const char* retry_message) { @@ -1786,7 +1786,7 @@ void CompileBroker::init_compiler_thread_log() { if (xtty != NULL) { ttyLocker ttyl; // Record any per thread log files - xtty->elem("thread_logfile thread='%d' filename='%s'", thread_id, file_name); + xtty->elem("thread_logfile thread='" INTX_FORMAT "' filename='%s'", thread_id, file_name); } return; } @@ -1817,7 +1817,7 @@ void CompileBroker::maybe_block() { if (_should_block) { #ifndef PRODUCT if (PrintCompilation && (Verbose || WizardMode)) - tty->print_cr("compiler thread " INTPTR_FORMAT " poll detects block request", Thread::current()); + tty->print_cr("compiler thread " INTPTR_FORMAT " poll detects block request", p2i(Thread::current())); #endif ThreadInVMfromNative tivfn(JavaThread::current()); } @@ -1834,7 +1834,7 @@ static void codecache_print(bool detailed) CodeCache::print_summary(&s, detailed); } ttyLocker ttyl; - tty->print(s.as_string()); + tty->print("%s", s.as_string()); } // ------------------------------------------------------------------ @@ -2039,7 +2039,7 @@ void CompileBroker::handle_full_code_cache() { // Lock to prevent tearing ttyLocker ttyl; xtty->begin_elem("code_cache_full"); - xtty->print(s.as_string()); + xtty->print("%s", s.as_string()); xtty->stamp(); xtty->end_elem(); } diff --git a/hotspot/src/share/vm/compiler/compileLog.cpp b/hotspot/src/share/vm/compiler/compileLog.cpp index 8753e7b2859..f2c04b6e4ff 100644 --- a/hotspot/src/share/vm/compiler/compileLog.cpp +++ b/hotspot/src/share/vm/compiler/compileLog.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -174,9 +174,9 @@ void CompileLog::name(ciSymbol* name) { void CompileLog::name(ciKlass* k) { print(" name='"); if (!k->is_loaded()) { - text()->print(k->name()->as_klass_external_name()); + text()->print("%s", k->name()->as_klass_external_name()); } else { - text()->print(k->external_name()); + text()->print("%s", k->external_name()); } print("'"); } @@ -303,7 +303,7 @@ void CompileLog::finish_log(outputStream* file) { // Print about successful method inlining. void CompileLog::inline_success(const char* reason) { begin_elem("inline_success reason='"); - text(reason); + text("%s", reason); end_elem("'"); } @@ -313,7 +313,7 @@ void CompileLog::inline_success(const char* reason) { // Print about failed method inlining. void CompileLog::inline_fail(const char* reason) { begin_elem("inline_fail reason='"); - text(reason); + text("%s", reason); end_elem("'"); } @@ -339,5 +339,5 @@ void CompileLog::set_context(const char* format, ...) { void CompileLog::code_cache_state() { begin_elem("code_cache"); CodeCache::log_state(this); - end_elem(""); + end_elem("%s", ""); } diff --git a/hotspot/src/share/vm/compiler/compileLog.hpp b/hotspot/src/share/vm/compiler/compileLog.hpp index 094dc767f7e..49e2b6a6180 100644 --- a/hotspot/src/share/vm/compiler/compileLog.hpp +++ b/hotspot/src/share/vm/compiler/compileLog.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ class CompileLog : public xmlStream { static CompileLog* _first; // head of static chain - void va_tag(bool push, const char* format, va_list ap); + void va_tag(bool push, const char* format, va_list ap) ATTRIBUTE_PRINTF(3, 0); public: CompileLog(const char* file_name, FILE* fp, intx thread_id); @@ -69,7 +69,7 @@ class CompileLog : public xmlStream { // or reset, context string will be silently ignored stringStream* context() { return &_context; } void clear_context() { context()->reset(); } - void set_context(const char* format, ...); + void set_context(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); void name(ciSymbol* s); // name='s' void name(Symbol* s) { xmlStream::name(s); } diff --git a/hotspot/src/share/vm/compiler/compilerOracle.cpp b/hotspot/src/share/vm/compiler/compilerOracle.cpp index 582ec675d4d..c58fb169309 100644 --- a/hotspot/src/share/vm/compiler/compilerOracle.cpp +++ b/hotspot/src/share/vm/compiler/compilerOracle.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -520,7 +520,7 @@ void CompilerOracle::parse_from_line(char* line) { tty->print_cr("CompilerOracle: unrecognized line"); tty->print_cr(" \"%s\"", original_line); if (error_msg != NULL) { - tty->print_cr(error_msg); + tty->print_cr("%s", error_msg); } } } @@ -642,7 +642,7 @@ void CompilerOracle::parse_compile_only(char * line) { char method_sep = have_colon ? ':' : '.'; if (Verbose) { - tty->print_cr(line); + tty->print_cr("%s", line); } ResourceMark rm; diff --git a/hotspot/src/share/vm/compiler/disassembler.cpp b/hotspot/src/share/vm/compiler/disassembler.cpp index 8495210c384..0e9c14c1549 100644 --- a/hotspot/src/share/vm/compiler/disassembler.cpp +++ b/hotspot/src/share/vm/compiler/disassembler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,6 +51,8 @@ #include "shark/sharkEntry.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + void* Disassembler::_library = NULL; bool Disassembler::_tried_to_load_library = false; @@ -411,6 +413,7 @@ static void* event_to_env(void* env_pv, const char* event, void* arg) { return env->handle_event(event, (address) arg); } +ATTRIBUTE_PRINTF(2, 3) static int printf_to_env(void* env_pv, const char* format, ...) { decode_env* env = (decode_env*) env_pv; outputStream* st = env->output(); diff --git a/hotspot/src/share/vm/compiler/methodLiveness.cpp b/hotspot/src/share/vm/compiler/methodLiveness.cpp index 4fcc5613336..0c1d9b09232 100644 --- a/hotspot/src/share/vm/compiler/methodLiveness.cpp +++ b/hotspot/src/share/vm/compiler/methodLiveness.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,8 @@ #include "memory/allocation.inline.hpp" #include "utilities/bitMap.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // The MethodLiveness class performs a simple liveness analysis on a method // in order to decide which locals are live (that is, will be used again) at // a particular bytecode index (bci). diff --git a/hotspot/src/share/vm/compiler/oopMap.cpp b/hotspot/src/share/vm/compiler/oopMap.cpp index c4c83fc164d..5e1801584c2 100644 --- a/hotspot/src/share/vm/compiler/oopMap.cpp +++ b/hotspot/src/share/vm/compiler/oopMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -633,8 +633,8 @@ void DerivedPointerTable::add(oop *derived_loc, oop *base_loc) { tty->print_cr( "Add derived pointer@" INTPTR_FORMAT " - Derived: " INTPTR_FORMAT - " Base: " INTPTR_FORMAT " (@" INTPTR_FORMAT ") (Offset: %d)", - derived_loc, (address)*derived_loc, (address)*base_loc, base_loc, offset + " Base: " INTPTR_FORMAT " (@" INTPTR_FORMAT ") (Offset: " INTX_FORMAT ")", + p2i(derived_loc), p2i((address)*derived_loc), p2i((address)*base_loc), p2i(base_loc), offset ); } // Set derived oop location to point to base. @@ -661,8 +661,8 @@ void DerivedPointerTable::update_pointers() { if (TraceDerivedPointers) { tty->print_cr("Updating derived pointer@" INTPTR_FORMAT - " - Derived: " INTPTR_FORMAT " Base: " INTPTR_FORMAT " (Offset: %d)", - derived_loc, (address)*derived_loc, (address)base, offset); + " - Derived: " INTPTR_FORMAT " Base: " INTPTR_FORMAT " (Offset: " INTX_FORMAT ")", + p2i(derived_loc), p2i((address)*derived_loc), p2i((address)base), offset); } // Delete entry diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp index 309fe014aa1..b7f7ed1f0a3 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -157,7 +157,7 @@ void AdaptiveFreeList<Chunk>::verify_stats() const { " split_deaths(" SIZE_FORMAT ")" " coal_deaths(" SIZE_FORMAT ")" " + count(" SSIZE_FORMAT ")", - this, size(), _allocation_stats.prev_sweep(), _allocation_stats.split_births(), + p2i(this), size(), _allocation_stats.prev_sweep(), _allocation_stats.split_births(), _allocation_stats.coal_births(), _allocation_stats.split_deaths(), _allocation_stats.coal_deaths(), count())); } diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp index bbaffb9bf2e..da4bf278299 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -428,7 +428,7 @@ size_t CompactibleFreeListSpace::max_alloc_in_words() const { void LinearAllocBlock::print_on(outputStream* st) const { st->print_cr(" LinearAllocBlock: ptr = " PTR_FORMAT ", word_size = " SIZE_FORMAT ", refillsize = " SIZE_FORMAT ", allocation_size_limit = " SIZE_FORMAT, - _ptr, _word_size, _refillSize, _allocation_size_limit); + p2i(_ptr), _word_size, _refillSize, _allocation_size_limit); } void CompactibleFreeListSpace::print_on(outputStream* st) const { @@ -459,7 +459,7 @@ const { for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL; fc = fc->next()) { gclog_or_tty->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ") %s", - fc, (HeapWord*)fc + i, + p2i(fc), p2i((HeapWord*)fc + i), fc->cantCoalesce() ? "\t CC" : ""); } } @@ -503,7 +503,7 @@ size_t BlkPrintingClosure::do_blk(HeapWord* addr) { if (_sp->block_is_obj(addr)) { const bool dead = _post_remark && !_live_bit_map->isMarked(addr); _st->print_cr(PTR_FORMAT ": %s object of size " SIZE_FORMAT "%s", - addr, + p2i(addr), dead ? "dead" : "live", sz, (!dead && CMSPrintObjectsInDump) ? ":" : "."); @@ -513,7 +513,7 @@ size_t BlkPrintingClosure::do_blk(HeapWord* addr) { } } else { // free block _st->print_cr(PTR_FORMAT ": free block of size " SIZE_FORMAT "%s", - addr, sz, CMSPrintChunksInDump ? ":" : "."); + p2i(addr), sz, CMSPrintChunksInDump ? ":" : "."); if (CMSPrintChunksInDump) { ((FreeChunk*)addr)->print_on(_st); _st->print_cr("--------------------------------------"); @@ -1983,7 +1983,7 @@ void CompactibleFreeListSpace::save_marks() { assert(ur.contains(urasm), err_msg(" Error at save_marks(): [" PTR_FORMAT "," PTR_FORMAT ")" " should contain [" PTR_FORMAT "," PTR_FORMAT ")", - ur.start(), ur.end(), urasm.start(), urasm.end())); + p2i(ur.start()), p2i(ur.end()), p2i(urasm.start()), p2i(urasm.end()))); #endif // inform allocator that promotions should be tracked. assert(_promoInfo.noPromotions(), "_promoInfo inconsistency"); @@ -2206,7 +2206,7 @@ void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) { if (PrintFLSStatistics > 0) { HeapWord* largestAddr = (HeapWord*) dictionary()->find_largest_dict(); gclog_or_tty->print_cr("CMS: Large block " PTR_FORMAT, - largestAddr); + p2i(largestAddr)); } setFLSurplus(); setFLHints(); @@ -2355,8 +2355,8 @@ class VerifyAllBlksClosure: public BlkClosure { gclog_or_tty->print_cr( " Current: addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n" " Previous: addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n", - addr, res, was_obj ?"true":"false", was_live ?"true":"false", - _last_addr, _last_size, _last_was_obj?"true":"false", _last_was_live?"true":"false"); + p2i(addr), res, was_obj ?"true":"false", was_live ?"true":"false", + p2i(_last_addr), _last_size, _last_was_obj?"true":"false", _last_was_live?"true":"false"); _sp->print_on(gclog_or_tty); guarantee(false, "Seppuku!"); } diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp index 9f01fcd54a4..e1d5e29a84b 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -403,7 +403,7 @@ class CompactibleFreeListSpace: public CompactibleSpace { if (CMSTraceSweeper) { gclog_or_tty->print_cr(">>>>> Saving sweep limit " PTR_FORMAT " for space [" PTR_FORMAT "," PTR_FORMAT ") <<<<<<", - _sweep_limit, bottom(), end()); + p2i(_sweep_limit), p2i(bottom()), p2i(end())); } } NOT_PRODUCT( diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index 3d108c28181..b3e47f03d80 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,6 +64,8 @@ #include "services/memoryService.hpp" #include "services/runtimeService.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // statics CMSCollector* ConcurrentMarkSweepGeneration::_collector = NULL; bool CMSCollector::_full_gc_requested = false; @@ -1182,7 +1184,7 @@ void CMSCollector::icms_update_allocation_limits() gclog_or_tty->print(" icms alloc limits: " PTR_FORMAT "," PTR_FORMAT " (" SIZE_FORMAT "%%," SIZE_FORMAT "%%) ", - _icms_start_limit, _icms_stop_limit, + p2i(_icms_start_limit), p2i(_icms_stop_limit), percent_of_space(eden, _icms_start_limit), percent_of_space(eden, _icms_stop_limit)); if (Verbose) { @@ -1210,7 +1212,7 @@ CMSCollector::allocation_limit_reached(Space* space, HeapWord* top, gclog_or_tty->print_cr(" start limit top=" PTR_FORMAT ", new limit=" PTR_FORMAT " (" SIZE_FORMAT "%%)", - top, _icms_stop_limit, + p2i(top), p2i(_icms_stop_limit), percent_of_space(space, _icms_stop_limit)); } ConcurrentMarkSweepThread::start_icms(); @@ -1227,7 +1229,7 @@ CMSCollector::allocation_limit_reached(Space* space, HeapWord* top, gclog_or_tty->print_cr(" +stop limit top=" PTR_FORMAT ", new limit=" PTR_FORMAT " (" SIZE_FORMAT "%%)", - top, space->end(), + p2i(top), p2i(space->end()), percent_of_space(space, space->end())); } ConcurrentMarkSweepThread::stop_icms(); @@ -1502,7 +1504,7 @@ bool CMSCollector::shouldConcurrentCollect() { if (PrintCMSInitiationStatistics && stats().valid()) { gclog_or_tty->print("CMSCollector shouldConcurrentCollect: "); gclog_or_tty->stamp(); - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); stats().print_on(gclog_or_tty); gclog_or_tty->print_cr("time_until_cms_gen_full %3.7f", stats().time_until_cms_gen_full()); @@ -3588,7 +3590,7 @@ CMSPhaseAccounting::~CMSPhaseAccounting() { _collector->cmsGen()->short_name(), _phase, _collector->timerValue(), _wallclock.seconds()); if (_print_cr) { - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); } if (PrintCMSStatistics != 0) { gclog_or_tty->print_cr(" (CMS-concurrent-%s yielded %d times)", _phase, diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp index 75c1ddcc0dd..0479143d4f9 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -111,7 +111,7 @@ void ConcurrentMarkSweepThread::run() { // From this time Thread::current() should be working. assert(this == Thread::current(), "just checking"); if (BindCMSThreadToCPU && !os::bind_to_processor(CPUForCMSThread)) { - warning("Couldn't bind CMS thread to processor %u", CPUForCMSThread); + warning("Couldn't bind CMS thread to processor " UINTX_FORMAT, CPUForCMSThread); } // Wait until Universe::is_fully_initialized() { diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp index 7da7511905f..5f508cc09a4 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -239,7 +239,7 @@ inline void ConcurrentMarkSweepThread::trace_state(const char* desc) { jio_snprintf(buf, sizeof(buf), " [%.3f: CMSThread %s] ", ts.seconds(), desc); buf[sizeof(buf) - 1] = '\0'; - gclog_or_tty->print(buf); + gclog_or_tty->print("%s", buf); } } @@ -271,7 +271,7 @@ class CMSLoopCountWarn: public StackObj { inline void tick() { _ticks++; if (CMSLoopWarn && _ticks % _threshold == 0) { - warning("%s has looped %d times %s", _src, _ticks, _msg); + warning("%s has looped " INTX_FORMAT " times %s", _src, _ticks, _msg); } } }; diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp index 34ee7d67b9a..133ed3c5969 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ #include "memory/freeBlockDictionary.hpp" #include "utilities/copy.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifndef PRODUCT #define baadbabeHeapWord badHeapWordVal diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp index cc870308548..44f5a287c6e 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,8 @@ #include "oops/markOop.inline.hpp" #include "oops/oop.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + ///////////////////////////////////////////////////////////////////////// //// PromotionInfo ///////////////////////////////////////////////////////////////////////// diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp index 46c0650a772..ca1a1124643 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,7 @@ #include "runtime/os.hpp" #include "utilities/dtrace.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC ////////////////////////////////////////////////////////// // Methods in abstract class VM_CMS_Operation diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index de13a943c10..ad21b8ed7b6 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -537,7 +537,7 @@ ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs) : if (verbose_low()) { gclog_or_tty->print_cr("[global] init, heap start = "PTR_FORMAT", " - "heap end = "PTR_FORMAT, _heap_start, _heap_end); + "heap end = " PTR_FORMAT, p2i(_heap_start), p2i(_heap_end)); } if (!_markBitMap1.allocate(heap_rs)) { @@ -651,7 +651,7 @@ ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs) : if (!(mark_stack_size >= 1 && mark_stack_size <= MarkStackSizeMax)) { warning("Invalid value calculated for MarkStackSize (" UINTX_FORMAT "): " "must be between " UINTX_FORMAT " and " UINTX_FORMAT, - mark_stack_size, 1, MarkStackSizeMax); + mark_stack_size, (uintx) 1, MarkStackSizeMax); return; } FLAG_SET_ERGO(uintx, MarkStackSize, mark_stack_size); @@ -662,7 +662,7 @@ ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs) : if (!(MarkStackSize >= 1 && MarkStackSize <= MarkStackSizeMax)) { warning("Invalid value specified for MarkStackSize (" UINTX_FORMAT "): " "must be between " UINTX_FORMAT " and " UINTX_FORMAT, - MarkStackSize, 1, MarkStackSizeMax); + MarkStackSize, (uintx) 1, MarkStackSizeMax); return; } } else if (FLAG_IS_CMDLINE(MarkStackSizeMax)) { @@ -821,7 +821,7 @@ void ConcurrentMark::set_concurrency_and_phase(uint active_tasks, bool concurren assert(!concurrent_marking_in_progress(), "invariant"); assert(_finger == _heap_end, err_msg("only way to get here: _finger: "PTR_FORMAT", _heap_end: "PTR_FORMAT, - _finger, _heap_end)); + p2i(_finger), p2i(_heap_end))); update_g1_committed(true); } } @@ -1424,7 +1424,7 @@ public: assert(start <= hr->end() && start <= ntams && ntams <= hr->end(), err_msg("Preconditions not met - " "start: "PTR_FORMAT", ntams: "PTR_FORMAT", end: "PTR_FORMAT, - start, ntams, hr->end())); + p2i(start), p2i(ntams), p2i(hr->end()))); // Find the first marked object at or after "start". start = _bm->getNextMarkedWordAddress(start, ntams); @@ -1609,7 +1609,7 @@ public: if (failures > 0 && _verbose) { gclog_or_tty->print_cr("Region " HR_FORMAT ", ntams: " PTR_FORMAT ", " "marked_bytes: calc/actual " SIZE_FORMAT "/" SIZE_FORMAT, - HR_FORMAT_PARAMS(hr), hr->next_top_at_mark_start(), + HR_FORMAT_PARAMS(hr), p2i(hr->next_top_at_mark_start()), _calc_cl.region_marked_bytes(), hr->next_marked_bytes()); } @@ -2241,7 +2241,7 @@ class G1CMKeepAliveAndDrainClosure: public OopClosure { if (_cm->verbose_high()) { gclog_or_tty->print_cr("\t[%u] we're looking at location " "*"PTR_FORMAT" = "PTR_FORMAT, - _task->worker_id(), p, (void*) obj); + _task->worker_id(), p2i(p), p2i((void*) obj)); } _task->deal_with_reference(obj); @@ -2675,7 +2675,7 @@ public: } _out->print_cr(" "PTR_FORMAT": "PTR_FORMAT"%s%s", - p, (void*) obj, str, str2); + p2i(p), p2i((void*) obj), str, str2); } }; @@ -2702,7 +2702,7 @@ public: if (print_it) { _out->print_cr(" "PTR_FORMAT"%s", - (void *)o, (over_tams) ? " >" : (marked) ? " M" : ""); + p2i((void *)o), (over_tams) ? " >" : (marked) ? " M" : ""); PrintReachableOopClosure oopCl(_out, _vo, _all); o->oop_iterate_no_header(&oopCl); } @@ -2723,14 +2723,14 @@ public: HeapWord* t = hr->top(); HeapWord* p = _g1h->top_at_mark_start(hr, _vo); _out->print_cr("** ["PTR_FORMAT", "PTR_FORMAT"] top: "PTR_FORMAT" " - "TAMS: "PTR_FORMAT, b, e, t, p); + "TAMS: " PTR_FORMAT, p2i(b), p2i(e), p2i(t), p2i(p)); _out->cr(); HeapWord* from = b; HeapWord* to = t; if (to > from) { - _out->print_cr("Objects in ["PTR_FORMAT", "PTR_FORMAT"]", from, to); + _out->print_cr("Objects in [" PTR_FORMAT ", " PTR_FORMAT "]", p2i(from), p2i(to)); _out->cr(); PrintReachableObjectClosure ocl(_out, _vo, _all, hr); hr->object_iterate_mem_careful(MemRegion(from, to), &ocl); @@ -2846,7 +2846,7 @@ ConcurrentMark::claim_region(uint worker_id) { gclog_or_tty->print_cr("[%u] curr_region = "PTR_FORMAT" " "["PTR_FORMAT", "PTR_FORMAT"), " "limit = "PTR_FORMAT, - worker_id, curr_region, bottom, end, limit); + worker_id, p2i(curr_region), p2i(bottom), p2i(end), p2i(limit)); } // Is the gap between reading the finger and doing the CAS too long? @@ -2860,13 +2860,13 @@ ConcurrentMark::claim_region(uint worker_id) { if (verbose_low()) { gclog_or_tty->print_cr("[%u] we were successful with region = " - PTR_FORMAT, worker_id, curr_region); + PTR_FORMAT, worker_id, p2i(curr_region)); } if (limit > bottom) { if (verbose_low()) { gclog_or_tty->print_cr("[%u] region "PTR_FORMAT" is not empty, " - "returning it ", worker_id, curr_region); + "returning it ", worker_id, p2i(curr_region)); } return curr_region; } else { @@ -2874,7 +2874,7 @@ ConcurrentMark::claim_region(uint worker_id) { "the region limit should be at bottom"); if (verbose_low()) { gclog_or_tty->print_cr("[%u] region "PTR_FORMAT" is empty, " - "returning NULL", worker_id, curr_region); + "returning NULL", worker_id, p2i(curr_region)); } // we return NULL and the caller should try calling // claim_region() again. @@ -2886,7 +2886,7 @@ ConcurrentMark::claim_region(uint worker_id) { gclog_or_tty->print_cr("[%u] somebody else moved the finger, " "global finger = "PTR_FORMAT", " "our finger = "PTR_FORMAT, - worker_id, _finger, finger); + worker_id, p2i(_finger), p2i(finger)); } // read it again @@ -2925,7 +2925,7 @@ private: void do_object_work(oop obj) { guarantee(!_g1h->obj_in_cs(obj), err_msg("obj: "PTR_FORMAT" in CSet, phase: %s, info: %d", - (void*) obj, phase_str(), _info)); + p2i((void*) obj), phase_str(), _info)); } public: @@ -3004,7 +3004,7 @@ void ConcurrentMark::verify_no_cset_oops(bool verify_stacks, HeapRegion* global_hr = _g1h->heap_region_containing_raw(global_finger); guarantee(global_finger == global_hr->bottom(), err_msg("global finger: "PTR_FORMAT" region: "HR_FORMAT, - global_finger, HR_FORMAT_PARAMS(global_hr))); + p2i(global_finger), HR_FORMAT_PARAMS(global_hr))); } // Verify the task fingers @@ -3018,7 +3018,7 @@ void ConcurrentMark::verify_no_cset_oops(bool verify_stacks, guarantee(task_finger == task_hr->bottom() || !task_hr->in_collection_set(), err_msg("task finger: "PTR_FORMAT" region: "HR_FORMAT, - task_finger, HR_FORMAT_PARAMS(task_hr))); + p2i(task_finger), HR_FORMAT_PARAMS(task_hr))); } } } @@ -3062,7 +3062,7 @@ class AggregateCountDataHRClosure: public HeapRegionClosure { err_msg("Preconditions not met - " "start: "PTR_FORMAT", limit: "PTR_FORMAT", " "top: "PTR_FORMAT", end: "PTR_FORMAT, - start, limit, hr->top(), hr->end())); + p2i(start), p2i(limit), p2i(hr->top()), p2i(hr->end()))); assert(hr->next_marked_bytes() == 0, "Precondition"); @@ -3303,7 +3303,7 @@ void ConcurrentMark::print_worker_threads_on(outputStream* st) const { void ConcurrentMark::print_on_error(outputStream* st) const { st->print_cr("Marking Bits (Prev, Next): (CMBitMap*) " PTR_FORMAT ", (CMBitMap*) " PTR_FORMAT, - _prevMarkBitMap, _nextMarkBitMap); + p2i(_prevMarkBitMap), p2i(_nextMarkBitMap)); _prevMarkBitMap->print_on_error(st, " Prev Bits: "); _nextMarkBitMap->print_on_error(st, " Next Bits: "); } @@ -3336,11 +3336,11 @@ bool ConcurrentMark::containing_cards_are_marked(void* start, // for debugging purposes void ConcurrentMark::print_finger() { gclog_or_tty->print_cr("heap ["PTR_FORMAT", "PTR_FORMAT"), global finger = "PTR_FORMAT, - _heap_start, _heap_end, _finger); + p2i(_heap_start), p2i(_heap_end), p2i(_finger)); for (uint i = 0; i < _max_worker_id; ++i) { - gclog_or_tty->print(" %u: "PTR_FORMAT, i, _tasks[i]->finger()); + gclog_or_tty->print(" %u: " PTR_FORMAT, i, p2i(_tasks[i]->finger())); } - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); } #endif @@ -3349,7 +3349,7 @@ void CMTask::scan_object(oop obj) { if (_cm->verbose_high()) { gclog_or_tty->print_cr("[%u] we're scanning object "PTR_FORMAT, - _worker_id, (void*) obj); + _worker_id, p2i((void*) obj)); } size_t obj_size = obj->size(); @@ -3428,7 +3428,7 @@ void CMTask::setup_for_region(HeapRegion* hr) { if (_cm->verbose_low()) { gclog_or_tty->print_cr("[%u] setting up for region "PTR_FORMAT, - _worker_id, hr); + _worker_id, p2i(hr)); } _curr_region = hr; @@ -3445,7 +3445,7 @@ void CMTask::update_region_limit() { if (_cm->verbose_low()) { gclog_or_tty->print_cr("[%u] found an empty region " "["PTR_FORMAT", "PTR_FORMAT")", - _worker_id, bottom, limit); + _worker_id, p2i(bottom), p2i(limit)); } // The region was collected underneath our feet. // We set the finger to bottom to ensure that the bitmap @@ -3477,7 +3477,7 @@ void CMTask::giveup_current_region() { assert(_curr_region != NULL, "invariant"); if (_cm->verbose_low()) { gclog_or_tty->print_cr("[%u] giving up region "PTR_FORMAT, - _worker_id, _curr_region); + _worker_id, p2i(_curr_region)); } clear_region_fields(); } @@ -3768,7 +3768,7 @@ void CMTask::drain_local_queue(bool partially) { if (_cm->verbose_high()) { gclog_or_tty->print_cr("[%u] popped "PTR_FORMAT, _worker_id, - (void*) obj); + p2i((void*) obj)); } assert(_g1h->is_in_g1_reserved((HeapWord*) obj), "invariant" ); @@ -4153,7 +4153,7 @@ void CMTask::do_marking_step(double time_target_ms, gclog_or_tty->print_cr("[%u] we're scanning part " "["PTR_FORMAT", "PTR_FORMAT") " "of region "HR_FORMAT, - _worker_id, _finger, _region_limit, + _worker_id, p2i(_finger), p2i(_region_limit), HR_FORMAT_PARAMS(_curr_region)); } @@ -4240,7 +4240,7 @@ void CMTask::do_marking_step(double time_target_ms, if (_cm->verbose_low()) { gclog_or_tty->print_cr("[%u] we successfully claimed " "region "PTR_FORMAT, - _worker_id, claimed_region); + _worker_id, p2i(claimed_region)); } setup_for_region(claimed_region); @@ -4301,7 +4301,7 @@ void CMTask::do_marking_step(double time_target_ms, if (_cm->try_stealing(_worker_id, &_hash_seed, obj)) { if (_cm->verbose_medium()) { gclog_or_tty->print_cr("[%u] stolen "PTR_FORMAT" successfully", - _worker_id, (void*) obj); + _worker_id, p2i((void*) obj)); } statsOnly( ++_steals ); @@ -4549,8 +4549,8 @@ G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name) G1PPRL_SUM_ADDR_FORMAT("committed") G1PPRL_SUM_ADDR_FORMAT("reserved") G1PPRL_SUM_BYTE_FORMAT("region-size"), - g1_committed.start(), g1_committed.end(), - g1_reserved.start(), g1_reserved.end(), + p2i(g1_committed.start()), p2i(g1_committed.end()), + p2i(g1_reserved.start()), p2i(g1_reserved.end()), HeapRegion::GrainBytes); _out->print_cr(G1PPRL_LINE_PREFIX); _out->print_cr(G1PPRL_LINE_PREFIX @@ -4667,7 +4667,7 @@ bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) { G1PPRL_DOUBLE_FORMAT G1PPRL_BYTE_FORMAT G1PPRL_BYTE_FORMAT, - type, bottom, end, + type, p2i(bottom), p2i(end), used_bytes, prev_live_bytes, next_live_bytes, gc_eff, remset_bytes, strong_code_roots_bytes); diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp index e4ca5ecee5e..12ba5683ed8 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -277,7 +277,7 @@ inline void CMTask::push(oop obj) { assert(_nextMarkBitMap->isMarked(objAddr), "invariant"); if (_cm->verbose_high()) { - gclog_or_tty->print_cr("[%u] pushing "PTR_FORMAT, _worker_id, (void*) obj); + gclog_or_tty->print_cr("[%u] pushing " PTR_FORMAT, _worker_id, p2i((void*) obj)); } if (!_task_queue->push(obj)) { @@ -317,7 +317,7 @@ inline void CMTask::push(oop obj) { inline void CMTask::deal_with_reference(oop obj) { if (_cm->verbose_high()) { gclog_or_tty->print_cr("[%u] we're dealing with reference = "PTR_FORMAT, - _worker_id, (void*) obj); + _worker_id, p2i((void*) obj)); } ++_refs_reached; @@ -334,7 +334,7 @@ inline void CMTask::deal_with_reference(oop obj) { if (!hr->obj_allocated_since_next_marking(obj)) { if (_cm->verbose_high()) { gclog_or_tty->print_cr("[%u] "PTR_FORMAT" is not considered marked", - _worker_id, (void*) obj); + _worker_id, p2i((void*) obj)); } // we need to mark it first @@ -349,7 +349,7 @@ inline void CMTask::deal_with_reference(oop obj) { if (_finger != NULL && objAddr < _finger) { if (_cm->verbose_high()) { gclog_or_tty->print_cr("[%u] below the local finger ("PTR_FORMAT"), " - "pushing it", _worker_id, _finger); + "pushing it", _worker_id, p2i(_finger)); } push(obj); } else if (_curr_region != NULL && objAddr < _region_limit) { @@ -367,7 +367,7 @@ inline void CMTask::deal_with_reference(oop obj) { if (_cm->verbose_high()) { gclog_or_tty->print_cr("[%u] below the global finger " "("PTR_FORMAT"), pushing it", - _worker_id, global_finger); + _worker_id, p2i(global_finger)); } push(obj); } else { @@ -382,7 +382,7 @@ inline void CMTask::deal_with_reference(oop obj) { if (_cm->verbose_high()) { gclog_or_tty->print_cr("[%u] below the global finger " "("PTR_FORMAT"), pushing it", - _worker_id, global_finger); + _worker_id, p2i(global_finger)); } push(obj); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp index 58a76c1dd26..a0d994738fd 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -143,7 +143,7 @@ HeapWord* G1AllocRegion::new_alloc_region_and_allocate(size_t word_size, void G1AllocRegion::fill_in_ext_msg(ar_ext_msg* msg, const char* message) { msg->append("[%s] %s c: %u b: %s r: "PTR_FORMAT" u: "SIZE_FORMAT, _name, message, _count, BOOL_TO_STR(_bot_updates), - _alloc_region, _used_bytes_before); + p2i(_alloc_region), _used_bytes_before); } void G1AllocRegion::init() { diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp index 3f6e040bf54..050490dbbef 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -184,7 +184,7 @@ public: class ar_ext_msg : public err_msg { public: - ar_ext_msg(G1AllocRegion* alloc_region, const char *message) : err_msg("") { + ar_ext_msg(G1AllocRegion* alloc_region, const char *message) : err_msg("%s", "") { alloc_region->fill_in_ext_msg(this, message); } }; diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.cpp index d5851a6d467..8c5bef77122 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,7 +65,7 @@ public: REGION_SIZE_IN_WORDS * HeapWordSize); // Check address calculation (bounds) assert(array.bottom_address_mapped() == fake_heap, - err_msg("bottom mapped address should be "PTR_FORMAT", but is "PTR_FORMAT, fake_heap, array.bottom_address_mapped())); + err_msg("bottom mapped address should be " PTR_FORMAT ", but is " PTR_FORMAT, p2i(fake_heap), p2i(array.bottom_address_mapped()))); assert(array.end_address_mapped() == (fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS), "must be"); int* bottom = array.address_mapped_to(fake_heap); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.hpp index b0b7a76e1fe..f7ec3e39f2d 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ protected: void initialize_base(address base, size_t length, size_t bias, size_t elem_size, uint shift_by) { assert(base != NULL, "just checking"); assert(length > 0, "just checking"); - assert(shift_by < sizeof(uintptr_t) * 8, err_msg("Shifting by %zd, larger than word size?", shift_by)); + assert(shift_by < sizeof(uintptr_t) * 8, err_msg("Shifting by %u, larger than word size?", shift_by)); _base = base; _length = length; _biased_base = base - (bias * elem_size); @@ -71,10 +71,10 @@ protected: err_msg("mapping granularity must be power of 2, is %zd", mapping_granularity_in_bytes)); assert((uintptr_t)bottom % mapping_granularity_in_bytes == 0, err_msg("bottom mapping area address must be a multiple of mapping granularity %zd, is "PTR_FORMAT, - mapping_granularity_in_bytes, bottom)); + mapping_granularity_in_bytes, p2i(bottom))); assert((uintptr_t)end % mapping_granularity_in_bytes == 0, err_msg("end mapping area address must be a multiple of mapping granularity %zd, is "PTR_FORMAT, - mapping_granularity_in_bytes, end)); + mapping_granularity_in_bytes, p2i(end))); size_t num_target_elems = pointer_delta(end, bottom, mapping_granularity_in_bytes); idx_t bias = (uintptr_t)bottom / mapping_granularity_in_bytes; address base = create_new_base_array(num_target_elems, target_elem_size_in_bytes); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp index 9777c17b5a8..14d0126e224 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ #include "runtime/java.hpp" #include "services/memTracker.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + ////////////////////////////////////////////////////////////////////// // G1BlockOffsetSharedArray ////////////////////////////////////////////////////////////////////// diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp index ba664ee5275..56dca4d26f8 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,7 +80,7 @@ public: virtual void set_bottom(HeapWord* new_bottom) { assert(new_bottom <= _end, err_msg("new_bottom (" PTR_FORMAT ") > _end (" PTR_FORMAT ")", - new_bottom, _end)); + p2i(new_bottom), p2i(_end))); _bottom = new_bottom; resize(pointer_delta(_end, _bottom)); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp index d300f56255f..5ae3bc1cdeb 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ inline size_t G1BlockOffsetSharedArray::index_for(const void* p) const { assert(pc >= (char*)_reserved.start() && pc < (char*)_reserved.end(), err_msg("p (" PTR_FORMAT ") not in reserved [" PTR_FORMAT ", " PTR_FORMAT ")", - p, (char*)_reserved.start(), (char*)_reserved.end())); + p2i(p), p2i(_reserved.start()), p2i(_reserved.end()))); size_t delta = pointer_delta(pc, _reserved.start(), sizeof(char)); size_t result = delta >> LogN; check_index(result, "bad index from address"); @@ -65,7 +65,7 @@ G1BlockOffsetSharedArray::address_for_index(size_t index) const { err_msg("bad address from index result " PTR_FORMAT " _reserved.start() " PTR_FORMAT " _reserved.end() " PTR_FORMAT, - result, _reserved.start(), _reserved.end())); + p2i(result), p2i(_reserved.start()), p2i(_reserved.end()))); return result; } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp index ccb7c3f10b3..9fff9604ff2 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ #include "services/memTracker.hpp" #include "utilities/copy.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) { if (has_count_table()) { assert(from_card_num >= 0 && from_card_num < _committed_max_card_num, diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp index 129b3b0d232..ef08479f60a 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,10 +77,10 @@ class G1CardCounts: public CHeapObj<mtGC> { err_msg("Invalid card pointer: " "card_ptr: " PTR_FORMAT ", " "_ct_bot: " PTR_FORMAT, - card_ptr, _ct_bot)); + p2i(card_ptr), p2i(_ct_bot))); size_t card_num = pointer_delta(card_ptr, _ct_bot, sizeof(jbyte)); assert(card_num >= 0 && card_num < _committed_max_card_num, - err_msg("card pointer out of range: " PTR_FORMAT, card_ptr)); + err_msg("card pointer out of range: " PTR_FORMAT, p2i(card_ptr))); return card_num; } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp index 1130278fa91..fbe7095f75c 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp @@ -28,6 +28,8 @@ #include "gc_implementation/g1/g1CodeCacheRemSet.hpp" #include "memory/iterator.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + G1CodeRootChunk::G1CodeRootChunk() : _top(NULL), _next(NULL), _prev(NULL) { _top = bottom(); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 46feeea2841..70a7568f62f 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -22,6 +22,11 @@ * */ +#if !defined(__clang_major__) && defined(__GNUC__) +// FIXME, formats have issues. Disable this macro definition, compile, and study warnings for more information. +#define ATTRIBUTE_PRINTF(x,y) +#endif + #include "precompiled.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" @@ -370,7 +375,7 @@ void YoungList::print() { } } - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); } void G1CollectedHeap::push_dirty_cards_region(HeapRegion* hr) @@ -3470,7 +3475,7 @@ void G1CollectedHeap::verify(bool silent, VerifyOption vo) { // help us track down what went wrong. This is why we call // print_extended_on() instead of print_on(). print_extended_on(gclog_or_tty); - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); #ifndef PRODUCT if (VerifyDuringGC && G1VerifyDuringGCPrintReachable) { concurrent_mark()->print_reachable("at-verification-failure", @@ -3664,7 +3669,7 @@ public: PrintRSetsClosure(const char* msg) : _msg(msg), _occupied_sum(0) { gclog_or_tty->cr(); gclog_or_tty->print_cr("========================================"); - gclog_or_tty->print_cr(msg); + gclog_or_tty->print_cr("%s", msg); gclog_or_tty->cr(); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp index b308d4a00dd..42a5931815b 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ G1CollectedHeap::heap_region_containing_raw(const T addr) const { assert(addr != NULL, "invariant"); assert(_g1_reserved.contains((const void*) addr), err_msg("Address "PTR_FORMAT" is outside of the heap ranging from ["PTR_FORMAT" to "PTR_FORMAT")", - (void*)addr, _g1_reserved.start(), _g1_reserved.end())); + p2i((void*)addr), p2i(_g1_reserved.start()), p2i(_g1_reserved.end()))); return _hrs.addr_to_region((HeapWord*) addr); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp index a0b40d4dbf1..89b6f3fa616 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,11 @@ * */ +#ifndef __clang_major__ +// FIXME, formats have issues. Disable this macro definition, compile, and study warnings for more information. +#define ATTRIBUTE_PRINTF(x,y) +#endif + #include "precompiled.hpp" #include "gc_implementation/g1/concurrentG1Refine.hpp" #include "gc_implementation/g1/concurrentMark.hpp" @@ -965,7 +970,7 @@ void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms, Evacua #ifndef PRODUCT if (G1YoungSurvRateVerbose) { - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); _short_lived_surv_rate_group->print(); // do that for any other surv rate groups too } @@ -2222,11 +2227,11 @@ void TraceGen0TimeData::print() const { gclog_or_tty->print_cr("ALL PAUSES"); print_summary_sd(" Total", &_total); - gclog_or_tty->print_cr(""); - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); + gclog_or_tty->cr(); gclog_or_tty->print_cr(" Young GC Pauses: %8d", _young_pause_num); gclog_or_tty->print_cr(" Mixed GC Pauses: %8d", _mixed_pause_num); - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); gclog_or_tty->print_cr("EVACUATION PAUSES"); @@ -2246,7 +2251,7 @@ void TraceGen0TimeData::print() const { print_summary(" Clear CT", &_clear_ct); print_summary(" Other", &_other); } - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); gclog_or_tty->print_cr("MISC"); print_summary_sd(" Stop World", &_all_stop_world_times_ms); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp index c4c3432ad43..8e361b63638 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp @@ -39,7 +39,7 @@ private: int _indent_level; int _cur; - void vappend(const char* format, va_list ap) { + void vappend(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0) { int res = vsnprintf(&_buffer[_cur], BUFFER_LEN - _cur, format, ap); if (res != -1) { _cur += res; @@ -63,14 +63,14 @@ public: } #endif - void append(const char* format, ...) { + void append(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) { va_list ap; va_start(ap, format); vappend(format, ap); va_end(ap); } - void append_and_print_cr(const char* format, ...) { + void append_and_print_cr(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) { va_list ap; va_start(ap, format); vappend(format, ap); @@ -80,6 +80,8 @@ public: } }; +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED template <class T> void WorkerDataArray<T>::print(int level, const char* title) { if (_length == 1) { @@ -109,7 +111,7 @@ void WorkerDataArray<T>::print(int level, const char* title) { } if (G1Log::finest()) { - buf.append_and_print_cr(""); + buf.append_and_print_cr("%s", ""); } double avg = (double)sum / (double)_length; @@ -129,6 +131,7 @@ void WorkerDataArray<T>::print(int level, const char* title) { } buf.append_and_print_cr("]"); } +PRAGMA_DIAG_POP #ifndef PRODUCT diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1HRPrinter.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1HRPrinter.cpp index 56a1a3be8a3..8139048ef23 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1HRPrinter.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1HRPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ #include "gc_implementation/g1/heapRegion.hpp" #include "utilities/ostream.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + const char* G1HRPrinter::action_name(ActionType action) { switch(action) { case Alloc: return "ALLOC"; diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp index 1fa7639729c..0c9f0cf2d49 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -114,7 +114,7 @@ inline void G1CMOopClosure::do_oop_nv(T* p) { if (_cm->verbose_high()) { gclog_or_tty->print_cr("[%u] we're looking at location " "*"PTR_FORMAT" = "PTR_FORMAT, - _task->worker_id(), p, (void*) obj); + _task->worker_id(), p2i(p), p2i((void*) obj)); } _task->deal_with_reference(obj); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp index 58212625c82..69b17c56702 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,8 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/intHisto.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #define CARD_REPEAT_HISTO 0 #if CARD_REPEAT_HISTO diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp index 57feb98db2e..24afeba238f 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp @@ -35,6 +35,8 @@ #include "oops/oop.inline.hpp" #include "runtime/orderAccess.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + int HeapRegion::LogOfHRGrainBytes = 0; int HeapRegion::LogOfHRGrainWords = 0; size_t HeapRegion::GrainBytes = 0; @@ -827,7 +829,7 @@ public: Mutex::_no_safepoint_check_flag); if (!_failures) { - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); gclog_or_tty->print_cr("----------"); } if (!_g1h->is_in_closed_subset(obj)) { @@ -882,7 +884,7 @@ public: Mutex::_no_safepoint_check_flag); if (!_failures) { - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); gclog_or_tty->print_cr("----------"); } gclog_or_tty->print_cr("Missing rem set entry:"); diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp index b10f32674cc..25ffe1c8264 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,7 @@ class nmethod; (_hr_)->startsHumongous() ? "HS" : \ (_hr_)->continuesHumongous() ? "HC" : \ !(_hr_)->is_empty() ? "O" : "F", \ - (_hr_)->bottom(), (_hr_)->top(), (_hr_)->end() + p2i((_hr_)->bottom()), p2i((_hr_)->top()), p2i((_hr_)->end()) // sentinel value for hrs_index #define G1_NULL_HRS_INDEX ((uint) -1) @@ -550,7 +550,7 @@ class HeapRegion: public G1OffsetTableContigSpace { (containing_set != NULL && _containing_set == NULL), err_msg("containing_set: "PTR_FORMAT" " "_containing_set: "PTR_FORMAT, - containing_set, _containing_set)); + p2i(containing_set), p2i(_containing_set))); _containing_set = containing_set; } diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp index 016e7b0109d..382a3fb32ec 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp @@ -36,6 +36,8 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/growableArray.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + class PerRegionTable: public CHeapObj<mtGC> { friend class OtherRegionsTable; friend class HeapRegionRemSetIterator; @@ -1218,7 +1220,7 @@ void HeapRegionRemSet::print_recorded() { while (cur_evnt < _n_recorded_events && i == cur_evnt_ind) { gclog_or_tty->print("Event: "); print_event(gclog_or_tty, cur_evnt_kind); - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); cur_evnt++; if (cur_evnt < MaxRecordedEvents) { cur_evnt_kind = _recorded_events[cur_evnt]; diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp index 62638a8f9b3..04f48e60550 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -233,7 +233,7 @@ void HeapRegionSeq::verify_optional() { guarantee(hr != NULL, err_msg("invariant: i: %u", i)); guarantee(hr->bottom() == prev_end, err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT, - i, HR_FORMAT_PARAMS(hr), prev_end)); + i, HR_FORMAT_PARAMS(hr), p2i(prev_end))); guarantee(hr->hrs_index() == i, err_msg("invariant: i: %u hrs_index(): %u", i, hr->hrs_index())); if (i < length()) { diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp index 429457a488f..4028b7a4a5d 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,9 +30,9 @@ inline HeapRegion* HeapRegionSeq::addr_to_region(HeapWord* addr) const { assert(addr < heap_end(), - err_msg("addr: "PTR_FORMAT" end: "PTR_FORMAT, addr, heap_end())); + err_msg("addr: "PTR_FORMAT" end: "PTR_FORMAT, p2i(addr), p2i(heap_end()))); assert(addr >= heap_bottom(), - err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, addr, heap_bottom())); + err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, p2i(addr), p2i(heap_bottom()))); HeapRegion* hr = _regions.get_by_address(addr); assert(hr != NULL, "invariant"); diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp index 6ec03d5ceae..fa5ab14287e 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp @@ -26,6 +26,8 @@ #include "gc_implementation/g1/heapRegionRemSet.hpp" #include "gc_implementation/g1/heapRegionSet.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + uint FreeRegionList::_unrealistically_long_length = 0; void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) { diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp index c54fc784719..222fc694f4c 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp @@ -162,7 +162,7 @@ public: // diagnosing failures. class hrs_ext_msg : public hrs_err_msg { public: - hrs_ext_msg(HeapRegionSetBase* set, const char* message) : hrs_err_msg("") { + hrs_ext_msg(HeapRegionSetBase* set, const char* message) : hrs_err_msg("%s","") { set->fill_in_ext_msg(this, message); } }; diff --git a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp index 7930e581b98..8a0e42ea4e5 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,8 @@ #include "runtime/thread.hpp" #include "runtime/vmThread.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + void ObjPtrQueue::flush() { // The buffer might contain refs into the CSet. We have to filter it // first before we flush it, otherwise we might end up with an diff --git a/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp b/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp index 49e4e01fa9e..3121c9c664e 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ #include "gc_implementation/g1/survRateGroup.hpp" #include "memory/allocation.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + SurvRateGroup::SurvRateGroup(G1CollectorPolicy* g1p, const char* name, size_t summary_surv_rates_len) : @@ -202,7 +204,7 @@ SurvRateGroup::print_surv_rate_summary() { if (length == 0) return; - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); gclog_or_tty->print_cr("%s Rate Summary (for up to age " SIZE_FORMAT ")", _name, length-1); gclog_or_tty->print_cr(" age range survival rate (avg) samples (avg)"); gclog_or_tty->print_cr(" ---------------------------------------------------------"); diff --git a/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp index 6d0e1a2243c..9b39c289900 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -259,22 +259,22 @@ void ASParNewGeneration::resize_spaces(size_t requested_eden_size, requested_eden_size, requested_survivor_size); gclog_or_tty->print_cr(" eden: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT, - eden()->bottom(), - eden()->end(), + p2i(eden()->bottom()), + p2i(eden()->end()), pointer_delta(eden()->end(), eden()->bottom(), sizeof(char))); gclog_or_tty->print_cr(" from: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT, - from()->bottom(), - from()->end(), + p2i(from()->bottom()), + p2i(from()->end()), pointer_delta(from()->end(), from()->bottom(), sizeof(char))); gclog_or_tty->print_cr(" to: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT, - to()->bottom(), - to()->end(), + p2i(to()->bottom()), + p2i(to()->end()), pointer_delta( to()->end(), to()->bottom(), sizeof(char))); @@ -382,18 +382,18 @@ void ASParNewGeneration::resize_spaces(size_t requested_eden_size, if (PrintAdaptiveSizePolicy && Verbose) { gclog_or_tty->print_cr(" [eden_start .. eden_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - eden_start, - eden_end, + p2i(eden_start), + p2i(eden_end), pointer_delta(eden_end, eden_start, sizeof(char))); gclog_or_tty->print_cr(" [from_start .. from_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - from_start, - from_end, + p2i(from_start), + p2i(from_end), pointer_delta(from_end, from_start, sizeof(char))); gclog_or_tty->print_cr(" [ to_start .. to_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - to_start, - to_end, + p2i(to_start), + p2i(to_end), pointer_delta( to_end, to_start, sizeof(char))); } } else { @@ -473,18 +473,18 @@ void ASParNewGeneration::resize_spaces(size_t requested_eden_size, if (PrintAdaptiveSizePolicy && Verbose) { gclog_or_tty->print_cr(" [eden_start .. eden_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - eden_start, - eden_end, + p2i(eden_start), + p2i(eden_end), pointer_delta(eden_end, eden_start, sizeof(char))); gclog_or_tty->print_cr(" [ to_start .. to_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - to_start, - to_end, + p2i(to_start), + p2i(to_end), pointer_delta( to_end, to_start, sizeof(char))); gclog_or_tty->print_cr(" [from_start .. from_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - from_start, - from_end, + p2i(from_start), + p2i(from_end), pointer_delta(from_end, from_start, sizeof(char))); } } diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp index 3a03b93a56f..c1033579cf5 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,8 @@ #include "runtime/virtualspace.hpp" #include "runtime/vmThread.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + void CardTableModRefBS::non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr, OopsInGenClosure* cl, CardTableRS* ct, diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp index 41c7bb827d8..2661e1280b6 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,6 +55,8 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/workgroup.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef _MSC_VER #pragma warning( push ) #pragma warning( disable:4355 ) // 'this' : used in base member initializer list diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp b/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp index 383a579bec9..2a3e3207195 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -79,12 +79,12 @@ inline void ParScanClosure::do_oop_work(T* p, if ((HeapWord*)obj < _boundary) { #ifndef PRODUCT if (_g->to()->is_in_reserved(obj)) { - tty->print_cr("Scanning field (" PTR_FORMAT ") twice?", p); + tty->print_cr("Scanning field (" PTR_FORMAT ") twice?", p2i(p)); GenCollectedHeap* gch = (GenCollectedHeap*)Universe::heap(); Space* sp = gch->space_containing(p); oop obj = oop(sp->block_start(p)); assert((HeapWord*)obj < (HeapWord*)p, "Error"); - tty->print_cr("Object: " PTR_FORMAT, (void *)obj); + tty->print_cr("Object: " PTR_FORMAT, p2i((void *)obj)); tty->print_cr("-------"); obj->print(); tty->print_cr("-----"); @@ -110,7 +110,7 @@ inline void ParScanClosure::do_oop_work(T* p, if (TraceScavenge) { gclog_or_tty->print_cr("{%s %s ( " PTR_FORMAT " ) " PTR_FORMAT " -> " PTR_FORMAT " (%d)}", "forwarded ", - new_obj->klass()->internal_name(), p, (void *)obj, (void *)new_obj, new_obj->size()); + new_obj->klass()->internal_name(), p2i(p), p2i((void *)obj), p2i((void *)new_obj), new_obj->size()); } #endif diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp index f403a3a3a62..d711104e459 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -252,22 +252,22 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size, requested_eden_size, requested_survivor_size); gclog_or_tty->print_cr(" eden: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT, - eden_space()->bottom(), - eden_space()->end(), + p2i(eden_space()->bottom()), + p2i(eden_space()->end()), pointer_delta(eden_space()->end(), eden_space()->bottom(), sizeof(char))); gclog_or_tty->print_cr(" from: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT, - from_space()->bottom(), - from_space()->end(), + p2i(from_space()->bottom()), + p2i(from_space()->end()), pointer_delta(from_space()->end(), from_space()->bottom(), sizeof(char))); gclog_or_tty->print_cr(" to: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT, - to_space()->bottom(), - to_space()->end(), + p2i(to_space()->bottom()), + p2i(to_space()->end()), pointer_delta( to_space()->end(), to_space()->bottom(), sizeof(char))); @@ -373,18 +373,18 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size, if (PrintAdaptiveSizePolicy && Verbose) { gclog_or_tty->print_cr(" [eden_start .. eden_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - eden_start, - eden_end, + p2i(eden_start), + p2i(eden_end), pointer_delta(eden_end, eden_start, sizeof(char))); gclog_or_tty->print_cr(" [from_start .. from_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - from_start, - from_end, + p2i(from_start), + p2i(from_end), pointer_delta(from_end, from_start, sizeof(char))); gclog_or_tty->print_cr(" [ to_start .. to_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - to_start, - to_end, + p2i(to_start), + p2i(to_end), pointer_delta( to_end, to_start, sizeof(char))); } } else { @@ -427,18 +427,18 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size, if (PrintAdaptiveSizePolicy && Verbose) { gclog_or_tty->print_cr(" [eden_start .. eden_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - eden_start, - eden_end, + p2i(eden_start), + p2i(eden_end), pointer_delta(eden_end, eden_start, sizeof(char))); gclog_or_tty->print_cr(" [ to_start .. to_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - to_start, - to_end, + p2i(to_start), + p2i(to_end), pointer_delta( to_end, to_start, sizeof(char))); gclog_or_tty->print_cr(" [from_start .. from_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - from_start, - from_end, + p2i(from_start), + p2i(from_end), pointer_delta(from_end, from_start, sizeof(char))); } } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp index b49ccb05c1e..502371f0169 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -478,23 +478,23 @@ void CardTableExtension::resize_covered_region_by_end(int changed_region, gclog_or_tty->print_cr(" " " _covered[%d].start(): " INTPTR_FORMAT " _covered[%d].last(): " INTPTR_FORMAT, - ind, _covered[ind].start(), - ind, _covered[ind].last()); + ind, p2i(_covered[ind].start()), + ind, p2i(_covered[ind].last())); gclog_or_tty->print_cr(" " " _committed[%d].start(): " INTPTR_FORMAT " _committed[%d].last(): " INTPTR_FORMAT, - ind, _committed[ind].start(), - ind, _committed[ind].last()); + ind, p2i(_committed[ind].start()), + ind, p2i(_committed[ind].last())); gclog_or_tty->print_cr(" " " byte_for(start): " INTPTR_FORMAT " byte_for(last): " INTPTR_FORMAT, - byte_for(_covered[ind].start()), - byte_for(_covered[ind].last())); + p2i(byte_for(_covered[ind].start())), + p2i(byte_for(_covered[ind].last()))); gclog_or_tty->print_cr(" " " addr_for(start): " INTPTR_FORMAT " addr_for(last): " INTPTR_FORMAT, - addr_for((jbyte*) _committed[ind].start()), - addr_for((jbyte*) _committed[ind].last())); + p2i(addr_for((jbyte*) _committed[ind].start())), + p2i(addr_for((jbyte*) _committed[ind].last()))); } debug_only(verify_guard();) } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp index ac7a1a31e45..5aecfb2a984 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,8 @@ #include "runtime/mutexLocker.hpp" #include "runtime/orderAccess.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // // GCTask // diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp index ec2e28f5674..ec5ac692ebd 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,8 @@ #include "runtime/os.hpp" #include "runtime/thread.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + GCTaskThread::GCTaskThread(GCTaskManager* manager, uint which, uint processor_id) : diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp index 32f7eed82cb..8d0153d485d 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -155,7 +155,7 @@ public: static inline idx_t bits_required(MemRegion covered_region); void print_on_error(outputStream* st) const { - st->print_cr("Marking Bits: (ParMarkBitMap*) " PTR_FORMAT, this); + st->print_cr("Marking Bits: (ParMarkBitMap*) " PTR_FORMAT, p2i(this)); _beg_bits.print_on_error(st, " Begin Bits: "); _end_bits.print_on_error(st, " End Bits: "); } @@ -390,9 +390,9 @@ inline void ParMarkBitMap::verify_bit(idx_t bit) const { inline void ParMarkBitMap::verify_addr(HeapWord* addr) const { // Allow one past the last valid address; useful for loop bounds. assert(addr >= region_start(), - err_msg("addr too small, addr: " PTR_FORMAT " region start: " PTR_FORMAT, addr, region_start())); + err_msg("addr too small, addr: " PTR_FORMAT " region start: " PTR_FORMAT, p2i(addr), p2i(region_start()))); assert(addr <= region_end(), - err_msg("addr too big, addr: " PTR_FORMAT " region end: " PTR_FORMAT, addr, region_end())); + err_msg("addr too big, addr: " PTR_FORMAT " region end: " PTR_FORMAT, p2i(addr), p2i(region_end()))); } #endif // #ifdef ASSERT diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp index 9ebdb841dfd..5a2f4e79d95 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -373,7 +373,7 @@ HeapWord* ParallelScavengeHeap::mem_allocate( if ((result == NULL) && (QueuedAllocationWarningCount > 0) && (loop_count % QueuedAllocationWarningCount == 0)) { warning("ParallelScavengeHeap::mem_allocate retries %d times \n\t" - " size=%d", loop_count, size); + " size=" SIZE_FORMAT, loop_count, size); } } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp index 47a7b90d984..1c646fe3e1d 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ inline bool ParallelScavengeHeap::is_in_young(oop p) { const void* loc = (void*) p; bool result = ((HeapWord*)p) >= young_gen()->reserved().start(); assert(result == young_gen()->is_in_reserved(p), - err_msg("incorrect test - result=%d, p=" PTR_FORMAT, result, (void*)p)); + err_msg("incorrect test - result=%d, p=" PTR_FORMAT, result, p2i((void*)p))); return result; } #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PARALLELSCAVENGEHEAP_INLINE_HPP diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp index 10932e6b9e6..5037c207c62 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,8 @@ #include "runtime/vmThread.hpp" #include "services/management.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // // ThreadRootsMarkingTask // diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp index f28b7458c6d..229b9dd3cfa 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ #include <math.h> +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + PSAdaptiveSizePolicy::PSAdaptiveSizePolicy(size_t init_eden_size, size_t init_promo_size, size_t init_survivor_size, @@ -1033,7 +1035,7 @@ size_t PSAdaptiveSizePolicy::adjust_promo_for_footprint( "AdaptiveSizePolicy::adjust_promo_for_footprint " "adjusting tenured gen for footprint. " "starting promo size " SIZE_FORMAT - " reduced promo size " SIZE_FORMAT, + " reduced promo size " SIZE_FORMAT " promo delta " SIZE_FORMAT, desired_promo_size, reduced_size, change ); } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp index cdfc31911ee..c3866f347bd 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,6 +54,8 @@ #include "utilities/events.hpp" #include "utilities/stack.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + elapsedTimer PSMarkSweep::_accumulated_time; jlong PSMarkSweep::_time_of_last_gc = 0; CollectorCounters* PSMarkSweep::_counters = NULL; diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp index 8ffdb0fbb37..8ef5abefdef 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,8 @@ #include "oops/oop.inline.hpp" #include "runtime/java.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + inline const char* PSOldGen::select_name() { return UseParallelOldGC ? "ParOldGen" : "PSOldGen"; } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp index e93f612e4bd..745a6de2fb0 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,6 +62,8 @@ #include <math.h> +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // All sizes are in HeapWords. const size_t ParallelCompactData::Log2RegionSize = 16; // 64K words const size_t ParallelCompactData::RegionSize = (size_t)1 << Log2RegionSize; diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp index 01b404eac55..93446fdbfa0 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ #include "oops/oop.inline.hpp" #include "oops/oop.psgc.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + PaddedEnd<PSPromotionManager>* PSPromotionManager::_manager_array = NULL; OopStarTaskQueueSet* PSPromotionManager::_stack_array_depth = NULL; PSOldGen* PSPromotionManager::_old_gen = NULL; @@ -136,7 +138,7 @@ PSPromotionManager::print_stats() { } const uint hlines = sizeof(pm_stats_hdr) / sizeof(pm_stats_hdr[0]); - for (uint i = 0; i < hlines; ++i) tty->print_cr(pm_stats_hdr[i]); + for (uint i = 0; i < hlines; ++i) tty->print_cr("%s", pm_stats_hdr[i]); for (uint i = 0; i < ParallelGCThreads + 1; ++i) { manager_array(i)->print_local_stats(i); } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp index 2a45c240c9f..356c2585168 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -226,7 +226,7 @@ oop PSPromotionManager::copy_to_survivor_space(oop o) { if (TraceScavenge) { gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}", PSScavenge::should_scavenge(&new_obj) ? "copying" : "tenuring", - new_obj->klass()->internal_name(), (void *)o, (void *)new_obj, new_obj->size()); + new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size()); } #endif diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp index de18bd00d05..c039b229b9f 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp @@ -56,6 +56,7 @@ #include "services/memoryService.hpp" #include "utilities/stack.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC HeapWord* PSScavenge::_to_space_top_before_gc = NULL; int PSScavenge::_consecutive_skipped_scavenges = 0; @@ -833,7 +834,7 @@ void PSScavenge::initialize() { if (AlwaysTenure || NeverTenure) { assert(MaxTenuringThreshold == 0 || MaxTenuringThreshold == markOopDesc::max_age + 1, - err_msg("MaxTenuringThreshold should be 0 or markOopDesc::max_age + 1, but is ", MaxTenuringThreshold)); + err_msg("MaxTenuringThreshold should be 0 or markOopDesc::max_age + 1, but is %d", (int) MaxTenuringThreshold)); _tenuring_threshold = MaxTenuringThreshold; } else { // We want to smooth out our startup times for the AdaptiveSizePolicy diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp index 3b8447988cb..8030aad21b9 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,7 +82,7 @@ inline void PSScavenge::copy_and_push_safe_barrier(PSPromotionManager* pm, if (TraceScavenge && o->is_forwarded()) { gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}", "forwarding", - new_obj->klass()->internal_name(), (void *)o, (void *)new_obj, new_obj->size()); + new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size()); } #endif @@ -180,7 +180,7 @@ class PSScavengeKlassClosure: public KlassClosure { if (TraceScavenge) { ResourceMark rm; gclog_or_tty->print_cr("PSScavengeKlassClosure::do_klass " PTR_FORMAT ", %s, dirty: %s", - klass, + p2i(klass), klass->external_name(), klass->has_modified_oops() ? "true" : "false"); } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp index 90672fba061..910a29c5259 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,8 @@ # include "os_bsd.inline.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // PSVirtualSpace PSVirtualSpace::PSVirtualSpace(ReservedSpace rs, size_t alignment) : diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp index 1ea30b4027f..b5902a23381 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,8 @@ #include "oops/oop.inline.hpp" #include "runtime/java.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + PSYoungGen::PSYoungGen(size_t initial_size, size_t min_size, size_t max_size) : diff --git a/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp b/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp index 2fe4de9c30e..634d0a5ddc5 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp @@ -84,7 +84,7 @@ uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) { if (AlwaysTenure || NeverTenure) { assert(MaxTenuringThreshold == 0 || MaxTenuringThreshold == markOopDesc::max_age + 1, - err_msg("MaxTenuringThreshold should be 0 or markOopDesc::max_age + 1, but is ", MaxTenuringThreshold)); + err_msg("MaxTenuringThreshold should be 0 or markOopDesc::max_age + 1, but is " UINTX_FORMAT, MaxTenuringThreshold)); result = MaxTenuringThreshold; } else { size_t total = 0; @@ -106,7 +106,7 @@ uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) { gclog_or_tty->cr(); gclog_or_tty->print_cr("Desired survivor size " SIZE_FORMAT " bytes, new threshold " UINTX_FORMAT " (max threshold " UINTX_FORMAT ")", - desired_survivor_size*oopSize, result, MaxTenuringThreshold); + desired_survivor_size*oopSize, (uintx) result, MaxTenuringThreshold); } size_t total = 0; @@ -115,8 +115,8 @@ uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) { total += sizes[age]; if (sizes[age] > 0) { if (PrintTenuringDistribution) { - gclog_or_tty->print_cr("- age %3u: %10ld bytes, %10ld total", - age, sizes[age]*oopSize, total*oopSize); + gclog_or_tty->print_cr("- age %3u: " SIZE_FORMAT_W(10) " bytes, " SIZE_FORMAT_W(10) " total", + age, sizes[age]*oopSize, total*oopSize); } } if (UsePerfData) { diff --git a/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp index d2282df167e..9459efbdefd 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -107,7 +107,7 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC { assert(demand >= 0, err_msg("Demand (" SSIZE_FORMAT ") should be non-negative for " PTR_FORMAT " (size=" SIZE_FORMAT ")", - demand, this, count)); + demand, p2i(this), count)); // Defensive: adjust for imprecision in event counting if (demand < 0) { demand = 0; diff --git a/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp b/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp index b1563ac8686..477680727ba 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,7 +66,7 @@ void ImmutableSpace::print_short() const { void ImmutableSpace::print() const { print_short(); - tty->print_cr(" [%#-6lx,%#-6lx)", bottom(), end()); + tty->print_cr(" [" INTPTR_FORMAT_W(#-6) "," INTPTR_FORMAT_W(#-6) ")", p2i(bottom()), p2i(end())); } #endif diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp index b4bc3f9aea5..07cbb23de4a 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,8 @@ #include "oops/objArrayKlass.inline.hpp" #include "oops/oop.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + uint MarkSweep::_total_invocations = 0; Stack<oop, mtGC> MarkSweep::_marking_stack; diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp index 20a7a6aa789..8590e850b60 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,8 @@ #include "oops/oop.inline.hpp" #include "runtime/thread.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + MutableNUMASpace::MutableNUMASpace(size_t alignment) : MutableSpace(alignment) { _lgrp_spaces = new (ResourceObj::C_HEAP, mtGC) GrowableArray<LGRPSpace*>(0, true); _page_size = os::vm_page_size(); diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp index 7e5b5a81125..17a3ecbc14a 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,8 @@ #include "runtime/thread.hpp" #endif // INCLUDE_ALL_GCS +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + MutableSpace::MutableSpace(size_t alignment): ImmutableSpace(), _top(NULL), _alignment(alignment) { assert(MutableSpace::alignment() >= 0 && MutableSpace::alignment() % os::vm_page_size() == 0, diff --git a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp index 2198a86aff6..01781705f93 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ #include "oops/oop.inline.hpp" #include "utilities/globalDefinitions.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + ParGCAllocBuffer::ParGCAllocBuffer(size_t desired_plab_sz_) : _word_sz(desired_plab_sz_), _bottom(NULL), _top(NULL), _end(NULL), _hard_end(NULL), diff --git a/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp index c2b42873a7c..15e38aa1ba1 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ #include "memory/space.inline.hpp" #include "utilities/copy.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Catch-all file for utility classes #ifndef PRODUCT diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp index 4b33afd66b7..1304092002e 100644 --- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp @@ -599,12 +599,12 @@ void CollectedHeap::test_is_in() { assert(heap_start >= ((uintptr_t)NULL + epsilon), "sanity"); void* before_heap = (void*)(heap_start - epsilon); assert(!heap->is_in(before_heap), - err_msg("before_heap: " PTR_FORMAT " is unexpectedly in the heap", before_heap)); + err_msg("before_heap: " PTR_FORMAT " is unexpectedly in the heap", p2i(before_heap))); // Test that a pointer to after the heap end is reported as outside the heap. assert(heap_end <= ((uintptr_t)-1 - epsilon), "sanity"); void* after_heap = (void*)(heap_end + epsilon); assert(!heap->is_in(after_heap), - err_msg("after_heap: " PTR_FORMAT " is unexpectedly in the heap", after_heap)); + err_msg("after_heap: " PTR_FORMAT " is unexpectedly in the heap", p2i(after_heap))); } #endif diff --git a/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp b/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp index 36867113eff..4600413dc5b 100644 --- a/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp +++ b/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -213,7 +213,7 @@ void print_oop(oop value, outputStream* st) { st->print_cr(" %s", buf); } } else { - st->print_cr(" " PTR_FORMAT, (void *)value); + st->print_cr(" " INTPTR_FORMAT, p2i((void *)value)); } } @@ -282,7 +282,7 @@ bool BytecodePrinter::check_cp_cache_index(int i, int& cp_index, outputStream* s if (i >= 0 && i < climit) { cp_index = cache->entry_at(i)->constant_pool_index(); } else { - st->print_cr(" not in CP[*]?", i); + st->print_cr("%d not in CP[*]?", i); return false; } return true; @@ -297,7 +297,7 @@ bool BytecodePrinter::check_obj_index(int i, int& cp_index, outputStream* st) { cp_index = constants->object_to_cp_index(i); return true; } else { - st->print_cr(" not in OBJ[*]?", i); + st->print_cr("%d not in OBJ[*]?", i); return false; } } @@ -321,7 +321,7 @@ void BytecodePrinter::print_constant(int i, outputStream* st) { if (tag.is_int()) { st->print_cr(" " INT32_FORMAT, constants->int_at(i)); } else if (tag.is_long()) { - st->print_cr(" " INT64_FORMAT, constants->long_at(i)); + st->print_cr(" " INT64_FORMAT, (int64_t)(constants->long_at(i))); } else if (tag.is_float()) { st->print_cr(" %f", constants->float_at(i)); } else if (tag.is_double()) { @@ -340,7 +340,7 @@ void BytecodePrinter::print_constant(int i, outputStream* st) { } else if (tag.is_method_handle()) { int kind = constants->method_handle_ref_kind_at(i); int i2 = constants->method_handle_index_at(i); - st->print(" <MethodHandle of kind %d>", kind, i2); + st->print(" <MethodHandle of kind %d index at %d>", kind, i2); print_field_or_method(-i, i2, st); } else { st->print_cr(" bad tag=%d at %d", tag.value(), i); @@ -389,6 +389,7 @@ void BytecodePrinter::print_field_or_method(int orig_i, int i, outputStream* st) } +PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL void BytecodePrinter::print_attributes(int bci, outputStream* st) { // Show attributes of pre-rewritten codes Bytecodes::Code code = Bytecodes::java_code(raw_code()); @@ -515,7 +516,10 @@ void BytecodePrinter::print_attributes(int bci, outputStream* st) { int idx = ll - lo; const char *format = first ? " %d:" INT32_FORMAT " (delta: %d)" : ", %d:" INT32_FORMAT " (delta: %d)"; +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL st->print(format, ll, dest[idx], dest[idx]-bci); +PRAGMA_DIAG_POP } st->cr(); } @@ -535,7 +539,10 @@ void BytecodePrinter::print_attributes(int bci, outputStream* st) { for (int ll = 0; ll < len; ll++, first = false) { const char *format = first ? " " INT32_FORMAT ":" INT32_FORMAT : ", " INT32_FORMAT ":" INT32_FORMAT ; +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL st->print(format, key[ll], dest[ll]); +PRAGMA_DIAG_POP } st->cr(); } diff --git a/hotspot/src/share/vm/interpreter/interpreter.cpp b/hotspot/src/share/vm/interpreter/interpreter.cpp index 60246e9013d..7ce4bdbb3ec 100644 --- a/hotspot/src/share/vm/interpreter/interpreter.cpp +++ b/hotspot/src/share/vm/interpreter/interpreter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -72,7 +72,7 @@ void InterpreterCodelet::print_on(outputStream* st) const { if (description() != NULL) st->print("%s ", description()); if (bytecode() >= 0 ) st->print("%d %s ", bytecode(), Bytecodes::name(bytecode())); st->print_cr("[" INTPTR_FORMAT ", " INTPTR_FORMAT "] %d bytes", - code_begin(), code_end(), code_size()); + p2i(code_begin()), p2i(code_end()), code_size()); if (PrintInterpreter) { st->cr(); diff --git a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp index 0e1c129038d..ca4f3e3e1b4 100644 --- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,6 +75,8 @@ #include "opto/runtime.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + class UnlockFlagSaver { private: JavaThread* _thread; diff --git a/hotspot/src/share/vm/interpreter/linkResolver.cpp b/hotspot/src/share/vm/interpreter/linkResolver.cpp index a0f204c6eb2..8ebb1ecabae 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp @@ -1626,7 +1626,7 @@ void LinkResolver::resolve_dynamic_call(CallInfo& result, THREAD); if (HAS_PENDING_EXCEPTION) { if (TraceMethodHandles) { - tty->print_cr("invokedynamic throws BSME for "INTPTR_FORMAT, (void *)PENDING_EXCEPTION); + tty->print_cr("invokedynamic throws BSME for " INTPTR_FORMAT, p2i((void *)PENDING_EXCEPTION)); PENDING_EXCEPTION->print(); } if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) { diff --git a/hotspot/src/share/vm/interpreter/oopMapCache.cpp b/hotspot/src/share/vm/interpreter/oopMapCache.cpp index 34f3edc17f0..79e2bba8bad 100644 --- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp +++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ #include "runtime/handles.inline.hpp" #include "runtime/signature.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + class OopMapCacheEntry: private InterpreterOopMap { friend class InterpreterOopMap; friend class OopMapForCacheEntry; diff --git a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp index e3e89e8eed9..66eb63eafb6 100644 --- a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp +++ b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -104,7 +104,7 @@ void EntryPoint::print() { tty->print("["); for (int i = 0; i < number_of_states; i++) { if (i > 0) tty->print(", "); - tty->print(INTPTR_FORMAT, _entry[i]); + tty->print(INTPTR_FORMAT, p2i(_entry[i])); } tty->print("]"); } diff --git a/hotspot/src/share/vm/libadt/dict.cpp b/hotspot/src/share/vm/libadt/dict.cpp index 29c16bb41e0..37559a097df 100644 --- a/hotspot/src/share/vm/libadt/dict.cpp +++ b/hotspot/src/share/vm/libadt/dict.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,6 +38,8 @@ #include <assert.h> +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // The iostream is not needed and it gets confused for gcc by the // define of bool. // diff --git a/hotspot/src/share/vm/libadt/set.cpp b/hotspot/src/share/vm/libadt/set.cpp index 7364795ed70..f91acd80cff 100644 --- a/hotspot/src/share/vm/libadt/set.cpp +++ b/hotspot/src/share/vm/libadt/set.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -116,7 +116,7 @@ char *Set::setstr() const void Set::print() const { char *printable_set = setstr(); - tty->print_cr(printable_set); + tty->print_cr("%s", printable_set); FreeHeap(printable_set); } diff --git a/hotspot/src/share/vm/memory/allocation.cpp b/hotspot/src/share/vm/memory/allocation.cpp index 9fece9b4ef4..a05e74b77a0 100644 --- a/hotspot/src/share/vm/memory/allocation.cpp +++ b/hotspot/src/share/vm/memory/allocation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -79,7 +79,7 @@ bool MetaspaceObj::is_metaspace_object() const { } void MetaspaceObj::print_address_on(outputStream* st) const { - st->print(" {"INTPTR_FORMAT"}", this); + st->print(" {" INTPTR_FORMAT "}", p2i(this)); } void* ResourceObj::operator new(size_t size, allocation_type type, MEMFLAGS flags) throw() { @@ -142,7 +142,7 @@ void ResourceObj::operator delete [](void* p) { void ResourceObj::set_allocation_type(address res, allocation_type type) { // Set allocation type in the resource object uintptr_t allocation = (uintptr_t)res; - assert((allocation & allocation_mask) == 0, err_msg("address should be aligned to 4 bytes at least: " PTR_FORMAT, res)); + assert((allocation & allocation_mask) == 0, err_msg("address should be aligned to 4 bytes at least: " INTPTR_FORMAT, p2i(res))); assert(type <= allocation_mask, "incorrect allocation type"); ResourceObj* resobj = (ResourceObj *)res; resobj->_allocation_t[0] = ~(allocation + type); @@ -179,7 +179,7 @@ ResourceObj::ResourceObj() { // default constructor // Operator new() was called and type was set. assert(!allocated_on_stack(), err_msg("not embedded or stack, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", - this, get_allocation_type(), _allocation_t[0], _allocation_t[1])); + p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1])); } else { // Operator new() was not called. // Assume that it is embedded or stack object. @@ -193,7 +193,7 @@ ResourceObj::ResourceObj(const ResourceObj& r) { // default copy constructor // Note: garbage may resembles valid value. assert(~(_allocation_t[0] | allocation_mask) != (uintptr_t)this || !is_type_set(), err_msg("embedded or stack only, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", - this, get_allocation_type(), _allocation_t[0], _allocation_t[1])); + p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1])); set_allocation_type((address)this, STACK_OR_EMBEDDED); _allocation_t[1] = 0; // Zap verification value } @@ -202,7 +202,7 @@ ResourceObj& ResourceObj::operator=(const ResourceObj& r) { // default copy assi // Used in InlineTree::ok_to_inline() for WarmCallInfo. assert(allocated_on_stack(), err_msg("copy only into local, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", - this, get_allocation_type(), _allocation_t[0], _allocation_t[1])); + p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1])); // Keep current _allocation_t value; return *this; } @@ -218,13 +218,13 @@ ResourceObj::~ResourceObj() { void trace_heap_malloc(size_t size, const char* name, void* p) { // A lock is not needed here - tty uses a lock internally - tty->print_cr("Heap malloc " INTPTR_FORMAT " " SIZE_FORMAT " %s", p, size, name == NULL ? "" : name); + tty->print_cr("Heap malloc " INTPTR_FORMAT " " SIZE_FORMAT " %s", p2i(p), size, name == NULL ? "" : name); } void trace_heap_free(void* p) { // A lock is not needed here - tty uses a lock internally - tty->print_cr("Heap free " INTPTR_FORMAT, p); + tty->print_cr("Heap free " INTPTR_FORMAT, p2i(p)); } //-------------------------------------------------------------------------------------- @@ -725,11 +725,11 @@ void AllocatedObj::print() const { print_on(tty); } void AllocatedObj::print_value() const { print_value_on(tty); } void AllocatedObj::print_on(outputStream* st) const { - st->print_cr("AllocatedObj(" INTPTR_FORMAT ")", this); + st->print_cr("AllocatedObj(" INTPTR_FORMAT ")", p2i(this)); } void AllocatedObj::print_value_on(outputStream* st) const { - st->print("AllocatedObj(" INTPTR_FORMAT ")", this); + st->print("AllocatedObj(" INTPTR_FORMAT ")", p2i(this)); } julong Arena::_bytes_allocated = 0; diff --git a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp index ac716bb01e2..60435e63c1d 100644 --- a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp +++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp @@ -1318,7 +1318,7 @@ class PrintFreeListsClosure : public AscendTreeCensusClosure<Chunk_t, FreeList_t for (Chunk_t* fc = fl->head(); fc != NULL; fc = fc->next()) { _st->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ") %s", - fc, (HeapWord*)fc + sz, + p2i(fc), p2i((HeapWord*)fc + sz), fc->cantCoalesce() ? "\t CC" : ""); } } diff --git a/hotspot/src/share/vm/memory/blockOffsetTable.cpp b/hotspot/src/share/vm/memory/blockOffsetTable.cpp index 7a54e147790..d64aff67dd7 100644 --- a/hotspot/src/share/vm/memory/blockOffsetTable.cpp +++ b/hotspot/src/share/vm/memory/blockOffsetTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,12 +59,12 @@ BlockOffsetSharedArray::BlockOffsetSharedArray(MemRegion reserved, " rs.base(): " INTPTR_FORMAT " rs.size(): " INTPTR_FORMAT " rs end(): " INTPTR_FORMAT, - rs.base(), rs.size(), rs.base() + rs.size()); + p2i(rs.base()), rs.size(), p2i(rs.base() + rs.size())); gclog_or_tty->print_cr(" " " _vs.low_boundary(): " INTPTR_FORMAT " _vs.high_boundary(): " INTPTR_FORMAT, - _vs.low_boundary(), - _vs.high_boundary()); + p2i(_vs.low_boundary()), + p2i(_vs.high_boundary())); } } @@ -537,10 +537,10 @@ HeapWord* BlockOffsetArrayNonContigSpace::block_start_unsafe( q -= (N_words * n_cards_back); assert(q >= _sp->bottom(), err_msg("q = " PTR_FORMAT " crossed below bottom = " PTR_FORMAT, - q, _sp->bottom())); + p2i(q), p2i(_sp->bottom()))); assert(q < _sp->end(), err_msg("q = " PTR_FORMAT " crossed above end = " PTR_FORMAT, - q, _sp->end())); + p2i(q), p2i(_sp->end()))); index -= n_cards_back; offset = _array->offset_array(index); } @@ -549,10 +549,10 @@ HeapWord* BlockOffsetArrayNonContigSpace::block_start_unsafe( q -= offset; assert(q >= _sp->bottom(), err_msg("q = " PTR_FORMAT " crossed below bottom = " PTR_FORMAT, - q, _sp->bottom())); + p2i(q), p2i(_sp->bottom()))); assert(q < _sp->end(), err_msg("q = " PTR_FORMAT " crossed above end = " PTR_FORMAT, - q, _sp->end())); + p2i(q), p2i(_sp->end()))); HeapWord* n = q; while (n <= addr) { @@ -563,14 +563,14 @@ HeapWord* BlockOffsetArrayNonContigSpace::block_start_unsafe( err_msg("Looping at n = " PTR_FORMAT " with last = " PTR_FORMAT"," " while querying blk_start(" PTR_FORMAT ")" " on _sp = [" PTR_FORMAT "," PTR_FORMAT ")", - n, last, addr, _sp->bottom(), _sp->end())); + p2i(n), p2i(last), p2i(addr), p2i(_sp->bottom()), p2i(_sp->end()))); } assert(q <= addr, err_msg("wrong order for current (" INTPTR_FORMAT ")" " <= arg (" INTPTR_FORMAT ")", - q, addr)); + p2i(q), p2i(addr))); assert(addr <= n, err_msg("wrong order for arg (" INTPTR_FORMAT ") <= next (" INTPTR_FORMAT ")", - addr, n)); + p2i(addr), p2i(n))); return q; } diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp index 4b54a404457..f5ff6aad2c1 100644 --- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -138,11 +138,11 @@ CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap, gclog_or_tty->print_cr(" " " &_byte_map[0]: " INTPTR_FORMAT " &_byte_map[_last_valid_index]: " INTPTR_FORMAT, - &_byte_map[0], - &_byte_map[_last_valid_index]); + p2i(&_byte_map[0]), + p2i(&_byte_map[_last_valid_index])); gclog_or_tty->print_cr(" " " byte_map_base: " INTPTR_FORMAT, - byte_map_base); + p2i(byte_map_base)); } } @@ -392,23 +392,23 @@ void CardTableModRefBS::resize_covered_region(MemRegion new_region) { gclog_or_tty->print_cr(" " " _covered[%d].start(): " INTPTR_FORMAT " _covered[%d].last(): " INTPTR_FORMAT, - ind, _covered[ind].start(), - ind, _covered[ind].last()); + ind, p2i(_covered[ind].start()), + ind, p2i(_covered[ind].last())); gclog_or_tty->print_cr(" " " _committed[%d].start(): " INTPTR_FORMAT " _committed[%d].last(): " INTPTR_FORMAT, - ind, _committed[ind].start(), - ind, _committed[ind].last()); + ind, p2i(_committed[ind].start()), + ind, p2i(_committed[ind].last())); gclog_or_tty->print_cr(" " " byte_for(start): " INTPTR_FORMAT " byte_for(last): " INTPTR_FORMAT, - byte_for(_covered[ind].start()), - byte_for(_covered[ind].last())); + p2i(byte_for(_covered[ind].start())), + p2i(byte_for(_covered[ind].last()))); gclog_or_tty->print_cr(" " " addr_for(start): " INTPTR_FORMAT " addr_for(last): " INTPTR_FORMAT, - addr_for((jbyte*) _committed[ind].start()), - addr_for((jbyte*) _committed[ind].last())); + p2i(addr_for((jbyte*) _committed[ind].start())), + p2i(addr_for((jbyte*) _committed[ind].last()))); } // Touch the last card of the covered region to show that it // is committed (or SEGV). @@ -657,14 +657,14 @@ void CardTableModRefBS::verify_region(MemRegion mr, if (failed) { if (!failures) { tty->cr(); - tty->print_cr("== CT verification failed: ["PTR_FORMAT","PTR_FORMAT"]", start, end); + tty->print_cr("== CT verification failed: [" INTPTR_FORMAT "," INTPTR_FORMAT "]", p2i(start), p2i(end)); tty->print_cr("== %sexpecting value: %d", (val_equals) ? "" : "not ", val); failures = true; } tty->print_cr("== card "PTR_FORMAT" ["PTR_FORMAT","PTR_FORMAT"], " - "val: %d", curr, addr_for(curr), - (HeapWord*) (((size_t) addr_for(curr)) + card_size), + "val: %d", p2i(curr), p2i(addr_for(curr)), + p2i((HeapWord*) (((size_t) addr_for(curr)) + card_size)), (int) curr_val); } } @@ -682,7 +682,7 @@ void CardTableModRefBS::verify_dirty_region(MemRegion mr) { void CardTableModRefBS::print_on(outputStream* st) const { st->print_cr("Card table byte_map: [" INTPTR_FORMAT "," INTPTR_FORMAT "] byte_map_base: " INTPTR_FORMAT, - _byte_map, _byte_map + _byte_map_size, byte_map_base); + p2i(_byte_map), p2i(_byte_map + _byte_map_size), p2i(byte_map_base)); } bool CardTableModRefBSForCTRS::card_will_be_scanned(jbyte cv) { diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp index 1aa5b41ab14..5e72b4640f9 100644 --- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -155,7 +155,7 @@ class CardTableModRefBS: public ModRefBarrierSet { assert(_whole_heap.contains(p), err_msg("Attempt to access p = "PTR_FORMAT" out of bounds of " " card marking array's _whole_heap = ["PTR_FORMAT","PTR_FORMAT")", - p, _whole_heap.start(), _whole_heap.end())); + p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end()))); jbyte* result = &byte_map_base[uintptr_t(p) >> card_shift]; assert(result >= _byte_map && result < _byte_map + _byte_map_size, "out of bounds accessor for card marking array"); @@ -431,7 +431,7 @@ public: assert(_whole_heap.contains(result), err_msg("Returning result = "PTR_FORMAT" out of bounds of " " card marking array's _whole_heap = ["PTR_FORMAT","PTR_FORMAT")", - result, _whole_heap.start(), _whole_heap.end())); + p2i(result), p2i(_whole_heap.start()), p2i(_whole_heap.end()))); return result; } @@ -440,7 +440,7 @@ public: assert(_whole_heap.contains(p), err_msg("Attempt to access p = "PTR_FORMAT" out of bounds of " " card marking array's _whole_heap = ["PTR_FORMAT","PTR_FORMAT")", - p, _whole_heap.start(), _whole_heap.end())); + p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end()))); return byte_for(p) - _byte_map; } diff --git a/hotspot/src/share/vm/memory/cardTableRS.cpp b/hotspot/src/share/vm/memory/cardTableRS.cpp index d79b4b92ec8..56af890a421 100644 --- a/hotspot/src/share/vm/memory/cardTableRS.cpp +++ b/hotspot/src/share/vm/memory/cardTableRS.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -288,14 +288,14 @@ void CardTableRS::younger_refs_in_space_iterate(Space* sp, err_msg("Did you forget to call save_marks()? " "[" PTR_FORMAT ", " PTR_FORMAT ") is not contained in " "[" PTR_FORMAT ", " PTR_FORMAT ")", - urasm.start(), urasm.end(), ur.start(), ur.end())); + p2i(urasm.start()), p2i(urasm.end()), p2i(ur.start()), p2i(ur.end()))); // In the case of CMS+ParNew, issue a warning if (!ur.contains(urasm)) { assert(UseConcMarkSweepGC && UseParNewGC, "Tautology: see assert above"); warning("CMS+ParNew: Did you forget to call save_marks()? " "[" PTR_FORMAT ", " PTR_FORMAT ") is not contained in " "[" PTR_FORMAT ", " PTR_FORMAT ")", - urasm.start(), urasm.end(), ur.start(), ur.end()); + p2i(urasm.start()), p2i(urasm.end()), p2i(ur.start()), p2i(ur.end())); MemRegion ur2 = sp->used_region(); MemRegion urasm2 = sp->used_region_at_save_marks(); if (!ur.equals(ur2)) { @@ -349,12 +349,12 @@ protected: assert(jp >= _begin && jp < _end, err_msg("Error: jp " PTR_FORMAT " should be within " "[_begin, _end) = [" PTR_FORMAT "," PTR_FORMAT ")", - jp, _begin, _end)); + p2i(jp), p2i(_begin), p2i(_end))); oop obj = oopDesc::load_decode_heap_oop(p); guarantee(obj == NULL || (HeapWord*)obj >= _boundary, err_msg("pointer " PTR_FORMAT " at " PTR_FORMAT " on " "clean card crosses boundary" PTR_FORMAT, - (HeapWord*)obj, jp, _boundary)); + p2i((HeapWord*)obj), p2i(jp), p2i(_boundary))); } public: @@ -362,10 +362,10 @@ public: _boundary(b), _begin(begin), _end(end) { assert(b <= begin, err_msg("Error: boundary " PTR_FORMAT " should be at or below begin " PTR_FORMAT, - b, begin)); + p2i(b), p2i(begin))); assert(begin <= end, err_msg("Error: begin " PTR_FORMAT " should be strictly below end " PTR_FORMAT, - begin, end)); + p2i(begin), p2i(end))); } virtual void do_oop(oop* p) { VerifyCleanCardClosure::do_oop_work(p); } diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp index 69d39e4d431..6d822a4b9e9 100644 --- a/hotspot/src/share/vm/memory/collectorPolicy.cpp +++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -736,7 +736,7 @@ HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size, if ((QueuedAllocationWarningCount > 0) && (try_count % QueuedAllocationWarningCount == 0)) { warning("TwoGenerationCollectorPolicy::mem_allocate_work retries %d times \n\t" - " size=%d %s", try_count, size, is_tlab ? "(TLAB)" : ""); + " size=" SIZE_FORMAT " %s", try_count, size, is_tlab ? "(TLAB)" : ""); } } } @@ -903,7 +903,7 @@ MetaWord* CollectorPolicy::satisfy_failed_metadata_allocation( if ((QueuedAllocationWarningCount > 0) && (loop_count % QueuedAllocationWarningCount == 0)) { warning("satisfy_failed_metadata_allocation() retries %d times \n\t" - " size=%d", loop_count, word_size); + " size=" SIZE_FORMAT, loop_count, word_size); } } while (true); // Until a GC is done } diff --git a/hotspot/src/share/vm/memory/defNewGeneration.cpp b/hotspot/src/share/vm/memory/defNewGeneration.cpp index 000be1f8bf3..32c2e28bee6 100644 --- a/hotspot/src/share/vm/memory/defNewGeneration.cpp +++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,8 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/stack.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // // DefNewGeneration functions. diff --git a/hotspot/src/share/vm/memory/filemap.cpp b/hotspot/src/share/vm/memory/filemap.cpp index 1420c279036..47527f21e9f 100644 --- a/hotspot/src/share/vm/memory/filemap.cpp +++ b/hotspot/src/share/vm/memory/filemap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,7 @@ #define O_BINARY 0 // otherwise do nothing. #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC extern address JVM_FunctionAtStart(); extern address JVM_FunctionAtEnd(); diff --git a/hotspot/src/share/vm/memory/gcLocker.cpp b/hotspot/src/share/vm/memory/gcLocker.cpp index fc267ad84f1..96742637939 100644 --- a/hotspot/src/share/vm/memory/gcLocker.cpp +++ b/hotspot/src/share/vm/memory/gcLocker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ void GC_locker::verify_critical_count() { tty->print_cr("critical counts don't match: %d != %d", _jni_lock_count, count); for (JavaThread* thr = Threads::first(); thr; thr = thr->next()) { if (thr->in_critical()) { - tty->print_cr(INTPTR_FORMAT " in_critical %d", thr, thr->in_critical()); + tty->print_cr(INTPTR_FORMAT " in_critical %d", p2i(thr), thr->in_critical()); } } } diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.cpp b/hotspot/src/share/vm/memory/genCollectedHeap.cpp index f3b2a8ec885..0f75d779d2a 100644 --- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp +++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -794,7 +794,7 @@ void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs, bool GenCollectedHeap::is_in_young(oop p) { bool result = ((HeapWord*)p) < _gens[_n_gens - 1]->reserved().start(); assert(result == _gens[0]->is_in_reserved(p), - err_msg("incorrect test - result=%d, p=" PTR_FORMAT, result, (void*)p)); + err_msg("incorrect test - result=%d, p=" INTPTR_FORMAT, result, p2i((void*)p))); return result; } @@ -1067,7 +1067,7 @@ void GenCollectedHeap::verify(bool silent, VerifyOption option /* ignored */) { for (int i = _n_gens-1; i >= 0; i--) { Generation* g = _gens[i]; if (!silent) { - gclog_or_tty->print(g->name()); + gclog_or_tty->print("%s", g->name()); gclog_or_tty->print(" "); } g->verify(); @@ -1270,7 +1270,7 @@ jlong GenCollectedHeap::millis_since_last_gc() { // back a time later than 'now'. jlong retVal = now - tolgc_cl.time(); if (retVal < 0) { - NOT_PRODUCT(warning("time warp: "INT64_FORMAT, retVal);) + NOT_PRODUCT(warning("time warp: "INT64_FORMAT, (int64_t) retVal);) return 0; } return retVal; diff --git a/hotspot/src/share/vm/memory/genOopClosures.hpp b/hotspot/src/share/vm/memory/genOopClosures.hpp index 1f24b2b3cab..977fcb34cf4 100644 --- a/hotspot/src/share/vm/memory/genOopClosures.hpp +++ b/hotspot/src/share/vm/memory/genOopClosures.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -193,7 +193,7 @@ class VerifyOopClosure: public OopClosure { protected: template <class T> inline void do_oop_work(T* p) { oop obj = oopDesc::load_decode_heap_oop(p); - guarantee(obj->is_oop_or_null(), err_msg("invalid oop: " INTPTR_FORMAT, (oopDesc*) obj)); + guarantee(obj->is_oop_or_null(), err_msg("invalid oop: " INTPTR_FORMAT, p2i((oopDesc*) obj))); } public: virtual void do_oop(oop* p); diff --git a/hotspot/src/share/vm/memory/generation.cpp b/hotspot/src/share/vm/memory/generation.cpp index 5d3ad791473..0c121503a17 100644 --- a/hotspot/src/share/vm/memory/generation.cpp +++ b/hotspot/src/share/vm/memory/generation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,8 @@ #include "utilities/copy.hpp" #include "utilities/events.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + Generation::Generation(ReservedSpace rs, size_t initial_size, int level) : _level(level), _ref_processor(NULL) { diff --git a/hotspot/src/share/vm/memory/generation.hpp b/hotspot/src/share/vm/memory/generation.hpp index f44f0245c36..de60d23f197 100644 --- a/hotspot/src/share/vm/memory/generation.hpp +++ b/hotspot/src/share/vm/memory/generation.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -422,7 +422,7 @@ class Generation: public CHeapObj<mtGC> { // have to guard against non-monotonicity. NOT_PRODUCT( if (now < _time_of_last_gc) { - warning("time warp: "INT64_FORMAT" to "INT64_FORMAT, _time_of_last_gc, now); + warning("time warp: "INT64_FORMAT" to "INT64_FORMAT, (int64_t)_time_of_last_gc, (int64_t)now); } ) return _time_of_last_gc; diff --git a/hotspot/src/share/vm/memory/heapInspection.cpp b/hotspot/src/share/vm/memory/heapInspection.cpp index bf65c882cd6..7a4c6fc8752 100644 --- a/hotspot/src/share/vm/memory/heapInspection.cpp +++ b/hotspot/src/share/vm/memory/heapInspection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" #endif // INCLUDE_ALL_GCS +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // HeapInspection int KlassInfoEntry::compare(KlassInfoEntry* e1, KlassInfoEntry* e2) { @@ -270,6 +272,7 @@ bool KlassInfoHisto::is_selected(const char *col_name) { return true; } +PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL void KlassInfoHisto::print_title(outputStream* st, bool csv_format, bool selected[], int width_table[], const char *name_table[]) { @@ -282,7 +285,10 @@ void KlassInfoHisto::print_title(outputStream* st, bool csv_format, } else { st->print("Index Super"); for (int c=0; c<KlassSizeStats::_num_columns; c++) { +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL if (selected[c]) {st->print(str_fmt(width_table[c]), name_table[c]);} +PRAGMA_DIAG_POP } st->print(" ClassName"); } @@ -395,12 +401,18 @@ void KlassInfoHisto::print_class_stats(outputStream* st, case KlassSizeStats::_index_inst_size: case KlassSizeStats::_index_inst_count: case KlassSizeStats::_index_method_count: +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL st->print(str_fmt(width_table[c]), "-"); +PRAGMA_DIAG_POP break; default: { double perc = (double)(100) * (double)(colsum_table[c]) / (double)sz_sum._total_bytes; +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL st->print(perc_fmt(width_table[c]), perc); +PRAGMA_DIAG_POP } } } diff --git a/hotspot/src/share/vm/memory/heapInspection.hpp b/hotspot/src/share/vm/memory/heapInspection.hpp index 8cdd4ccdf65..b305f08fdb3 100644 --- a/hotspot/src/share/vm/memory/heapInspection.hpp +++ b/hotspot/src/share/vm/memory/heapInspection.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -295,6 +295,9 @@ class KlassInfoHisto : public StackObj { // returns a format string to print a julong with the given width. E.g, // printf(num_fmt(6), julong(10)) would print out the number 10 with 4 // leading spaces. +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED + static void print_julong(outputStream* st, int width, julong n) { int num_spaces = width - julong_width(n); if (num_spaces > 0) { @@ -302,6 +305,7 @@ class KlassInfoHisto : public StackObj { } st->print(JULONG_FORMAT, n); } +PRAGMA_DIAG_POP static char* perc_fmt(int width) { static char buf[32]; diff --git a/hotspot/src/share/vm/memory/metachunk.cpp b/hotspot/src/share/vm/memory/metachunk.cpp index 81a1f8f8224..6cb6625b186 100644 --- a/hotspot/src/share/vm/memory/metachunk.cpp +++ b/hotspot/src/share/vm/memory/metachunk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,8 @@ #include "utilities/copy.hpp" #include "utilities/debug.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + class VirtualSpaceNode; const size_t metadata_chunk_initialize = 0xf7f7f7f7; diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 0ace09a0735..e005263aa0b 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,6 +48,8 @@ #include "utilities/copy.hpp" #include "utilities/debug.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + typedef BinaryTreeDictionary<Metablock, FreeList<Metablock> > BlockTreeDictionary; typedef BinaryTreeDictionary<Metachunk, FreeList<Metachunk> > ChunkTreeDictionary; @@ -1961,7 +1963,7 @@ void SpaceManager::locked_print_chunks_in_use_on(outputStream* st) const { st->print_cr(" free " SIZE_FORMAT, chunk->free_word_size()); } else { - st->print_cr(""); + st->cr(); } } @@ -2245,7 +2247,7 @@ SpaceManager::~SpaceManager() { humongous_chunks = next_humongous_chunks; } if (TraceMetadataChunkAllocation && Verbose) { - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); gclog_or_tty->print_cr("updated dictionary count %d %s", chunk_manager()->humongous_dictionary()->total_count(), chunk_size_name(HumongousIndex)); diff --git a/hotspot/src/share/vm/memory/metaspaceShared.cpp b/hotspot/src/share/vm/memory/metaspaceShared.cpp index ef4572824f7..fc303f050a8 100644 --- a/hotspot/src/share/vm/memory/metaspaceShared.cpp +++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,7 @@ #include "runtime/vmThread.hpp" #include "utilities/hashtable.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC int MetaspaceShared::_max_alignment = 0; @@ -337,13 +338,14 @@ void DumpAllocClosure::dump_stats(int ro_all, int rw_all, int md_all, int mc_all int all_rw_count = 0; int all_rw_bytes = 0; - const char *fmt = "%-20s: %8d %10d %5.1f | %8d %10d %5.1f | %8d %10d %5.1f"; +// To make fmt_stats be a syntactic constant (for format warnings), use #define. +#define fmt_stats "%-20s: %8d %10d %5.1f | %8d %10d %5.1f | %8d %10d %5.1f" const char *sep = "--------------------+---------------------------+---------------------------+--------------------------"; const char *hdr = " ro_cnt ro_bytes % | rw_cnt rw_bytes % | all_cnt all_bytes %"; tty->print_cr("Detailed metadata info (rw includes md and mc):"); - tty->print_cr(hdr); - tty->print_cr(sep); + tty->print_cr("%s", hdr); + tty->print_cr("%s", sep); for (int type = 0; type < int(_number_of_types); type ++) { const char *name = type_name((Type)type); int ro_count = _counts[RO][type]; @@ -357,7 +359,7 @@ void DumpAllocClosure::dump_stats(int ro_all, int rw_all, int md_all, int mc_all double rw_perc = 100.0 * double(rw_bytes) / double(rw_all); double perc = 100.0 * double(bytes) / double(ro_all + rw_all); - tty->print_cr(fmt, name, + tty->print_cr(fmt_stats, name, ro_count, ro_bytes, ro_perc, rw_count, rw_bytes, rw_perc, count, bytes, perc); @@ -375,14 +377,15 @@ void DumpAllocClosure::dump_stats(int ro_all, int rw_all, int md_all, int mc_all double all_rw_perc = 100.0 * double(all_rw_bytes) / double(rw_all); double all_perc = 100.0 * double(all_bytes) / double(ro_all + rw_all); - tty->print_cr(sep); - tty->print_cr(fmt, "Total", + tty->print_cr("%s", sep); + tty->print_cr(fmt_stats, "Total", all_ro_count, all_ro_bytes, all_ro_perc, all_rw_count, all_rw_bytes, all_rw_perc, all_count, all_bytes, all_perc); assert(all_ro_bytes == ro_all, "everything should have been counted"); assert(all_rw_bytes == rw_all, "everything should have been counted"); +#undef fmt_stats } // Populate the shared space. @@ -514,7 +517,8 @@ void VM_PopulateDumpSharedSpace::doit() { md_top = wc.get_top(); // Print shared spaces all the time - const char* fmt = "%s space: %9d [ %4.1f%% of total] out of %9d bytes [%4.1f%% used] at " PTR_FORMAT; +// To make fmt_space be a syntactic constant (for format warnings), use #define. +#define fmt_space "%s space: %9d [ %4.1f%% of total] out of %9d bytes [%4.1f%% used] at " INTPTR_FORMAT Metaspace* ro_space = _loader_data->ro_metaspace(); Metaspace* rw_space = _loader_data->rw_metaspace(); @@ -545,10 +549,10 @@ void VM_PopulateDumpSharedSpace::doit() { const double mc_u_perc = mc_bytes / double(mc_alloced) * 100.0; const double total_u_perc = total_bytes / double(total_alloced) * 100.0; - tty->print_cr(fmt, "ro", ro_bytes, ro_t_perc, ro_alloced, ro_u_perc, ro_space->bottom()); - tty->print_cr(fmt, "rw", rw_bytes, rw_t_perc, rw_alloced, rw_u_perc, rw_space->bottom()); - tty->print_cr(fmt, "md", md_bytes, md_t_perc, md_alloced, md_u_perc, md_low); - tty->print_cr(fmt, "mc", mc_bytes, mc_t_perc, mc_alloced, mc_u_perc, mc_low); + tty->print_cr(fmt_space, "ro", ro_bytes, ro_t_perc, ro_alloced, ro_u_perc, ro_space->bottom()); + tty->print_cr(fmt_space, "rw", rw_bytes, rw_t_perc, rw_alloced, rw_u_perc, rw_space->bottom()); + tty->print_cr(fmt_space, "md", md_bytes, md_t_perc, md_alloced, md_u_perc, md_low); + tty->print_cr(fmt_space, "mc", mc_bytes, mc_t_perc, mc_alloced, mc_u_perc, mc_low); tty->print_cr("total : %9d [100.0%% of total] out of %9d bytes [%4.1f%% used]", total_bytes, total_alloced, total_u_perc); @@ -603,6 +607,7 @@ void VM_PopulateDumpSharedSpace::doit() { dac.dump_stats(int(ro_bytes), int(rw_bytes), int(md_bytes), int(mc_bytes)); } +#undef fmt_space } static void link_shared_classes(Klass* obj, TRAPS) { diff --git a/hotspot/src/share/vm/memory/referenceProcessor.cpp b/hotspot/src/share/vm/memory/referenceProcessor.cpp index 72a43d85df3..2a87b4b65b6 100644 --- a/hotspot/src/share/vm/memory/referenceProcessor.cpp +++ b/hotspot/src/share/vm/memory/referenceProcessor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ #include "runtime/java.hpp" #include "runtime/jniHandles.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL; ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy = NULL; bool ReferenceProcessor::_pending_list_uses_discovered_field = false; diff --git a/hotspot/src/share/vm/memory/sharedHeap.cpp b/hotspot/src/share/vm/memory/sharedHeap.cpp index b59635c9f33..7b187ee01ad 100644 --- a/hotspot/src/share/vm/memory/sharedHeap.cpp +++ b/hotspot/src/share/vm/memory/sharedHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ #include "utilities/copy.hpp" #include "utilities/workgroup.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + SharedHeap* SharedHeap::_sh; // The set of potentially parallel tasks in strong root scanning. diff --git a/hotspot/src/share/vm/memory/space.cpp b/hotspot/src/share/vm/memory/space.cpp index 8bff19441d9..68e2631d115 100644 --- a/hotspot/src/share/vm/memory/space.cpp +++ b/hotspot/src/share/vm/memory/space.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,8 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + HeapWord* DirtyCardToOopClosure::get_actual_top(HeapWord* top, HeapWord* top_obj) { if (top_obj != NULL) { diff --git a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp index 715e6214c9b..b59cfd80d39 100644 --- a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp +++ b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ #include "runtime/thread.inline.hpp" #include "utilities/copy.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Thread-Local Edens support // static member initialization diff --git a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp index ea803157300..cf3fefbfe3a 100644 --- a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp +++ b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -98,7 +98,7 @@ void ThreadLocalAllocBuffer::record_slow_allocation(size_t obj_size) { " obj: "SIZE_FORMAT " free: "SIZE_FORMAT " waste: "SIZE_FORMAT"\n", - "slow", thrd, thrd->osthread()->thread_id(), + "slow", p2i(thrd), thrd->osthread()->thread_id(), obj_size, free(), refill_waste_limit()); } } diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index 63c7c005d44..ffecfc19cc8 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,6 +78,8 @@ #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" #endif // INCLUDE_ALL_GCS +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Known objects Klass* Universe::_boolArrayKlassObj = NULL; Klass* Universe::_byteArrayKlassObj = NULL; @@ -1348,7 +1350,7 @@ void Universe::verify(VerifyOption option, const char* prefix, bool silent) { HandleMark hm; // Handles created during verification can be zapped _verify_count++; - if (!silent) gclog_or_tty->print(prefix); + if (!silent) gclog_or_tty->print("%s", prefix); if (!silent) gclog_or_tty->print("[Verifying "); if (!silent) gclog_or_tty->print("threads "); Threads::verify(); diff --git a/hotspot/src/share/vm/oops/annotations.cpp b/hotspot/src/share/vm/oops/annotations.cpp index 1eb3afbb740..776b8606b66 100644 --- a/hotspot/src/share/vm/oops/annotations.cpp +++ b/hotspot/src/share/vm/oops/annotations.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,7 +76,7 @@ typeArrayOop Annotations::make_java_array(AnnotationArray* annotations, TRAPS) { void Annotations::print_value_on(outputStream* st) const { - st->print("Anotations(" INTPTR_FORMAT ")", this); + st->print("Anotations(" INTPTR_FORMAT ")", p2i(this)); } #if INCLUDE_SERVICES diff --git a/hotspot/src/share/vm/oops/constMethod.cpp b/hotspot/src/share/vm/oops/constMethod.cpp index 4c0720908f7..ea51a2c02c4 100644 --- a/hotspot/src/share/vm/oops/constMethod.cpp +++ b/hotspot/src/share/vm/oops/constMethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -388,8 +388,8 @@ void ConstMethod::copy_annotations_from(ConstMethod* cm) { void ConstMethod::print_on(outputStream* st) const { ResourceMark rm; assert(is_constMethod(), "must be constMethod"); - st->print_cr(internal_name()); - st->print(" - method: " INTPTR_FORMAT " ", (address)method()); + st->print_cr("%s", internal_name()); + st->print(" - method: " INTPTR_FORMAT " ", p2i((address)method())); method()->print_value_on(st); st->cr(); if (has_stackmap_table()) { st->print(" - stackmap data: "); diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index bd2ee585149..34dba443f83 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -42,6 +42,8 @@ #include "runtime/signature.hpp" #include "runtime/vframe.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, TRAPS) { // Tags are RW but comment below applies to tags also. Array<u1>* tags = MetadataFactory::new_writeable_array<u1>(loader_data, length, 0, CHECK_NULL); @@ -1892,7 +1894,7 @@ void ConstantPool::preload_and_initialize_all_classes(ConstantPool* obj, TRAPS) void ConstantPool::print_on(outputStream* st) const { assert(is_constantPool(), "must be constantPool"); - st->print_cr(internal_name()); + st->print_cr("%s", internal_name()); if (flags() != 0) { st->print(" - flags: 0x%x", flags()); if (has_preresolution()) st->print(" has_preresolution"); diff --git a/hotspot/src/share/vm/oops/cpCache.cpp b/hotspot/src/share/vm/oops/cpCache.cpp index cdd3cef4ad1..4b6459ee33f 100644 --- a/hotspot/src/share/vm/oops/cpCache.cpp +++ b/hotspot/src/share/vm/oops/cpCache.cpp @@ -39,8 +39,9 @@ # include "gc_implementation/parallelScavenge/psPromotionManager.hpp" #endif // INCLUDE_ALL_GCS +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC -// Implememtation of ConstantPoolCacheEntry +// Implementation of ConstantPoolCacheEntry void ConstantPoolCacheEntry::initialize_entry(int index) { assert(0 < index && index < 0x10000, "sanity check"); @@ -668,7 +669,7 @@ void ConstantPoolCache::dump_cache() { void ConstantPoolCache::print_on(outputStream* st) const { assert(is_constantPoolCache(), "obj must be constant pool cache"); - st->print_cr(internal_name()); + st->print_cr("%s", internal_name()); // print constant pool cache entries for (int i = 0; i < length(); i++) entry_at(i)->print(st, i); } diff --git a/hotspot/src/share/vm/oops/generateOopMap.hpp b/hotspot/src/share/vm/oops/generateOopMap.hpp index ad0578c323a..48c49f443e9 100644 --- a/hotspot/src/share/vm/oops/generateOopMap.hpp +++ b/hotspot/src/share/vm/oops/generateOopMap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -412,9 +412,9 @@ class GenerateOopMap VALUE_OBJ_CLASS_SPEC { int copy_cts (CellTypeState *dst, CellTypeState *src); // Error handling - void error_work (const char *format, va_list ap); - void report_error (const char *format, ...); - void verify_error (const char *format, ...); + void error_work (const char *format, va_list ap) ATTRIBUTE_PRINTF(2, 0); + void report_error (const char *format, ...) ATTRIBUTE_PRINTF(2, 3); + void verify_error (const char *format, ...) ATTRIBUTE_PRINTF(2, 3); bool got_error() { return _got_error; } // Create result set diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 84775407262..9c4c9b8fbf5 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -77,6 +77,8 @@ #include "c1/c1_Compiler.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef DTRACE_ENABLED @@ -2857,7 +2859,7 @@ void InstanceKlass::print_on(outputStream* st) const { st->print(BULLET"instance size: %d", size_helper()); st->cr(); st->print(BULLET"klass size: %d", size()); st->cr(); st->print(BULLET"access: "); access_flags().print_on(st); st->cr(); - st->print(BULLET"state: "); st->print_cr(state_names[_init_state]); + st->print(BULLET"state: "); st->print_cr("%s", state_names[_init_state]); st->print(BULLET"name: "); name()->print_value_on(st); st->cr(); st->print(BULLET"super: "); super()->print_value_on_maybe_null(st); st->cr(); st->print(BULLET"sub: "); diff --git a/hotspot/src/share/vm/oops/instanceRefKlass.cpp b/hotspot/src/share/vm/oops/instanceRefKlass.cpp index f388980adc3..7340e5adc91 100644 --- a/hotspot/src/share/vm/oops/instanceRefKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceRefKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,8 @@ #include "oops/oop.pcgc.inline.hpp" #endif // INCLUDE_ALL_GCS +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + template <class T> void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) { T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); diff --git a/hotspot/src/share/vm/oops/klass.inline.hpp b/hotspot/src/share/vm/oops/klass.inline.hpp index 841a4873a32..8b05c3c2945 100644 --- a/hotspot/src/share/vm/oops/klass.inline.hpp +++ b/hotspot/src/share/vm/oops/klass.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,7 @@ inline Klass* Klass::decode_klass_not_null(narrowKlass v) { assert(!is_null(v), "narrow klass value can never be zero"); int shift = Universe::narrow_klass_shift(); Klass* result = (Klass*)(void*)((uintptr_t)Universe::narrow_klass_base() + ((uintptr_t)v << shift)); - assert(check_klass_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result)); + assert(check_klass_alignment(result), err_msg("address not aligned: " INTPTR_FORMAT, p2i((void*) result))); return result; } diff --git a/hotspot/src/share/vm/oops/klassVtable.cpp b/hotspot/src/share/vm/oops/klassVtable.cpp index ad185c7f1a8..6d122de680a 100644 --- a/hotspot/src/share/vm/oops/klassVtable.cpp +++ b/hotspot/src/share/vm/oops/klassVtable.cpp @@ -39,6 +39,8 @@ #include "runtime/handles.inline.hpp" #include "utilities/copy.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + inline InstanceKlass* klassVtable::ik() const { Klass* k = _klass(); assert(k->oop_is_instance(), "not an InstanceKlass"); diff --git a/hotspot/src/share/vm/oops/markOop.cpp b/hotspot/src/share/vm/oops/markOop.cpp index af722e7cf72..85dd5a06a65 100644 --- a/hotspot/src/share/vm/oops/markOop.cpp +++ b/hotspot/src/share/vm/oops/markOop.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,9 +26,11 @@ #include "oops/markOop.hpp" #include "runtime/thread.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + void markOopDesc::print_on(outputStream* st) const { if (is_locked()) { - st->print("locked(0x%lx)->", value()); + st->print("locked(" INTPTR_FORMAT ")->", value()); markOop(*(markOop*)value())->print_on(st); } else { assert(is_unlocked() || has_bias_pattern(), "just checking"); diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index 883ff487b26..0ce786e572f 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -56,6 +56,7 @@ #include "utilities/quickSort.hpp" #include "utilities/xmlstream.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC // Implementation of Method @@ -1425,7 +1426,7 @@ class SignatureTypePrinter : public SignatureTypeNames { void type_name(const char* name) { if (_use_separator) _st->print(", "); - _st->print(name); + _st->print("%s", name); _use_separator = true; } @@ -1898,7 +1899,7 @@ void Method::print_jmethod_ids(ClassLoaderData* loader_data, outputStream* out) void Method::print_on(outputStream* st) const { ResourceMark rm; assert(is_method(), "must be method"); - st->print_cr(internal_name()); + st->print_cr("%s", internal_name()); // get the effect of PrintOopAddress, always, for methods: st->print_cr(" - this oop: "INTPTR_FORMAT, (intptr_t)this); st->print (" - method holder: "); method_holder()->print_value_on(st); st->cr(); @@ -1981,7 +1982,7 @@ void Method::print_on(outputStream* st) const { void Method::print_value_on(outputStream* st) const { assert(is_method(), "must be method"); - st->print(internal_name()); + st->print("%s", internal_name()); print_address_on(st); st->print(" "); name()->print_value_on(st); diff --git a/hotspot/src/share/vm/oops/methodData.cpp b/hotspot/src/share/vm/oops/methodData.cpp index 06d9dcb51bf..4bbdc992d86 100644 --- a/hotspot/src/share/vm/oops/methodData.cpp +++ b/hotspot/src/share/vm/oops/methodData.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,8 @@ #include "runtime/handles.inline.hpp" #include "runtime/orderAccess.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // ================================================================== // DataLayout // @@ -127,7 +129,7 @@ void ProfileData::print_shared(outputStream* st, const char* name, const char* e st->print("trap(%s) ", Deoptimization::format_trap_state(buf, sizeof(buf), trap)); } if (extra != NULL) { - st->print(extra); + st->print("%s", extra); } int flags = data()->flags(); if (flags != 0) { @@ -635,7 +637,7 @@ bool ParametersTypeData::profiling_enabled() { } void ParametersTypeData::print_data_on(outputStream* st, const char* extra) const { - st->print("parameter types", extra); + st->print("parameter types"); // FIXME extra ignored? _parameters.print_data_on(st); } diff --git a/hotspot/src/share/vm/oops/oop.cpp b/hotspot/src/share/vm/oops/oop.cpp index 281188354a0..1be57811ede 100644 --- a/hotspot/src/share/vm/oops/oop.cpp +++ b/hotspot/src/share/vm/oops/oop.cpp @@ -30,6 +30,8 @@ #include "runtime/thread.inline.hpp" #include "utilities/copy.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + bool always_do_update_barrier = false; BarrierSet* oopDesc::_bs = NULL; diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp index 7dd78ef8eb2..0dc0db8e946 100644 --- a/hotspot/src/share/vm/oops/oop.inline.hpp +++ b/hotspot/src/share/vm/oops/oop.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -211,7 +211,7 @@ inline oop oopDesc::decode_heap_oop_not_null(narrowOop v) { address base = Universe::narrow_oop_base(); int shift = Universe::narrow_oop_shift(); oop result = (oop)(void*)((uintptr_t)base + ((uintptr_t)v << shift)); - assert(check_obj_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result)); + assert(check_obj_alignment(result), err_msg("address not aligned: " INTPTR_FORMAT, p2i((void*) result))); return result; } diff --git a/hotspot/src/share/vm/opto/block.cpp b/hotspot/src/share/vm/opto/block.cpp index 3eaa2abcb7c..f9fec29359f 100644 --- a/hotspot/src/share/vm/opto/block.cpp +++ b/hotspot/src/share/vm/opto/block.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -339,7 +339,7 @@ void Block::dump_head(const PhaseCFG* cfg, outputStream* st) const { st->print(" FRegPressure: %d",_freg_pressure); st->print(" FHRP Index: %d",_fhrp_index); } - st->print_cr(""); + st->cr(); } void Block::dump() const { diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp index 1637741176d..b2cd166b4dd 100644 --- a/hotspot/src/share/vm/opto/callnode.cpp +++ b/hotspot/src/share/vm/opto/callnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -112,7 +112,7 @@ const char * const ParmNode::names[TypeFunc::Parms+1] = { #ifndef PRODUCT void ParmNode::dump_spec(outputStream *st) const { if( _con < TypeFunc::Parms ) { - st->print(names[_con]); + st->print("%s", names[_con]); } else { st->print("Parm%d: ",_con-TypeFunc::Parms); // Verbose and WizardMode dump bottom_type for all nodes @@ -348,19 +348,19 @@ static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, c break; case Type::AryPtr: case Type::InstPtr: - st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->isa_oopptr()->const_oop()); + st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,p2i(t->isa_oopptr()->const_oop())); break; case Type::KlassPtr: - st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->make_ptr()->isa_klassptr()->klass()); + st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,p2i(t->make_ptr()->isa_klassptr()->klass())); break; case Type::MetadataPtr: - st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->make_ptr()->isa_metadataptr()->metadata()); + st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,p2i(t->make_ptr()->isa_metadataptr()->metadata())); break; case Type::NarrowOop: - st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->make_ptr()->isa_oopptr()->const_oop()); + st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,p2i(t->make_ptr()->isa_oopptr()->const_oop())); break; case Type::RawPtr: - st->print(" %s%d]=#Raw" INTPTR_FORMAT,msg,i,t->is_rawptr()); + st->print(" %s%d]=#Raw" INTPTR_FORMAT,msg,i,p2i(t->is_rawptr())); break; case Type::DoubleCon: st->print(" %s%d]=#%fD",msg,i,t->is_double_constant()->_d); @@ -369,7 +369,7 @@ static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, c st->print(" %s%d]=#%fF",msg,i,t->is_float_constant()->_f); break; case Type::Long: - st->print(" %s%d]=#"INT64_FORMAT,msg,i,t->is_long()->get_con()); + st->print(" %s%d]=#"INT64_FORMAT,msg,i,(int64_t)(t->is_long()->get_con())); break; case Type::Half: case Type::Top: @@ -428,7 +428,7 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) for (i = 0; i < (uint)scobjs.length(); i++) { // Scalar replaced objects. - st->print_cr(""); + st->cr(); st->print(" # ScObj" INT32_FORMAT " ", i); SafePointScalarObjectNode* spobj = scobjs.at(i); ciKlass* cik = spobj->bottom_type()->is_oopptr()->klass(); @@ -485,7 +485,7 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) st->print(" }"); } } - st->print_cr(""); + st->cr(); if (caller() != NULL) caller()->format(regalloc, n, st); } @@ -981,7 +981,7 @@ uint CallRuntimeNode::cmp( const Node &n ) const { #ifndef PRODUCT void CallRuntimeNode::dump_spec(outputStream *st) const { st->print("# "); - st->print(_name); + st->print("%s", _name); CallNode::dump_spec(st); } #endif @@ -999,7 +999,7 @@ void CallRuntimeNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_reg #ifndef PRODUCT void CallLeafNode::dump_spec(outputStream *st) const { st->print("# "); - st->print(_name); + st->print("%s", _name); CallNode::dump_spec(st); } #endif diff --git a/hotspot/src/share/vm/opto/chaitin.cpp b/hotspot/src/share/vm/opto/chaitin.cpp index 24328546fec..f6e2065e26d 100644 --- a/hotspot/src/share/vm/opto/chaitin.cpp +++ b/hotspot/src/share/vm/opto/chaitin.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2020,25 +2020,25 @@ void PhaseChaitin::dump() const { tty->print_cr("new LRG"); } } - tty->print_cr(""); + tty->cr(); // Dump lo-degree list tty->print("Lo degree: "); for(uint i3 = _lo_degree; i3; i3 = lrgs(i3)._next ) tty->print("L%d ",i3); - tty->print_cr(""); + tty->cr(); // Dump lo-stk-degree list tty->print("Lo stk degree: "); for(uint i4 = _lo_stk_degree; i4; i4 = lrgs(i4)._next ) tty->print("L%d ",i4); - tty->print_cr(""); + tty->cr(); // Dump lo-degree list tty->print("Hi degree: "); for(uint i5 = _hi_degree; i5; i5 = lrgs(i5)._next ) tty->print("L%d ",i5); - tty->print_cr(""); + tty->cr(); } void PhaseChaitin::dump_degree_lists() const { @@ -2046,26 +2046,26 @@ void PhaseChaitin::dump_degree_lists() const { tty->print("Lo degree: "); for( uint i = _lo_degree; i; i = lrgs(i)._next ) tty->print("L%d ",i); - tty->print_cr(""); + tty->cr(); // Dump lo-stk-degree list tty->print("Lo stk degree: "); for(uint i2 = _lo_stk_degree; i2; i2 = lrgs(i2)._next ) tty->print("L%d ",i2); - tty->print_cr(""); + tty->cr(); // Dump lo-degree list tty->print("Hi degree: "); for(uint i3 = _hi_degree; i3; i3 = lrgs(i3)._next ) tty->print("L%d ",i3); - tty->print_cr(""); + tty->cr(); } void PhaseChaitin::dump_simplified() const { tty->print("Simplified: "); for( uint i = _simplified; i; i = lrgs(i)._next ) tty->print("L%d ",i); - tty->print_cr(""); + tty->cr(); } static char *print_reg( OptoReg::Name reg, const PhaseChaitin *pc, char *buf ) { @@ -2144,7 +2144,7 @@ void PhaseChaitin::dump_frame() const { } tty->print(" : parm %d: ", k); domain->field_at(k + TypeFunc::Parms)->dump(); - tty->print_cr(""); + tty->cr(); } } @@ -2166,7 +2166,7 @@ void PhaseChaitin::dump_frame() const { _matcher._parm_regs[j].second() == reg ) { tty->print("parm %d: ",j); domain->field_at(j + TypeFunc::Parms)->dump(); - tty->print_cr(""); + tty->cr(); break; } } diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index 7226a725a7c..738644001b1 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2424,7 +2424,7 @@ void Compile::dump_asm(int *pcs, uint pc_limit) { starts_bundle = ' '; tty->print("\t"); delay->format(_regalloc, tty); - tty->print_cr(""); + tty->cr(); delay = NULL; } @@ -2438,12 +2438,12 @@ void Compile::dump_asm(int *pcs, uint pc_limit) { if (pcs && n->_idx < pc_limit) tty->print_cr("%3.3x", pcs[n->_idx]); else - tty->print_cr(""); + tty->cr(); assert(cut_short || delay == NULL, "no unconditional delay branch"); } // End of per-block dump - tty->print_cr(""); + tty->cr(); if (cut_short) tty->print_cr("*** disassembly is cut short ***"); } @@ -3688,7 +3688,8 @@ void Compile::ConstantTable::emit(CodeBuffer& cb) { default: ShouldNotReachHere(); } assert(constant_addr, "consts section too small"); - assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), err_msg_res("must be: %d == %d", constant_addr - _masm.code()->consts()->start(), con.offset())); + assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), + err_msg_res("must be: %d == %d", (int) (constant_addr - _masm.code()->consts()->start()), (int)(con.offset()))); } } @@ -3768,7 +3769,7 @@ void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n for (uint i = 0; i < n->outcnt(); i++) { address* constant_addr = &jump_table_base[i]; - assert(*constant_addr == (((address) n) + i), err_msg_res("all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, *constant_addr, (((address) n) + i))); + assert(*constant_addr == (((address) n) + i), err_msg_res("all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, p2i(*constant_addr), p2i(((address) n) + i))); *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr); cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type); } @@ -3884,7 +3885,7 @@ void Compile::dump_inlining() { } if (do_print_inlining) { for (int i = 0; i < _print_inlining_list->length(); i++) { - tty->print(_print_inlining_list->adr_at(i)->ss()->as_string()); + tty->print("%s", _print_inlining_list->adr_at(i)->ss()->as_string()); } } } diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp index 3d561556881..aa4a5720502 100644 --- a/hotspot/src/share/vm/opto/compile.hpp +++ b/hotspot/src/share/vm/opto/compile.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -459,7 +459,7 @@ class Compile : public Phase { void print_inlining(ciMethod* method, int inline_level, int bci, const char* msg = NULL) { stringStream ss; CompileTask::print_inlining(&ss, method, inline_level, bci, msg); - print_inlining_stream()->print(ss.as_string()); + print_inlining_stream()->print("%s", ss.as_string()); } void log_late_inline(CallGenerator* cg); diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp index d806d0acf22..e3a95c079f3 100644 --- a/hotspot/src/share/vm/opto/doCall.cpp +++ b/hotspot/src/share/vm/opto/doCall.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,7 +57,7 @@ void trace_type_profile(Compile* C, ciMethod *method, int depth, int bci, ciMeth out->print(" \\-> TypeProfile (%d/%d counts) = ", receiver_count, site_count); stringStream ss; prof_klass->name()->print_symbol_on(&ss); - out->print(ss.as_string()); + out->print("%s", ss.as_string()); out->cr(); } } diff --git a/hotspot/src/share/vm/opto/gcm.cpp b/hotspot/src/share/vm/opto/gcm.cpp index fcfb3880e19..4aa770d5af5 100644 --- a/hotspot/src/share/vm/opto/gcm.cpp +++ b/hotspot/src/share/vm/opto/gcm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2014,7 +2014,7 @@ void CFGLoop::dump() const { tty->print("%s: %d trip_count: %6.0f freq: %6.0f\n", _depth == 0 ? "Method" : "Loop", _id, trip_count(), _freq); for (int i = 0; i < _depth; i++) tty->print(" "); - tty->print(" members:", _id); + tty->print(" members:"); int k = 0; for (int i = 0; i < _members.length(); i++) { if (k++ >= 6) { diff --git a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp index 851b70d3f8f..b222526c620 100644 --- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp +++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -155,7 +155,7 @@ IdealGraphPrinter::IdealGraphPrinter() { } else { // It would be nice if we could shut down cleanly but it should // be an error if we can't connect to the visualizer. - fatal(err_msg_res("Couldn't connect to visualizer at %s:%d", + fatal(err_msg_res("Couldn't connect to visualizer at %s:" INTX_FORMAT, PrintIdealGraphAddress, PrintIdealGraphPort)); } } @@ -195,7 +195,7 @@ IdealGraphPrinter::~IdealGraphPrinter() { void IdealGraphPrinter::begin_elem(const char *s) { - _xml->begin_elem(s); + _xml->begin_elem("%s", s); } void IdealGraphPrinter::end_elem() { @@ -203,7 +203,7 @@ void IdealGraphPrinter::end_elem() { } void IdealGraphPrinter::begin_head(const char *s) { - _xml->begin_head(s); + _xml->begin_head("%s", s); } void IdealGraphPrinter::end_head() { @@ -223,7 +223,7 @@ void IdealGraphPrinter::print_attr(const char *name, const char *val) { } void IdealGraphPrinter::head(const char *name) { - _xml->head(name); + _xml->head("%s", name); } void IdealGraphPrinter::tail(const char *name) { @@ -231,7 +231,7 @@ void IdealGraphPrinter::tail(const char *name) { } void IdealGraphPrinter::text(const char *s) { - _xml->text(s); + _xml->text("%s", s); } void IdealGraphPrinter::print_prop(const char *name, int val) { @@ -359,7 +359,7 @@ void IdealGraphPrinter::end_method() { void IdealGraphPrinter::print_indent() { tty->print_cr("printing ident %d", _depth); for (int i = 0; i < _depth; i++) { - _xml->print(INDENT); + _xml->print("%s", INDENT); } } diff --git a/hotspot/src/share/vm/opto/ifg.cpp b/hotspot/src/share/vm/opto/ifg.cpp index 825a7a25533..59c407aaeeb 100644 --- a/hotspot/src/share/vm/opto/ifg.cpp +++ b/hotspot/src/share/vm/opto/ifg.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -256,7 +256,7 @@ void PhaseIFG::stats() const { for( i = 0; i < _maxlrg*2; i++ ) if( h_cnt[i] ) tty->print("%d/%d ",i,h_cnt[i]); - tty->print_cr(""); + tty->cr(); } void PhaseIFG::verify( const PhaseChaitin *pc ) const { diff --git a/hotspot/src/share/vm/opto/loopPredicate.cpp b/hotspot/src/share/vm/opto/loopPredicate.cpp index 0e86e403473..aeb3ffad0d5 100644 --- a/hotspot/src/share/vm/opto/loopPredicate.cpp +++ b/hotspot/src/share/vm/opto/loopPredicate.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -639,7 +639,7 @@ BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl, if (TraceLoopPredicate) { predString->print_cr("<u range"); - tty->print(predString->as_string()); + tty->print("%s", predString->as_string()); } return bol; } diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp index 5436fd5f640..f11583a25b2 100644 --- a/hotspot/src/share/vm/opto/loopnode.cpp +++ b/hotspot/src/share/vm/opto/loopnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3569,7 +3569,7 @@ void PhaseIdealLoop::build_loop_late_post( Node *n ) { #ifdef ASSERT void PhaseIdealLoop::dump_bad_graph(const char* msg, Node* n, Node* early, Node* LCA) { - tty->print_cr(msg); + tty->print_cr("%s", msg); tty->print("n: "); n->dump(); tty->print("early(n): "); early->dump(); if (n->in(0) != NULL && !n->in(0)->is_top() && diff --git a/hotspot/src/share/vm/opto/matcher.cpp b/hotspot/src/share/vm/opto/matcher.cpp index 0e650639d0c..7cdf630e1dc 100644 --- a/hotspot/src/share/vm/opto/matcher.cpp +++ b/hotspot/src/share/vm/opto/matcher.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2622,7 +2622,7 @@ void State::dump(int depth) { tty->print_cr("%s %d %s", ruleName[i], _cost[i], ruleName[_rule[i]] ); } - tty->print_cr(""); + tty->cr(); for( i=0; i<2; i++ ) if( _kids[i] ) diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index 24b7c909923..1d908c5b577 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3981,7 +3981,7 @@ bool InitializeNode::stores_are_sane(PhaseTransform* phase) { intptr_t st_off = get_store_offset(st, phase); if (st_off < 0) continue; // ignore dead garbage if (last_off > st_off) { - tty->print_cr("*** bad store offset at %d: %d > %d", i, last_off, st_off); + tty->print_cr("*** bad store offset at %d: " INTX_FORMAT " > " INTX_FORMAT, i, last_off, st_off); this->dump(2); assert(false, "ascending store offsets"); return false; diff --git a/hotspot/src/share/vm/opto/node.cpp b/hotspot/src/share/vm/opto/node.cpp index 2064b07f451..cec7f0d517b 100644 --- a/hotspot/src/share/vm/opto/node.cpp +++ b/hotspot/src/share/vm/opto/node.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1688,7 +1688,7 @@ void Node::dump(const char* suffix, outputStream *st) const { } } } - if (suffix) st->print(suffix); + if (suffix) st->print("%s", suffix); C->_in_dump_cnt--; } diff --git a/hotspot/src/share/vm/opto/parse1.cpp b/hotspot/src/share/vm/opto/parse1.cpp index 9d7bef8edbd..d7c7a40bc50 100644 --- a/hotspot/src/share/vm/opto/parse1.cpp +++ b/hotspot/src/share/vm/opto/parse1.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -611,7 +611,7 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses, Pars set_map(entry_map); do_exits(); - if (log) log->done("parse nodes='%d' live='%d' memory='%d'", + if (log) log->done("parse nodes='%d' live='%d' memory='" SIZE_FORMAT "'", C->unique(), C->live_nodes(), C->node_arena()->used()); } @@ -1395,7 +1395,7 @@ void Parse::do_one_block() { tty->print((( i < ns) ? " %d" : " %d(e)"), b->successor_at(i)->rpo()); } if (b->is_loop_head()) tty->print(" lphd"); - tty->print_cr(""); + tty->cr(); } assert(block()->is_merged(), "must be merged before being parsed"); diff --git a/hotspot/src/share/vm/opto/parse2.cpp b/hotspot/src/share/vm/opto/parse2.cpp index cce96328b9b..9d9a21f8812 100644 --- a/hotspot/src/share/vm/opto/parse2.cpp +++ b/hotspot/src/share/vm/opto/parse2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -628,7 +628,7 @@ void Parse::jump_switch_ranges(Node* key_val, SwitchRange *lo, SwitchRange *hi, _method->print_short_name(); tty->print_cr(" switch decision tree"); tty->print_cr(" %d ranges (%d singletons), max_depth=%d, est_depth=%d", - hi-lo+1, nsing, _max_switch_depth, _est_switch_depth); + (int) (hi-lo+1), nsing, _max_switch_depth, _est_switch_depth); if (_max_switch_depth > _est_switch_depth) { tty->print_cr("******** BAD SWITCH DEPTH ********"); } @@ -636,7 +636,7 @@ void Parse::jump_switch_ranges(Node* key_val, SwitchRange *lo, SwitchRange *hi, for( r = lo; r <= hi; r++ ) { r->print(); } - tty->print_cr(""); + tty->cr(); } #endif } diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp index 276fafcdbb5..8cc008f8f56 100644 --- a/hotspot/src/share/vm/opto/phaseX.cpp +++ b/hotspot/src/share/vm/opto/phaseX.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -958,10 +958,10 @@ void PhaseIterGVN::verify_PhaseIterGVN() { if (VerifyIterativeGVN && PrintOpto) { if (_verify_counter == _verify_full_passes) { tty->print_cr("VerifyIterativeGVN: %d transforms and verify passes", - _verify_full_passes); + (int) _verify_full_passes); } else { tty->print_cr("VerifyIterativeGVN: %d transforms, %d full verify passes", - _verify_counter, _verify_full_passes); + (int) _verify_counter, (int) _verify_full_passes); } } } diff --git a/hotspot/src/share/vm/opto/regmask.cpp b/hotspot/src/share/vm/opto/regmask.cpp index 07fddd151c3..4b367117ebf 100644 --- a/hotspot/src/share/vm/opto/regmask.cpp +++ b/hotspot/src/share/vm/opto/regmask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -116,7 +116,7 @@ void OptoReg::dump(int r, outputStream *st) { case Special: st->print("r---"); break; case Bad: st->print("rBAD"); break; default: - if (r < _last_Mach_Reg) st->print(Matcher::regName[r]); + if (r < _last_Mach_Reg) st->print("%s", Matcher::regName[r]); else st->print("rS%d",r); break; } diff --git a/hotspot/src/share/vm/opto/runtime.cpp b/hotspot/src/share/vm/opto/runtime.cpp index cabf1675735..6081d449506 100644 --- a/hotspot/src/share/vm/opto/runtime.cpp +++ b/hotspot/src/share/vm/opto/runtime.cpp @@ -1393,7 +1393,7 @@ static void trace_exception(oop exception_oop, address exception_pc, const char* } else { tty->print("<unknown>"); } - tty->print(" at " INTPTR_FORMAT, exception_pc); + tty->print(" at " INTPTR_FORMAT, p2i(exception_pc)); tty->print_cr("]"); } diff --git a/hotspot/src/share/vm/opto/subnode.cpp b/hotspot/src/share/vm/opto/subnode.cpp index 469d4141e32..31bb9f6d133 100644 --- a/hotspot/src/share/vm/opto/subnode.cpp +++ b/hotspot/src/share/vm/opto/subnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1065,7 +1065,7 @@ const Type *BoolTest::cc2logical( const Type *CC ) const { #ifndef PRODUCT void BoolTest::dump_on(outputStream *st) const { const char *msg[] = {"eq","gt","of","lt","ne","le","nof","ge"}; - st->print(msg[_test]); + st->print("%s", msg[_test]); } #endif diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp index 0f011e04864..39662643ac9 100644 --- a/hotspot/src/share/vm/opto/type.cpp +++ b/hotspot/src/share/vm/opto/type.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,8 @@ #include "opto/opcodes.hpp" #include "opto/type.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Portions of code courtesy of Clifford Click // Optimization - Graph Style @@ -842,7 +844,7 @@ bool Type::has_memory() const { #ifndef PRODUCT //------------------------------dump2------------------------------------------ void Type::dump2( Dict &d, uint depth, outputStream *st ) const { - st->print(_type_info[_base].msg); + st->print("%s", _type_info[_base].msg); } //------------------------------dump------------------------------------------- diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index 53215062573..baf1cc6be21 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -275,7 +275,7 @@ const int MAX_REASONABLE_LOCAL_CAPACITY = 4*K; class JNITraceWrapper : public StackObj { public: - JNITraceWrapper(const char* format, ...) { + JNITraceWrapper(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) { if (TraceJNICalls) { va_list ap; va_start(ap, format); diff --git a/hotspot/src/share/vm/prims/jniCheck.cpp b/hotspot/src/share/vm/prims/jniCheck.cpp index 7937090cc27..0d5ffab1cdc 100644 --- a/hotspot/src/share/vm/prims/jniCheck.cpp +++ b/hotspot/src/share/vm/prims/jniCheck.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -100,7 +100,7 @@ extern "C" { \ result_type JNICALL header { \ JavaThread* thr = (JavaThread*)ThreadLocalStorage::get_thread_slow();\ if (thr == NULL || !thr->is_Java_thread()) { \ - tty->print_cr(fatal_using_jnienv_in_nonjava); \ + tty->print_cr("%s", fatal_using_jnienv_in_nonjava); \ os::abort(true); \ } \ JNIEnv* xenv = thr->jni_environment(); \ @@ -184,7 +184,7 @@ static inline void functionEnter(JavaThread* thr) { if (thr->in_critical()) { - tty->print_cr(warn_other_function_in_critical); + tty->print_cr("%s", warn_other_function_in_critical); } if (thr->has_pending_exception()) { NativeReportJNIWarning(thr, "JNI call made with exception pending"); @@ -195,7 +195,7 @@ static inline void functionEnterExceptionAllowed(JavaThread* thr) { if (thr->in_critical()) { - tty->print_cr(warn_other_function_in_critical); + tty->print_cr("%s", warn_other_function_in_critical); } } diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index cc6ec977fdf..c6e6cf09296 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -215,7 +215,7 @@ void trace_class_resolution(Klass* to_class) { #ifdef ASSERT class JVMTraceWrapper : public StackObj { public: - JVMTraceWrapper(const char* format, ...) { + JVMTraceWrapper(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) { if (TraceJVMCalls) { va_list ap; va_start(ap, format); @@ -2736,14 +2736,14 @@ JVM_END JVM_LEAF(jlong, JVM_Lseek(jint fd, jlong offset, jint whence)) - JVMWrapper4("JVM_Lseek (0x%x, %Ld, %d)", fd, offset, whence); + JVMWrapper4("JVM_Lseek (0x%x, " INT64_FORMAT ", %d)", fd, (int64_t) offset, whence); //%note jvm_r6 return os::lseek(fd, offset, whence); JVM_END JVM_LEAF(jint, JVM_SetLength(jint fd, jlong length)) - JVMWrapper3("JVM_SetLength (0x%x, %Ld)", fd, length); + JVMWrapper3("JVM_SetLength (0x%x, " INT64_FORMAT ")", fd, (int64_t) length); return os::ftruncate(fd, length); JVM_END @@ -2758,13 +2758,14 @@ JVM_END // Printing support ////////////////////////////////////////////////// extern "C" { +ATTRIBUTE_PRINTF(3, 0) int jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args) { // see bug 4399518, 4417214 if ((intptr_t)count <= 0) return -1; return vsnprintf(str, count, fmt, args); } - +ATTRIBUTE_PRINTF(3, 0) int jio_snprintf(char *str, size_t count, const char *fmt, ...) { va_list args; int len; @@ -2774,7 +2775,7 @@ int jio_snprintf(char *str, size_t count, const char *fmt, ...) { return len; } - +ATTRIBUTE_PRINTF(2,3) int jio_fprintf(FILE* f, const char *fmt, ...) { int len; va_list args; @@ -2784,7 +2785,7 @@ int jio_fprintf(FILE* f, const char *fmt, ...) { return len; } - +ATTRIBUTE_PRINTF(2, 0) int jio_vfprintf(FILE* f, const char *fmt, va_list args) { if (Arguments::vfprintf_hook() != NULL) { return Arguments::vfprintf_hook()(f, fmt, args); @@ -2793,7 +2794,7 @@ int jio_vfprintf(FILE* f, const char *fmt, va_list args) { } } - +ATTRIBUTE_PRINTF(1, 2) JNIEXPORT int jio_printf(const char *fmt, ...) { int len; va_list args; @@ -2930,7 +2931,7 @@ JVM_ENTRY(void, JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable)) JavaThread* receiver = java_lang_Thread::thread(java_thread); Events::log_exception(JavaThread::current(), "JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]", - receiver, (address)java_thread, throwable); + p2i(receiver), p2i((address)java_thread), p2i(throwable)); // First check if thread is alive if (receiver != NULL) { // Check if exception is getting thrown at self (use oop equality, since the diff --git a/hotspot/src/share/vm/prims/jvmtiEnter.xsl b/hotspot/src/share/vm/prims/jvmtiEnter.xsl index ff609eee2f9..e855d21dd81 100644 --- a/hotspot/src/share/vm/prims/jvmtiEnter.xsl +++ b/hotspot/src/share/vm/prims/jvmtiEnter.xsl @@ -1,6 +1,6 @@ <?xml version="1.0"?> <!-- - Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,9 @@ # include "prims/jvmtiRawMonitor.hpp" # include "prims/jvmtiUtil.hpp" +// There are known-bad format/arg pairings in the code generated by this file. +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + </xsl:text> <xsl:if test="$trace = 'Trace'"> diff --git a/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp b/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp index 3b290af1a0d..d7ffd105596 100644 --- a/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp +++ b/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp @@ -113,7 +113,7 @@ void JvmtiFramePops::print() { JvmtiFramePop fp = JvmtiFramePop(_pops->at(i)); tty->print("%d: ", i); fp.print(); - tty->print_cr(""); + tty->cr(); } } #endif diff --git a/hotspot/src/share/vm/prims/jvmtiEventController.cpp b/hotspot/src/share/vm/prims/jvmtiEventController.cpp index dff9989736e..639c184bd23 100644 --- a/hotspot/src/share/vm/prims/jvmtiEventController.cpp +++ b/hotspot/src/share/vm/prims/jvmtiEventController.cpp @@ -38,6 +38,8 @@ #include "runtime/vmThread.hpp" #include "runtime/vm_operations.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef JVMTI_TRACE #define EC_TRACE(out) do { \ if (JvmtiTrace::trace_event_controller()) { \ diff --git a/hotspot/src/share/vm/prims/jvmtiExport.cpp b/hotspot/src/share/vm/prims/jvmtiExport.cpp index 035288e97de..cec38ec821a 100644 --- a/hotspot/src/share/vm/prims/jvmtiExport.cpp +++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp @@ -56,6 +56,8 @@ #include "gc_implementation/parallelScavenge/psMarkSweep.hpp" #endif // INCLUDE_ALL_GCS +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef JVMTI_TRACE #define EVT_TRACE(evt,out) if ((JvmtiTrace::event_trace_flags(evt) & JvmtiTrace::SHOW_EVENT_SENT) != 0) { SafeResourceMark rm; tty->print_cr out; } #define EVT_TRIG_TRACE(evt,out) if ((JvmtiTrace::event_trace_flags(evt) & JvmtiTrace::SHOW_EVENT_TRIGGER) != 0) { SafeResourceMark rm; tty->print_cr out; } diff --git a/hotspot/src/share/vm/prims/jvmtiImpl.cpp b/hotspot/src/share/vm/prims/jvmtiImpl.cpp index ad90eeb9435..0d6d00d4ec6 100644 --- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp +++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -413,7 +413,7 @@ void JvmtiBreakpoints::print() { JvmtiBreakpoint& bp = _bps.at(i); tty->print("%d: ", i); bp.print(); - tty->print_cr(""); + tty->cr(); } #endif } diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index 1c3bbbfeed0..5f3d05478f6 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,7 @@ #include "runtime/relocator.hpp" #include "utilities/bitMap.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC Array<Method*>* VM_RedefineClasses::_old_methods = NULL; Array<Method*>* VM_RedefineClasses::_new_methods = NULL; @@ -1904,6 +1905,8 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_annotation_struct( // annotations_typeArray if needed. Returns the original constant // pool reference if a rewrite was not needed or the new constant // pool reference if a rewrite was needed. +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED u2 VM_RedefineClasses::rewrite_cp_ref_in_annotation_data( AnnotationArray* annotations_typeArray, int &byte_i_ref, const char * trace_mesg, TRAPS) { @@ -1920,6 +1923,7 @@ u2 VM_RedefineClasses::rewrite_cp_ref_in_annotation_data( byte_i_ref += 2; return old_cp_index; } +PRAGMA_DIAG_POP // Rewrite constant pool references in the element_value portion of an diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp index f6df49774a5..249464f056c 100644 --- a/hotspot/src/share/vm/prims/methodHandles.cpp +++ b/hotspot/src/share/vm/prims/methodHandles.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -536,7 +536,7 @@ void MethodHandles::print_as_basic_type_signature_on(outputStream* st, // unknown letter, or we don't want to know its name st->put(ch); } else { - st->print(n); + st->print("%s", n); prev_type = true; } break; diff --git a/hotspot/src/share/vm/prims/privilegedStack.cpp b/hotspot/src/share/vm/prims/privilegedStack.cpp index 7ffc2ea5fe5..b214d4bde3e 100644 --- a/hotspot/src/share/vm/prims/privilegedStack.cpp +++ b/hotspot/src/share/vm/prims/privilegedStack.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ #include "prims/privilegedStack.hpp" #include "runtime/vframe.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC void PrivilegedElement::initialize(vframeStream* vfst, oop context, PrivilegedElement* next, TRAPS) { Method* method = vfst->method(); diff --git a/hotspot/src/share/vm/prims/unsafe.cpp b/hotspot/src/share/vm/prims/unsafe.cpp index b10516fca7f..b3160771aed 100644 --- a/hotspot/src/share/vm/prims/unsafe.cpp +++ b/hotspot/src/share/vm/prims/unsafe.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,8 @@ #include "utilities/copy.hpp" #include "utilities/dtrace.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + /* * Implementation of class sun.misc.Unsafe */ diff --git a/hotspot/src/share/vm/prims/whitebox.cpp b/hotspot/src/share/vm/prims/whitebox.cpp index 2289618ff6d..2e6b9952b8b 100644 --- a/hotspot/src/share/vm/prims/whitebox.cpp +++ b/hotspot/src/share/vm/prims/whitebox.cpp @@ -53,6 +53,8 @@ #include "compiler/compileBroker.hpp" #include "runtime/compilationPolicy.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #define SIZE_T_MAX_VALUE ((size_t) -1) bool WhiteBox::_used = false; diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index d146785b53b..634d5299be6 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -852,7 +852,7 @@ void Arguments::print_jvm_flags_on(outputStream* st) { for (int i=0; i < _num_jvm_flags; i++) { st->print("%s ", _jvm_flags_array[i]); } - st->print_cr(""); + st->cr(); } } @@ -861,7 +861,7 @@ void Arguments::print_jvm_args_on(outputStream* st) { for (int i=0; i < _num_jvm_args; i++) { st->print("%s ", _jvm_args_array[i]); } - st->print_cr(""); + st->cr(); } } @@ -1349,8 +1349,8 @@ void Arguments::set_cms_and_parnew_gc_flags() { } if (PrintGCDetails && Verbose) { tty->print_cr("MarkStackSize: %uk MarkStackSizeMax: %uk", - MarkStackSize / K, MarkStackSizeMax / K); - tty->print_cr("ConcGCThreads: %u", ConcGCThreads); + (unsigned int) (MarkStackSize / K), (uint) (MarkStackSizeMax / K)); + tty->print_cr("ConcGCThreads: %u", (uint) ConcGCThreads); } } #endif // INCLUDE_ALL_GCS @@ -1430,7 +1430,7 @@ bool Arguments::should_auto_select_low_pause_collector() { if (PrintGCDetails) { // Cannot use gclog_or_tty yet. tty->print_cr("Automatic selection of the low pause collector" - " based on pause goal of %d (ms)", MaxGCPauseMillis); + " based on pause goal of %d (ms)", (int) MaxGCPauseMillis); } return true; } @@ -1647,8 +1647,8 @@ void Arguments::set_g1_gc_flags() { if (PrintGCDetails && Verbose) { tty->print_cr("MarkStackSize: %uk MarkStackSizeMax: %uk", - MarkStackSize / K, MarkStackSizeMax / K); - tty->print_cr("ConcGCThreads: %u", ConcGCThreads); + (unsigned int) (MarkStackSize / K), (uint) (MarkStackSizeMax / K)); + tty->print_cr("ConcGCThreads: %u", (uint) ConcGCThreads); } } @@ -1732,7 +1732,7 @@ void Arguments::set_heap_size() { if (PrintGCDetails && Verbose) { // Cannot use gclog_or_tty yet. - tty->print_cr(" Maximum heap size " SIZE_FORMAT, reasonable_max); + tty->print_cr(" Maximum heap size " SIZE_FORMAT, (size_t) reasonable_max); } FLAG_SET_ERGO(uintx, MaxHeapSize, (uintx)reasonable_max); } @@ -2105,7 +2105,7 @@ bool Arguments::check_vm_args_consistency() { // Using "else if" below to avoid printing two error messages if min > max. // This will also prevent us from reporting both min>100 and max>100 at the // same time, but that is less annoying than printing two identical errors IMHO. - FormatBuffer<80> err_msg(""); + FormatBuffer<80> err_msg("%s",""); if (!verify_MinHeapFreeRatio(err_msg, MinHeapFreeRatio)) { jio_fprintf(defaultStream::error_stream(), "%s\n", err_msg.buffer()); status = false; diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp index f898c24b22d..905481c8fe4 100644 --- a/hotspot/src/share/vm/runtime/arguments.hpp +++ b/hotspot/src/share/vm/runtime/arguments.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ extern "C" { typedef void (JNICALL *abort_hook_t)(void); typedef void (JNICALL *exit_hook_t)(jint code); - typedef jint (JNICALL *vfprintf_hook_t)(FILE *fp, const char *format, va_list args); + typedef jint (JNICALL *vfprintf_hook_t)(FILE *fp, const char *format, va_list args) ATTRIBUTE_PRINTF(2, 0); } // Forward declarations diff --git a/hotspot/src/share/vm/runtime/biasedLocking.cpp b/hotspot/src/share/vm/runtime/biasedLocking.cpp index f4ba0328baf..c8c2acf37df 100644 --- a/hotspot/src/share/vm/runtime/biasedLocking.cpp +++ b/hotspot/src/share/vm/runtime/biasedLocking.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -161,7 +161,7 @@ static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_ if (TraceBiasedLocking && (Verbose || !is_bulk)) { ResourceMark rm; tty->print_cr("Revoking bias of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT " , allow rebias %d , requesting thread " INTPTR_FORMAT, - (void *)obj, (intptr_t) mark, obj->klass()->external_name(), (intptr_t) obj->klass()->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread); + p2i((void *)obj), (intptr_t) mark, obj->klass()->external_name(), (intptr_t) obj->klass()->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread); } JavaThread* biased_thread = mark->biased_locker(); @@ -214,8 +214,8 @@ static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_ if (mon_info->owner() == obj) { if (TraceBiasedLocking && Verbose) { tty->print_cr(" mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")", - (void *) mon_info->owner(), - (void *) obj); + p2i((void *) mon_info->owner()), + p2i((void *) obj)); } // Assume recursive case and fix up highest lock later markOop mark = markOopDesc::encode((BasicLock*) NULL); @@ -224,8 +224,8 @@ static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_ } else { if (TraceBiasedLocking && Verbose) { tty->print_cr(" mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")", - (void *) mon_info->owner(), - (void *) obj); + p2i((void *) mon_info->owner()), + p2i((void *) obj)); } } } @@ -328,7 +328,7 @@ static BiasedLocking::Condition bulk_revoke_or_rebias_at_safepoint(oop o, tty->print_cr("* Beginning bulk revocation (kind == %s) because of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", (bulk_rebias ? "rebias" : "revoke"), - (void *) o, (intptr_t) o->mark(), o->klass()->external_name()); + p2i((void *) o), (intptr_t) o->mark(), o->klass()->external_name()); } jlong cur_time = os::javaTimeMillis(); diff --git a/hotspot/src/share/vm/runtime/compilationPolicy.cpp b/hotspot/src/share/vm/runtime/compilationPolicy.cpp index 268a6708828..db8122b754d 100644 --- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp +++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -170,7 +170,7 @@ void CompilationPolicy::print_time() { void NonTieredCompPolicy::trace_osr_completion(nmethod* osr_nm) { if (TraceOnStackReplacement) { if (osr_nm == NULL) tty->print_cr("compilation failed"); - else tty->print_cr("nmethod " INTPTR_FORMAT, osr_nm); + else tty->print_cr("nmethod " INTPTR_FORMAT, p2i(osr_nm)); } } #endif // !PRODUCT @@ -417,6 +417,7 @@ nmethod* NonTieredCompPolicy::event(methodHandle method, methodHandle inlinee, i } #ifndef PRODUCT +PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL void NonTieredCompPolicy::trace_frequency_counter_overflow(methodHandle m, int branch_bci, int bci) { if (TraceInvocationCounterOverflow) { MethodCounters* mcs = m->method_counters(); @@ -428,7 +429,10 @@ void NonTieredCompPolicy::trace_frequency_counter_overflow(methodHandle m, int b bci == InvocationEntryBci ? "comp-policy cntr ovfl @ %d in entry of " : "comp-policy cntr ovfl @ %d in loop of "; +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL tty->print(msg, bci); +PRAGMA_DIAG_POP m->print_value(); tty->cr(); ic->print(); @@ -503,7 +507,7 @@ void StackWalkCompPolicy::method_invocation_event(methodHandle m, JavaThread* th if (TraceCompilationPolicy) { tty->print("method invocation trigger: "); m->print_short_name(tty); - tty->print(" ( interpreted " INTPTR_FORMAT ", size=%d ) ", (address)m(), m->code_size()); + tty->print(" ( interpreted " INTPTR_FORMAT ", size=%d ) ", p2i((address)m()), m->code_size()); } RegisterMap reg_map(thread, false); javaVFrame* triggerVF = thread->last_java_vframe(®_map); @@ -512,7 +516,7 @@ void StackWalkCompPolicy::method_invocation_event(methodHandle m, JavaThread* th if (first->top_method()->code() != NULL) { // called obsolete method/nmethod -- no need to recompile - if (TraceCompilationPolicy) tty->print_cr(" --> " INTPTR_FORMAT, first->top_method()->code()); + if (TraceCompilationPolicy) tty->print_cr(" --> " INTPTR_FORMAT, p2i(first->top_method()->code())); } else { if (TimeCompilationPolicy) accumulated_time()->start(); GrowableArray<RFrame*>* stack = new GrowableArray<RFrame*>(50); @@ -640,7 +644,7 @@ RFrame* StackWalkCompPolicy::findTopInlinableFrame(GrowableArray<RFrame*>* stack if (TraceCompilationPolicy && Verbose) { tty->print("\n\t check caller: "); next_m->print_short_name(tty); - tty->print(" ( interpreted " INTPTR_FORMAT ", size=%d ) ", (address)next_m(), next_m->code_size()); + tty->print(" ( interpreted " INTPTR_FORMAT ", size=%d ) ", p2i((address)next_m()), next_m->code_size()); } current = next; diff --git a/hotspot/src/share/vm/runtime/deoptimization.cpp b/hotspot/src/share/vm/runtime/deoptimization.cpp index 75e68590b2e..1ec4e3b12f8 100644 --- a/hotspot/src/share/vm/runtime/deoptimization.cpp +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -89,6 +89,8 @@ #endif #endif // COMPILER2 +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + bool DeoptimizationMarker::_is_active = false; Deoptimization::UnrollBlock::UnrollBlock(int size_of_deoptimized_frame, diff --git a/hotspot/src/share/vm/runtime/fprofiler.cpp b/hotspot/src/share/vm/runtime/fprofiler.cpp index 7e497b73541..58cb6e89daa 100644 --- a/hotspot/src/share/vm/runtime/fprofiler.cpp +++ b/hotspot/src/share/vm/runtime/fprofiler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,8 @@ #include "runtime/vframe.hpp" #include "utilities/macros.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Static fields of FlatProfiler int FlatProfiler::received_gc_ticks = 0; int FlatProfiler::vm_operation_ticks = 0; @@ -309,7 +311,7 @@ class ProfilerNode { st->fill_to(col2); t->print_native(st); st->fill_to(col3); - st->print(msg); + st->print("%s", msg); st->cr(); } diff --git a/hotspot/src/share/vm/runtime/frame.cpp b/hotspot/src/share/vm/runtime/frame.cpp index 1409bd79651..2f7cb8f186a 100644 --- a/hotspot/src/share/vm/runtime/frame.cpp +++ b/hotspot/src/share/vm/runtime/frame.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,6 +62,8 @@ # include "nativeInst_ppc.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + RegisterMap::RegisterMap(JavaThread *thread, bool update_map) { _thread = thread; _update_map = update_map; diff --git a/hotspot/src/share/vm/runtime/globals.cpp b/hotspot/src/share/vm/runtime/globals.cpp index 526d47c9ad6..05daec54cf8 100644 --- a/hotspot/src/share/vm/runtime/globals.cpp +++ b/hotspot/src/share/vm/runtime/globals.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,8 @@ #include "shark/shark_globals.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + RUNTIME_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, \ MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \ MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_EXPERIMENTAL_FLAG, \ @@ -283,6 +285,7 @@ bool Flag::is_external() const { // Length of format string (e.g. "%.1234s") for printing ccstr below #define FORMAT_BUFFER_LEN 16 +PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL void Flag::print_on(outputStream* st, bool withComments) { // Don't print notproduct and develop flags in a product build. if (is_constant_in_binary()) { @@ -315,7 +318,10 @@ void Flag::print_on(outputStream* st, bool withComments) { size_t llen = pointer_delta(eol, cp, sizeof(char)); jio_snprintf(format_buffer, FORMAT_BUFFER_LEN, "%%." SIZE_FORMAT "s", llen); +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL st->print(format_buffer, cp); +PRAGMA_DIAG_POP st->cr(); cp = eol+1; st->print("%5s %-35s += ", "", _name); @@ -372,7 +378,7 @@ void Flag::print_kind(outputStream* st) { } else { st->print(" "); } - st->print(d.name); + st->print("%s", d.name); } } diff --git a/hotspot/src/share/vm/runtime/handles.cpp b/hotspot/src/share/vm/runtime/handles.cpp index ca73f86ba7f..e80b6d79828 100644 --- a/hotspot/src/share/vm/runtime/handles.cpp +++ b/hotspot/src/share/vm/runtime/handles.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,8 @@ # include "os_bsd.inline.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef ASSERT oop* HandleArea::allocate_handle(oop obj) { assert(_handle_mark_nesting > 1, "memory leak: allocating handle outside HandleMark"); diff --git a/hotspot/src/share/vm/runtime/interfaceSupport.cpp b/hotspot/src/share/vm/runtime/interfaceSupport.cpp index 61bdfcebf85..09757155d9d 100644 --- a/hotspot/src/share/vm/runtime/interfaceSupport.cpp +++ b/hotspot/src/share/vm/runtime/interfaceSupport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ #include "runtime/vframe.hpp" #include "utilities/preserveException.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC // Implementation of InterfaceSupport diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp index cddfd3d1ffc..8b352765b13 100644 --- a/hotspot/src/share/vm/runtime/java.cpp +++ b/hotspot/src/share/vm/runtime/java.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -97,6 +97,7 @@ #include "opto/runtime.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC GrowableArray<Method*>* collected_profiled_methods; @@ -366,7 +367,7 @@ void print_statistics() { BaselineTTYOutputer outputer(tty); MemTracker::print_memory_usage(outputer, K, false); } else { - tty->print_cr(MemTracker::reason()); + tty->print_cr("%s", MemTracker::reason()); } } } @@ -407,7 +408,7 @@ void print_statistics() { BaselineTTYOutputer outputer(tty); MemTracker::print_memory_usage(outputer, K, false); } else { - tty->print_cr(MemTracker::reason()); + tty->print_cr("%s", MemTracker::reason()); } } } diff --git a/hotspot/src/share/vm/runtime/jniHandles.cpp b/hotspot/src/share/vm/runtime/jniHandles.cpp index 373c3359d02..7ff38335029 100644 --- a/hotspot/src/share/vm/runtime/jniHandles.cpp +++ b/hotspot/src/share/vm/runtime/jniHandles.cpp @@ -30,6 +30,7 @@ #include "runtime/mutexLocker.hpp" #include "runtime/thread.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC JNIHandleBlock* JNIHandles::_global_handles = NULL; JNIHandleBlock* JNIHandles::_weak_global_handles = NULL; diff --git a/hotspot/src/share/vm/runtime/mutex.cpp b/hotspot/src/share/vm/runtime/mutex.cpp index 8789e5d0df4..34c9366f0d1 100644 --- a/hotspot/src/share/vm/runtime/mutex.cpp +++ b/hotspot/src/share/vm/runtime/mutex.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,8 @@ # include "mutex_bsd.inline.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o // // Native Monitor-Mutex locking - theory of operations diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp index 82361d3fd43..70c6c064fbf 100644 --- a/hotspot/src/share/vm/runtime/os.cpp +++ b/hotspot/src/share/vm/runtime/os.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,6 +65,8 @@ # include <signal.h> +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + OSThread* os::_starting_thread = NULL; address os::_polling_page = NULL; volatile int32_t* os::_mem_serialize_page = NULL; @@ -909,9 +911,9 @@ void os::print_environment_variables(outputStream* st, const char** env_list, for (int i = 0; env_list[i] != NULL; i++) { if (getenv(env_list[i], buffer, len)) { - st->print(env_list[i]); + st->print("%s", env_list[i]); st->print("="); - st->print_cr(buffer); + st->print_cr("%s", buffer); } } } diff --git a/hotspot/src/share/vm/runtime/osThread.cpp b/hotspot/src/share/vm/runtime/osThread.cpp index 8c7b5e61c96..57bf1f524fd 100644 --- a/hotspot/src/share/vm/runtime/osThread.cpp +++ b/hotspot/src/share/vm/runtime/osThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ #include "oops/oop.inline.hpp" #include "runtime/osThread.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC OSThread::OSThread(OSThreadStartFunc start_proc, void* start_parm) { pd_initialize(); diff --git a/hotspot/src/share/vm/runtime/perfData.cpp b/hotspot/src/share/vm/runtime/perfData.cpp index f2152ab1c64..caf4c99295e 100644 --- a/hotspot/src/share/vm/runtime/perfData.cpp +++ b/hotspot/src/share/vm/runtime/perfData.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,8 @@ #include "utilities/exceptions.hpp" #include "utilities/globalDefinitions.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + PerfDataList* PerfDataManager::_all = NULL; PerfDataList* PerfDataManager::_sampled = NULL; PerfDataList* PerfDataManager::_constants = NULL; diff --git a/hotspot/src/share/vm/runtime/perfMemory.cpp b/hotspot/src/share/vm/runtime/perfMemory.cpp index 209288cb680..4eddf2a9722 100644 --- a/hotspot/src/share/vm/runtime/perfMemory.cpp +++ b/hotspot/src/share/vm/runtime/perfMemory.cpp @@ -35,6 +35,8 @@ #include "runtime/statSampler.hpp" #include "utilities/globalDefinitions.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Prefix of performance data file. const char PERFDATA_NAME[] = "hsperfdata"; diff --git a/hotspot/src/share/vm/runtime/safepoint.cpp b/hotspot/src/share/vm/runtime/safepoint.cpp index cbf11d17311..1cb4190cc2d 100644 --- a/hotspot/src/share/vm/runtime/safepoint.cpp +++ b/hotspot/src/share/vm/runtime/safepoint.cpp @@ -82,6 +82,8 @@ #include "c1/c1_globals.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // -------------------------------------------------------------------------------------------------- // Implementation of Safepoint begin/end @@ -787,7 +789,7 @@ static void print_me(intptr_t *new_sp, intptr_t *old_sp, bool *was_oops) { old_sp += incr*32; new_sp += incr*32; was_oops += incr*32; for( int i2=0; i2<16; i2++ ) { tty->print("call %c%d |"PTR_FORMAT" ","LI"[i2>>3],i2&7,new_sp); print_ptrs(*old_sp++,*new_sp++,*was_oops++); } - tty->print_cr(""); + tty->cr(); } #endif // SPARC #endif // PRODUCT @@ -829,7 +831,7 @@ void SafepointSynchronize::print_safepoint_timeout(SafepointTimeoutReason reason timeout_error_printed = true; // Print out the thread info which didn't reach the safepoint for debugging // purposes (useful when there are lots of threads in the debugger). - tty->print_cr(""); + tty->cr(); tty->print_cr("# SafepointSynchronize::begin: Timeout detected:"); if (reason == _spinning_timeout) { tty->print_cr("# SafepointSynchronize::begin: Timed out while spinning to reach a safepoint."); @@ -849,7 +851,7 @@ void SafepointSynchronize::print_safepoint_timeout(SafepointTimeoutReason reason (reason == _blocking_timeout && !cur_state->has_called_back()))) { tty->print("# "); cur_thread->print(); - tty->print_cr(""); + tty->cr(); } } tty->print_cr("# SafepointSynchronize::begin: (End of list)"); @@ -1322,7 +1324,7 @@ void SafepointSynchronize::print_stat_on_exit() { spstat->_time_to_sync > PrintSafepointStatisticsTimeout * MICROUNITS) { print_statistics(); } - tty->print_cr(""); + tty->cr(); // Print out polling page sampling status. if (!need_to_track_page_armed_status) { diff --git a/hotspot/src/share/vm/runtime/safepoint.hpp b/hotspot/src/share/vm/runtime/safepoint.hpp index e43eef4df96..ab5d2e9445d 100644 --- a/hotspot/src/share/vm/runtime/safepoint.hpp +++ b/hotspot/src/share/vm/runtime/safepoint.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -174,7 +174,7 @@ public: // Debugging static void print_state() PRODUCT_RETURN; - static void safepoint_msg(const char* format, ...) PRODUCT_RETURN; + static void safepoint_msg(const char* format, ...) ATTRIBUTE_PRINTF(1, 2) PRODUCT_RETURN; static void deferred_initialize_stat(); static void print_stat_on_exit(); @@ -240,7 +240,7 @@ class ThreadSafepointState: public CHeapObj<mtInternal> { static void create(JavaThread *thread); static void destroy(JavaThread *thread); - void safepoint_msg(const char* format, ...) { + void safepoint_msg(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) { if (ShowSafepointMsgs) { va_list ap; va_start(ap, format); diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index ad69dcec364..fad31fd02f1 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -82,6 +82,8 @@ #include "c1/c1_Runtime1.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Shared stub locations RuntimeStub* SharedRuntime::_wrong_method_blob; RuntimeStub* SharedRuntime::_wrong_method_abstract_blob; diff --git a/hotspot/src/share/vm/runtime/signature.cpp b/hotspot/src/share/vm/runtime/signature.cpp index 3bad97a71d9..a92f5e73b28 100644 --- a/hotspot/src/share/vm/runtime/signature.cpp +++ b/hotspot/src/share/vm/runtime/signature.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ #include "oops/typeArrayKlass.hpp" #include "runtime/signature.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC // Implementation of SignatureIterator diff --git a/hotspot/src/share/vm/runtime/stackValue.cpp b/hotspot/src/share/vm/runtime/stackValue.cpp index ce274103d3f..a0e6f5104f8 100644 --- a/hotspot/src/share/vm/runtime/stackValue.cpp +++ b/hotspot/src/share/vm/runtime/stackValue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -196,7 +196,7 @@ void StackValue::print_on(outputStream* st) const { case T_OBJECT: _o()->print_value_on(st); - st->print(" <" INTPTR_FORMAT ">", (address)_o()); + st->print(" <" INTPTR_FORMAT ">", p2i((address)_o())); break; case T_CONFLICT: diff --git a/hotspot/src/share/vm/runtime/stackValueCollection.cpp b/hotspot/src/share/vm/runtime/stackValueCollection.cpp index 110f7120d4f..3794f64d78c 100644 --- a/hotspot/src/share/vm/runtime/stackValueCollection.cpp +++ b/hotspot/src/share/vm/runtime/stackValueCollection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,8 @@ # include "jniTypes_ppc.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + jint StackValueCollection::int_at(int slot) const { intptr_t val = at(slot)->get_int(); jint ival = *((jint*) (&val)); diff --git a/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp b/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp index 92f3d0be1dd..5ecbe028724 100644 --- a/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp +++ b/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,10 +60,10 @@ const char* StubCodeDesc::name_for(address pc) { void StubCodeDesc::print_on(outputStream* st) const { - st->print(group()); + st->print("%s", group()); st->print("::"); - st->print(name()); - st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT "[ (%d bytes)", begin(), end(), size_in_bytes()); + st->print("%s", name()); + st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT "[ (%d bytes)", p2i(begin()), p2i(end()), size_in_bytes()); } // Implementation of StubCodeGenerator diff --git a/hotspot/src/share/vm/runtime/sweeper.cpp b/hotspot/src/share/vm/runtime/sweeper.cpp index 6d30bd34032..4eba81debe6 100644 --- a/hotspot/src/share/vm/runtime/sweeper.cpp +++ b/hotspot/src/share/vm/runtime/sweeper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,8 @@ #include "utilities/ticks.inline.hpp" #include "utilities/xmlstream.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef ASSERT #define SWEEP(nm) record_sweep(nm, __LINE__) @@ -627,7 +629,7 @@ void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { tty->vprint(format, ap); va_end(ap); } - tty->print_cr(s.as_string()); + tty->print_cr("%s", s.as_string()); } if (LogCompilation && (xtty != NULL)) { @@ -644,7 +646,7 @@ void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { xtty->vprint(format, ap); va_end(ap); } - xtty->print(s.as_string()); + xtty->print("%s", s.as_string()); xtty->stamp(); xtty->end_elem(); } diff --git a/hotspot/src/share/vm/runtime/sweeper.hpp b/hotspot/src/share/vm/runtime/sweeper.hpp index abee1ec77d2..f7482d8194d 100644 --- a/hotspot/src/share/vm/runtime/sweeper.hpp +++ b/hotspot/src/share/vm/runtime/sweeper.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,7 +94,7 @@ class NMethodSweeper : public AllStatic { static const Tickspan total_time_sweeping() { return _total_time_sweeping; } static const Tickspan peak_sweep_time() { return _peak_sweep_time; } static const Tickspan peak_sweep_fraction_time() { return _peak_sweep_fraction_time; } - static void log_sweep(const char* msg, const char* format = NULL, ...); + static void log_sweep(const char* msg, const char* format = NULL, ...) ATTRIBUTE_PRINTF(2, 3); #ifdef ASSERT diff --git a/hotspot/src/share/vm/runtime/synchronizer.cpp b/hotspot/src/share/vm/runtime/synchronizer.cpp index e6d4913d71a..62bd1ab9139 100644 --- a/hotspot/src/share/vm/runtime/synchronizer.cpp +++ b/hotspot/src/share/vm/runtime/synchronizer.cpp @@ -60,6 +60,8 @@ #define ATTR #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // The "core" versions of monitor enter and exit reside in this file. // The interpreter and compilers contain specialized transliterated // variants of the enter-exit fast-path operations. See i486.ad fast_lock(), diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index 0d8b90e11a4..e6d9eee7927 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -112,6 +112,8 @@ #include "runtime/rtmLocking.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef DTRACE_ENABLED // Only bother with this argument setup if dtrace is available @@ -4273,7 +4275,7 @@ JavaThread *Threads::owning_thread_from_monitor_owner(address owner, bool doLock // Threads::print_on() is called at safepoint by VM_PrintThreads operation. void Threads::print_on(outputStream* st, bool print_stacks, bool internal_format, bool print_concurrent_locks) { char buf[32]; - st->print_cr(os::local_time_string(buf, sizeof(buf))); + st->print_cr("%s", os::local_time_string(buf, sizeof(buf))); st->print_cr("Full thread dump %s (%s %s):", Abstract_VM_Version::vm_name(), diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp index 422ba755e48..a5f0a92246d 100644 --- a/hotspot/src/share/vm/runtime/thread.hpp +++ b/hotspot/src/share/vm/runtime/thread.hpp @@ -684,7 +684,7 @@ class NamedThread: public Thread { NamedThread(); ~NamedThread(); // May only be called once per thread. - void set_name(const char* format, ...); + void set_name(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); virtual bool is_Named_thread() const { return true; } virtual char* name() const { return _name == NULL ? (char*)"Unknown Thread" : _name; } JavaThread *processed_thread() { return _processed_thread; } diff --git a/hotspot/src/share/vm/runtime/timer.cpp b/hotspot/src/share/vm/runtime/timer.cpp index e33a51cfb97..9067f20b3d3 100644 --- a/hotspot/src/share/vm/runtime/timer.cpp +++ b/hotspot/src/share/vm/runtime/timer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -204,7 +204,7 @@ TraceCPUTime::~TraceCPUTime() { _logfile->print("[Error in TraceCPUTime]"); } if (_print_cr) { - _logfile->print_cr(""); + _logfile->cr(); } _logfile->flush(); } diff --git a/hotspot/src/share/vm/runtime/unhandledOops.cpp b/hotspot/src/share/vm/runtime/unhandledOops.cpp index cc0002d42c9..d27b1fb2f71 100644 --- a/hotspot/src/share/vm/runtime/unhandledOops.cpp +++ b/hotspot/src/share/vm/runtime/unhandledOops.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ #include "runtime/unhandledOops.hpp" #include "utilities/globalDefinitions.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef CHECK_UNHANDLED_OOPS const int free_list_size = 256; diff --git a/hotspot/src/share/vm/runtime/vframe.cpp b/hotspot/src/share/vm/runtime/vframe.cpp index 2487ad3c6cd..d5b5fa1f480 100644 --- a/hotspot/src/share/vm/runtime/vframe.cpp +++ b/hotspot/src/share/vm/runtime/vframe.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,6 +46,8 @@ #include "runtime/vframeArray.hpp" #include "runtime/vframe_hp.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + vframe::vframe(const frame* fr, const RegisterMap* reg_map, JavaThread* thread) : _reg_map(reg_map), _thread(thread) { assert(fr != NULL, "must have frame"); diff --git a/hotspot/src/share/vm/runtime/vframe.hpp b/hotspot/src/share/vm/runtime/vframe.hpp index 27966b1a73e..a284b13de0c 100644 --- a/hotspot/src/share/vm/runtime/vframe.hpp +++ b/hotspot/src/share/vm/runtime/vframe.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -399,7 +399,7 @@ inline void vframeStreamCommon::fill_from_compiled_frame(int decode_offset) { if (WizardMode) { tty->print_cr("Error in fill_from_frame: pc_desc for " INTPTR_FORMAT " not found or invalid at %d", - _frame.pc(), decode_offset); + p2i(_frame.pc()), decode_offset); nm()->print(); nm()->method()->print_codes(); nm()->print_code(); diff --git a/hotspot/src/share/vm/runtime/vframeArray.cpp b/hotspot/src/share/vm/runtime/vframeArray.cpp index 5dff2d7b62a..72e2e8717cb 100644 --- a/hotspot/src/share/vm/runtime/vframeArray.cpp +++ b/hotspot/src/share/vm/runtime/vframeArray.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,7 @@ #include "opto/runtime.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC int vframeArrayElement:: bci(void) const { return (_bci == SynchronizationEntryBCI ? 0 : _bci); } diff --git a/hotspot/src/share/vm/runtime/virtualspace.cpp b/hotspot/src/share/vm/runtime/virtualspace.cpp index 5ef3a976c49..19f699464b2 100644 --- a/hotspot/src/share/vm/runtime/virtualspace.cpp +++ b/hotspot/src/share/vm/runtime/virtualspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,7 @@ # include "os_bsd.inline.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC // ReservedSpace diff --git a/hotspot/src/share/vm/runtime/vmThread.cpp b/hotspot/src/share/vm/runtime/vmThread.cpp index a3ff582fab9..ab755589403 100644 --- a/hotspot/src/share/vm/runtime/vmThread.cpp +++ b/hotspot/src/share/vm/runtime/vmThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,8 @@ #include "utilities/events.hpp" #include "utilities/xmlstream.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Dummy VM operation to act as first element in our circular double-linked list class VM_Dummy: public VM_Operation { VMOp_Type type() const { return VMOp_Dummy; } diff --git a/hotspot/src/share/vm/runtime/vm_operations.cpp b/hotspot/src/share/vm/runtime/vm_operations.cpp index e26c3938b20..d46e1f775ac 100644 --- a/hotspot/src/share/vm/runtime/vm_operations.cpp +++ b/hotspot/src/share/vm/runtime/vm_operations.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,8 @@ #include "services/threadService.hpp" #include "trace/tracing.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #define VM_OP_NAME_INITIALIZE(name) #name, const char* VM_Operation::_names[VM_Operation::VMOp_Terminating] = \ diff --git a/hotspot/src/share/vm/runtime/vm_version.cpp b/hotspot/src/share/vm/runtime/vm_version.cpp index d2d7efcafa2..5df7d221a2b 100644 --- a/hotspot/src/share/vm/runtime/vm_version.cpp +++ b/hotspot/src/share/vm/runtime/vm_version.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -117,7 +117,7 @@ void Abstract_VM_Version::initialize() { set_version_field(&_vm_minor_version, JDK_MINOR_VERSION, "bad minor version"); set_version_field(&_vm_micro_version, JDK_MICRO_VERSION, "bad micro version"); int offset = (JDK_BUILD_NUMBER != NULL && JDK_BUILD_NUMBER[0] == 'b') ? 1 : 0; - set_version_field(&_vm_build_number, JDK_BUILD_NUMBER + offset, + set_version_field(&_vm_build_number, &JDK_BUILD_NUMBER[offset], "bad build number"); _initialized = true; diff --git a/hotspot/src/share/vm/services/attachListener.cpp b/hotspot/src/share/vm/services/attachListener.cpp index 8551563f59f..9d68175518a 100644 --- a/hotspot/src/share/vm/services/attachListener.cpp +++ b/hotspot/src/share/vm/services/attachListener.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -284,15 +284,15 @@ static jint set_uintx_flag(const char* name, AttachOperation* op, outputStream* } if (strncmp(name, "MaxHeapFreeRatio", 17) == 0) { - FormatBuffer<80> err_msg(""); + FormatBuffer<80> err_msg("%s", ""); if (!Arguments::verify_MaxHeapFreeRatio(err_msg, value)) { - out->print_cr(err_msg.buffer()); + out->print_cr("%s", err_msg.buffer()); return JNI_ERR; } } else if (strncmp(name, "MinHeapFreeRatio", 17) == 0) { - FormatBuffer<80> err_msg(""); + FormatBuffer<80> err_msg("%s", ""); if (!Arguments::verify_MinHeapFreeRatio(err_msg, value)) { - out->print_cr(err_msg.buffer()); + out->print_cr("%s", err_msg.buffer()); return JNI_ERR; } } @@ -381,7 +381,7 @@ static jint print_flag(AttachOperation* op, outputStream* out) { Flag* f = Flag::find_flag((char*)name, strlen(name)); if (f) { f->print_as_flag(out); - out->print_cr(""); + out->cr(); } else { out->print_cr("no such flag '%s'", name); } diff --git a/hotspot/src/share/vm/services/classLoadingService.cpp b/hotspot/src/share/vm/services/classLoadingService.cpp index bdc33fdd2bb..8ce6eb8e532 100644 --- a/hotspot/src/share/vm/services/classLoadingService.cpp +++ b/hotspot/src/share/vm/services/classLoadingService.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -136,7 +136,7 @@ void ClassLoadingService::notify_class_unloaded(InstanceKlass* k) { if (TraceClassUnloading) { ResourceMark rm; - tty->print_cr("[Unloading class %s " INTPTR_FORMAT "]", k->external_name(), k); + tty->print_cr("[Unloading class %s " INTPTR_FORMAT "]", k->external_name(), p2i(k)); } } diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp index 74444d6168d..ca031f87963 100644 --- a/hotspot/src/share/vm/services/diagnosticCommand.cpp +++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,8 @@ #include "services/management.hpp" #include "utilities/macros.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + void DCmdRegistrant::register_dcmds(){ // Registration of the diagnostic commands // First argument specifies which interfaces will export the command @@ -101,7 +103,7 @@ void HelpDCmd::execute(DCmdSource source, TRAPS) { if (factory != NULL) { output()->print_cr("%s%s", factory->name(), factory->is_enabled() ? "" : " [disabled]"); - output()->print_cr(factory->description()); + output()->print_cr("%s", factory->description()); output()->print_cr("\nImpact: %s", factory->impact()); JavaPermission p = factory->permission(); if(p._class != NULL) { diff --git a/hotspot/src/share/vm/services/diagnosticFramework.cpp b/hotspot/src/share/vm/services/diagnosticFramework.cpp index dcc2a21e48a..dcb67d36c3b 100644 --- a/hotspot/src/share/vm/services/diagnosticFramework.cpp +++ b/hotspot/src/share/vm/services/diagnosticFramework.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -259,7 +259,7 @@ void DCmdParser::print_help(outputStream* out, const char* cmd_name) { } arg = arg->next(); } - out->print_cr(""); + out->cr(); if (_arguments_list != NULL) { out->print_cr("\nArguments:"); arg = _arguments_list; @@ -268,7 +268,7 @@ void DCmdParser::print_help(outputStream* out, const char* cmd_name) { arg->is_mandatory() ? "" : "[optional]", arg->description(), arg->type()); if (arg->has_default()) { - out->print(arg->default_string()); + out->print("%s", arg->default_string()); } else { out->print("no default value"); } @@ -284,7 +284,7 @@ void DCmdParser::print_help(outputStream* out, const char* cmd_name) { arg->is_mandatory() ? "" : "[optional]", arg->description(), arg->type()); if (arg->has_default()) { - out->print(arg->default_string()); + out->print("%s", arg->default_string()); } else { out->print("no default value"); } diff --git a/hotspot/src/share/vm/services/heapDumper.cpp b/hotspot/src/share/vm/services/heapDumper.cpp index 39c9a395d73..79c6c8ca7e0 100644 --- a/hotspot/src/share/vm/services/heapDumper.cpp +++ b/hotspot/src/share/vm/services/heapDumper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1842,6 +1842,7 @@ void VM_HeapDumper::dump_stack_traces() { } // dump the heap to given path. +PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL int HeapDumper::dump(const char* path) { assert(path != NULL && strlen(path) > 0, "path missing"); @@ -1882,7 +1883,10 @@ int HeapDumper::dump(const char* path) { char msg[256]; sprintf(msg, "Heap dump file created [%s bytes in %3.3f secs]", JLONG_FORMAT, timer()->seconds()); +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL tty->print_cr(msg, writer.bytes_written()); +PRAGMA_DIAG_POP } else { tty->print_cr("Dump file is incomplete: %s", writer.error()); } diff --git a/hotspot/src/share/vm/services/lowMemoryDetector.cpp b/hotspot/src/share/vm/services/lowMemoryDetector.cpp index 199a342dd77..b68be23dfa4 100644 --- a/hotspot/src/share/vm/services/lowMemoryDetector.cpp +++ b/hotspot/src/share/vm/services/lowMemoryDetector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -353,7 +353,7 @@ void SensorInfo::clear(int count, TRAPS) { #ifndef PRODUCT void SensorInfo::print() { - tty->print_cr("%s count = " SIZE_FORMAT " pending_triggers = %ld pending_clears = %ld", + tty->print_cr("%s count = " SIZE_FORMAT " pending_triggers = %d pending_clears = %d", (_sensor_on ? "on" : "off"), _sensor_count, _pending_trigger_count, _pending_clear_count); } diff --git a/hotspot/src/share/vm/services/management.cpp b/hotspot/src/share/vm/services/management.cpp index 7c99aa47730..dc901876104 100644 --- a/hotspot/src/share/vm/services/management.cpp +++ b/hotspot/src/share/vm/services/management.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,6 +56,8 @@ #include "services/threadService.hpp" #include "utilities/macros.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + PerfVariable* Management::_begin_vm_creation_time = NULL; PerfVariable* Management::_end_vm_creation_time = NULL; PerfVariable* Management::_vm_init_done_time = NULL; @@ -1839,12 +1841,12 @@ JVM_ENTRY(void, jmm_SetVMGlobal(JNIEnv *env, jstring flag_name, jvalue new_value uintx uvalue = (uintx)new_value.j; if (strncmp(name, "MaxHeapFreeRatio", 17) == 0) { - FormatBuffer<80> err_msg(""); + FormatBuffer<80> err_msg("%s", ""); if (!Arguments::verify_MaxHeapFreeRatio(err_msg, uvalue)) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), err_msg.buffer()); } } else if (strncmp(name, "MinHeapFreeRatio", 17) == 0) { - FormatBuffer<80> err_msg(""); + FormatBuffer<80> err_msg("%s", ""); if (!Arguments::verify_MinHeapFreeRatio(err_msg, uvalue)) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), err_msg.buffer()); } diff --git a/hotspot/src/share/vm/services/memReporter.cpp b/hotspot/src/share/vm/services/memReporter.cpp index c9cbc08046c..305693dad08 100644 --- a/hotspot/src/share/vm/services/memReporter.cpp +++ b/hotspot/src/share/vm/services/memReporter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,8 @@ #include "services/memPtrArray.hpp" #include "services/memTracker.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + const char* BaselineOutputer::memory_unit(size_t scale) { switch(scale) { case K: return "KB"; diff --git a/hotspot/src/share/vm/services/memSnapshot.cpp b/hotspot/src/share/vm/services/memSnapshot.cpp index 3bfd19324bb..8f5ca4f4195 100644 --- a/hotspot/src/share/vm/services/memSnapshot.cpp +++ b/hotspot/src/share/vm/services/memSnapshot.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ #include "services/memSnapshot.hpp" #include "services/memTracker.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef ASSERT void decode_pointer_record(MemPointerRecord* rec) { @@ -733,7 +735,7 @@ void MemSnapshot::dump_all_vm_pointers() { if (os::dll_address_to_function_name(ex->pc(), buf, sizeof(buf), NULL)) { tty->print_cr("\t%s", buf); } else { - tty->print_cr(""); + tty->cr(); } } } diff --git a/hotspot/src/share/vm/services/memTrackWorker.cpp b/hotspot/src/share/vm/services/memTrackWorker.cpp index e1382dd1a3a..7bf18eb273c 100644 --- a/hotspot/src/share/vm/services/memTrackWorker.cpp +++ b/hotspot/src/share/vm/services/memTrackWorker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ MemTrackWorker::MemTrackWorker(MemSnapshot* snapshot): _snapshot(snapshot) { // create thread uses cgc thread type for now. We should revisit // the option, or create new thread type. _has_error = !os::create_thread(this, os::cgc_thread); - set_name("MemTrackWorker", 0); + set_name("MemTrackWorker"); // initial generation circuit buffer if (!has_error()) { diff --git a/hotspot/src/share/vm/services/nmtDCmd.cpp b/hotspot/src/share/vm/services/nmtDCmd.cpp index 823e3c443f2..8ced28772f3 100644 --- a/hotspot/src/share/vm/services/nmtDCmd.cpp +++ b/hotspot/src/share/vm/services/nmtDCmd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -128,7 +128,7 @@ void NMTDCmd::execute(DCmdSource source, TRAPS) { // native memory tracking has to be on if (!MemTracker::is_on() || MemTracker::shutdown_in_progress()) { // if it is not on, what's the reason? - output()->print_cr(MemTracker::reason()); + output()->print_cr("%s", MemTracker::reason()); return; } diff --git a/hotspot/src/share/vm/services/threadService.cpp b/hotspot/src/share/vm/services/threadService.cpp index a46067981a0..02156a2f3e2 100644 --- a/hotspot/src/share/vm/services/threadService.cpp +++ b/hotspot/src/share/vm/services/threadService.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,6 +38,8 @@ #include "runtime/vm_operations.hpp" #include "services/threadService.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // TODO: we need to define a naming convention for perf counters // to distinguish counters for: // - standard JSR174 use diff --git a/hotspot/src/share/vm/trace/traceStream.hpp b/hotspot/src/share/vm/trace/traceStream.hpp index 4acbbb88498..2166a75126c 100644 --- a/hotspot/src/share/vm/trace/traceStream.hpp +++ b/hotspot/src/share/vm/trace/traceStream.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -113,7 +113,7 @@ class TraceStream : public StackObj { } void print(const char* val) { - _st.print(val); + _st.print("%s", val); } }; diff --git a/hotspot/src/share/vm/utilities/array.hpp b/hotspot/src/share/vm/utilities/array.hpp index 99c84a6ddfe..632b7c656b2 100644 --- a/hotspot/src/share/vm/utilities/array.hpp +++ b/hotspot/src/share/vm/utilities/array.hpp @@ -376,7 +376,7 @@ protected: // FIXME: How to handle this? void print_value_on(outputStream* st) const { - st->print("Array<T>(" INTPTR_FORMAT ")", this); + st->print("Array<T>(" INTPTR_FORMAT ")", p2i(this)); } #ifndef PRODUCT diff --git a/hotspot/src/share/vm/utilities/bitMap.cpp b/hotspot/src/share/vm/utilities/bitMap.cpp index 024e35e374d..bfcda11fdea 100644 --- a/hotspot/src/share/vm/utilities/bitMap.cpp +++ b/hotspot/src/share/vm/utilities/bitMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -522,13 +522,13 @@ BitMap::idx_t BitMap::count_one_bits() const { void BitMap::print_on_error(outputStream* st, const char* prefix) const { st->print_cr("%s[" PTR_FORMAT ", " PTR_FORMAT ")", - prefix, map(), (char*)map() + (size() >> LogBitsPerByte)); + prefix, p2i(map()), p2i((char*)map() + (size() >> LogBitsPerByte))); } #ifndef PRODUCT void BitMap::print_on(outputStream* st) const { - tty->print("Bitmap(%d):", size()); + tty->print("Bitmap(" SIZE_FORMAT "):", size()); for (idx_t index = 0; index < size(); index++) { tty->print("%c", at(index) ? '1' : '0'); } diff --git a/hotspot/src/share/vm/utilities/constantTag.cpp b/hotspot/src/share/vm/utilities/constantTag.cpp index 8f3b68a9b5d..1495a42e624 100644 --- a/hotspot/src/share/vm/utilities/constantTag.cpp +++ b/hotspot/src/share/vm/utilities/constantTag.cpp @@ -28,7 +28,7 @@ #ifndef PRODUCT void constantTag::print_on(outputStream* st) const { - st->print(internal_name()); + st->print("%s", internal_name()); } #endif // PRODUCT diff --git a/hotspot/src/share/vm/utilities/debug.cpp b/hotspot/src/share/vm/utilities/debug.cpp index 31d13f794b8..604018f8dd9 100644 --- a/hotspot/src/share/vm/utilities/debug.cpp +++ b/hotspot/src/share/vm/utilities/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,6 +88,8 @@ # endif #endif // PRODUCT +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + FormatBufferResource::FormatBufferResource(const char * format, ...) : FormatBufferBase((char*)resource_allocate_bytes(RES_BUFSZ)) { va_list argp; @@ -96,6 +98,7 @@ FormatBufferResource::FormatBufferResource(const char * format, ...) va_end(argp); } +ATTRIBUTE_PRINTF(1, 2) void warning(const char* format, ...) { if (PrintWarnings) { FILE* const err = defaultStream::error_stream(); diff --git a/hotspot/src/share/vm/utilities/debug.hpp b/hotspot/src/share/vm/utilities/debug.hpp index 310080dbb0e..9070fd80ee4 100644 --- a/hotspot/src/share/vm/utilities/debug.hpp +++ b/hotspot/src/share/vm/utilities/debug.hpp @@ -43,17 +43,17 @@ class FormatBufferBase { #define RES_BUFSZ 256 class FormatBufferResource : public FormatBufferBase { public: - FormatBufferResource(const char * format, ...); + FormatBufferResource(const char * format, ...) ATTRIBUTE_PRINTF(2, 3); }; // Use stack for buffer template <size_t bufsz = 256> class FormatBuffer : public FormatBufferBase { public: - inline FormatBuffer(const char * format, ...); - inline void append(const char* format, ...); - inline void print(const char* format, ...); - inline void printv(const char* format, va_list ap); + inline FormatBuffer(const char * format, ...) ATTRIBUTE_PRINTF(2, 3); + inline void append(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + inline void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + inline void printv(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0); char* buffer() { return _buf; } int size() { return bufsz; } @@ -223,7 +223,7 @@ void report_should_not_reach_here(const char* file, int line); void report_unimplemented(const char* file, int line); void report_untested(const char* file, int line, const char* message); -void warning(const char* format, ...); +void warning(const char* format, ...) ATTRIBUTE_PRINTF(1, 2); #ifdef ASSERT // Compile-time asserts. diff --git a/hotspot/src/share/vm/utilities/events.cpp b/hotspot/src/share/vm/utilities/events.cpp index 8ccd65095e4..4d17c9bba42 100644 --- a/hotspot/src/share/vm/utilities/events.cpp +++ b/hotspot/src/share/vm/utilities/events.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,7 +82,7 @@ EventMark::EventMark(const char* format, ...) { va_start(ap, format); // Save a copy of begin message and log it. _buffer.printv(format, ap); - Events::log(NULL, _buffer); + Events::log(NULL, "%s", _buffer.buffer()); va_end(ap); } } @@ -91,6 +91,6 @@ EventMark::~EventMark() { if (LogEvents) { // Append " done" to the begin message and log it _buffer.append(" done"); - Events::log(NULL, _buffer); + Events::log(NULL, "%s", _buffer.buffer()); } } diff --git a/hotspot/src/share/vm/utilities/events.hpp b/hotspot/src/share/vm/utilities/events.hpp index 804fe77df2d..71a4a436694 100644 --- a/hotspot/src/share/vm/utilities/events.hpp +++ b/hotspot/src/share/vm/utilities/events.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -128,7 +128,7 @@ template <class T> class EventLogBase : public EventLog { void print(outputStream* out, EventRecord<T>& e) { out->print("Event: %.3f ", e.timestamp); if (e.thread != NULL) { - out->print("Thread " INTPTR_FORMAT " ", e.thread); + out->print("Thread " INTPTR_FORMAT " ", p2i(e.thread)); } print(out, e.data); } @@ -148,7 +148,7 @@ class StringEventLog : public EventLogBase<StringLogMessage> { public: StringEventLog(const char* name, int count = LogEventsBufferEntries) : EventLogBase<StringLogMessage>(name, count) {} - void logv(Thread* thread, const char* format, va_list ap) { + void logv(Thread* thread, const char* format, va_list ap) ATTRIBUTE_PRINTF(3, 0) { if (!should_log()) return; double timestamp = fetch_timestamp(); @@ -159,7 +159,7 @@ class StringEventLog : public EventLogBase<StringLogMessage> { _records[index].data.printv(format, ap); } - void log(Thread* thread, const char* format, ...) { + void log(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(3, 4) { va_list ap; va_start(ap, format); logv(thread, format, ap); @@ -193,18 +193,17 @@ class Events : AllStatic { static void print(); // Logs a generic message with timestamp and format as printf. - static void log(Thread* thread, const char* format, ...); + static void log(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3); // Log exception related message - static void log_exception(Thread* thread, const char* format, ...); + static void log_exception(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3); - static void log_deopt_message(Thread* thread, const char* format, ...); + static void log_deopt_message(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3); // Register default loggers static void init(); }; - inline void Events::log(Thread* thread, const char* format, ...) { if (LogEvents) { va_list ap; @@ -283,7 +282,7 @@ class EventMark : public StackObj { public: // log a begin event, format as printf - EventMark(const char* format, ...); + EventMark(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); // log an end event ~EventMark(); }; diff --git a/hotspot/src/share/vm/utilities/exceptions.cpp b/hotspot/src/share/vm/utilities/exceptions.cpp index e3d08d5946f..0759eda3789 100644 --- a/hotspot/src/share/vm/utilities/exceptions.cpp +++ b/hotspot/src/share/vm/utilities/exceptions.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ #include "utilities/events.hpp" #include "utilities/exceptions.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC // Implementation of ThreadShadow void check_ThreadShadow() { @@ -237,6 +238,7 @@ void Exceptions::fthrow(Thread* thread, const char* file, int line, Symbol* h_na _throw_msg(thread, file, line, h_name, msg); } + // Creates an exception oop, calls the <init> method with the given signature. // and returns a Handle Handle Exceptions::new_exception(Thread *thread, Symbol* name, diff --git a/hotspot/src/share/vm/utilities/exceptions.hpp b/hotspot/src/share/vm/utilities/exceptions.hpp index 504d4caf5e3..52805805d59 100644 --- a/hotspot/src/share/vm/utilities/exceptions.hpp +++ b/hotspot/src/share/vm/utilities/exceptions.hpp @@ -132,7 +132,7 @@ class Exceptions { // There is no THROW... macro for this method. Caller should remember // to do a return after calling it. static void fthrow(Thread* thread, const char* file, int line, Symbol* name, - const char* format, ...); + const char* format, ...) ATTRIBUTE_PRINTF(5, 6); // Create and initialize a new exception static Handle new_exception(Thread* thread, Symbol* name, diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp index ca9bc2f16a6..50074f387b5 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,32 @@ # include "utilities/globalDefinitions_xlc.hpp" #endif +#ifndef PRAGMA_DIAG_PUSH +#define PRAGMA_DIAG_PUSH +#endif +#ifndef PRAGMA_DIAG_POP +#define PRAGMA_DIAG_POP +#endif +#ifndef PRAGMA_FORMAT_NONLITERAL_IGNORED +#define PRAGMA_FORMAT_NONLITERAL_IGNORED +#endif +#ifndef PRAGMA_FORMAT_IGNORED +#define PRAGMA_FORMAT_IGNORED +#endif +#ifndef PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL +#define PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL +#endif +#ifndef PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL +#define PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL +#endif +#ifndef PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC +#define PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC +#endif +#ifndef ATTRIBUTE_PRINTF +#define ATTRIBUTE_PRINTF(fmt, vargs) +#endif + + #include "utilities/macros.hpp" // This file holds all globally used constants & types, class (forward) @@ -1284,6 +1310,11 @@ inline int build_int_from_shorts( jushort low, jushort high ) { return ((int)((unsigned int)high << 16) | (unsigned int)low); } +// Convert pointer to intptr_t, for use in printing pointers. +inline intptr_t p2i(const void * p) { + return (intptr_t) p; +} + // Printf-style formatters for fixed- and variable-width types as pointers and // integers. These are derived from the definitions in inttypes.h. If the platform // doesn't provide appropriate definitions, they should be provided in @@ -1302,6 +1333,7 @@ inline int build_int_from_shorts( jushort low, jushort high ) { // Format 64-bit quantities. #define INT64_FORMAT "%" PRId64 #define UINT64_FORMAT "%" PRIu64 +#define UINT64_FORMAT_X "%" PRIx64 #define INT64_FORMAT_W(width) "%" #width PRId64 #define UINT64_FORMAT_W(width) "%" #width PRIu64 @@ -1324,6 +1356,8 @@ inline int build_int_from_shorts( jushort low, jushort high ) { #define PTR_FORMAT "0x%08" PRIxPTR #endif // _LP64 +#define INTPTR_FORMAT_W(width) "%" #width PRIxPTR + #define SSIZE_FORMAT "%" PRIdPTR #define SIZE_FORMAT "%" PRIuPTR #define SIZE_FORMAT_HEX "0x%" PRIxPTR @@ -1355,7 +1389,6 @@ static inline void* dereference_vptr(void* addr) { return *(void**)addr; } - #ifndef PRODUCT // For unit testing only diff --git a/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp b/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp index f66fb721e3a..3125859be31 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -282,6 +282,35 @@ inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); } #define PRAGMA_IMPLEMENTATION #pragma implementation #define VALUE_OBJ_CLASS_SPEC +#ifndef ATTRIBUTE_PRINTF +#define ATTRIBUTE_PRINTF(fmt,vargs) __attribute__((format(printf, fmt, vargs))) +#endif + +#define PRAGMA_FORMAT_NONLITERAL_IGNORED _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") _Pragma("GCC diagnostic ignored \"-Wformat-security\"") +#define PRAGMA_FORMAT_IGNORED _Pragma("GCC diagnostic ignored \"-Wformat\"") + +#if defined(__clang_major__) && (__clang_major__ >= 4 || (__clang_major__ >= 3 && __clang_minor__ >= 1)) || (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6) +// Tested to work with clang version 3.1 and better. +#define PRAGMA_DIAG_PUSH _Pragma("GCC diagnostic push") +#define PRAGMA_DIAG_POP _Pragma("GCC diagnostic pop") +#define PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL +#define PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL PRAGMA_FORMAT_NONLITERAL_IGNORED + +// Hack to deal with gcc yammering about non-security format stuff +#else +// Old versions of gcc don't do push/pop, also do not cope with this pragma within a function +// One method does so much varied printing that it is decorated with both internal and external +// versions of the macro-pragma to obtain better checking with newer compilers. +#define PRAGMA_DIAG_PUSH +#define PRAGMA_DIAG_POP +#define PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL PRAGMA_FORMAT_NONLITERAL_IGNORED +#define PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL +#endif + +#ifndef __clang_major__ +#define PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC _Pragma("GCC diagnostic ignored \"-Wformat\"") _Pragma("GCC diagnostic error \"-Wformat-nonliteral\"") _Pragma("GCC diagnostic error \"-Wformat-security\"") +#endif + #if (__GNUC__ == 2) && (__GNUC_MINOR__ < 95) #define TEMPLATE_TABLE_BUG #endif diff --git a/hotspot/src/share/vm/utilities/numberSeq.cpp b/hotspot/src/share/vm/utilities/numberSeq.cpp index 06fcf40b7a8..230447b2167 100644 --- a/hotspot/src/share/vm/utilities/numberSeq.cpp +++ b/hotspot/src/share/vm/utilities/numberSeq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -258,5 +258,5 @@ void TruncatedSeq::dump_on(outputStream* s) { } s->print("\t[%d]=%7.3f", i, _sequence[i]); } - s->print_cr(""); + s->cr(); } diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp index e09dfccf123..54536c50742 100644 --- a/hotspot/src/share/vm/utilities/ostream.cpp +++ b/hotspot/src/share/vm/utilities/ostream.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -268,7 +268,7 @@ void outputStream::print_data(void* data, size_t len, bool with_ascii) { size_t limit = (len + 16) / 16 * 16; for (size_t i = 0; i < limit; ++i) { if (i % 16 == 0) { - indent().print("%07x:", i); + indent().print(INTPTR_FORMAT_W(07)":", i); } if (i % 2 == 0) { print(" "); @@ -289,7 +289,7 @@ void outputStream::print_data(void* data, size_t len, bool with_ascii) { } } } - print_cr(""); + cr(); } } } @@ -606,7 +606,7 @@ void fdStream::write(const char* s, size_t len) { // memory usage and command line flags into header void gcLogFileStream::dump_loggc_header() { if (is_open()) { - print_cr(Abstract_VM_Version::internal_vm_info_string()); + print_cr("%s", Abstract_VM_Version::internal_vm_info_string()); os::print_memory_info(this); print("CommandLine flags: "); CommandLineFlags::printSetFlags(this); @@ -687,7 +687,7 @@ void gcLogFileStream::rotate_log(bool force, outputStream* out) { write(time_msg, strlen(time_msg)); if (out != NULL) { - out->print(time_msg); + out->print("%s", time_msg); } dump_loggc_header(); @@ -720,7 +720,7 @@ void gcLogFileStream::rotate_log(bool force, outputStream* out) { write(time_msg, strlen(time_msg)); if (out != NULL) { - out->print(time_msg); + out->print("%s", time_msg); } fclose(_file); @@ -765,7 +765,7 @@ void gcLogFileStream::rotate_log(bool force, outputStream* out) { write(time_msg, strlen(time_msg)); if (out != NULL) { - out->print(time_msg); + out->print("%s", time_msg); } dump_loggc_header(); @@ -845,7 +845,7 @@ void defaultStream::init_log() { xs->head("hotspot_log version='%d %d'" " process='%d' time_ms='"INT64_FORMAT"'", LOG_MAJOR_VERSION, LOG_MINOR_VERSION, - os::current_process_id(), time_ms); + os::current_process_id(), (int64_t)time_ms); // Write VM version header immediately. xs->head("vm_version"); xs->head("name"); xs->text("%s", VM_Version::vm_name()); xs->cr(); diff --git a/hotspot/src/share/vm/utilities/ostream.hpp b/hotspot/src/share/vm/utilities/ostream.hpp index 92440ee0a64..563bbe432b5 100644 --- a/hotspot/src/share/vm/utilities/ostream.hpp +++ b/hotspot/src/share/vm/utilities/ostream.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ class outputStream : public ResourceObj { static const char* do_vsnprintf(char* buffer, size_t buflen, const char* format, va_list ap, bool add_cr, - size_t& result_len); + size_t& result_len) ATTRIBUTE_PRINTF(3, 0); public: // creation @@ -80,10 +80,10 @@ class outputStream : public ResourceObj { void set_position(int pos) { _position = pos; } // printing - void print(const char* format, ...); - void print_cr(const char* format, ...); - void vprint(const char *format, va_list argptr); - void vprint_cr(const char* format, va_list argptr); + void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void print_cr(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void vprint(const char *format, va_list argptr) ATTRIBUTE_PRINTF(2, 0); + void vprint_cr(const char* format, va_list argptr) ATTRIBUTE_PRINTF(2, 0); void print_raw(const char* str) { write(str, strlen(str)); } void print_raw(const char* str, int len) { write(str, len); } void print_raw_cr(const char* str) { write(str, strlen(str)); cr(); } @@ -274,10 +274,10 @@ class staticBufferStream : public outputStream { ~staticBufferStream() {}; virtual void write(const char* c, size_t len); void flush(); - void print(const char* format, ...); - void print_cr(const char* format, ...); - void vprint(const char *format, va_list argptr); - void vprint_cr(const char* format, va_list argptr); + void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void print_cr(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void vprint(const char *format, va_list argptr) ATTRIBUTE_PRINTF(2, 0); + void vprint_cr(const char* format, va_list argptr) ATTRIBUTE_PRINTF(2, 0); }; // In the non-fixed buffer case an underlying buffer will be created and diff --git a/hotspot/src/share/vm/utilities/quickSort.cpp b/hotspot/src/share/vm/utilities/quickSort.cpp index 0cb7f6ef833..de008877989 100644 --- a/hotspot/src/share/vm/utilities/quickSort.cpp +++ b/hotspot/src/share/vm/utilities/quickSort.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,7 +77,7 @@ void QuickSort::print_array(const char* prefix, int* array, int length) { for (int i = 0; i < length; i++) { tty->print(" %d", array[i]); } - tty->print_cr(""); + tty->cr(); } bool QuickSort::compare_arrays(int* actual, int* expected, int length) { diff --git a/hotspot/src/share/vm/utilities/taskqueue.cpp b/hotspot/src/share/vm/utilities/taskqueue.cpp index 2811c84d75d..a3daa8847b6 100644 --- a/hotspot/src/share/vm/utilities/taskqueue.cpp +++ b/hotspot/src/share/vm/utilities/taskqueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,8 @@ #include "utilities/stack.inline.hpp" #include "utilities/taskqueue.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef TRACESPINNING uint ParallelTaskTerminator::_total_yields = 0; uint ParallelTaskTerminator::_total_spins = 0; diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp index 097e28de9c5..62d8ba6b176 100644 --- a/hotspot/src/share/vm/utilities/vmError.cpp +++ b/hotspot/src/share/vm/utilities/vmError.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,8 @@ #include "utilities/top.hpp" #include "utilities/vmError.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // List of environment variables that should be reported in error log file. const char *env_list[] = { // All platforms @@ -358,17 +360,17 @@ void VMError::report(outputStream* st) { st->print((_id == (int)OOM_MALLOC_ERROR) ? "(malloc) failed to allocate " : "(mmap) failed to map "); jio_snprintf(buf, sizeof(buf), SIZE_FORMAT, _size); - st->print(buf); + st->print("%s", buf); st->print(" bytes"); if (_message != NULL) { st->print(" for "); - st->print(_message); + st->print("%s", _message); } st->cr(); } else { if (_message != NULL) st->print("# "); - st->print_cr(_message); + st->print_cr("%s", _message); } // In error file give some solutions if (_verbose) { @@ -485,7 +487,7 @@ void VMError::report(outputStream* st) { } else { st->print("Failed to write core dump. %s", coredump_message); } - st->print_cr(""); + st->cr(); st->print_cr("#"); STEP(65, "(printing bug submit message)") diff --git a/hotspot/src/share/vm/utilities/workgroup.cpp b/hotspot/src/share/vm/utilities/workgroup.cpp index 479cd04029a..beab5906f42 100644 --- a/hotspot/src/share/vm/utilities/workgroup.cpp +++ b/hotspot/src/share/vm/utilities/workgroup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,8 @@ #include "runtime/os.hpp" #include "utilities/workgroup.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Definitions of WorkGang methods. AbstractWorkGang::AbstractWorkGang(const char* name, diff --git a/hotspot/src/share/vm/utilities/xmlstream.cpp b/hotspot/src/share/vm/utilities/xmlstream.cpp index e6714e15a86..785f927b10e 100644 --- a/hotspot/src/share/vm/utilities/xmlstream.cpp +++ b/hotspot/src/share/vm/utilities/xmlstream.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -336,6 +336,8 @@ void xmlStream::done_raw(const char* kind) { print_raw_cr(">"); } +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED // ------------------------------------------------------------------ void xmlStream::va_done(const char* format, va_list ap) { char buffer[200]; @@ -354,6 +356,7 @@ void xmlStream::va_done(const char* format, va_list ap) { buffer[kind_len] = 0; tail(buffer); } +PRAGMA_DIAG_POP // Output a timestamp attribute. void xmlStream::stamp() { @@ -399,7 +402,7 @@ void xmlStream::method_text(methodHandle method) { ResourceMark rm; assert_if_no_error(inside_attrs(), "printing attributes"); if (method.is_null()) return; - text()->print(method->method_holder()->external_name()); + text()->print("%s", method->method_holder()->external_name()); print_raw(" "); // " " is easier for tools to parse than "::" method->name()->print_symbol_on(text()); print_raw(" "); // separator diff --git a/hotspot/src/share/vm/utilities/xmlstream.hpp b/hotspot/src/share/vm/utilities/xmlstream.hpp index 7ab93744b27..22a12cacda3 100644 --- a/hotspot/src/share/vm/utilities/xmlstream.hpp +++ b/hotspot/src/share/vm/utilities/xmlstream.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,7 +80,7 @@ class xmlStream : public outputStream { outputStream* out() { return _out; } // helpers for writing XML elements - void va_tag(bool push, const char* format, va_list ap); + void va_tag(bool push, const char* format, va_list ap) ATTRIBUTE_PRINTF(3, 0); virtual void see_tag(const char* tag, bool push) NOT_DEBUG({}); virtual void pop_tag(const char* tag) NOT_DEBUG({}); @@ -109,29 +109,29 @@ class xmlStream : public outputStream { int unflushed_count() { return (int)(out()->count() - _last_flush); } // writing complete XML elements - void elem(const char* format, ...); - void begin_elem(const char* format, ...); - void end_elem(const char* format, ...); + void elem(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void begin_elem(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void end_elem(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); void end_elem(); - void head(const char* format, ...); - void begin_head(const char* format, ...); - void end_head(const char* format, ...); + void head(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void begin_head(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void end_head(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); void end_head(); - void done(const char* format, ...); // xxx_done event, plus tail + void done(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); // xxx_done event, plus tail void done_raw(const char * kind); void tail(const char* kind); // va_list versions - void va_elem(const char* format, va_list ap); - void va_begin_elem(const char* format, va_list ap); - void va_head(const char* format, va_list ap); - void va_begin_head(const char* format, va_list ap); - void va_done(const char* format, va_list ap); + void va_elem(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0); + void va_begin_elem(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0); + void va_head(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0); + void va_begin_head(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0); + void va_done(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0); // write text (with quoting of special XML characters <>&'" etc.) outputStream* text() { return _text; } - void text(const char* format, ...); - void va_text(const char* format, va_list ap) { + void text(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void va_text(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0) { text()->vprint(format, ap); } From 6049e98a0e8b36f8e99dbceda12b19afcb0a7c6c Mon Sep 17 00:00:00 2001 From: Jon Masamitsu <jmasa@openjdk.org> Date: Sun, 11 May 2014 16:35:43 -0700 Subject: [PATCH 061/157] 8038928: gc/g1/TestGCLogMessages.java fail with "[Evacuation Failure' Reviewed-by: ysr, brutisso, tschatzl --- hotspot/test/gc/g1/TestGCLogMessages.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/hotspot/test/gc/g1/TestGCLogMessages.java b/hotspot/test/gc/g1/TestGCLogMessages.java index 0d5ba41fac9..dbb617001ba 100644 --- a/hotspot/test/gc/g1/TestGCLogMessages.java +++ b/hotspot/test/gc/g1/TestGCLogMessages.java @@ -22,7 +22,7 @@ */ /* - * @test TestPrintGCDetails + * @test TestGCLogMessages * @bug 8035406 8027295 8035398 8019342 * @summary Ensure that the PrintGCDetails output for a minor GC with G1 * includes the expected necessary messages. @@ -90,12 +90,6 @@ public class TestGCLogMessages { output.shouldContain("[String Dedup Fixup"); output.shouldContain("[Young Free CSet"); output.shouldContain("[Non-Young Free CSet"); - - // also check evacuation failure messages once - output.shouldNotContain("[Evacuation Failure"); - output.shouldNotContain("[Recalculate Used"); - output.shouldNotContain("[Remove Self Forwards"); - output.shouldNotContain("[Restore RemSet"); output.shouldHaveExitValue(0); } From abd503efebbeac59b0d7dbb66e4bec1610463da5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Borggr=C3=A9n-Franck?= <jfranck@openjdk.org> Date: Mon, 12 May 2014 14:47:55 +0200 Subject: [PATCH 062/157] 8038994: AnnotatedType.getType() of a TypeVariable boundary without annotations return null Reviewed-by: psandoz --- .../annotation/TypeAnnotationParser.java | 13 +- .../lang/annotation/TypeVariableBounds.java | 129 ++++++++++++++++++ 2 files changed, 135 insertions(+), 7 deletions(-) create mode 100644 jdk/test/java/lang/annotation/TypeVariableBounds.java diff --git a/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java b/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java index 9bd4b6c64c6..8eab556fdee 100644 --- a/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java +++ b/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java @@ -75,7 +75,7 @@ public final class TypeAnnotationParser { if (ti.getTarget() == filter) l.add(t); } - TypeAnnotation[] typeAnnotations = l.toArray(new TypeAnnotation[0]); + TypeAnnotation[] typeAnnotations = l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY); return AnnotatedTypeFactory.buildAnnotatedType(type, LocationInfo.BASE_LOCATION, typeAnnotations, @@ -245,7 +245,6 @@ public final class TypeAnnotationParser { if (bounds != null) { int startIndex = 0; AnnotatedType[] res = new AnnotatedType[bounds.length]; - Arrays.fill(res, AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE); // Adjust bounds index // @@ -276,12 +275,12 @@ public final class TypeAnnotationParser { tInfo.getCount() == typeVarIndex) { l.add(t); } - res[i] = AnnotatedTypeFactory.buildAnnotatedType(bounds[i], - loc, - l.toArray(new TypeAnnotation[0]), - candidates.toArray(new TypeAnnotation[0]), - (AnnotatedElement)decl); } + res[i] = AnnotatedTypeFactory.buildAnnotatedType(bounds[i], + loc, + l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), + candidates.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), + (AnnotatedElement)decl); } return res; } diff --git a/jdk/test/java/lang/annotation/TypeVariableBounds.java b/jdk/test/java/lang/annotation/TypeVariableBounds.java new file mode 100644 index 00000000000..1a2e33ae396 --- /dev/null +++ b/jdk/test/java/lang/annotation/TypeVariableBounds.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @bug 8038994 + * @summary Test that getAnnotatedBounds().getType() match getBounds() + * @run testng TypeVariableBounds + */ + +import java.io.Serializable; +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.util.concurrent.Callable; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import static org.testng.Assert.*; + +public class TypeVariableBounds { + @Test(dataProvider = "classData") + public void testClass(Class<?> c) throws Exception { + assertNotEquals(c.getTypeParameters().length, 0); + + TypeVariable[] tv = c.getTypeParameters(); + + for(TypeVariable t : tv) + testTv(t); + + } + + @Test(dataProvider = "methodData") + public void testMethod(Class<?>c) throws Exception { + Method m = c.getMethod("aMethod"); + TypeVariable[] tv = m.getTypeParameters(); + + for(TypeVariable t : tv) + testTv(t); + + } + + public void testTv(TypeVariable<?> tv) { + Type[] t = tv.getBounds(); + AnnotatedType[] at = tv.getAnnotatedBounds(); + + assertEquals(t.length, at.length, Arrays.asList(t) + " and " + Arrays.asList(at) + " should be the same length"); + + for (int i = 0; i < t.length; i++) + assertSame(at[i].getType(), t[i], "T: " + t[i] + ", AT: " + at[i] + ", AT.getType(): " + at[i].getType() + "\n"); + } + + @DataProvider + public Object[][] classData() { return CLASS_TESTS; } + + @DataProvider + public Object[][] methodData() { return METHOD_TESTS; } + + public static final Object[][] CLASS_TESTS = { + { Case1.class, }, + { Case2.class, }, + { Case5.class, }, + { Case6.class, }, + }; + + public static final Object[][] METHOD_TESTS = { + { Case3.class, }, + { Case4.class, }, + { Case5.class, }, + { Case6.class, }, + }; + + // Class type var + public static class Case1<C1T1, C1T2 extends AnnotatedElement, C1T3 extends AnnotatedElement & Type & Serializable> {} + public static class Case2<C2T0, @TA C2T1 extends Type, C2T2 extends @TB AnnotatedElement, C2T3 extends AnnotatedElement & @TB Type & Serializable> {} + + // Method type var + public static class Case3 { public <C3T1, C3T2 extends AnnotatedElement, C3T3 extends AnnotatedElement & Type & Serializable> void aMethod() {}} + public static class Case4 { public <C4T0, @TA C4T1 extends List, C4T2 extends @TB Set, C4T3 extends Set & @TB Callable & Serializable> void aMethod() {}} + + // Both + public static class Case5 <C5CT1, C5CT2 extends Runnable> { + public <C5MT1, + C5MT2 extends AnnotatedElement, + C5MT3 extends AnnotatedElement & Type & Serializable, + C5MT4 extends C5CT2> + void aMethod() {}} + + public static class Case6 <@TA C6CT1, C6CT2 extends @TB Runnable> { + public <@TA C6MT1, + C6MT2 extends @TB AnnotatedElement, + C6MT3 extends @TB AnnotatedElement & @TB2 Type & Serializable, + C6MT4 extends @TB2 C6CT2> + void aMethod() {}} + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE_PARAMETER) + public @interface TA {} + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE_USE) + public @interface TB {} + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE_USE) + public @interface TB2 {} +} From 630cca22439b32a0b6721359af95e0322d70c0ef Mon Sep 17 00:00:00 2001 From: Mikael Vidstedt <mikael@openjdk.org> Date: Mon, 12 May 2014 06:16:36 -0700 Subject: [PATCH 063/157] 8042804: Support invoking Hotspot tests from top level Reviewed-by: sla, erikj --- test/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/Makefile b/test/Makefile index 08b91bf7f9c..7a66290318c 100644 --- a/test/Makefile +++ b/test/Makefile @@ -33,6 +33,7 @@ TOPDIR=.. # This makefile depends on the availability of sibling directories. LANGTOOLS_DIR=$(TOPDIR)/langtools JDK_DIR=$(TOPDIR)/jdk +HOTSPOT_DIR=$(TOPDIR)/hotspot # Macro to run a test target in a subdir define SUBDIR_TEST # subdirectory target @@ -62,6 +63,9 @@ langtools_% : jdk_% core_%s svc_%: @$(NO_STOPPING)$(call SUBDIR_TEST, $(JDK_DIR), TEST="$@" $@) +hotspot_%: + @$(NO_STOPPING)$(call SUBDIR_TEST, $(HOTSPOT_DIR), TEST="$@" $@) + ################################################################ # Phony targets (e.g. these are not filenames) From f8bbbb68e6ab3d40a712cc9cc568f593cce15c5d Mon Sep 17 00:00:00 2001 From: Mikael Vidstedt <mikael@openjdk.org> Date: Mon, 12 May 2014 06:17:05 -0700 Subject: [PATCH 064/157] 8042804: Support invoking Hotspot tests from top level Reviewed-by: sla, erikj --- hotspot/test/Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hotspot/test/Makefile b/hotspot/test/Makefile index f29ef326c1d..f81cc8d64df 100644 --- a/hotspot/test/Makefile +++ b/hotspot/test/Makefile @@ -147,6 +147,11 @@ BUNDLE_UP_FAILED = ( exitCode=$$? && $(BUNDLE_UP) && exit $${exitCode} ) all: jtreg_tests @$(ECHO) "Testing completed successfully" +# Support "hotspot_" prefixed test make targets too +# The hotspot_% targets are for example invoked by the top level Makefile +hotspot_%: + $(MAKE) $* + # Prep for output prep: clean @$(MKDIR) -p $(ABS_TEST_OUTPUT_DIR) From 693f28c0128dac5184f4e743c70467edb47869d8 Mon Sep 17 00:00:00 2001 From: Volker Simonis <simonis@openjdk.org> Date: Mon, 12 May 2014 09:59:56 -0400 Subject: [PATCH 065/157] 8039805: Fix the signature of the global new/delete operators in allocation.cpp Reviewed-by: dholmes, lfoltan --- hotspot/make/aix/makefiles/vm.make | 2 - hotspot/make/bsd/makefiles/vm.make | 3 -- hotspot/src/os/aix/vm/os_aix.cpp | 2 +- hotspot/src/os/aix/vm/porting_aix.cpp | 3 +- hotspot/src/share/vm/memory/allocation.cpp | 49 +++++++++++++++------- 5 files changed, 36 insertions(+), 23 deletions(-) diff --git a/hotspot/make/aix/makefiles/vm.make b/hotspot/make/aix/makefiles/vm.make index 4cdb6d92e5a..b579babfffa 100644 --- a/hotspot/make/aix/makefiles/vm.make +++ b/hotspot/make/aix/makefiles/vm.make @@ -136,8 +136,6 @@ include $(MAKEFILES_DIR)/dtrace.make JVM = jvm LIBJVM = lib$(JVM).so -CFLAGS += -DALLOW_OPERATOR_NEW_USAGE - LIBJVM_DEBUGINFO = lib$(JVM).debuginfo LIBJVM_DIZ = lib$(JVM).diz diff --git a/hotspot/make/bsd/makefiles/vm.make b/hotspot/make/bsd/makefiles/vm.make index 40a9d6594af..77dde8bc930 100644 --- a/hotspot/make/bsd/makefiles/vm.make +++ b/hotspot/make/bsd/makefiles/vm.make @@ -146,9 +146,6 @@ JVM = jvm ifeq ($(OS_VENDOR), Darwin) LIBJVM = lib$(JVM).dylib CFLAGS += -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE - ifeq (${VERSION}, $(filter ${VERSION}, debug fastdebug)) - CFLAGS += -DALLOW_OPERATOR_NEW_USAGE - endif LIBJVM_DEBUGINFO = lib$(JVM).dylib.dSYM LIBJVM_DIZ = lib$(JVM).diz diff --git a/hotspot/src/os/aix/vm/os_aix.cpp b/hotspot/src/os/aix/vm/os_aix.cpp index 66a1fc0bbfd..f8b07db7bb5 100644 --- a/hotspot/src/os/aix/vm/os_aix.cpp +++ b/hotspot/src/os/aix/vm/os_aix.cpp @@ -1870,7 +1870,7 @@ public: // properties. // ShmBkBlock: base class for all blocks in the shared memory bookkeeping -class ShmBkBlock { +class ShmBkBlock : public CHeapObj<mtInternal> { ShmBkBlock* _next; diff --git a/hotspot/src/os/aix/vm/porting_aix.cpp b/hotspot/src/os/aix/vm/porting_aix.cpp index b79d33d742c..5e6a78ddcc9 100644 --- a/hotspot/src/os/aix/vm/porting_aix.cpp +++ b/hotspot/src/os/aix/vm/porting_aix.cpp @@ -23,6 +23,7 @@ */ #include "asm/assembler.hpp" +#include "memory/allocation.hpp" #include "loadlib_aix.hpp" #include "porting_aix.hpp" #include "utilities/debug.hpp" @@ -67,7 +68,7 @@ inline char* align_ptr_up(char* ptr, intptr_t alignment) { // a primitive string map. Should this turn out to be a performance // problem, a better hashmap has to be used. class fixed_strings { - struct node { + struct node : public CHeapObj<mtInternal> { char* v; node* next; }; diff --git a/hotspot/src/share/vm/memory/allocation.cpp b/hotspot/src/share/vm/memory/allocation.cpp index 9fece9b4ef4..a3ad5945775 100644 --- a/hotspot/src/share/vm/memory/allocation.cpp +++ b/hotspot/src/share/vm/memory/allocation.cpp @@ -686,40 +686,57 @@ void* Arena::internal_malloc_4(size_t x) { // a memory leak. Use CHeapObj as the base class of such objects to make it explicit // that they're allocated on the C heap. // Commented out in product version to avoid conflicts with third-party C++ native code. -// On certain platforms, such as Mac OS X (Darwin), in debug version, new is being called -// from jdk source and causing data corruption. Such as -// Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair -// define ALLOW_OPERATOR_NEW_USAGE for platform on which global operator new allowed. // -#ifndef ALLOW_OPERATOR_NEW_USAGE -void* operator new(size_t size) throw() { - assert(false, "Should not call global operator new"); +// In C++98/03 the throwing new operators are defined with the following signature: +// +// void* operator new(std::size_tsize) throw(std::bad_alloc); +// void* operator new[](std::size_tsize) throw(std::bad_alloc); +// +// while all the other (non-throwing) new and delete operators are defined with an empty +// throw clause (i.e. "operator delete(void* p) throw()") which means that they do not +// throw any exceptions (see section 18.4 of the C++ standard). +// +// In the new C++11/14 standard, the signature of the throwing new operators was changed +// by completely omitting the throw clause (which effectively means they could throw any +// exception) while all the other new/delete operators where changed to have a 'nothrow' +// clause instead of an empty throw clause. +// +// Unfortunately, the support for exception specifications among C++ compilers is still +// very fragile. While some more strict compilers like AIX xlC or HP aCC reject to +// override the default throwing new operator with a user operator with an empty throw() +// clause, the MS Visual C++ compiler warns for every non-empty throw clause like +// throw(std::bad_alloc) that it will ignore the exception specification. The following +// operator definitions have been checked to correctly work with all currently supported +// compilers and they should be upwards compatible with C++11/14. Therefore +// PLEASE BE CAREFUL if you change the signature of the following operators! + +void* operator new(size_t size) /* throw(std::bad_alloc) */ { + fatal("Should not call global operator new"); return 0; } -void* operator new [](size_t size) throw() { - assert(false, "Should not call global operator new[]"); +void* operator new [](size_t size) /* throw(std::bad_alloc) */ { + fatal("Should not call global operator new[]"); return 0; } void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() { - assert(false, "Should not call global operator new"); + fatal("Should not call global operator new"); return 0; } void* operator new [](size_t size, std::nothrow_t& nothrow_constant) throw() { - assert(false, "Should not call global operator new[]"); + fatal("Should not call global operator new[]"); return 0; } -void operator delete(void* p) { - assert(false, "Should not call global delete"); +void operator delete(void* p) throw() { + fatal("Should not call global delete"); } -void operator delete [](void* p) { - assert(false, "Should not call global delete []"); +void operator delete [](void* p) throw() { + fatal("Should not call global delete []"); } -#endif // ALLOW_OPERATOR_NEW_USAGE void AllocatedObj::print() const { print_on(tty); } void AllocatedObj::print_value() const { print_value_on(tty); } From 6e71a0cb82a7690c33660d0d2267b60889566c7c Mon Sep 17 00:00:00 2001 From: Anton Nashatyrev <anashaty@openjdk.org> Date: Mon, 12 May 2014 18:21:15 +0400 Subject: [PATCH 066/157] 8024932: [TEST_BUG] [macosx] javax/swing/text/StyledEditorKit/8016833/bug8016833.java failed Reviewed-by: serb, alexsch --- .../swing/text/StyledEditorKit/8016833/bug8016833.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/test/javax/swing/text/StyledEditorKit/8016833/bug8016833.java b/jdk/test/javax/swing/text/StyledEditorKit/8016833/bug8016833.java index 601a31de688..1dec0972346 100644 --- a/jdk/test/javax/swing/text/StyledEditorKit/8016833/bug8016833.java +++ b/jdk/test/javax/swing/text/StyledEditorKit/8016833/bug8016833.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -190,9 +190,9 @@ public class bug8016833 { // not too wide assertTrue(out3.getWidth() * 0.8 < out2.getWidth()); // not too low - assertTrue(out3.getY() - (out1.getY() + out2.getHeight()) < 3); + assertTrue(out3.getY() - (out1.getY() + out2.getHeight() - 1) < 4); // not too high - assertTrue(out3.getY() - (out1.getY() + out2.getHeight()) > 0); + assertTrue(out3.getY() - (out1.getY() + out2.getHeight() - 1) > 0); } void testStrikthrough() { @@ -217,7 +217,7 @@ public class bug8016833 { // not too wide assertTrue(out3.getWidth() * 0.8 < out2.getWidth()); // not too low - assertTrue(out3.getY() - (out1.getY() + out2.getHeight()) < 0); + assertTrue(out3.getY() - (out1.getY() + out2.getHeight() - 1) < 0); // not too high assertTrue(out3.getY() - out1.getY() > 1); } From 23759a15dd7dbfc19c41903a6011e0b42257b6d5 Mon Sep 17 00:00:00 2001 From: Andrey Nazarov <anazarov@openjdk.org> Date: Mon, 12 May 2014 17:09:26 +0100 Subject: [PATCH 067/157] 8042771: Missing bug id in test/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java Reviewed-by: jjg --- .../attributes/SourceFile/NoSourceFileAttribute.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/langtools/test/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java b/langtools/test/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java index 835f801d209..90321ed2901 100644 --- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java +++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java @@ -24,10 +24,11 @@ /* * @test * @summary sourcefile attribute test for file compiled without debug information. + * @bug 8040129 * @library /tools/javac/lib ../lib * @build SourceFileTestBase TestBase InMemoryFileManager ToolBox * @compile -g:none NoSourceFileAttribute.java - * @run main NoSourceFileAttribute + * @run main NoSourceFileAttribute */ import com.sun.tools.classfile.Attribute; From a80118b3ae552c3306ffbe5399a79e4219bdf3f4 Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Mon, 12 May 2014 09:32:23 -0700 Subject: [PATCH 068/157] 8038876: Remove use of ServiceLoader in finding class implementing sun.java2d.cmm.CMMServiceProvider Reviewed-by: bae, mchung --- jdk/make/CopyIntoClasses.gmk | 10 ------ jdk/make/profile-rtjar-includes.txt | 3 +- .../classes/sun/java2d/cmm/CMSManager.java | 36 ++++++++----------- .../sun.java2d.cmm.CMMServiceProvider | 2 -- 4 files changed, 15 insertions(+), 36 deletions(-) delete mode 100644 jdk/src/share/classes/sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider diff --git a/jdk/make/CopyIntoClasses.gmk b/jdk/make/CopyIntoClasses.gmk index 322901603a3..b3a216fb90e 100644 --- a/jdk/make/CopyIntoClasses.gmk +++ b/jdk/make/CopyIntoClasses.gmk @@ -111,18 +111,8 @@ else ALL_META-INF_DIRS := $(ALL_META-INF_DIRS_share) endif -ifndef OPENJDK - ALL_META-INF_DIRS += $(JDK_TOPDIR)/src/closed/share/classes/sun/java2d/cmm/kcms/META-INF -endif - SRC_SERVICES_FILES := $(wildcard $(addsuffix /services/*, $(ALL_META-INF_DIRS))) -ifdef OPENJDK - SRC_SERVICES_FILES := $(filter-out %sun/java2d/cmm/kcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider, $(SRC_SERVICES_FILES)) -else - SRC_SERVICES_FILES := $(filter-out %sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider, $(SRC_SERVICES_FILES)) -endif - # The number of services files are relatively few. If the increase in numbers, then # we have to use ListPathsSafelyNow here. # Change $(JDK_TOPDIR)/src/.../META-INF/services/yyyy into $(JDK_OUTPUTDIR)/classes/META-INF/services/yyyy diff --git a/jdk/make/profile-rtjar-includes.txt b/jdk/make/profile-rtjar-includes.txt index 6cce159e400..061a927e616 100644 --- a/jdk/make/profile-rtjar-includes.txt +++ b/jdk/make/profile-rtjar-includes.txt @@ -241,5 +241,4 @@ FULL_JRE_INCLUDE_METAINF_SERVICES := \ META-INF/services/javax.sound.sampled.spi.AudioFileReader \ META-INF/services/javax.sound.sampled.spi.AudioFileWriter \ META-INF/services/javax.sound.sampled.spi.FormatConversionProvider \ - META-INF/services/javax.sound.sampled.spi.MixerProvider \ - META-INF/services/sun.java2d.cmm.PCMM + META-INF/services/javax.sound.sampled.spi.MixerProvider diff --git a/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java b/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java index 6970c59a19c..6036a3c2636 100644 --- a/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java +++ b/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java @@ -34,7 +34,6 @@ import java.awt.image.WritableRaster; import java.security.AccessController; import java.security.PrivilegedAction; import sun.security.action.GetPropertyAction; -import java.util.ServiceLoader; public class CMSManager { public static ColorSpace GRAYspace; // These two fields allow access @@ -52,35 +51,28 @@ public class CMSManager { return cmmImpl; } - CMMServiceProvider spi = AccessController.doPrivileged( - new PrivilegedAction<CMMServiceProvider>() { - public CMMServiceProvider run() { - String cmmClass = System.getProperty( - "sun.java2d.cmm", "sun.java2d.cmm.lcms.LcmsServiceProvider"); - - ServiceLoader<CMMServiceProvider> cmmLoader - = ServiceLoader.loadInstalled(CMMServiceProvider.class); - - CMMServiceProvider spi = null; - - for (CMMServiceProvider cmm : cmmLoader) { - spi = cmm; - if (cmm.getClass().getName().equals(cmmClass)) { - break; - } - } - return spi; + GetPropertyAction gpa = new GetPropertyAction("sun.java2d.cmm"); + String cmmProviderClass = AccessController.doPrivileged(gpa); + CMMServiceProvider provider = null; + if (cmmProviderClass != null) { + try { + Class<?> cls = Class.forName(cmmProviderClass); + provider = (CMMServiceProvider)cls.newInstance(); + } catch (ReflectiveOperationException e) { } - }); + } + if (provider == null) { + provider = new sun.java2d.cmm.lcms.LcmsServiceProvider(); + } - cmmImpl = spi.getColorManagementModule(); + cmmImpl = provider.getColorManagementModule(); if (cmmImpl == null) { throw new CMMException("Cannot initialize Color Management System."+ "No CM module found"); } - GetPropertyAction gpa = new GetPropertyAction("sun.java2d.cmm.trace"); + gpa = new GetPropertyAction("sun.java2d.cmm.trace"); String cmmTrace = AccessController.doPrivileged(gpa); if (cmmTrace != null) { cmmImpl = new CMMTracer(cmmImpl); diff --git a/jdk/src/share/classes/sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider b/jdk/src/share/classes/sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider deleted file mode 100644 index ce7ea564ffb..00000000000 --- a/jdk/src/share/classes/sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider +++ /dev/null @@ -1,2 +0,0 @@ -# Little CMS color management module -sun.java2d.cmm.lcms.LcmsServiceProvider From 976e7c8aa70cde6bde4a9eaa6fdd7e9284739a67 Mon Sep 17 00:00:00 2001 From: Harold Seigel <hseigel@openjdk.org> Date: Mon, 12 May 2014 13:12:30 -0400 Subject: [PATCH 069/157] 8040292: Annotation attributes must not appear more than once Add checks for duplicate attributes. Reviewed-by: coleenp, lfoltan --- .../share/vm/classfile/classFileParser.cpp | 99 +- .../duplAttributes/DuplAttributes.jcod | 1310 +++++++++++++++++ .../duplAttributes/DuplAttributesTest.java | 63 + hotspot/test/runtime/duplAttributes/test.jar | Bin 0 -> 4478 bytes 4 files changed, 1452 insertions(+), 20 deletions(-) create mode 100644 hotspot/test/runtime/duplAttributes/DuplAttributes.jcod create mode 100644 hotspot/test/runtime/duplAttributes/DuplAttributesTest.java create mode 100644 hotspot/test/runtime/duplAttributes/test.jar diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 8d73c099a71..e78a6b2615f 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -875,6 +875,7 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count, int runtime_visible_type_annotations_length = 0; u1* runtime_invisible_type_annotations = NULL; int runtime_invisible_type_annotations_length = 0; + bool runtime_invisible_annotations_exists = false; bool runtime_invisible_type_annotations_exists = false; while (attributes_count--) { cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length @@ -920,6 +921,10 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count, } generic_signature_index = cfs->get_u2(CHECK); } else if (attribute_name == vmSymbols::tag_runtime_visible_annotations()) { + if (runtime_visible_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleAnnotations attributes for field in class file %s", CHECK); + } runtime_visible_annotations_length = attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); @@ -928,11 +933,18 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count, parsed_annotations, CHECK); cfs->skip_u1(runtime_visible_annotations_length, CHECK); - } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { - runtime_invisible_annotations_length = attribute_length; - runtime_invisible_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_annotations != NULL, "null invisible annotations"); - cfs->skip_u1(runtime_invisible_annotations_length, CHECK); + } else if (attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { + if (runtime_invisible_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleAnnotations attributes for field in class file %s", CHECK); + } + runtime_invisible_annotations_exists = true; + if (PreserveAllAnnotations) { + runtime_invisible_annotations_length = attribute_length; + runtime_invisible_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_annotations != NULL, "null invisible annotations"); + } + cfs->skip_u1(attribute_length, CHECK); } else if (attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { if (runtime_visible_type_annotations != NULL) { classfile_parse_error( @@ -2066,7 +2078,9 @@ methodHandle ClassFileParser::parse_method(bool is_interface, int runtime_visible_type_annotations_length = 0; u1* runtime_invisible_type_annotations = NULL; int runtime_invisible_type_annotations_length = 0; + bool runtime_invisible_annotations_exists = false; bool runtime_invisible_type_annotations_exists = false; + bool runtime_invisible_parameter_annotations_exists = false; u1* annotation_default = NULL; int annotation_default_length = 0; @@ -2295,6 +2309,10 @@ methodHandle ClassFileParser::parse_method(bool is_interface, cfs->guarantee_more(2, CHECK_(nullHandle)); // generic_signature_index generic_signature_index = cfs->get_u2_fast(); } else if (method_attribute_name == vmSymbols::tag_runtime_visible_annotations()) { + if (runtime_visible_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleAnnotations attributes for method in class file %s", CHECK_(nullHandle)); + } runtime_visible_annotations_length = method_attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); @@ -2302,22 +2320,45 @@ methodHandle ClassFileParser::parse_method(bool is_interface, runtime_visible_annotations_length, &parsed_annotations, CHECK_(nullHandle)); cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle)); - } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { - runtime_invisible_annotations_length = method_attribute_length; - runtime_invisible_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_annotations != NULL, "null invisible annotations"); - cfs->skip_u1(runtime_invisible_annotations_length, CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { + if (runtime_invisible_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleAnnotations attributes for method in class file %s", CHECK_(nullHandle)); + } + runtime_invisible_annotations_exists = true; + if (PreserveAllAnnotations) { + runtime_invisible_annotations_length = method_attribute_length; + runtime_invisible_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_annotations != NULL, "null invisible annotations"); + } + cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); } else if (method_attribute_name == vmSymbols::tag_runtime_visible_parameter_annotations()) { + if (runtime_visible_parameter_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleParameterAnnotations attributes for method in class file %s", CHECK_(nullHandle)); + } runtime_visible_parameter_annotations_length = method_attribute_length; runtime_visible_parameter_annotations = cfs->get_u1_buffer(); assert(runtime_visible_parameter_annotations != NULL, "null visible parameter annotations"); cfs->skip_u1(runtime_visible_parameter_annotations_length, CHECK_(nullHandle)); - } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_parameter_annotations()) { - runtime_invisible_parameter_annotations_length = method_attribute_length; - runtime_invisible_parameter_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_parameter_annotations != NULL, "null invisible parameter annotations"); - cfs->skip_u1(runtime_invisible_parameter_annotations_length, CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_parameter_annotations()) { + if (runtime_invisible_parameter_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleParameterAnnotations attributes for method in class file %s", CHECK_(nullHandle)); + } + runtime_invisible_parameter_annotations_exists = true; + if (PreserveAllAnnotations) { + runtime_invisible_parameter_annotations_length = method_attribute_length; + runtime_invisible_parameter_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_parameter_annotations != NULL, "null invisible parameter annotations"); + } + cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); } else if (method_attribute_name == vmSymbols::tag_annotation_default()) { + if (annotation_default != NULL) { + classfile_parse_error( + "Multiple AnnotationDefault attributes for method in class file %s", + CHECK_(nullHandle)); + } annotation_default_length = method_attribute_length; annotation_default = cfs->get_u1_buffer(); assert(annotation_default != NULL, "null annotation default"); @@ -2846,6 +2887,8 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio u1* runtime_invisible_type_annotations = NULL; int runtime_invisible_type_annotations_length = 0; bool runtime_invisible_type_annotations_exists = false; + bool runtime_invisible_annotations_exists = false; + bool parsed_source_debug_ext_annotations_exist = false; u1* inner_classes_attribute_start = NULL; u4 inner_classes_attribute_length = 0; u2 enclosing_method_class_index = 0; @@ -2873,6 +2916,11 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio parse_classfile_sourcefile_attribute(CHECK); } else if (tag == vmSymbols::tag_source_debug_extension()) { // Check for SourceDebugExtension tag + if (parsed_source_debug_ext_annotations_exist) { + classfile_parse_error( + "Multiple SourceDebugExtension attributes in class file %s", CHECK); + } + parsed_source_debug_ext_annotations_exist = true; parse_classfile_source_debug_extension_attribute((int)attribute_length, CHECK); } else if (tag == vmSymbols::tag_inner_classes()) { // Check for InnerClasses tag @@ -2909,6 +2957,10 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio } parse_classfile_signature_attribute(CHECK); } else if (tag == vmSymbols::tag_runtime_visible_annotations()) { + if (runtime_visible_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleAnnotations attributes in class file %s", CHECK); + } runtime_visible_annotations_length = attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); @@ -2917,11 +2969,18 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio parsed_annotations, CHECK); cfs->skip_u1(runtime_visible_annotations_length, CHECK); - } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_annotations()) { - runtime_invisible_annotations_length = attribute_length; - runtime_invisible_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_annotations != NULL, "null invisible annotations"); - cfs->skip_u1(runtime_invisible_annotations_length, CHECK); + } else if (tag == vmSymbols::tag_runtime_invisible_annotations()) { + if (runtime_invisible_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleAnnotations attributes in class file %s", CHECK); + } + runtime_invisible_annotations_exists = true; + if (PreserveAllAnnotations) { + runtime_invisible_annotations_length = attribute_length; + runtime_invisible_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_annotations != NULL, "null invisible annotations"); + } + cfs->skip_u1(attribute_length, CHECK); } else if (tag == vmSymbols::tag_enclosing_method()) { if (parsed_enclosingmethod_attribute) { classfile_parse_error("Multiple EnclosingMethod attributes in class file %s", CHECK); diff --git a/hotspot/test/runtime/duplAttributes/DuplAttributes.jcod b/hotspot/test/runtime/duplAttributes/DuplAttributes.jcod new file mode 100644 index 00000000000..1a9a1ae8f4b --- /dev/null +++ b/hotspot/test/runtime/duplAttributes/DuplAttributes.jcod @@ -0,0 +1,1310 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + + +/* + * This file contains ten different sub-tests. Each sub-test consists of a + * class with a different case of an invalid duplicate attribute. The main + * test runs each of these tests individually. If any of them fail then the + * whole test fails. + */ + + + +/* + * This test contains a class with invalid duplicate AnnotationDefault attributes. + */ +class AnnotationDefaultDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #11; // #1 + class #12; // #2 + class #13; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "Signature"; // #7 + Utf8 "<T:Ljava/lang/Object;>Ljava/lang/Object;"; // #8 + Utf8 "AnnotationDefault"; // #9 + Utf8 "LAnnotationDefaultI;"; // #10 + NameAndType #4 #5; // #11 + Utf8 "AnnotationDefaultDup"; // #12 + Utf8 "java/lang/Object"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #14 #15; // #16 + class #19; // #17 + Method #17 #16; // #18 + Utf8 "AnnotationDefaultDupChecker"; // #19 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + ; + + Attr(#9) { // AnnotationDefault + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end AnnotationDefault + // wrong: + ; + Attr(#9) { // AnnotationDefault + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end AnnotationDefault + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80012AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#7) { // Signature + #8; + } // end Signature + ; + Attr(#9) { // AnnotationDefault + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end AnnotationDefault + } // Attributes + +} // end class + + + +/* + * This test contains a class with invalid duplicate RuntimeInvisibleAnnotations + * attributes. + */ +class ClassInvisAnnotsDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #11; // #1 + class #12; // #2 + class #13; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "Signature"; // #7 + Utf8 "<T:Ljava/lang/Object;>Ljava/lang/Object;"; // #8 + Utf8 "RuntimeInvisibleAnnotations"; // #9 + Utf8 "LClassInvisAnnotsI;"; // #10 + NameAndType #4 #5; // #11 + Utf8 "ClassInvisAnnotsDup"; // #12 + Utf8 "java/lang/Object"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #14 #15; // #16 + class #19; // #17 + Method #17 #16; // #18 + Utf8 "ClassInvisAnnotsDupChecker"; // #19 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80012AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#7) { // Signature + #8; + } // end Signature + ; + Attr(#9) { // RuntimeInvisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeInvisibleAnnotations +// wrong: + ; + Attr(#9) { // RuntimeInvisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeInvisibleAnnotations +// end wrong + } // Attributes + +} // end class + + + +/* + * This test contains a class with invalid duplicate RuntimeVisibleAnnotations + * attributes. + */ +class ClassVisAnnotsDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #11; // #1 + class #12; // #2 + class #13; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "Signature"; // #7 + Utf8 "<T:Ljava/lang/Object;>Ljava/lang/Object;"; // #8 + Utf8 "RuntimeVisibleAnnotations"; // #9 + Utf8 "LClassVisAnnotsI;"; // #10 + NameAndType #4 #5; // #11 + Utf8 "ClassVisAnnotsDup"; // #12 + Utf8 "java/lang/Object"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #14 #15; // #16 + class #19; // #17 + Method #17 #16; // #18 + Utf8 "ClassVisAnnotsDupChecker"; // #19 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80012AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#7) { // Signature + #8; + } // end Signature + ; + Attr(#9) { // RuntimeVisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeVisibleAnnotations +// wrong: + ; + Attr(#9) { // RuntimeVisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeVisibleAnnotations +// end wrong + } // Attributes + +} // end class + + + +/* + * This test contains a field with invalid duplicate RuntimeInvisibleAnnotations + * attributes. + */ +class FieldInvisAnnotsDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #16; // #1 + Method #17 #18; // #2 + class #19; // #3 + class #20; // #4 + Utf8 "fld"; // #5 + Utf8 "Ljava/util/ArrayList;"; // #6 + Utf8 "Signature"; // #7 + Utf8 "Ljava/util/ArrayList<Ljava/lang/Object;>;"; // #8 + Utf8 "RuntimeInvisibleAnnotations"; // #9 + Utf8 "LFieldInvisAnnotsI;"; // #10 + Utf8 "<init>"; // #11 + Utf8 "()V"; // #12 + Utf8 "Code"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #11 #12; // #16 + class #21; // #17 + NameAndType #14 #15; // #18 + Utf8 "FieldInvisAnnotsDup"; // #19 + Utf8 "java/lang/Object"; // #20 + Utf8 "FieldInvisAnnotsDupChecker"; // #21 + } // Constant Pool + + 0x0021; // access + #3;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x0001; // access + #5; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // Signature + #8; + } // end Signature + ; + Attr(#9) { // RuntimeInvisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeInvisibleAnnotations + // wrong: + ; + Attr(#9) { // RuntimeInvisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeInvisibleAnnotations + // end wrong + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x0001; // access + #11; // name_cpx + #12; // sig_cpx + [] { // Attributes + Attr(#13) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#13) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80002AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + } // Attributes +} // end class + + + +/* + * This test contains a field with invalid duplicate RuntimeVisibleAnnotations + * attributes. + */ +class FieldVisAnnotsDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #16; // #1 + Method #17 #18; // #2 + class #19; // #3 + class #20; // #4 + Utf8 "fld"; // #5 + Utf8 "Ljava/util/ArrayList;"; // #6 + Utf8 "Signature"; // #7 + Utf8 "Ljava/util/ArrayList<Ljava/lang/Object;>;"; // #8 + Utf8 "RuntimeVisibleAnnotations"; // #9 + Utf8 "LFieldVisAnnotsI;"; // #10 + Utf8 "<init>"; // #11 + Utf8 "()V"; // #12 + Utf8 "Code"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #11 #12; // #16 + class #21; // #17 + NameAndType #14 #15; // #18 + Utf8 "FieldVisAnnotsDup"; // #19 + Utf8 "java/lang/Object"; // #20 + Utf8 "FieldVisAnnotsDupChecker"; // #21 + } // Constant Pool + + 0x0021; // access + #3;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x0001; // access + #5; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // Signature + #8; + } // end Signature + ; + Attr(#9) { // RuntimeVisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeVisibleAnnotations + // wrong: + ; + Attr(#9) { // RuntimeVisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeVisibleAnnotations + // end wrong + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x0001; // access + #11; // name_cpx + #12; // sig_cpx + [] { // Attributes + Attr(#13) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#13) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80002AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + } // Attributes +} // end class + + + +/* + * This test contains a method with invalid duplicate RuntimeInvisibleAnnotations + * attributes. + */ +class MethInvisAnnotsDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #11; // #1 + class #12; // #2 + class #13; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "Signature"; // #7 + Utf8 "<T:Ljava/lang/Object;>Ljava/lang/Object;"; // #8 + Utf8 "RuntimeInvisibleAnnotations"; // #9 + Utf8 "LMethInvisAnnotsI;"; // #10 + NameAndType #4 #5; // #11 + Utf8 "MethInvisAnnotsDup"; // #12 + Utf8 "java/lang/Object"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #14 #15; // #16 + class #19; // #17 + Method #17 #16; // #18 + Utf8 "MethInvisAnnotsDupChecker"; // #19 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + ; + + Attr(#9) { // RuntimeInvisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeInvisibleAnnotations + // wrong: + ; + Attr(#9) { // RuntimeInvisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeInvisibleAnnotations + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80012AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#7) { // Signature + #8; + } // end Signature + ; + Attr(#9) { // RuntimeInvisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeInvisibleAnnotations + } // Attributes + +} // end class + + + +/* + * This test contains a method with invalid duplicate + * RuntimeInvisibleParameterAnnotations attributes. + */ +class MethInvisParamAnnotsDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #16; // #1 + Method #17 #18; // #2 + class #19; // #3 + class #20; // #4 + Utf8 "<init>"; // #5 + Utf8 "()V"; // #6 + Utf8 "Code"; // #7 + Utf8 "m"; // #8 + Utf8 "()I"; // #9 + Utf8 "Signature"; // #10 + Utf8 "<T:Ljava/lang/Object;>()I"; // #11 + Utf8 "RuntimeInvisibleParameterAnnotations"; // #12 + Utf8 "LMethInvisParamAnnotsI;"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #5 #6; // #16 + class #21; // #17 + NameAndType #14 #15; // #18 + Utf8 "MethInvisParamAnnotsDup"; // #19 + Utf8 "java/lang/Object"; // #20 + Utf8 "MethInvisParamAnnotsDupChecker"; // #21 + } // Constant Pool + + 0x0021; // access + #3;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #5; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0001; // access + #8; // name_cpx + #9; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x03AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + ; + Attr(#10) { // Signature + #11; + } // end Signature + ; + Attr(#12) { // RuntimeInvisibleParameterAnnotations + 0x0001010000000D00; + 0x00; + } // end RuntimeInvisibleParameterAnnotations +// wrong: + ; + Attr(#12) { // RuntimeInvisibleParameterAnnotations + 0x0001010000000D00; + 0x00; + } // end RuntimeInvisibleParameterAnnotations +// end wrong + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80002AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + } // Attributes +} // end class + + + +/* + * This test contains a method with invalid duplicate RuntimeVisibleAnnotations + * attributes. + */ +class MethVisAnnotsDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #11; // #1 + class #12; // #2 + class #13; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "Signature"; // #7 + Utf8 "<T:Ljava/lang/Object;>Ljava/lang/Object;"; // #8 + Utf8 "RuntimeVisibleAnnotations"; // #9 + Utf8 "LMethodVisAnnotsDupI;"; // #10 + NameAndType #4 #5; // #11 + Utf8 "MethVisAnnotsDup"; // #12 + Utf8 "java/lang/Object"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #14 #15; // #16 + class #19; // #17 + Method #17 #16; // #18 + Utf8 "MethVisAnnotsDupChecker"; // #19 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + ; + + Attr(#9) { // RuntimeVisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeVisibleAnnotations + // wrong: + ; + Attr(#9) { // RuntimeVisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeVisibleAnnotations + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80012AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#7) { // Signature + #8; + } // end Signature + ; + Attr(#9) { // RuntimeVisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeVisibleAnnotations + } // Attributes + +} // end class + + + +/* + * This test contains a method with invalid duplicate + * RuntimeVisibleParameterAnnotations attributes. + */ +class MethVisParamAnnotsDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #16; // #1 + Method #17 #18; // #2 + class #19; // #3 + class #20; // #4 + Utf8 "<init>"; // #5 + Utf8 "()V"; // #6 + Utf8 "Code"; // #7 + Utf8 "m"; // #8 + Utf8 "()I"; // #9 + Utf8 "Signature"; // #10 + Utf8 "<T:Ljava/lang/Object;>()I"; // #11 + Utf8 "RuntimeVisibleParameterAnnotations"; // #12 + Utf8 "LMethVisParamAnnotsI;"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #5 #6; // #16 + class #21; // #17 + NameAndType #14 #15; // #18 + Utf8 "MethVisParamAnnotsDup"; // #19 + Utf8 "java/lang/Object"; // #20 + Utf8 "MethVisParamAnnotsDupChecker"; // #21 + } // Constant Pool + + 0x0021; // access + #3;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #5; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0001; // access + #8; // name_cpx + #9; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x03AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + ; + Attr(#10) { // Signature + #11; + } // end Signature + ; + Attr(#12) { // RuntimeVisibleParameterAnnotations + 0x0001010000000D00; + 0x00; + } // end RuntimeVisibleParameterAnnotations +// wrong: + ; + Attr(#12) { // RuntimeVisibleParameterAnnotations + 0x0001010000000D00; + 0x00; + } // end RuntimeVisibleParameterAnnotations +// end wrong + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80002AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + } // Attributes +} // end class + + + +/* + * This test contains a method with invalid duplicate SourceDebugExtension + * attributes. + */ +class SrcDbgExtDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #11; // #1 + class #12; // #2 + class #13; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "Signature"; // #7 + Utf8 "<T:Ljava/lang/Object;>Ljava/lang/Object;"; // #8 + Utf8 "SourceDebugExtension"; // #9 + Utf8 "LSrcDbgExtDupI;"; // #10 + NameAndType #4 #5; // #11 + Utf8 "SrcDbgExtDup"; // #12 + Utf8 "java/lang/Object"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #14 #15; // #16 + class #19; // #17 + Method #17 #16; // #18 + Utf8 "SrcDbgExt_dupChecker"; // #19 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80012AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#7) { // Signature + #8; + } // end Signature + ; + Attr(#9) { // SourceDebugExtension + [] { // debug_extensions + { // type debug_extension + []b { // type_path + } + } // type debug_extension + } // type debug_extensions + } // end SourceDebugExtension +// wrong: + ; + Attr(#9) { // SourceDebugExtension + [] { // debug_extensions + { // type debug_extension + []b { // type_path + } + } // type debug_extension + } // type debug_extensions + } // end SourceDebugExtension +// end wrong + } // Attributes + +} // end class diff --git a/hotspot/test/runtime/duplAttributes/DuplAttributesTest.java b/hotspot/test/runtime/duplAttributes/DuplAttributesTest.java new file mode 100644 index 00000000000..8b5235ebc01 --- /dev/null +++ b/hotspot/test/runtime/duplAttributes/DuplAttributesTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @bug 8040292 + * @library /testlibrary + * @summary Throw exceptions when duplicate attributes are detected. + * @run main DuplAttributesTest + */ + +import java.io.File; +import com.oracle.java.testlibrary.*; + +public class DuplAttributesTest { + + static final String testsrc = System.getProperty("test.src"); + + public static void runTest(String test, String result) throws Throwable { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-cp", testsrc + File.separator + "test.jar", test); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("java.lang.ClassFormatError: Multiple " + result); + } + + public static void main(String args[]) throws Throwable { + System.out.println("Regression test for bug 8040292"); + + runTest("ClassInvisAnnotsDup", "RuntimeInvisibleAnnotations"); + runTest("ClassVisAnnotsDup", "RuntimeVisibleAnnotations"); + runTest("SrcDbgExtDup", "SourceDebugExtension"); + + runTest("FieldInvisAnnotsDup", "RuntimeInvisibleAnnotations"); + runTest("FieldVisAnnotsDup", "RuntimeVisibleAnnotations"); + + runTest("AnnotationDefaultDup", "AnnotationDefault"); + runTest("MethInvisAnnotsDup", "RuntimeInvisibleAnnotations"); + runTest("MethVisAnnotsDup", "RuntimeVisibleAnnotations"); + runTest("MethInvisParamAnnotsDup", "RuntimeInvisibleParameterAnnotations"); + runTest("MethVisParamAnnotsDup", "RuntimeVisibleParameterAnnotations"); + } +} + diff --git a/hotspot/test/runtime/duplAttributes/test.jar b/hotspot/test/runtime/duplAttributes/test.jar new file mode 100644 index 0000000000000000000000000000000000000000..af160708f17c8d8f97e6dee6f3138bd73fe4d189 GIT binary patch literal 4478 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 literal 0 HcmV?d00001 From 24cbe2a44dae6890d03f550e285811beab21ae20 Mon Sep 17 00:00:00 2001 From: David Holmes <dholmes@openjdk.org> Date: Mon, 12 May 2014 20:20:19 -0400 Subject: [PATCH 070/157] 8032551: Remove UsePPCLWSYNC from globals.hpp Reviewed-by: lfoltan, zgu --- hotspot/src/share/vm/runtime/globals.hpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index ae4cc4e2149..9674e267960 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -525,13 +525,6 @@ class CommandLineFlags { product_pd(bool, UseMembar, \ "(Unstable) Issues membars on thread state transitions") \ \ - /* Temp PPC Flag to allow disabling the use of lwsync on ppc platforms \ - * that don't support it. This will be replaced by processor detection \ - * logic. \ - */ \ - product(bool, UsePPCLWSYNC, true, \ - "Use lwsync instruction if true, else use slower sync") \ - \ develop(bool, CleanChunkPoolAsync, falseInEmbedded, \ "Clean the chunk pool asynchronously") \ \ From db84d6b169f3bf12b2d4c51881adfff8953c720a Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov <serb@openjdk.org> Date: Tue, 13 May 2014 16:06:12 +0400 Subject: [PATCH 071/157] 8042007: Javadoc cleanup of javax.sound.sampled.spi package Reviewed-by: pchelko, bagiras --- .../sound/sampled/spi/AudioFileReader.java | 139 ++++++++------ .../sound/sampled/spi/AudioFileWriter.java | 106 +++++----- .../sampled/spi/FormatConversionProvider.java | 181 +++++++++--------- .../sound/sampled/spi/MixerProvider.java | 53 +++-- 4 files changed, 248 insertions(+), 231 deletions(-) diff --git a/jdk/src/share/classes/javax/sound/sampled/spi/AudioFileReader.java b/jdk/src/share/classes/javax/sound/sampled/spi/AudioFileReader.java index 7829a900bf2..cc476452126 100644 --- a/jdk/src/share/classes/javax/sound/sampled/spi/AudioFileReader.java +++ b/jdk/src/share/classes/javax/sound/sampled/spi/AudioFileReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.UnsupportedAudioFileException; /** - * Provider for audio file reading services. Classes providing concrete + * Provider for audio file reading services. Classes providing concrete * implementations can parse the format information from one or more types of * audio file, and can produce audio input streams from files of these types. * @@ -45,93 +45,106 @@ import javax.sound.sampled.UnsupportedAudioFileException; public abstract class AudioFileReader { /** - * Obtains the audio file format of the input stream provided. The stream must - * point to valid audio file data. In general, audio file readers may + * Obtains the audio file format of the input stream provided. The stream + * must point to valid audio file data. In general, audio file readers may * need to read some data from the stream before determining whether they - * support it. These parsers must - * be able to mark the stream, read enough data to determine whether they - * support the stream, and, if not, reset the stream's read pointer to its original - * position. If the input stream does not support this, this method may fail - * with an <code>IOException</code>. - * @param stream the input stream from which file format information should be - * extracted - * @return an <code>AudioFileFormat</code> object describing the audio file format - * @throws UnsupportedAudioFileException if the stream does not point to valid audio - * file data recognized by the system + * support it. These parsers must be able to mark the stream, read enough + * data to determine whether they support the stream, and, if not, reset the + * stream's read pointer to its original position. If the input stream does + * not support this, this method may fail with an {@code IOException}. + * + * @param stream the input stream from which file format information should + * be extracted + * @return an {@code AudioFileFormat} object describing the audio file + * format + * @throws UnsupportedAudioFileException if the stream does not point to + * valid audio file data recognized by the system * @throws IOException if an I/O exception occurs * @see InputStream#markSupported * @see InputStream#mark */ - public abstract AudioFileFormat getAudioFileFormat(InputStream stream) throws UnsupportedAudioFileException, IOException; + public abstract AudioFileFormat getAudioFileFormat(InputStream stream) + throws UnsupportedAudioFileException, IOException; /** - * Obtains the audio file format of the URL provided. The URL must - * point to valid audio file data. - * @param url the URL from which file format information should be - * extracted - * @return an <code>AudioFileFormat</code> object describing the audio file format - * @throws UnsupportedAudioFileException if the URL does not point to valid audio - * file data recognized by the system + * Obtains the audio file format of the URL provided. The URL must point to + * valid audio file data. + * + * @param url the URL from which file format information should be + * extracted + * @return an {@code AudioFileFormat} object describing the audio file + * format + * @throws UnsupportedAudioFileException if the URL does not point to valid + * audio file data recognized by the system * @throws IOException if an I/O exception occurs */ - public abstract AudioFileFormat getAudioFileFormat(URL url) throws UnsupportedAudioFileException, IOException; + public abstract AudioFileFormat getAudioFileFormat(URL url) + throws UnsupportedAudioFileException, IOException; /** - * Obtains the audio file format of the <code>File</code> provided. The <code>File</code> must - * point to valid audio file data. - * @param file the <code>File</code> from which file format information should be - * extracted - * @return an <code>AudioFileFormat</code> object describing the audio file format - * @throws UnsupportedAudioFileException if the <code>File</code> does not point to valid audio - * file data recognized by the system + * Obtains the audio file format of the {@code File} provided. + * The {@code File} must point to valid audio file data. + * + * @param file the {@code File} from which file format information + * should be extracted + * @return an {@code AudioFileFormat} object describing the audio file + * format + * @throws UnsupportedAudioFileException if the {@code File} does not point + * to valid audio file data recognized by the system * @throws IOException if an I/O exception occurs */ - public abstract AudioFileFormat getAudioFileFormat(File file) throws UnsupportedAudioFileException, IOException; + public abstract AudioFileFormat getAudioFileFormat(File file) + throws UnsupportedAudioFileException, IOException; /** - * Obtains an audio input stream from the input stream provided. The stream must - * point to valid audio file data. In general, audio file readers may + * Obtains an audio input stream from the input stream provided. The stream + * must point to valid audio file data. In general, audio file readers may * need to read some data from the stream before determining whether they - * support it. These parsers must - * be able to mark the stream, read enough data to determine whether they - * support the stream, and, if not, reset the stream's read pointer to its original - * position. If the input stream does not support this, this method may fail - * with an <code>IOException</code>. - * @param stream the input stream from which the <code>AudioInputStream</code> should be - * constructed - * @return an <code>AudioInputStream</code> object based on the audio file data contained - * in the input stream. - * @throws UnsupportedAudioFileException if the stream does not point to valid audio - * file data recognized by the system + * support it. These parsers must be able to mark the stream, read enough + * data to determine whether they support the stream, and, if not, reset the + * stream's read pointer to its original position. If the input stream does + * not support this, this method may fail with an {@code IOException}. + * + * @param stream the input stream from which the {@code AudioInputStream} + * should be constructed + * @return an {@code AudioInputStream} object based on the audio file data + * contained in the input stream. + * @throws UnsupportedAudioFileException if the stream does not point to + * valid audio file data recognized by the system * @throws IOException if an I/O exception occurs * @see InputStream#markSupported * @see InputStream#mark */ - public abstract AudioInputStream getAudioInputStream(InputStream stream) throws UnsupportedAudioFileException, IOException; + public abstract AudioInputStream getAudioInputStream(InputStream stream) + throws UnsupportedAudioFileException, IOException; /** - * Obtains an audio input stream from the URL provided. The URL must - * point to valid audio file data. - * @param url the URL for which the <code>AudioInputStream</code> should be - * constructed - * @return an <code>AudioInputStream</code> object based on the audio file data pointed - * to by the URL - * @throws UnsupportedAudioFileException if the URL does not point to valid audio - * file data recognized by the system + * Obtains an audio input stream from the URL provided. The URL must point + * to valid audio file data. + * + * @param url the URL for which the {@code AudioInputStream} should be + * constructed + * @return an {@code AudioInputStream} object based on the audio file data + * pointed to by the URL + * @throws UnsupportedAudioFileException if the URL does not point to valid + * audio file data recognized by the system * @throws IOException if an I/O exception occurs */ - public abstract AudioInputStream getAudioInputStream(URL url) throws UnsupportedAudioFileException, IOException; + public abstract AudioInputStream getAudioInputStream(URL url) + throws UnsupportedAudioFileException, IOException; /** - * Obtains an audio input stream from the <code>File</code> provided. The <code>File</code> must - * point to valid audio file data. - * @param file the <code>File</code> for which the <code>AudioInputStream</code> should be - * constructed - * @return an <code>AudioInputStream</code> object based on the audio file data pointed - * to by the File - * @throws UnsupportedAudioFileException if the <code>File</code> does not point to valid audio - * file data recognized by the system + * Obtains an audio input stream from the {@code File} provided. + * The {@code File} must point to valid audio file data. + * + * @param file the {@code File} for which the {@code AudioInputStream} + * should be constructed + * @return an {@code AudioInputStream} object based on the audio file data + * pointed to by the File + * @throws UnsupportedAudioFileException if the {@code File} does not point + * to valid audio file data recognized by the system * @throws IOException if an I/O exception occurs */ - public abstract AudioInputStream getAudioInputStream(File file) throws UnsupportedAudioFileException, IOException; + public abstract AudioInputStream getAudioInputStream(File file) + throws UnsupportedAudioFileException, IOException; } diff --git a/jdk/src/share/classes/javax/sound/sampled/spi/AudioFileWriter.java b/jdk/src/share/classes/javax/sound/sampled/spi/AudioFileWriter.java index 0207a3b7124..a4cc31bdf18 100644 --- a/jdk/src/share/classes/javax/sound/sampled/spi/AudioFileWriter.java +++ b/jdk/src/share/classes/javax/sound/sampled/spi/AudioFileWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,16 +26,15 @@ package javax.sound.sampled.spi; import java.io.File; -import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; -import javax.sound.sampled.AudioFileFormat; import javax.sound.sampled.AudioInputStream; +import static javax.sound.sampled.AudioFileFormat.Type; /** - * Provider for audio file writing services. Classes providing concrete + * Provider for audio file writing services. Classes providing concrete * implementations can write one or more types of audio file from an audio * stream. * @@ -47,22 +46,23 @@ public abstract class AudioFileWriter { /** * Obtains the file types for which file writing support is provided by this * audio file writer. - * @return array of file types. If no file types are supported, - * an array of length 0 is returned. + * + * @return array of file types. If no file types are supported, an array of + * length 0 is returned. */ - public abstract AudioFileFormat.Type[] getAudioFileTypes(); - + public abstract Type[] getAudioFileTypes(); /** - * Indicates whether file writing support for the specified file type is provided - * by this audio file writer. - * @param fileType the file type for which write capabilities are queried - * @return <code>true</code> if the file type is supported, - * otherwise <code>false</code> + * Indicates whether file writing support for the specified file type is + * provided by this audio file writer. + * + * @param fileType the file type for which write capabilities are queried + * @return {@code true} if the file type is supported, otherwise + * {@code false} */ - public boolean isFileTypeSupported(AudioFileFormat.Type fileType) { + public boolean isFileTypeSupported(Type fileType) { - AudioFileFormat.Type types[] = getAudioFileTypes(); + Type types[] = getAudioFileTypes(); for(int i=0; i<types.length; i++) { if( fileType.equals( types[i] ) ) { @@ -72,29 +72,29 @@ public abstract class AudioFileWriter { return false; } - /** * Obtains the file types that this audio file writer can write from the * audio input stream specified. - * @param stream the audio input stream for which audio file type support - * is queried - * @return array of file types. If no file types are supported, - * an array of length 0 is returned. + * + * @param stream the audio input stream for which audio file type support + * is queried + * @return array of file types. If no file types are supported, an array of + * length 0 is returned. */ - public abstract AudioFileFormat.Type[] getAudioFileTypes(AudioInputStream stream); - + public abstract Type[] getAudioFileTypes(AudioInputStream stream); /** - * Indicates whether an audio file of the type specified can be written - * from the audio input stream indicated. - * @param fileType file type for which write capabilities are queried - * @param stream for which file writing support is queried - * @return <code>true</code> if the file type is supported for this audio input stream, - * otherwise <code>false</code> + * Indicates whether an audio file of the type specified can be written from + * the audio input stream indicated. + * + * @param fileType file type for which write capabilities are queried + * @param stream for which file writing support is queried + * @return {@code true} if the file type is supported for this audio input + * stream, otherwise {@code false} */ - public boolean isFileTypeSupported(AudioFileFormat.Type fileType, AudioInputStream stream) { + public boolean isFileTypeSupported(Type fileType, AudioInputStream stream) { - AudioFileFormat.Type types[] = getAudioFileTypes( stream ); + Type types[] = getAudioFileTypes( stream ); for(int i=0; i<types.length; i++) { if( fileType.equals( types[i] ) ) { @@ -104,44 +104,44 @@ public abstract class AudioFileWriter { return false; } - /** * Writes a stream of bytes representing an audio file of the file type - * indicated to the output stream provided. Some file types require that + * indicated to the output stream provided. Some file types require that * the length be written into the file header, and cannot be written from - * start to finish unless the length is known in advance. An attempt - * to write such a file type will fail with an IOException if the length in - * the audio file format is - * {@link javax.sound.sampled.AudioSystem#NOT_SPECIFIED AudioSystem.NOT_SPECIFIED}. - * @param stream the audio input stream containing audio data to be - * written to the output stream - * @param fileType file type to be written to the output stream - * @param out stream to which the file data should be written + * start to finish unless the length is known in advance. An attempt to + * write such a file type will fail with an IOException if the length in the + * audio file format is {@link javax.sound.sampled.AudioSystem#NOT_SPECIFIED + * AudioSystem.NOT_SPECIFIED}. + * + * @param stream the audio input stream containing audio data to be written + * to the output stream + * @param fileType file type to be written to the output stream + * @param out stream to which the file data should be written * @return the number of bytes written to the output stream * @throws IOException if an I/O exception occurs - * @throws IllegalArgumentException if the file type is not supported by - * the system - * @see #isFileTypeSupported(AudioFileFormat.Type, AudioInputStream) + * @throws IllegalArgumentException if the file type is not supported by the + * system + * @see #isFileTypeSupported(Type, AudioInputStream) * @see #getAudioFileTypes */ - public abstract int write(AudioInputStream stream, AudioFileFormat.Type fileType, OutputStream out) throws IOException; - + public abstract int write(AudioInputStream stream, Type fileType, + OutputStream out) throws IOException; /** * Writes a stream of bytes representing an audio file of the file format * indicated to the external file provided. - * @param stream the audio input stream containing audio data to be - * written to the file - * @param fileType file type to be written to the file - * @param out external file to which the file data should be written + * + * @param stream the audio input stream containing audio data to be written + * to the file + * @param fileType file type to be written to the file + * @param out external file to which the file data should be written * @return the number of bytes written to the file * @throws IOException if an I/O exception occurs * @throws IllegalArgumentException if the file format is not supported by - * the system + * the system * @see #isFileTypeSupported * @see #getAudioFileTypes */ - public abstract int write(AudioInputStream stream, AudioFileFormat.Type fileType, File out) throws IOException; - - + public abstract int write(AudioInputStream stream, Type fileType, File out) + throws IOException; } diff --git a/jdk/src/share/classes/javax/sound/sampled/spi/FormatConversionProvider.java b/jdk/src/share/classes/javax/sound/sampled/spi/FormatConversionProvider.java index a27184a0b87..7693087c9d9 100644 --- a/jdk/src/share/classes/javax/sound/sampled/spi/FormatConversionProvider.java +++ b/jdk/src/share/classes/javax/sound/sampled/spi/FormatConversionProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,63 +25,62 @@ package javax.sound.sampled.spi; -import java.io.InputStream; - import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; +import static javax.sound.sampled.AudioFormat.Encoding; + /** - * A format conversion provider provides format conversion services - * from one or more input formats to one or more output formats. - * Converters include codecs, which encode and/or decode audio data, - * as well as transcoders, etc. Format converters provide methods for - * determining what conversions are supported and for obtaining an audio - * stream from which converted data can be read. + * A format conversion provider provides format conversion services from one or + * more input formats to one or more output formats. Converters include codecs, + * which encode and/or decode audio data, as well as transcoders, etc. Format + * converters provide methods for determining what conversions are supported and + * for obtaining an audio stream from which converted data can be read. * <p> - * The source format represents the format of the incoming - * audio data, which will be converted. + * The source format represents the format of the incoming audio data, which + * will be converted. * <p> - * The target format represents the format of the processed, converted - * audio data. This is the format of the data that can be read from - * the stream returned by one of the <code>getAudioInputStream</code> methods. + * The target format represents the format of the processed, converted audio + * data. This is the format of the data that can be read from the stream + * returned by one of the {@code getAudioInputStream} methods. * * @author Kara Kytle * @since 1.3 */ public abstract class FormatConversionProvider { - - // NEW METHODS - /** - * Obtains the set of source format encodings from which format - * conversion services are provided by this provider. + * Obtains the set of source format encodings from which format conversion + * services are provided by this provider. + * * @return array of source format encodings. If for some reason provider - * does not provide any conversion services, an array of length 0 is - * returned. + * does not provide any conversion services, an array of length 0 is + * returned. */ - public abstract AudioFormat.Encoding[] getSourceEncodings(); - + public abstract Encoding[] getSourceEncodings(); /** - * Obtains the set of target format encodings to which format - * conversion services are provided by this provider. + * Obtains the set of target format encodings to which format conversion + * services are provided by this provider. + * * @return array of target format encodings. If for some reason provider - * does not provide any conversion services, an array of length 0 is - * returned. + * does not provide any conversion services, an array of length 0 is + * returned. */ - public abstract AudioFormat.Encoding[] getTargetEncodings(); - + public abstract Encoding[] getTargetEncodings(); /** * Indicates whether the format converter supports conversion from the * specified source format encoding. - * @param sourceEncoding the source format encoding for which support is queried - * @return <code>true</code> if the encoding is supported, otherwise <code>false</code> + * + * @param sourceEncoding the source format encoding for which support is + * queried + * @return {@code true} if the encoding is supported, otherwise + * {@code false} */ - public boolean isSourceEncodingSupported(AudioFormat.Encoding sourceEncoding){ + public boolean isSourceEncodingSupported(Encoding sourceEncoding) { - AudioFormat.Encoding sourceEncodings[] = getSourceEncodings(); + Encoding sourceEncodings[] = getSourceEncodings(); for(int i=0; i<sourceEncodings.length; i++) { if( sourceEncoding.equals( sourceEncodings[i]) ) { @@ -91,16 +90,18 @@ public abstract class FormatConversionProvider { return false; } - /** * Indicates whether the format converter supports conversion to the * specified target format encoding. - * @param targetEncoding the target format encoding for which support is queried - * @return <code>true</code> if the encoding is supported, otherwise <code>false</code> + * + * @param targetEncoding the target format encoding for which support is + * queried + * @return {@code true} if the encoding is supported, otherwise + * {@code false} */ - public boolean isTargetEncodingSupported(AudioFormat.Encoding targetEncoding){ + public boolean isTargetEncodingSupported(Encoding targetEncoding) { - AudioFormat.Encoding targetEncodings[] = getTargetEncodings(); + Encoding targetEncodings[] = getTargetEncodings(); for(int i=0; i<targetEncodings.length; i++) { if( targetEncoding.equals( targetEncodings[i]) ) { @@ -110,28 +111,29 @@ public abstract class FormatConversionProvider { return false; } - /** - * Obtains the set of target format encodings supported by the format converter - * given a particular source format. - * If no target format encodings are supported for this source format, - * an array of length 0 is returned. - * @param sourceFormat format of the incoming data + * Obtains the set of target format encodings supported by the format + * converter given a particular source format. If no target format encodings + * are supported for this source format, an array of length 0 is returned. + * + * @param sourceFormat format of the incoming data * @return array of supported target format encodings. */ - public abstract AudioFormat.Encoding[] getTargetEncodings(AudioFormat sourceFormat); - + public abstract Encoding[] getTargetEncodings(AudioFormat sourceFormat); /** - * Indicates whether the format converter supports conversion to a particular encoding - * from a particular format. - * @param targetEncoding desired encoding of the outgoing data - * @param sourceFormat format of the incoming data - * @return <code>true</code> if the conversion is supported, otherwise <code>false</code> + * Indicates whether the format converter supports conversion to a + * particular encoding from a particular format. + * + * @param targetEncoding desired encoding of the outgoing data + * @param sourceFormat format of the incoming data + * @return {@code true} if the conversion is supported, otherwise + * {@code false} */ - public boolean isConversionSupported(AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat){ + public boolean isConversionSupported(Encoding targetEncoding, + AudioFormat sourceFormat) { - AudioFormat.Encoding targetEncodings[] = getTargetEncodings(sourceFormat); + Encoding targetEncodings[] = getTargetEncodings(sourceFormat); for(int i=0; i<targetEncodings.length; i++) { if( targetEncoding.equals( targetEncodings[i]) ) { @@ -141,27 +143,29 @@ public abstract class FormatConversionProvider { return false; } - /** - * Obtains the set of target formats with the encoding specified - * supported by the format converter - * If no target formats with the specified encoding are supported - * for this source format, an array of length 0 is returned. - * @param targetEncoding desired encoding of the stream after processing - * @param sourceFormat format of the incoming data + * Obtains the set of target formats with the encoding specified supported + * by the format converter If no target formats with the specified encoding + * are supported for this source format, an array of length 0 is returned. + * + * @param targetEncoding desired encoding of the stream after processing + * @param sourceFormat format of the incoming data * @return array of supported target formats. */ - public abstract AudioFormat[] getTargetFormats(AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat); - + public abstract AudioFormat[] getTargetFormats(Encoding targetEncoding, + AudioFormat sourceFormat); /** * Indicates whether the format converter supports conversion to one * particular format from another. - * @param targetFormat desired format of outgoing data - * @param sourceFormat format of the incoming data - * @return <code>true</code> if the conversion is supported, otherwise <code>false</code> + * + * @param targetFormat desired format of outgoing data + * @param sourceFormat format of the incoming data + * @return {@code true} if the conversion is supported, otherwise + * {@code false} */ - public boolean isConversionSupported(AudioFormat targetFormat, AudioFormat sourceFormat){ + public boolean isConversionSupported(AudioFormat targetFormat, + AudioFormat sourceFormat) { AudioFormat targetFormats[] = getTargetFormats( targetFormat.getEncoding(), sourceFormat ); @@ -173,28 +177,33 @@ public abstract class FormatConversionProvider { return false; } + /** + * Obtains an audio input stream with the specified encoding from the given + * audio input stream. + * + * @param targetEncoding desired encoding of the stream after processing + * @param sourceStream stream from which data to be processed should be + * read + * @return stream from which processed data with the specified target + * encoding may be read + * @throws IllegalArgumentException if the format combination supplied is + * not supported. + */ + public abstract AudioInputStream getAudioInputStream( + Encoding targetEncoding, AudioInputStream sourceStream); /** - * Obtains an audio input stream with the specified encoding from the given audio - * input stream. - * @param targetEncoding desired encoding of the stream after processing - * @param sourceStream stream from which data to be processed should be read - * @return stream from which processed data with the specified target encoding may be read + * Obtains an audio input stream with the specified format from the given + * audio input stream. + * + * @param targetFormat desired data format of the stream after processing + * @param sourceStream stream from which data to be processed should be + * read + * @return stream from which processed data with the specified format may be + * read * @throws IllegalArgumentException if the format combination supplied is - * not supported. + * not supported. */ - public abstract AudioInputStream getAudioInputStream(AudioFormat.Encoding targetEncoding, AudioInputStream sourceStream); - - - /** - * Obtains an audio input stream with the specified format from the given audio - * input stream. - * @param targetFormat desired data format of the stream after processing - * @param sourceStream stream from which data to be processed should be read - * @return stream from which processed data with the specified format may be read - * @throws IllegalArgumentException if the format combination supplied is - * not supported. - */ - public abstract AudioInputStream getAudioInputStream(AudioFormat targetFormat, AudioInputStream sourceStream); - + public abstract AudioInputStream getAudioInputStream( + AudioFormat targetFormat, AudioInputStream sourceStream); } diff --git a/jdk/src/share/classes/javax/sound/sampled/spi/MixerProvider.java b/jdk/src/share/classes/javax/sound/sampled/spi/MixerProvider.java index d1167c0b8a6..638de86b320 100644 --- a/jdk/src/share/classes/javax/sound/sampled/spi/MixerProvider.java +++ b/jdk/src/share/classes/javax/sound/sampled/spi/MixerProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,28 +28,27 @@ package javax.sound.sampled.spi; import javax.sound.sampled.Mixer; /** - * A provider or factory for a particular mixer type. - * This mechanism allows the implementation to determine - * how resources are managed in creation / management of - * a mixer. + * A provider or factory for a particular mixer type. This mechanism allows the + * implementation to determine how resources are managed in creation / + * management of a mixer. * * @author Kara Kytle * @since 1.3 */ public abstract class MixerProvider { - /** * Indicates whether the mixer provider supports the mixer represented by * the specified mixer info object. * <p> - * The full set of mixer info objects that represent the mixers supported - * by this {@code MixerProvider} may be obtained - * through the {@code getMixerInfo} method. + * The full set of mixer info objects that represent the mixers supported by + * this {@code MixerProvider} may be obtained through the + * {@code getMixerInfo} method. * - * @param info an info object that describes the mixer for which support is queried - * @return {@code true} if the specified mixer is supported, - * otherwise {@code false} + * @param info an info object that describes the mixer for which support is + * queried + * @return {@code true} if the specified mixer is supported, otherwise + * {@code false} * @see #getMixerInfo() */ public boolean isMixerSupported(Mixer.Info info) { @@ -64,38 +63,34 @@ public abstract class MixerProvider { return false; } - /** - * Obtains the set of info objects representing the mixer - * or mixers provided by this MixerProvider. + * Obtains the set of info objects representing the mixer or mixers provided + * by this MixerProvider. * <p> - * The {@code isMixerSupported} method returns {@code true} - * for all the info objects returned by this method. - * The corresponding mixer instances for the info objects - * are returned by the {@code getMixer} method. + * The {@code isMixerSupported} method returns {@code true} for all the info + * objects returned by this method. The corresponding mixer instances for + * the info objects are returned by the {@code getMixer} method. * * @return a set of mixer info objects - * @see #getMixer(javax.sound.sampled.Mixer.Info) getMixer(Mixer.Info) - * @see #isMixerSupported(javax.sound.sampled.Mixer.Info) isMixerSupported(Mixer.Info) + * @see #getMixer(Mixer.Info) + * @see #isMixerSupported(Mixer.Info) */ public abstract Mixer.Info[] getMixerInfo(); - /** * Obtains an instance of the mixer represented by the info object. * <p> * The full set of the mixer info objects that represent the mixers - * supported by this {@code MixerProvider} may be obtained - * through the {@code getMixerInfo} method. - * Use the {@code isMixerSupported} method to test whether - * this {@code MixerProvider} supports a particular mixer. + * supported by this {@code MixerProvider} may be obtained through the + * {@code getMixerInfo} method. Use the {@code isMixerSupported} method to + * test whether this {@code MixerProvider} supports a particular mixer. * - * @param info an info object that describes the desired mixer + * @param info an info object that describes the desired mixer * @return mixer instance * @throws IllegalArgumentException if the info object specified does not - * match the info object for a mixer supported by this MixerProvider. + * match the info object for a mixer supported by this MixerProvider * @see #getMixerInfo() - * @see #isMixerSupported(javax.sound.sampled.Mixer.Info) isMixerSupported(Mixer.Info) + * @see #isMixerSupported(Mixer.Info) */ public abstract Mixer getMixer(Mixer.Info info); } From a89eab1dc79148333e7a713f9f4c48b5188591c6 Mon Sep 17 00:00:00 2001 From: Andrew Brygin <bae@openjdk.org> Date: Wed, 14 May 2014 18:19:14 +0400 Subject: [PATCH 072/157] 6945174: IndexOutOfBoundsException calling ImageIO.read() on malformed PNG Reviewed-by: prr, serb --- .../imageio/plugins/png/PNGImageReader.java | 8 +- .../plugins/png/ReadMalformedPngTest.java | 160 ++++++++++++++++++ 2 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 jdk/test/javax/imageio/plugins/png/ReadMalformedPngTest.java diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java index 13f2d9349d0..3b2a081d860 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java @@ -664,6 +664,12 @@ public class PNGImageReader extends ImageReader { try { while (true) { int chunkLength = stream.readInt(); + + // verify the chunk length first + if (chunkLength < 0 || chunkLength + 4 < 0) { + throw new IIOException("Invalid chunk length " + chunkLength); + } + int chunkType = stream.readInt(); if (chunkType == IDAT_TYPE) { @@ -692,7 +698,7 @@ public class PNGImageReader extends ImageReader { // verify the chunk length if (chunkLength < 0) { - throw new IIOException("Invalid chunk lenght " + chunkLength); + throw new IIOException("Invalid chunk length " + chunkLength); }; try { diff --git a/jdk/test/javax/imageio/plugins/png/ReadMalformedPngTest.java b/jdk/test/javax/imageio/plugins/png/ReadMalformedPngTest.java new file mode 100644 index 00000000000..7aadebc627b --- /dev/null +++ b/jdk/test/javax/imageio/plugins/png/ReadMalformedPngTest.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @bug 6945174 + * @summary Test verifies that PNG image readr throw correct exception + * if image contains a chunk with incorrect length. + * @run main ReadMalformedPngTest + */ + +import java.awt.Color; +import java.awt.GradientPaint; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import javax.imageio.IIOException; +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.metadata.IIOMetadataNode; +import javax.imageio.stream.ImageOutputStream; +import org.w3c.dom.Node; + +public class ReadMalformedPngTest { + + public static void main(String[] args) throws IOException { + ByteArrayInputStream bais = new ByteArrayInputStream(createTestPng()); + + IIOException expected = null; + try { + ImageIO.read(bais); + } catch (IIOException e) { + expected = e; + } catch (Throwable e) { + throw new RuntimeException("Test failed!", e); + } + + if (expected == null) { + throw new RuntimeException("Test failed."); + } + + System.out.println("Test passed."); + } + + private static byte[] createTestPng() throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + BufferedImage img = createTestImage(); + + try { + ImageOutputStream ios = ImageIO.createImageOutputStream(baos); + + ImageWriter w = ImageIO.getImageWritersByFormatName("PNG").next(); + + w.setOutput(ios); + + ImageWriteParam p = w.getDefaultWriteParam(); + + ImageTypeSpecifier t = ImageTypeSpecifier.createFromRenderedImage(img); + + IIOMetadata m = w.getDefaultImageMetadata(t, p); + + String nativeMetadataFormat = m.getNativeMetadataFormatName(); + + Node root = m.getAsTree(nativeMetadataFormat); + + IIOMetadataNode textEntry = new IIOMetadataNode("tEXtEntry"); + textEntry.setAttribute("keyword", "comment"); + textEntry.setAttribute("value", "This is a test image for JDK-6945174"); + + IIOMetadataNode text = new IIOMetadataNode("tEXt"); + text.appendChild(textEntry); + + root.appendChild(text); + + m.mergeTree(nativeMetadataFormat, root); + + IIOImage iio_img = new IIOImage(img, null, m); + + w.write(iio_img); + + w.dispose(); + ios.flush(); + ios.close(); + } catch (IOException e) { + throw new RuntimeException("Test failed.", e); + } + + baos.flush(); + + byte[] data = baos.toByteArray(); + + adjustCommentLength(Integer.MAX_VALUE + 0x1000, data); + + return data; + } + + private static void adjustCommentLength(int v, byte[] data) { + final int pos = getCommentPos(data); + data[pos + 3] = (byte) (v & 0xFF); + v = v >> 8; + data[pos + 2] = (byte) (v & 0xFF); + v = v >> 8; + data[pos + 1] = (byte) (v & 0xFF); + v = v >> 8; + data[pos + 0] = (byte) (v & 0xFF); + } + + private static int getCommentPos(byte[] d) { + int p = 8; + while (p + 8 < d.length) { + if (d[p + 4] == (byte) 0x74 && d[p + 5] == (byte) 0x45 && + d[p + 6] == (byte) 0x58 && d[p + 7] == (byte) 0x74) + { + return p; + } + p++; + } + throw new RuntimeException("Test chunk was not found!"); + } + + private static BufferedImage createTestImage() { + final int w = 128; + final int h = 128; + + BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR); + Graphics2D g = img.createGraphics(); + g.setPaint(new GradientPaint(0, 0, Color.blue, + w, h, Color.red)); + g.fillRect(0, 0, w, h); + g.dispose(); + return img; + } +} From 9aa0cef64a155a41e673b1e6ed4c671b5e60eb53 Mon Sep 17 00:00:00 2001 From: Oleg Pekhovskiy <bagiras@openjdk.org> Date: Thu, 15 May 2014 20:09:38 +0400 Subject: [PATCH 073/157] 8014755: [TEST_BUG] frames didn't closed after execution some awt/dnd/ tests Reviewed-by: serb, pchelko --- .../DragInterceptorAppletTest.html | 48 ++ .../DragInterceptorAppletTest.java | 154 ++++++ .../DragInterceptorFrame.java | 128 +++++ .../InterprocessMessages.java | 32 ++ .../SourceFrame.java | 68 +++ .../InterJVMGetDropSuccessTest.html | 43 ++ .../InterJVMGetDropSuccessTest.java | 499 ++++++++++++++++++ .../NoFormatsCrashTest.html | 45 ++ .../NoFormatsCrashTest.java | 488 +++++++++++++++++ .../process/ProcessCommunicator.java | 62 ++- 10 files changed, 1545 insertions(+), 22 deletions(-) create mode 100644 jdk/test/java/awt/dnd/DragInterceptorAppletTest/DragInterceptorAppletTest.html create mode 100644 jdk/test/java/awt/dnd/DragInterceptorAppletTest/DragInterceptorAppletTest.java create mode 100644 jdk/test/java/awt/dnd/DragInterceptorAppletTest/DragInterceptorFrame.java create mode 100644 jdk/test/java/awt/dnd/DragInterceptorAppletTest/InterprocessMessages.java create mode 100644 jdk/test/java/awt/dnd/DragInterceptorAppletTest/SourceFrame.java create mode 100644 jdk/test/java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.html create mode 100644 jdk/test/java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.java create mode 100644 jdk/test/java/awt/dnd/NoFormatsCrashTest/NoFormatsCrashTest.html create mode 100644 jdk/test/java/awt/dnd/NoFormatsCrashTest/NoFormatsCrashTest.java diff --git a/jdk/test/java/awt/dnd/DragInterceptorAppletTest/DragInterceptorAppletTest.html b/jdk/test/java/awt/dnd/DragInterceptorAppletTest/DragInterceptorAppletTest.html new file mode 100644 index 00000000000..7d4a3a5a774 --- /dev/null +++ b/jdk/test/java/awt/dnd/DragInterceptorAppletTest/DragInterceptorAppletTest.html @@ -0,0 +1,48 @@ +<!-- + Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + This code is free software; you can redistribute it and/or modify it + 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. +--> + +<html> +<!-- + @test + @bug 6887703 + @summary Unsigned applet can retrieve the dragged information before drop action occurs + @author : area=dnd + @library ../../regtesthelpers + @library ../../regtesthelpers/process + @build Util + @build ProcessResults ProcessCommunicator + @run applet/othervm DragInterceptorAppletTest.html + +--> +<head> +<title> Unsigned applet can retrieve the dragged information before drop action occurs </title> +</head> +<body> + +<h1>DragInterceptorAppletTest<br>Bug ID: 6887703</h1> + +<p> This is an AUTOMATIC test, simply wait for completion </p> + +<APPLET CODE="DragInterceptorAppletTest.class" WIDTH=200 HEIGHT=200></APPLET> +</body> +</html> diff --git a/jdk/test/java/awt/dnd/DragInterceptorAppletTest/DragInterceptorAppletTest.java b/jdk/test/java/awt/dnd/DragInterceptorAppletTest/DragInterceptorAppletTest.java new file mode 100644 index 00000000000..5f70e2de35b --- /dev/null +++ b/jdk/test/java/awt/dnd/DragInterceptorAppletTest/DragInterceptorAppletTest.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + @bug 6887703 + @summary Unsigned applet can retrieve the dragged information before drop action occurs + @author : area=dnd + @run applet DragInterceptorAppletTest.html +*/ + +/** + * DragInterceptorAppletTest.java + * + * summary: Unsigned applet can retrieve the dragged information before drop action occurs + */ + +import static java.lang.Thread.sleep; + +import test.java.awt.regtesthelpers.process.ProcessCommunicator; +import test.java.awt.regtesthelpers.process.ProcessResults; +import test.java.awt.regtesthelpers.Util; +import java.applet.Applet; +import java.awt.*; +import java.awt.event.InputEvent; + +public class DragInterceptorAppletTest extends Applet { + + public void init() { + setLayout(new BorderLayout()); + }//End init() + + public void start() { + + SourceFrame sourceFrame = new SourceFrame(); + + Util.waitForIdle(null); + + String [] args = new String [] { + String.valueOf(sourceFrame.getNextLocationX()), + String.valueOf(sourceFrame.getNextLocationY()), + String.valueOf(sourceFrame.getDragSourcePointX()), + String.valueOf(sourceFrame.getDragSourcePointY()), + }; + String classpath = System.getProperty("java.class.path"); + ProcessResults processResults = + ProcessCommunicator.executeChildProcess(this.getClass(),classpath,args); + + verifyTestResults(processResults); + + }// start() + + private static void verifyTestResults(ProcessResults processResults) { + + switch (processResults.getExitValue()) { + case InterprocessMessages.DATA_WAS_INTERCEPTED_AND_EXCEPTION_HANDLER_WAS_NOT_TRIGGERED: + processResults.printProcessErrorOutput(System.err); + throw new RuntimeException("TEST IS FAILED: Target applet can intercept data " + + "without a clipboard permission and an exception handler was not triggered."); + //Unreachable... + + case InterprocessMessages.DATA_WAS_INTERCEPTED: + processResults.printProcessErrorOutput(System.err); + throw new RuntimeException("TEST IS FAILED: Target applet can intercept data " + + "without a clipboard permission"); + //Unreachable... + + case InterprocessMessages.EXCEPTION_HANDLER_WAS_NOT_TRIGGERED: + processResults.printProcessErrorOutput(System.err); + throw new RuntimeException("TEST IS FAILED: An exception handler was not triggered."); + //Unreachable... + + } + + // The child process throws an exception. do not look at the stderr. + processResults.verifyStdErr(System.err); + processResults.verifyProcessExitValue(System.err); + processResults.printProcessStandartOutput(System.out); + } + + //We cannot make an instance of the applet without the default constructor + public DragInterceptorAppletTest() { + super(); + } + + //We need in this constructor to pass frame position between JVMs + public DragInterceptorAppletTest(Point targetFrameLocation, Point dragSourcePoint) + throws InterruptedException + { + DragInterceptorFrame targetFrame = new DragInterceptorFrame(targetFrameLocation); + + Util.waitForIdle(null); + + final Robot robot = Util.createRobot(); + + robot.mouseMove((int)dragSourcePoint.getX(),(int)dragSourcePoint.getY()); + sleep(100); + robot.mousePress(InputEvent.BUTTON1_MASK); + sleep(100); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + sleep(100); + + Util.drag(robot, dragSourcePoint, targetFrame.getDropTargetPoint(), + InputEvent.BUTTON1_MASK); + + sleep(2000); + ProcessCommunicator.destroyProcess(); + } + + enum InterprocessArguments { + TARGET_FRAME_X_POSITION_ARGUMENT, + TARGET_FRAME_Y_POSITION_ARGUMENT, + DRAG_SOURCE_POINT_X_ARGUMENT, + DRAG_SOURCE_POINT_Y_ARGUMENT; + + int extract (String [] args) { + return Integer.parseInt(args[this.ordinal()]); + } + } + + public static void main (String [] args) { + Point dragSourcePoint = new Point(InterprocessArguments.DRAG_SOURCE_POINT_X_ARGUMENT.extract(args), + InterprocessArguments.DRAG_SOURCE_POINT_Y_ARGUMENT.extract(args)); + Point targetFrameLocation = new Point(InterprocessArguments.TARGET_FRAME_X_POSITION_ARGUMENT.extract(args), + InterprocessArguments.TARGET_FRAME_Y_POSITION_ARGUMENT.extract(args)); + try { + new DragInterceptorAppletTest(targetFrameLocation, dragSourcePoint); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + +}// class DragInterceptorAppletTest diff --git a/jdk/test/java/awt/dnd/DragInterceptorAppletTest/DragInterceptorFrame.java b/jdk/test/java/awt/dnd/DragInterceptorAppletTest/DragInterceptorFrame.java new file mode 100644 index 00000000000..69d4a014ba9 --- /dev/null +++ b/jdk/test/java/awt/dnd/DragInterceptorAppletTest/DragInterceptorFrame.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import java.awt.*; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.dnd.*; +import java.io.IOException; +import java.security.Permission; +import java.security.AccessControlException; + +class DragInterceptorFrame extends Frame implements DropTargetListener { + + private static int exitMessage = InterprocessMessages.TEST_PASSED; + private static boolean dataIsAccessible = false; + private static boolean exceptionHasBeenThrown = false; + + DragInterceptorFrame(Point location) { + System.setSecurityManager(new ClipboardDefender()); + initGUI(location); + setDropTarget(new DropTarget(this, DnDConstants.ACTION_COPY, + this)); + } + + private void initGUI(Point location) { + this.setLocation(location); + this.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + DragInterceptorFrame.this.dispose(); + } + }); + setSize (200, 200); + this.setVisible(true); + } + + public void dragEnter(DropTargetDragEvent dtde) { + // We want to set the exception handler on EDT + Thread.currentThread().setUncaughtExceptionHandler ( + new Thread.UncaughtExceptionHandler() { + public void uncaughtException(Thread t, Throwable e) { + exceptionHasBeenThrown = true; + } + } + ); + examineTransferable(dtde); + } + + public void dragOver(DropTargetDragEvent dtde) { + examineTransferable(dtde); + } + + public void dropActionChanged(DropTargetDragEvent dtde) { + examineTransferable(dtde); + } + + public void dragExit(DropTargetEvent dte) {} + + public void drop(DropTargetDropEvent dtde) { + + if (dataIsAccessible && !exceptionHasBeenThrown) { + exitMessage = InterprocessMessages.DATA_WAS_INTERCEPTED_AND_EXCEPTION_HANDLER_WAS_NOT_TRIGGERED; + } else if (dataIsAccessible) { + exitMessage = InterprocessMessages.DATA_WAS_INTERCEPTED; + } else if (!exceptionHasBeenThrown) { + exitMessage = InterprocessMessages.EXCEPTION_HANDLER_WAS_NOT_TRIGGERED; + } + + // This returns the diagnostic code from the child VM + System.exit(exitMessage); + } + + Point getDropTargetPoint() { + return new Point((int)getLocationOnScreen().getX()+(getWidth()/2), + (int)getLocationOnScreen().getY()+(getHeight()/2)); + } + + private void examineTransferable(DropTargetDragEvent dtde) { + if (dtde.getCurrentDataFlavorsAsList().contains(DataFlavor.stringFlavor)) { + dtde.acceptDrag(DnDConstants.ACTION_COPY); + try{ + if (null != dtde.getTransferable().getTransferData(DataFlavor.stringFlavor)) { + dataIsAccessible = true; + } + } catch (IOException e) { + e.printStackTrace(); + exitMessage = InterprocessMessages.UNEXPECTED_IO_EXCEPTION; + } catch (UnsupportedFlavorException e) { + e.printStackTrace(); + exitMessage = InterprocessMessages.UNEXPECTED_UNSUPPORTED_FLAVOR_EXCEPTION; + } + } + } + + static class ClipboardDefender extends SecurityManager { + public void checkPermission(Permission p) { + if (p instanceof java.awt.AWTPermission && + p.getName().equals("accessClipboard")) { + throw new AccessControlException("access denied "); + } + } + } + + public static void main(String[] args) { + new DragInterceptorFrame(new Point(200,200)); + } +} diff --git a/jdk/test/java/awt/dnd/DragInterceptorAppletTest/InterprocessMessages.java b/jdk/test/java/awt/dnd/DragInterceptorAppletTest/InterprocessMessages.java new file mode 100644 index 00000000000..6506565cd05 --- /dev/null +++ b/jdk/test/java/awt/dnd/DragInterceptorAppletTest/InterprocessMessages.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +public interface InterprocessMessages { + final static int TEST_PASSED = 0; + final static int DATA_WAS_INTERCEPTED = 212; + final static int EXCEPTION_HANDLER_WAS_NOT_TRIGGERED = 213; + final static int DATA_WAS_INTERCEPTED_AND_EXCEPTION_HANDLER_WAS_NOT_TRIGGERED = 214; + + final static int UNEXPECTED_IO_EXCEPTION = 400; + final static int UNEXPECTED_UNSUPPORTED_FLAVOR_EXCEPTION = 401; +} diff --git a/jdk/test/java/awt/dnd/DragInterceptorAppletTest/SourceFrame.java b/jdk/test/java/awt/dnd/DragInterceptorAppletTest/SourceFrame.java new file mode 100644 index 00000000000..7a7c833b91a --- /dev/null +++ b/jdk/test/java/awt/dnd/DragInterceptorAppletTest/SourceFrame.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +import test.java.awt.regtesthelpers.Util; + +import java.awt.*; +import java.awt.datatransfer.StringSelection; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; + +class SourceFrame extends Frame implements DragGestureListener { + + SourceFrame() { + super("Source File List Frame"); + initGUI(); + new DragSource().createDefaultDragGestureRecognizer(this, + DnDConstants.ACTION_COPY,this); + } + + private void initGUI() { + this.addWindowListener(Util.getClosingWindowAdapter()); + this.setLocation(300,250); + this.setSize(200,200); + this.setVisible(true); + } + + int getNextLocationX() { + return getX()+getWidth(); + } + + int getNextLocationY() { + return getY(); + } + + int getDragSourcePointX() { + return (int)getLocationOnScreen().getX()+(getWidth()/2); + } + + int getDragSourcePointY() { + return (int)getLocationOnScreen().getY()+ (getHeight()/2); + } + + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, new StringSelection("A TEXT")); + } +} diff --git a/jdk/test/java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.html b/jdk/test/java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.html new file mode 100644 index 00000000000..2b3aa7aa60c --- /dev/null +++ b/jdk/test/java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.html @@ -0,0 +1,43 @@ +<!-- + Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + This code is free software; you can redistribute it and/or modify it + 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. +--> + +<html> +<!-- + @test + @bug 4658741 + @summary verifies that getDropSuccess() returns correct value for inter-JVM DnD + @author das@sparc.spb.su area=dnd + @run applet InterJVMGetDropSuccessTest.html + --> +<head> +<title> </title> +</head> +<body> + +<h1>InterJVMGetDropSuccessTest<br>Bug ID: 4658741</h1> + +<p> This is an AUTOMATIC test, simply wait for completion </p> + +<APPLET CODE="InterJVMGetDropSuccessTest.class" WIDTH=200 HEIGHT=200></APPLET> +</body> +</html> diff --git a/jdk/test/java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.java b/jdk/test/java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.java new file mode 100644 index 00000000000..9307fa26df5 --- /dev/null +++ b/jdk/test/java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.java @@ -0,0 +1,499 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + @bug 4658741 + @summary verifies that getDropSuccess() returns correct value for inter-JVM DnD + @author das@sparc.spb.su area=dnd + @run applet InterJVMGetDropSuccessTest.html +*/ + +// Note there is no @ in front of test above. This is so that the +// harness will not mistake this file as a test file. It should +// only see the html file as a test file. (the harness runs all +// valid test files, so it would run this test twice if this file +// were valid as well as the html file.) +// Also, note the area= after Your Name in the author tag. Here, you +// should put which functional area the test falls in. See the +// AWT-core home page -> test areas and/or -> AWT team for a list of +// areas. +// Note also the 'InterJVMGetDropSuccessTest.html' in the run tag. This should +// be changed to the name of the test. + + +/** + * InterJVMGetDropSuccessTest.java + * + * summary: verifies that getDropSuccess() returns correct value for inter-JVM DnD + */ + +import java.applet.Applet; +import java.awt.*; +import java.awt.datatransfer.*; +import java.awt.dnd.*; +import java.awt.event.*; +import java.io.*; +import javax.swing.*; + + +//Automated tests should run as applet tests if possible because they +// get their environments cleaned up, including AWT threads, any +// test created threads, and any system resources used by the test +// such as file descriptors. (This is normally not a problem as +// main tests usually run in a separate VM, however on some platforms +// such as the Mac, separate VMs are not possible and non-applet +// tests will cause problems). Also, you don't have to worry about +// synchronisation stuff in Applet tests they way you do in main +// tests... + + +public class InterJVMGetDropSuccessTest extends Applet { + + private int returnCode = Util.CODE_NOT_RETURNED; + private boolean successCodes[] = { true, false }; + private int dropCount = 0; + + final Frame frame = new Frame("Target Frame"); + + final DropTargetListener dropTargetListener = new DropTargetAdapter() { + public void drop(DropTargetDropEvent dtde) { + dtde.acceptDrop(DnDConstants.ACTION_COPY); + dtde.dropComplete(successCodes[dropCount]); + dropCount++; + } + }; + final DropTarget dropTarget = new DropTarget(frame, dropTargetListener); + + public void init() { + //Create instructions for the user here, as well as set up + // the environment -- set the layout manager, add buttons, + // etc. + + String[] instructions = + { + "This is an AUTOMATIC test", + "simply wait until it is done" + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + frame.setTitle("Test frame"); + frame.setBounds(100, 100, 150, 150); + } // init() + + public void start() { + + frame.setVisible(true); + + try { + Thread.sleep(Util.FRAME_ACTIVATION_TIMEOUT); + + Point p = frame.getLocationOnScreen(); + Dimension d = frame.getSize(); + + String javaPath = System.getProperty("java.home", ""); + String command = javaPath + File.separator + "bin" + + File.separator + "java -cp " + System.getProperty("test.classes", ".") + + " Child " + + p.x + " " + p.y + " " + d.width + " " + d.height; + + Process process = Runtime.getRuntime().exec(command); + returnCode = process.waitFor(); + + InputStream errorStream = process.getErrorStream(); + int count = errorStream.available(); + if (count > 0) { + byte[] b = new byte[count]; + errorStream.read(b); + System.err.println("========= Child VM System.err ========"); + System.err.print(new String(b)); + System.err.println("======================================"); + } + + InputStream outputStream = process.getInputStream(); + count = outputStream.available(); + if (count > 0) { + byte[] b = new byte[count]; + outputStream.read(b); + System.err.println("========= Child VM System.out ========"); + System.err.print(new String(b)); + System.err.println("======================================"); + } + } catch (Throwable e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + switch (returnCode) { + case Util.CODE_NOT_RETURNED: + throw new RuntimeException("Child VM: failed to start"); + case Util.CODE_FAILURE: + throw new RuntimeException("Child VM: abnormal termination"); + default: + if (dropCount == 2) { + int expectedRetCode = 0; + if (successCodes[0]) { + expectedRetCode |= Util.CODE_FIRST_SUCCESS; + } + if (successCodes[1]) { + expectedRetCode |= Util.CODE_SECOND_SUCCESS; + } + if (expectedRetCode != returnCode) { + throw new RuntimeException("The test failed. Expected:" + + expectedRetCode + ". Returned:" + + returnCode); + } + } + break; + } + } // start() +} // class InterJVMGetDropSuccessTest + +final class Util implements AWTEventListener { + public static final int CODE_NOT_RETURNED = -1; + public static final int CODE_FIRST_SUCCESS = 0x2; + public static final int CODE_SECOND_SUCCESS = 0x2; + public static final int CODE_FAILURE = 0x1; + + public static final int FRAME_ACTIVATION_TIMEOUT = 3000; + + static final Object SYNC_LOCK = new Object(); + static final int MOUSE_RELEASE_TIMEOUT = 1000; + + static final Util theInstance = new Util(); + + static { + Toolkit.getDefaultToolkit().addAWTEventListener(theInstance, AWTEvent.MOUSE_EVENT_MASK); + } + + public static Point getCenterLocationOnScreen(Component c) { + Point p = c.getLocationOnScreen(); + Dimension d = c.getSize(); + p.translate(d.width / 2, d.height / 2); + return p; + } + + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } + + private Component clickedComponent = null; + + private void reset() { + clickedComponent = null; + } + + public void eventDispatched(AWTEvent e) { + if (e.getID() == MouseEvent.MOUSE_RELEASED) { + clickedComponent = (Component)e.getSource(); + synchronized (SYNC_LOCK) { + SYNC_LOCK.notifyAll(); + } + } + } + + public static boolean pointInComponent(Robot robot, Point p, Component comp) + throws InterruptedException { + return theInstance.pointInComponentImpl(robot, p, comp); + } + + private boolean pointInComponentImpl(Robot robot, Point p, Component comp) + throws InterruptedException { + robot.waitForIdle(); + reset(); + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + synchronized (SYNC_LOCK) { + robot.mouseRelease(InputEvent.BUTTON1_MASK); + SYNC_LOCK.wait(MOUSE_RELEASE_TIMEOUT); + } + + Component c = clickedComponent; + + while (c != null && c != comp) { + c = c.getParent(); + } + + return c == comp; + } +} + +class Child { + static class DragSourceDropListener extends DragSourceAdapter { + private boolean finished = false; + private boolean dropSuccess = false; + + public void reset() { + finished = false; + dropSuccess = false; + } + + public boolean isDropFinished() { + return finished; + } + + public boolean getDropSuccess() { + return dropSuccess; + } + + public void dragDropEnd(DragSourceDropEvent dsde) { + finished = true; + dropSuccess = dsde.getDropSuccess(); + synchronized (Util.SYNC_LOCK) { + Util.SYNC_LOCK.notifyAll(); + } + } + } + + final Frame frame = new Frame("Source Frame"); + final DragSource dragSource = DragSource.getDefaultDragSource(); + final DragSourceDropListener dragSourceListener = new DragSourceDropListener(); + final Transferable transferable = new StringSelection("TEXT"); + final DragGestureListener dragGestureListener = new DragGestureListener() { + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, transferable, dragSourceListener); + } + }; + final DragGestureRecognizer dragGestureRecognizer = + dragSource.createDefaultDragGestureRecognizer(frame, DnDConstants.ACTION_COPY, + dragGestureListener); + + public static void main(String[] args) { + Child child = new Child(); + child.run(args); + } + + public void run(String[] args) { + try { + if (args.length != 4) { + throw new RuntimeException("Incorrect command line arguments."); + } + + int x = Integer.parseInt(args[0]); + int y = Integer.parseInt(args[1]); + int w = Integer.parseInt(args[2]); + int h = Integer.parseInt(args[3]); + + frame.setBounds(300, 200, 150, 150); + frame.setVisible(true); + + Thread.sleep(Util.FRAME_ACTIVATION_TIMEOUT); + + Point sourcePoint = Util.getCenterLocationOnScreen(frame); + + Point targetPoint = new Point(x + w / 2, y + h / 2); + + Robot robot = new Robot(); + robot.mouseMove(sourcePoint.x, sourcePoint.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + for (Point p = new Point(sourcePoint); !p.equals(targetPoint); + p.translate(Util.sign(targetPoint.x - p.x), + Util.sign(targetPoint.y - p.y))) { + robot.mouseMove(p.x, p.y); + Thread.sleep(50); + } + + synchronized (Util.SYNC_LOCK) { + robot.mouseRelease(InputEvent.BUTTON1_MASK); + Util.SYNC_LOCK.wait(Util.FRAME_ACTIVATION_TIMEOUT); + } + + if (!dragSourceListener.isDropFinished()) { + throw new RuntimeException("Drop not finished"); + } + + boolean success1 = dragSourceListener.getDropSuccess(); + + dragSourceListener.reset(); + robot.mouseMove(sourcePoint.x, sourcePoint.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + for (Point p = new Point(sourcePoint); !p.equals(targetPoint); + p.translate(Util.sign(targetPoint.x - p.x), + Util.sign(targetPoint.y - p.y))) { + robot.mouseMove(p.x, p.y); + Thread.sleep(50); + } + + synchronized (Util.SYNC_LOCK) { + robot.mouseRelease(InputEvent.BUTTON1_MASK); + Util.SYNC_LOCK.wait(Util.FRAME_ACTIVATION_TIMEOUT); + } + + if (!dragSourceListener.isDropFinished()) { + throw new RuntimeException("Drop not finished"); + } + + boolean success2 = dragSourceListener.getDropSuccess(); + int retCode = 0; + + if (success1) { + retCode |= Util.CODE_FIRST_SUCCESS; + } + if (success2) { + retCode |= Util.CODE_SECOND_SUCCESS; + } + // This returns the diagnostic code from the child VM + System.exit(retCode); + } catch (Throwable e) { + e.printStackTrace(); + // This returns the diagnostic code from the child VM + System.exit(Util.CODE_FAILURE); + } + } // run() +} // class child + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog + { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("South", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/dnd/NoFormatsCrashTest/NoFormatsCrashTest.html b/jdk/test/java/awt/dnd/NoFormatsCrashTest/NoFormatsCrashTest.html new file mode 100644 index 00000000000..c19a0a02354 --- /dev/null +++ b/jdk/test/java/awt/dnd/NoFormatsCrashTest/NoFormatsCrashTest.html @@ -0,0 +1,45 @@ +<!-- + Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + This code is free software; you can redistribute it and/or modify it + 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. +--> + +<html> +<!-- + @test + @bug 4870762 + @summary tests that a drop target JVM doesn't crash if the source doesn't export + data in native formats. + @author das@sparc.spb.su area=dnd + @run applet NoFormatsCrashTest.html + --> +<head> +<title> </title> +</head> +<body> + +<h1>NoFormatsCrashTest<br>Bug ID: 4870762</h1> + +<p> This is an AUTOMATIC test, simply wait for completion </p> + +<APPLET CODE="NoFormatsCrashTest.class" WIDTH=200 HEIGHT=200></APPLET> +</body> +</html> + diff --git a/jdk/test/java/awt/dnd/NoFormatsCrashTest/NoFormatsCrashTest.java b/jdk/test/java/awt/dnd/NoFormatsCrashTest/NoFormatsCrashTest.java new file mode 100644 index 00000000000..3be0adc666e --- /dev/null +++ b/jdk/test/java/awt/dnd/NoFormatsCrashTest/NoFormatsCrashTest.java @@ -0,0 +1,488 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + @bug 4870762 + @summary tests that a drop target JVM doesn't crash if the source doesn't export + data in native formats. + @author das@sparc.spb.su area=dnd + @compile NoFormatsCrashTest.java + @run applet NoFormatsCrashTest.html +*/ + +// Note there is no @ in front of test above. This is so that the +// harness will not mistake this file as a test file. It should +// only see the html file as a test file. (the harness runs all +// valid test files, so it would run this test twice if this file +// were valid as well as the html file.) +// Also, note the area= after Your Name in the author tag. Here, you +// should put which functional area the test falls in. See the +// AWT-core home page -> test areas and/or -> AWT team for a list of +// areas. +// Note also the 'NoFormatsCrashTest.html' in the run tag. This should +// be changed to the name of the test. + + +/** + * NoFormatsCrashTest.java + * + * summary: tests that a drop target JVM doesn't crash if the source doesn't export + * data in native formats. + */ + +import java.applet.Applet; +import java.awt.*; +import java.awt.datatransfer.*; +import java.awt.dnd.*; +import java.awt.event.*; +import java.io.*; + + +//Automated tests should run as applet tests if possible because they +// get their environments cleaned up, including AWT threads, any +// test created threads, and any system resources used by the test +// such as file descriptors. (This is normally not a problem as +// main tests usually run in a separate VM, however on some platforms +// such as the Mac, separate VMs are not possible and non-applet +// tests will cause problems). Also, you don't have to worry about +// synchronisation stuff in Applet tests they way you do in main +// tests... + + +public class NoFormatsCrashTest extends Applet { + + final Frame frame = new Frame(); + private volatile Process process; + + static final int FRAME_ACTIVATION_TIMEOUT = 2000; + + public static void main(String[] args) { + NoFormatsCrashTest test = new NoFormatsCrashTest(); + test.run(args); + } + + public void run(String[] args) { + try { + if (args.length != 4) { + throw new RuntimeException("Incorrect command line arguments."); + } + + int x = Integer.parseInt(args[0]); + int y = Integer.parseInt(args[1]); + int w = Integer.parseInt(args[2]); + int h = Integer.parseInt(args[3]); + + Panel panel = new DragSourcePanel(); + + frame.setTitle("Drag source frame"); + frame.setLocation(500, 200); + frame.add(panel); + frame.pack(); + frame.setVisible(true); + + Thread.sleep(FRAME_ACTIVATION_TIMEOUT); + + Point sourcePoint = panel.getLocationOnScreen(); + Dimension d = panel.getSize(); + sourcePoint.translate(d.width / 2, d.height / 2); + + Point targetPoint = new Point(x + w / 2, y + h / 2); + + Robot robot = new Robot(); + robot.mouseMove(sourcePoint.x, sourcePoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_MASK); + for (; !sourcePoint.equals(targetPoint); + sourcePoint.translate(sign(targetPoint.x - sourcePoint.x), + sign(targetPoint.y - sourcePoint.y))) { + robot.mouseMove(sourcePoint.x, sourcePoint.y); + Thread.sleep(50); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.keyRelease(KeyEvent.VK_CONTROL); + + Thread.sleep(FRAME_ACTIVATION_TIMEOUT); + + if (process.isAlive()) { + process.destroy(); + } + } catch (Throwable e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } // run() + + public void init() { + //Create instructions for the user here, as well as set up + // the environment -- set the layout manager, add buttons, + // etc. + + String[] instructions = + { + "This is an AUTOMATIC test", + "simply wait until it is done" + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + frame.setTitle("Drop target frame"); + frame.setLocation(200, 200); + + } // init() + + public void start() { + DropTargetPanel panel = new DropTargetPanel(); + frame.add(panel); + frame.pack(); + frame.setVisible(true); + + try { + Thread.sleep(FRAME_ACTIVATION_TIMEOUT); + + Point p = frame.getLocationOnScreen(); + Dimension d = frame.getSize(); + + String javaPath = System.getProperty("java.home", ""); + String command = javaPath + File.separator + "bin" + + File.separator + "java -cp " + System.getProperty("test.classes", ".") + + " NoFormatsCrashTest " + + p.x + " " + p.y + " " + d.width + " " + d.height; + + process = Runtime.getRuntime().exec(command); + ProcessResults pres = ProcessResults.doWaitFor(process); + System.err.println("Child VM return code: " + pres.exitValue); + + if (pres.stderr != null && pres.stderr.length() > 0) { + System.err.println("========= Child VM System.err ========"); + System.err.print(pres.stderr); + System.err.println("======================================"); + } + + if (pres.stdout != null && pres.stdout.length() > 0) { + System.err.println("========= Child VM System.out ========"); + System.err.print(pres.stdout); + System.err.println("======================================"); + } + + } catch (Throwable e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + + if (panel.isTestFailed()) { + throw new RuntimeException(); + } + } // start() + + public static int sign(int n) { + return n < 0 ? -1 : n > 0 ? 1 : 0; + } +} // class NoFormatsCrashTest + +class TestTransferable implements Transferable { + + public static DataFlavor dataFlavor = null; + static final Object data = new Object(); + + static { + DataFlavor df = null; + try { + df = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + + "; class=java.lang.Object"); + } catch (ClassNotFoundException e) { + throw new ExceptionInInitializerError(e); + } + dataFlavor = df; + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { dataFlavor }; + } + + public boolean isDataFlavorSupported(DataFlavor df) { + return dataFlavor.equals(df); + } + + public Object getTransferData(DataFlavor df) + throws UnsupportedFlavorException, IOException { + if (!isDataFlavorSupported(df)) { + throw new UnsupportedFlavorException(df); + } + return data; + } +} + +class DragSourcePanel extends Panel { + public DragSourcePanel() { + final Transferable t = new TestTransferable(); + final DragSourceListener dsl = new DragSourceAdapter() { + public void dragDropEnd(DragSourceDropEvent dtde) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + // This finishes child VM + System.exit(0); + } + }; + final DragGestureListener dgl = new DragGestureListener() { + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, t, dsl); + } + }; + final DragSource ds = DragSource.getDefaultDragSource(); + final DragGestureRecognizer dgr = + ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, + dgl); + } + + public Dimension getPreferredSize() { + return new Dimension(100, 100); + } +} + +class DropTargetPanel extends Panel { + private boolean testFailed = false; + public DropTargetPanel() { + final DropTargetListener dtl = new DropTargetAdapter() { + public void dragOver(DropTargetDragEvent dtde) { + try { + dtde.getCurrentDataFlavorsAsList(); + } catch (Exception e) { + testFailed = true; + e.printStackTrace(); + } + } + public void drop(DropTargetDropEvent dtde) { + dtde.rejectDrop(); + } + }; + final DropTarget dt = new DropTarget(this, dtl); + } + + public boolean isTestFailed() { + return testFailed; + } + + public Dimension getPreferredSize() { + return new Dimension(100, 100); + } +} + +class ProcessResults { + public int exitValue; + public String stdout; + public String stderr; + + public ProcessResults() { + exitValue = -1; + stdout = ""; + stderr = ""; + } + + /** + * Method to perform a "wait" for a process and return its exit value. + * This is a workaround for <code>Process.waitFor()</code> never returning. + */ + public static ProcessResults doWaitFor(Process p) { + ProcessResults pres = new ProcessResults(); + + InputStream in = null; + InputStream err = null; + + try { + in = p.getInputStream(); + err = p.getErrorStream(); + + boolean finished = false; + + while (!finished) { + try { + while (in.available() > 0) { + pres.stdout += (char)in.read(); + } + while (err.available() > 0) { + pres.stderr += (char)err.read(); + } + // Ask the process for its exitValue. If the process + // is not finished, an IllegalThreadStateException + // is thrown. If it is finished, we fall through and + // the variable finished is set to true. + pres.exitValue = p.exitValue(); + finished = true; + } + catch (IllegalThreadStateException e) { + // Process is not finished yet; + // Sleep a little to save on CPU cycles + Thread.currentThread().sleep(500); + } + } + if (in != null) in.close(); + if (err != null) err.close(); + } + catch (Throwable e) { + System.err.println("doWaitFor(): unexpected exception"); + e.printStackTrace(); + throw new RuntimeException(e); + } + return pres; + } +} + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog + { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("South", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/regtesthelpers/process/ProcessCommunicator.java b/jdk/test/java/awt/regtesthelpers/process/ProcessCommunicator.java index 8c0e6db916a..8177a2d2ab3 100644 --- a/jdk/test/java/awt/regtesthelpers/process/ProcessCommunicator.java +++ b/jdk/test/java/awt/regtesthelpers/process/ProcessCommunicator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,21 +25,22 @@ package test.java.awt.regtesthelpers.process; import java.io.*; -/** This class is created to solve interprocess communication problems. +/** + * This class is created to solve interprocess communication problems. * When you need to write a regression test which should verify inter jvm * behavior such as DnD data transfer, Clipboard data transfer, focus * transfer etc., you could use the next scenario: * * 1. Write an implementation for the parent JVM, using applet test. - * 2. Write an implimentation for the child JVM or native application, using + * 2. Write an implementation for the child JVM or native application, using * main() function. * 3. Execute child process using ProcessCommunicator.executeChildProcess() * method. - * 4. You can decide whetherthe test is passed on the basis of + * 4. You can decide whether the test is passed on the basis of * ProcessResults class data. * - * Note: The class is not thread safe. You should access its methods only from the same - * thread. + * Note: The class is not thread safe. You should access its methods only from + * the same thread. */ public class ProcessCommunicator { @@ -48,31 +49,34 @@ public class ProcessCommunicator { private static final String javaPath = javaHome + File.separator + "bin" + File.separator + "java "; private static String command = ""; + private static volatile Process process; private ProcessCommunicator() {} - /** The same as {#link #executeChildProcess(Class,String)} except - * the {@code classPathArgument} parameter. The class path - * parameter is for the debug purposes + /** + * The same as {#link #executeChildProcess(Class,String)} except + * the {@code classPathArgument} parameter. The class path + * parameter is for the debug purposes * - * @param classToExecute is passed to the child JVM - * @param classPathArguments class path for the child JVM - * @param args arguments that will be passed to the executed class - * @return results of the executed {@code Process} + * @param classToExecute is passed to the child JVM + * @param classPathArguments class path for the child JVM + * @param args arguments that will be passed to the executed class + * @return results of the executed {@code Process} */ public static ProcessResults executeChildProcess(final Class classToExecute, final String classPathArguments, final String [] args) { try { String command = buildCommand(classToExecute, classPathArguments, args); - Process process = Runtime.getRuntime().exec(command); + process = Runtime.getRuntime().exec(command); return doWaitFor(process); } catch (IOException e) { throw new RuntimeException(e); } } - /** Executes child {code Process} + /** + * Executes child {code Process} * * @param classToExecute class to be executed as a child java process * @param args args to be passed in to the child process @@ -86,11 +90,11 @@ public class ProcessCommunicator { /** * Waits for a process and return its results. - * This is a workaround for <code>Process.waitFor()</code> never returning. + * This is a workaround for {@code Process.waitFor()} never returning. * * @return results of the executed {@code Process} */ - private static ProcessResults doWaitFor(final Process p) { + public static ProcessResults doWaitFor(final Process p) { ProcessResults pres = new ProcessResults(); final InputStream in; @@ -133,13 +137,14 @@ public class ProcessCommunicator { return pres; } - /** Builds command on the basis of the passed class name, - * class path and arguments. + /** + * Builds command on the basis of the passed class name, + * class path and arguments. * * @param classToExecute with class will be executed in the new JVM * @param classPathArguments java class path (only for test purposes) * @param args arguments for the new application. This could be used - * to pass some information from the parnent to child JVM. + * to pass some information from the parent to child JVM. * @return command to execute the {@code Process} */ private static String buildCommand(final Class classToExecute, @@ -162,11 +167,24 @@ public class ProcessCommunicator { return command; } - /** Could be used for the debug purposes. + /** + * Could be used for the debug purposes. * - * @return command that was build to execute the child process + * @return command that was build to execute the child process */ public static String getExecutionCommand () { return command; } + + /** + * Terminates the process created by {@code executeChildProcess} methods. + */ + public static void destroyProcess() { + if (process != null) { + if (process.isAlive()) { + process.destroy(); + } + process = null; + } + } } From 5b7ccb7c0a20d9154ae64164f09e600deac0cad3 Mon Sep 17 00:00:00 2001 From: Anton Litvinov <alitvinov@openjdk.org> Date: Thu, 15 May 2014 20:21:17 +0400 Subject: [PATCH 074/157] 8041725: Nimbus JList selection colors persist across L&F changes Reviewed-by: alexsch, alexp --- .../classes/javax/swing/plaf/nimbus/skin.laf | 12 +-- .../swing/plaf/nimbus/8041725/bug8041725.java | 82 +++++++++++++++++++ 2 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 jdk/test/javax/swing/plaf/nimbus/8041725/bug8041725.java diff --git a/jdk/src/share/classes/javax/swing/plaf/nimbus/skin.laf b/jdk/src/share/classes/javax/swing/plaf/nimbus/skin.laf index 39010042190..394721e1c41 100644 --- a/jdk/src/share/classes/javax/swing/plaf/nimbus/skin.laf +++ b/jdk/src/share/classes/javax/swing/plaf/nimbus/skin.laf @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. This code is free software; you can redistribute it and/or modify it @@ -13424,10 +13424,10 @@ <state stateKeys="Selected"> <style> <textForeground> - <matte red="255" green="255" blue="255" alpha="255" uiDefaultParentName="nimbusLightBackground" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0" uiResource="false"/> + <matte red="255" green="255" blue="255" alpha="255" uiDefaultParentName="nimbusLightBackground" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> </textForeground> <textBackground> - <matte red="57" green="105" blue="138" alpha="255" uiDefaultParentName="nimbusSelectionBackground" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0" uiResource="false"/> + <matte red="57" green="105" blue="138" alpha="255" uiDefaultParentName="nimbusSelectionBackground" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> </textBackground> <background/> <inherit-textForeground>false</inherit-textForeground> @@ -13453,7 +13453,7 @@ <style> <textForeground/> <textBackground> - <matte red="57" green="105" blue="138" alpha="255" uiDefaultParentName="nimbusSelectionBackground" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0" uiResource="false"/> + <matte red="57" green="105" blue="138" alpha="255" uiDefaultParentName="nimbusSelectionBackground" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> </textBackground> <background/> <inherit-textBackground>false</inherit-textBackground> @@ -13477,7 +13477,7 @@ <state stateKeys="Disabled"> <style> <textForeground> - <matte red="142" green="143" blue="145" alpha="255" uiDefaultParentName="nimbusDisabledText" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0" uiResource="false"/> + <matte red="142" green="143" blue="145" alpha="255" uiDefaultParentName="nimbusDisabledText" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> </textForeground> <textBackground/> <background/> @@ -13520,7 +13520,7 @@ </textForeground> <textBackground/> <background> - <matte red="57" green="105" blue="138" alpha="255" uiDefaultParentName="nimbusSelectionBackground" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0" uiResource="false"/> + <matte red="57" green="105" blue="138" alpha="255" uiDefaultParentName="nimbusSelectionBackground" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> </background> <inherit-textForeground>false</inherit-textForeground> <inherit-background>false</inherit-background> diff --git a/jdk/test/javax/swing/plaf/nimbus/8041725/bug8041725.java b/jdk/test/javax/swing/plaf/nimbus/8041725/bug8041725.java new file mode 100644 index 00000000000..d668a3411de --- /dev/null +++ b/jdk/test/javax/swing/plaf/nimbus/8041725/bug8041725.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + @bug 8041725 + @summary JList selection colors are not UIResource instances in Nimbus L&F + @author Anton Litvinov +*/ + +import java.awt.*; +import javax.swing.*; +import javax.swing.plaf.*; +import javax.swing.plaf.nimbus.*; + +public class bug8041725 { + public static void main(String[] args) throws Exception { + UIManager.setLookAndFeel(new NimbusLookAndFeel()); + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + JFrame frame = new JFrame("bug8041725"); + frame.setSize(200, 200); + JList list = new JList(new String[]{"Item1", "Item2", "Item3"}); + frame.getContentPane().add(list); + frame.pack(); + frame.setVisible(true); + + System.err.println("Test #1: No items are selected, list is enabled."); + testSelectionColors(list); + + System.err.println("Test #2: No items are selected, list is disabled."); + list.setEnabled(false); + testSelectionColors(list); + + System.err.println("Test #3: One item is selected, list is disabled."); + list.setSelectedIndex(0); + testSelectionColors(list); + + System.err.println("Test #4: One item is selected, list is enabled."); + list.setEnabled(true); + testSelectionColors(list); + + frame.dispose(); + } + }); + } + + private static void testSelectionColors(JList list) { + Color selBackColor = list.getSelectionBackground(); + if (!(selBackColor instanceof UIResource)) { + throw new RuntimeException(String.format( + "JList.getSelectionBackground() returned instance of '%s' instead of UIResource.", + selBackColor.getClass())); + } + Color selForeColor = list.getSelectionForeground(); + if (!(selForeColor instanceof UIResource)) { + throw new RuntimeException(String.format( + "JList.getSelectionForeground() returned instance of '%s' instead of UIResource.", + selForeColor.getClass())); + } + } +} From 6975db94bc462c1307947069c6d355f7ae9bec45 Mon Sep 17 00:00:00 2001 From: Alexander Zvegintsev <azvegint@openjdk.org> Date: Thu, 15 May 2014 20:24:13 +0400 Subject: [PATCH 075/157] 8041896: Test closed/java/awt/Choice/RemoveAllShrinkTest/RemoveAllShrinkTest fails with java.awt.IllegalComponentStateException Reviewed-by: pchelko, serb --- .../com/apple/laf/AquaComboBoxPopup.java | 4 + .../classes/sun/lwawt/LWChoicePeer.java | 4 +- .../RemoveAllShrinkTest.java | 85 +++++++++++++++++++ 3 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/awt/Choice/RemoveAllShrinkTest/RemoveAllShrinkTest.java diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaComboBoxPopup.java b/jdk/src/macosx/classes/com/apple/laf/AquaComboBoxPopup.java index dde9b1be337..9fbf67283cd 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaComboBoxPopup.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaComboBoxPopup.java @@ -121,6 +121,10 @@ class AquaComboBoxPopup extends BasicComboPopup { public void show() { final int startItemCount = comboBox.getItemCount(); + if (startItemCount == 0) { + return; + } + final Rectangle popupBounds = adjustPopupAndGetBounds(); if (popupBounds == null) return; // null means don't show diff --git a/jdk/src/macosx/classes/sun/lwawt/LWChoicePeer.java b/jdk/src/macosx/classes/sun/lwawt/LWChoicePeer.java index bb360d6d677..27d43b1bfce 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWChoicePeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWChoicePeer.java @@ -171,7 +171,9 @@ final class LWChoicePeer extends LWComponentPeer<Choice, JComboBox<String>> SwingUtilities.invokeLater(() -> { JPopupMenu popupMenu = getPopupMenu(); // Need to override the invoker for proper grab handling - if (popupMenu != null && popupMenu.getInvoker() != getTarget()) { + if (popupMenu != null + && popupMenu.isShowing() + && popupMenu.getInvoker() != getTarget()) { // The popup is now visible with correct location // Save it and restore after toggling visibility and changing invoker Point loc = popupMenu.getLocationOnScreen(); diff --git a/jdk/test/java/awt/Choice/RemoveAllShrinkTest/RemoveAllShrinkTest.java b/jdk/test/java/awt/Choice/RemoveAllShrinkTest/RemoveAllShrinkTest.java new file mode 100644 index 00000000000..311f7eb9ca0 --- /dev/null +++ b/jdk/test/java/awt/Choice/RemoveAllShrinkTest/RemoveAllShrinkTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + @bug 4851798 8041896 + @summary Tests Choice List shrinks after removeAll + @run main RemoveAllShrinkTest +*/ + +import java.awt.*; +import java.awt.event.*; + + +public class RemoveAllShrinkTest { + + public static void main(String[] args) { + Frame f = new Frame(); + Choice choice = new Choice(); + + for (int i = 0; i < 10; ++i) { + choice.addItem("Item " + i); + } + + f.add(choice, BorderLayout.NORTH); + Panel panel = new Panel(); + panel.setBackground(Color.RED); + f.add(panel); + + f.setSize(200, 200); + f.setVisible(true); + f.toFront(); + + choice.removeAll(); + + try { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + + robot.waitForIdle(); + Thread.sleep(200); + + Point pt = choice.getLocationOnScreen(); + robot.mouseMove(pt.x + choice.getWidth() - choice.getHeight() / 2, + pt.y + choice.getHeight() / 2); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + Thread.sleep(400); + + Point pt1 = panel.getLocationOnScreen(); + + Color color = robot.getPixelColor(pt1.x + panel.getWidth() / 2, + pt1.y + panel.getHeight() / 2); + + if (!color.equals(Color.RED)) { + throw new RuntimeException("RemoveAllShrinkTest failed. " + color); + } + } catch (Exception e) { + throw new RuntimeException("The test was not completed.\n\n" + e); + } + } +} + From 17a7184b51b80deefbc5d24e1a916f7538225d48 Mon Sep 17 00:00:00 2001 From: David DeHaven <david.dehaven@oracle.com> Date: Tue, 13 May 2014 10:29:12 -0700 Subject: [PATCH 076/157] 8003900: X11 dependencies should be removed from Mac OS X build Reviewed-by: anthony, art, pchelko --- jdk/make/lib/Awt2dLibraries.gmk | 2 +- jdk/src/solaris/native/sun/awt/awt.h | 8 ++++---- jdk/src/solaris/native/sun/awt/color.h | 6 +++--- jdk/src/solaris/native/sun/awt/img_util_md.h | 6 +++--- jdk/src/solaris/native/sun/awt/utility/rect.h | 12 +++++++++++- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/jdk/make/lib/Awt2dLibraries.gmk b/jdk/make/lib/Awt2dLibraries.gmk index 880a52ff096..06a5672d00a 100644 --- a/jdk/make/lib/Awt2dLibraries.gmk +++ b/jdk/make/lib/Awt2dLibraries.gmk @@ -318,7 +318,7 @@ ifeq ($(OPENJDK_TARGET_OS), aix) endif ifeq ($(OPENJDK_TARGET_OS), macosx) - LIBAWT_FILES += awt_LoadLibrary.c img_colors.c + LIBAWT_FILES += awt_LoadLibrary.c LIBAWT_CFLAGS += -F/System/Library/Frameworks/JavaVM.framework/Frameworks endif diff --git a/jdk/src/solaris/native/sun/awt/awt.h b/jdk/src/solaris/native/sun/awt/awt.h index 352a90e2ad8..b611338311e 100644 --- a/jdk/src/solaris/native/sun/awt/awt.h +++ b/jdk/src/solaris/native/sun/awt/awt.h @@ -34,9 +34,9 @@ #include "jni_util.h" #include "debug_util.h" -#ifndef HEADLESS +#if !defined(HEADLESS) && !defined(MACOSX) #include <X11/Intrinsic.h> -#endif /* !HEADLESS */ +#endif /* !HEADLESS && !MACOSX */ /* The JVM instance: defined in awt_MToolkit.c */ @@ -110,9 +110,9 @@ extern void awt_output_flush(); #define AWT_NOTIFY() AWT_NOTIFY_IMPL() #define AWT_NOTIFY_ALL() AWT_NOTIFY_ALL_IMPL() -#ifndef HEADLESS +#if !defined(HEADLESS) && !defined(MACOSX) extern Display *awt_display; /* awt_GraphicsEnv.c */ extern Boolean awt_ModLockIsShiftLock; /* XToolkit.c */ -#endif /* !HEADLESS */ +#endif /* !HEADLESS && !MACOSX */ #endif /* ! _AWT_ */ diff --git a/jdk/src/solaris/native/sun/awt/color.h b/jdk/src/solaris/native/sun/awt/color.h index 16a0c552e3a..92df41caf07 100644 --- a/jdk/src/solaris/native/sun/awt/color.h +++ b/jdk/src/solaris/native/sun/awt/color.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,13 +28,13 @@ #include "awt.h" #include "colordata.h" -#ifndef HEADLESS +#if !defined(HEADLESS) && !defined(MACOSX) typedef struct { unsigned int Depth; XPixmapFormatValues wsImageFormat; ImgColorData clrdata; ImgConvertFcn *convert[NUM_IMGCV]; } awtImageData; -#endif /* !HEADLESS */ +#endif /* !HEADLESS && !MACOSX */ #endif /* _COLOR_H_ */ diff --git a/jdk/src/solaris/native/sun/awt/img_util_md.h b/jdk/src/solaris/native/sun/awt/img_util_md.h index c8d13f3b182..68a1884696b 100644 --- a/jdk/src/solaris/native/sun/awt/img_util_md.h +++ b/jdk/src/solaris/native/sun/awt/img_util_md.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #include "color.h" -#ifndef HEADLESS +#if !defined(HEADLESS) && !defined(MACOSX) typedef struct { ImgConvertData cvdata; /* The data needed by ImgConvertFcn's */ struct Hsun_awt_image_ImageRepresentation *hJavaObject; /* backptr */ @@ -68,7 +68,7 @@ extern void *image_InitMask(IRData *ird, int x1, int y1, int x2, int y2); #define MaskScan(cvdata) \ ((((IRData *)cvdata)->maskim->bytes_per_line) >> 2) -#endif /* !HEADLESS */ +#endif /* !HEADLESS && !MACOSX */ #define MaskOffset(x) ((x) >> 5) diff --git a/jdk/src/solaris/native/sun/awt/utility/rect.h b/jdk/src/solaris/native/sun/awt/utility/rect.h index 948b4ce0a77..063caa3e1d7 100644 --- a/jdk/src/solaris/native/sun/awt/utility/rect.h +++ b/jdk/src/solaris/native/sun/awt/utility/rect.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,18 @@ #ifndef _AWT_RECT_H #define _AWT_RECT_H +#ifndef MACOSX #include <X11/Xlib.h> typedef XRectangle RECT_T; +#else +// OSX still needs this for BitmapToYXBandedRectangles +typedef struct { + int x; + int y; + int width; + int height; +} RECT_T; +#endif /* !MACOSX */ #define RECT_EQ_X(r1,r2) ((r1).x==(r2).x && (r1).width==(r2).width) From 3f35cb0ca0faa95fa6df9e24d79891ca631c88a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Lid=C3=A9n?= <pliden@openjdk.org> Date: Wed, 14 May 2014 13:32:44 +0200 Subject: [PATCH 077/157] 8040803: G1: Concurrent mark hangs when mark stack overflows Reviewed-by: brutisso, ehelin --- .../gc_implementation/g1/concurrentMark.cpp | 28 ++++++++++++++++--- hotspot/src/share/vm/utilities/workgroup.cpp | 20 +++++++++---- hotspot/src/share/vm/utilities/workgroup.hpp | 18 ++++++++---- 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index de13a943c10..080926c837f 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -978,7 +978,9 @@ void ConcurrentMark::enter_first_sync_barrier(uint worker_id) { if (concurrent()) { SuspendibleThreadSet::leave(); } - _first_overflow_barrier_sync.enter(); + + bool barrier_aborted = !_first_overflow_barrier_sync.enter(); + if (concurrent()) { SuspendibleThreadSet::join(); } @@ -986,7 +988,17 @@ void ConcurrentMark::enter_first_sync_barrier(uint worker_id) { // more work if (verbose_low()) { - gclog_or_tty->print_cr("[%u] leaving first barrier", worker_id); + if (barrier_aborted) { + gclog_or_tty->print_cr("[%u] aborted first barrier", worker_id); + } else { + gclog_or_tty->print_cr("[%u] leaving first barrier", worker_id); + } + } + + if (barrier_aborted) { + // If the barrier aborted we ignore the overflow condition and + // just abort the whole marking phase as quickly as possible. + return; } // If we're executing the concurrent phase of marking, reset the marking @@ -1026,14 +1038,20 @@ void ConcurrentMark::enter_second_sync_barrier(uint worker_id) { if (concurrent()) { SuspendibleThreadSet::leave(); } - _second_overflow_barrier_sync.enter(); + + bool barrier_aborted = !_second_overflow_barrier_sync.enter(); + if (concurrent()) { SuspendibleThreadSet::join(); } // at this point everything should be re-initialized and ready to go if (verbose_low()) { - gclog_or_tty->print_cr("[%u] leaving second barrier", worker_id); + if (barrier_aborted) { + gclog_or_tty->print_cr("[%u] aborted second barrier", worker_id); + } else { + gclog_or_tty->print_cr("[%u] leaving second barrier", worker_id); + } } } @@ -3240,6 +3258,8 @@ void ConcurrentMark::abort() { for (uint i = 0; i < _max_worker_id; ++i) { _tasks[i]->clear_region_fields(); } + _first_overflow_barrier_sync.abort(); + _second_overflow_barrier_sync.abort(); _has_aborted = true; SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); diff --git a/hotspot/src/share/vm/utilities/workgroup.cpp b/hotspot/src/share/vm/utilities/workgroup.cpp index 479cd04029a..abf1b6cf746 100644 --- a/hotspot/src/share/vm/utilities/workgroup.cpp +++ b/hotspot/src/share/vm/utilities/workgroup.cpp @@ -376,21 +376,22 @@ const char* AbstractGangTask::name() const { WorkGangBarrierSync::WorkGangBarrierSync() : _monitor(Mutex::safepoint, "work gang barrier sync", true), - _n_workers(0), _n_completed(0), _should_reset(false) { + _n_workers(0), _n_completed(0), _should_reset(false), _aborted(false) { } WorkGangBarrierSync::WorkGangBarrierSync(uint n_workers, const char* name) : _monitor(Mutex::safepoint, name, true), - _n_workers(n_workers), _n_completed(0), _should_reset(false) { + _n_workers(n_workers), _n_completed(0), _should_reset(false), _aborted(false) { } void WorkGangBarrierSync::set_n_workers(uint n_workers) { - _n_workers = n_workers; - _n_completed = 0; + _n_workers = n_workers; + _n_completed = 0; _should_reset = false; + _aborted = false; } -void WorkGangBarrierSync::enter() { +bool WorkGangBarrierSync::enter() { MutexLockerEx x(monitor(), Mutex::_no_safepoint_check_flag); if (should_reset()) { // The should_reset() was set and we are the first worker to enter @@ -413,10 +414,17 @@ void WorkGangBarrierSync::enter() { set_should_reset(true); monitor()->notify_all(); } else { - while (n_completed() != n_workers()) { + while (n_completed() != n_workers() && !aborted()) { monitor()->wait(/* no_safepoint_check */ true); } } + return !aborted(); +} + +void WorkGangBarrierSync::abort() { + MutexLockerEx x(monitor(), Mutex::_no_safepoint_check_flag); + set_aborted(); + monitor()->notify_all(); } // SubTasksDone functions. diff --git a/hotspot/src/share/vm/utilities/workgroup.hpp b/hotspot/src/share/vm/utilities/workgroup.hpp index e1184a67972..30337f1ef50 100644 --- a/hotspot/src/share/vm/utilities/workgroup.hpp +++ b/hotspot/src/share/vm/utilities/workgroup.hpp @@ -359,18 +359,20 @@ class FlexibleWorkGang: public WorkGang { class WorkGangBarrierSync : public StackObj { protected: Monitor _monitor; - uint _n_workers; - uint _n_completed; + uint _n_workers; + uint _n_completed; bool _should_reset; + bool _aborted; Monitor* monitor() { return &_monitor; } uint n_workers() { return _n_workers; } uint n_completed() { return _n_completed; } bool should_reset() { return _should_reset; } + bool aborted() { return _aborted; } void zero_completed() { _n_completed = 0; } void inc_completed() { _n_completed++; } - + void set_aborted() { _aborted = true; } void set_should_reset(bool v) { _should_reset = v; } public: @@ -383,8 +385,14 @@ public: // Enter the barrier. A worker that enters the barrier will // not be allowed to leave until all other threads have - // also entered the barrier. - void enter(); + // also entered the barrier or the barrier is aborted. + // Returns false if the barrier was aborted. + bool enter(); + + // Aborts the barrier and wakes up any threads waiting for + // the barrier to complete. The barrier will remain in the + // aborted state until the next call to set_n_workers(). + void abort(); }; // A class to manage claiming of subtasks within a group of tasks. The From 04341bfffbc43a54ad5aad4cd966cad1d7153ad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Lid=C3=A9n?= <pliden@openjdk.org> Date: Wed, 14 May 2014 14:32:23 +0200 Subject: [PATCH 078/157] 8040804: G1: Concurrent mark stuck in loop calling os::elapsedVTime() Reviewed-by: brutisso, tschatzl --- .../src/share/vm/gc_implementation/g1/concurrentMark.cpp | 2 +- .../src/share/vm/gc_implementation/g1/concurrentMark.hpp | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index 080926c837f..1bebb9f69a3 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -819,7 +819,7 @@ void ConcurrentMark::set_concurrency_and_phase(uint active_tasks, bool concurren // false before we start remark. At this point we should also be // in a STW phase. assert(!concurrent_marking_in_progress(), "invariant"); - assert(_finger == _heap_end, + assert(out_of_regions(), err_msg("only way to get here: _finger: "PTR_FORMAT", _heap_end: "PTR_FORMAT, _finger, _heap_end)); update_g1_committed(true); diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp index 21327485863..9d049a2a255 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp @@ -542,8 +542,12 @@ protected: // frequently. HeapRegion* claim_region(uint worker_id); - // It determines whether we've run out of regions to scan - bool out_of_regions() { return _finger == _heap_end; } + // It determines whether we've run out of regions to scan. Note that + // the finger can point past the heap end in case the heap was expanded + // to satisfy an allocation without doing a GC. This is fine, because all + // objects in those regions will be considered live anyway because of + // SATB guarantees (i.e. their TAMS will be equal to bottom). + bool out_of_regions() { return _finger >= _heap_end; } // Returns the task with the given id CMTask* task(int id) { From 6e58e65cf702c7ded266930ded29e45a6a021824 Mon Sep 17 00:00:00 2001 From: Mikhailo Seledtsov <mseledtsov@openjdk.org> Date: Wed, 14 May 2014 10:38:40 -0400 Subject: [PATCH 079/157] 8041938: [TESTBUG] runtime/SharedArchiveFile/CdsWriteError.java failed in RT_Baseline with 'Unable to create shared archive file' missing from stdout/stderr His test is unstable in automated testing system, team agreed to remove it Reviewed-by: coleenp, gtriantafill --- .../SharedArchiveFile/CdsWriteError.java | 85 ------------------- 1 file changed, 85 deletions(-) delete mode 100644 hotspot/test/runtime/SharedArchiveFile/CdsWriteError.java diff --git a/hotspot/test/runtime/SharedArchiveFile/CdsWriteError.java b/hotspot/test/runtime/SharedArchiveFile/CdsWriteError.java deleted file mode 100644 index 162f3ad4722..00000000000 --- a/hotspot/test/runtime/SharedArchiveFile/CdsWriteError.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * 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 CdsWriteError - * @summary Test how VM handles situation when it is impossible to write the - * CDS archive. VM is expected to exit gracefully and display the - * correct reason for the error. - * @library /testlibrary - * @run main CdsWriteError - * @bug 8032222 - */ - -import com.oracle.java.testlibrary.*; -import java.io.File; - -public class CdsWriteError { - public static void main(String[] args) throws Exception { - - if (Platform.isWindows()) { - System.out.println("This test is ignored on Windows. This test " + - "manipulates folder writable attribute, which is known to be " + - "often ignored by Windows"); - - return; - } - - // This test has been unstable for Mac OSx (see JDK-8032222) - if (Platform.isOSX()) { - System.out.println("This test is skipped on Mac"); - return; - } - - String folderName = "tmp"; - String fileName = folderName + File.separator + "empty.jsa"; - - // create an empty archive file and make it read only - File folder = new File(folderName); - if (!folder.mkdir()) - throw new RuntimeException("Error when creating a tmp folder"); - - File cdsFile = new File(fileName); - if (!cdsFile.createNewFile()) - throw new RuntimeException("Error when creating an empty CDS file"); - if (!cdsFile.setWritable(false)) - throw new RuntimeException("Error: could not set writable attribute on cds file"); - if (!folder.setWritable(false)) - throw new RuntimeException("Error: could not set writable attribute on the cds folder"); - - try { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./" + fileName, "-Xshare:dump"); - - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("Unable to create shared archive file"); - output.shouldHaveExitValue(1); - } finally { - // doing this, just in case, to make sure that files can be deleted by the harness - // on any subsequent run - folder.setWritable(true); - cdsFile.setWritable(true); - } - } -} - From 397abe646b70d28cb87f3ab15ac5696b7df6b1c4 Mon Sep 17 00:00:00 2001 From: Volker Simonis <simonis@openjdk.org> Date: Wed, 14 May 2014 12:09:13 -0400 Subject: [PATCH 080/157] 8043029: Change 8037816 breaks HS build with older GCC versions which don't support diagnostic pragmas Added conditions around macro definitions for pragmas. Reviewed-by: kvn --- .../share/vm/utilities/globalDefinitions_gcc.hpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp b/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp index 3125859be31..22e5d277c81 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp @@ -283,13 +283,25 @@ inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); } #define VALUE_OBJ_CLASS_SPEC #ifndef ATTRIBUTE_PRINTF +// Diagnostic pragmas like the ones defined below in PRAGMA_FORMAT_NONLITERAL_IGNORED +// were only introduced in GCC 4.2. Because we have no other possibility to ignore +// these warnings for older versions of GCC, we simply don't decorate our printf-style +// functions with __attribute__(format) in that case. +#if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) || (__GNUC__ > 4) #define ATTRIBUTE_PRINTF(fmt,vargs) __attribute__((format(printf, fmt, vargs))) +#else +#define ATTRIBUTE_PRINTF(fmt,vargs) +#endif #endif -#define PRAGMA_FORMAT_NONLITERAL_IGNORED _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") _Pragma("GCC diagnostic ignored \"-Wformat-security\"") +#define PRAGMA_FORMAT_NONLITERAL_IGNORED _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") \ + _Pragma("GCC diagnostic ignored \"-Wformat-security\"") #define PRAGMA_FORMAT_IGNORED _Pragma("GCC diagnostic ignored \"-Wformat\"") -#if defined(__clang_major__) && (__clang_major__ >= 4 || (__clang_major__ >= 3 && __clang_minor__ >= 1)) || (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6) +#if defined(__clang_major__) && \ + (__clang_major__ >= 4 || \ + (__clang_major__ >= 3 && __clang_minor__ >= 1)) || \ + ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) // Tested to work with clang version 3.1 and better. #define PRAGMA_DIAG_PUSH _Pragma("GCC diagnostic push") #define PRAGMA_DIAG_POP _Pragma("GCC diagnostic pop") From d8ec75da3489b1a1650cb0445175c760fd192b85 Mon Sep 17 00:00:00 2001 From: Christian Tornqvist <ctornqvi@openjdk.org> Date: Wed, 14 May 2014 18:18:58 +0200 Subject: [PATCH 081/157] 8042595: [TESTBUG] runtime/7110720/Test7110720.sh rarely fails with message "explicit compiler command file not read" Removed the shell test and moved the testcases into the already existing Java based tests Reviewed-by: coleenp, lfoltan --- hotspot/test/runtime/7110720/Test7110720.sh | 119 ------------------ .../CompilerConfigFileWarning.java | 29 +++-- .../CommandLine/ConfigFileWarning.java | 29 +++-- 3 files changed, 40 insertions(+), 137 deletions(-) delete mode 100644 hotspot/test/runtime/7110720/Test7110720.sh diff --git a/hotspot/test/runtime/7110720/Test7110720.sh b/hotspot/test/runtime/7110720/Test7110720.sh deleted file mode 100644 index ae6c4098a1c..00000000000 --- a/hotspot/test/runtime/7110720/Test7110720.sh +++ /dev/null @@ -1,119 +0,0 @@ -# -# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# - - -# -# @test Test7110720.sh -# @bug 7110720 -# @summary improve VM configuration file loading -# @run shell Test7110720.sh -# - -if [ "${TESTSRC}" = "" ] -then - TESTSRC=${PWD} - echo "TESTSRC not set. Using "${TESTSRC}" as default" -fi -echo "TESTSRC=${TESTSRC}" -## Adding common setup Variables for running shell tests. -. ${TESTSRC}/../../test_env.sh - -# Jtreg sets TESTVMOPTS which may include -d64 which is -# required to test a 64-bit JVM on some platforms. -# If another test harness still creates HOME/JDK64BIT, -# we can recognise that. - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - SunOS | Linux | Darwin ) - FS="/" - RM=/bin/rm - CP=/bin/cp - MV=/bin/mv - ## for solaris, linux it's HOME - FILE_LOCATION=$HOME - if [ -f ${FILE_LOCATION}${FS}JDK64BIT -a ${OS} = "SunOS" ] - then - TESTVMOPTS=`cat ${FILE_LOCATION}${FS}JDK64BIT` - fi - ;; - Windows_* ) - FS="\\" - RM=rm - CP=cp - MV=mv - ;; - CYGWIN_* ) - FS="/" - RM=rm - CP=cp - MV=mv - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - - -JAVA=${TESTJAVA}${FS}bin${FS}java - -# Don't test debug builds, they do read the config files: -${JAVA} ${TESTVMOPTS} -version 2>&1 | grep "debug" >/dev/null -if [ "$?" = "0" ]; then - echo Skipping test for debug build. - exit 0 -fi - -ok=yes - -$RM -f .hotspot_compiler .hotspotrc - -${JAVA} ${TESTVMOPTS} -version 2>&1 | grep "garbage in" >/dev/null -if [ "$?" = "0" ]; then - echo "FAILED: base case failure" - exit 1 -fi - - -echo "garbage in, garbage out" > .hotspot_compiler -${JAVA} ${TESTVMOPTS} -version 2>&1 | grep "garbage in" >/dev/null -if [ "$?" = "0" ]; then - echo "FAILED: .hotspot_compiler was read" - ok=no -fi - -$MV .hotspot_compiler hs_comp.txt -${JAVA} ${TESTVMOPTS} -XX:CompileCommandFile=hs_comp.txt -version 2>&1 | grep "garbage in" >/dev/null -if [ "$?" = "1" ]; then - echo "FAILED: explicit compiler command file not read" - ok=no -fi - -$RM -f .hotspot_compiler hs_comp.txt - -echo "garbage" > .hotspotrc -${JAVA} ${TESTVMOPTS} -version 2>&1 | grep "garbage" >/dev/null -if [ "$?" = "0" ]; then - echo "FAILED: .hotspotrc was read" - ok=no -fi - -$MV .hotspotrc hs_flags.txt -${JAVA} ${TESTVMOPTS} -XX:Flags=hs_flags.txt -version 2>&1 | grep "garbage" >/dev/null -if [ "$?" = "1" ]; then - echo "FAILED: explicit flags file not read" - ok=no -fi - -if [ "${ok}" = "no" ]; then - echo "Some tests failed." - exit 1 -else - echo "Passed" - exit 0 -fi - diff --git a/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java b/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java index e5df0c9450b..aa5b4746139 100644 --- a/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java +++ b/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java @@ -33,17 +33,28 @@ import com.oracle.java.testlibrary.*; public class CompilerConfigFileWarning { public static void main(String[] args) throws Exception { - if (Platform.isDebugBuild()) { - System.out.println("Skip on debug builds since we'll always read the file there"); - return; - } + ProcessBuilder pb; + OutputAnalyzer output; + PrintWriter pw; - PrintWriter pw = new PrintWriter(".hotspot_compiler"); - pw.println("aa"); + pw = new PrintWriter("hs_comp.txt"); + pw.println("aaa, aaa"); pw.close(); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("warning: .hotspot_compiler file is present but has been ignored. Run with -XX:CompileCommandFile=.hotspot_compiler to load the file."); + pb = ProcessTools.createJavaProcessBuilder("-XX:CompileCommandFile=hs_comp.txt", "-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("CompilerOracle: unrecognized line"); + output.shouldContain("aaa aaa"); + + // Skip on debug builds since we'll always read the file there + if (!Platform.isDebugBuild()) { + pw = new PrintWriter(".hotspot_compiler"); + pw.println("aa"); + pw.close(); + + pb = ProcessTools.createJavaProcessBuilder("-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("warning: .hotspot_compiler file is present but has been ignored. Run with -XX:CompileCommandFile=.hotspot_compiler to load the file."); + } } } diff --git a/hotspot/test/runtime/CommandLine/ConfigFileWarning.java b/hotspot/test/runtime/CommandLine/ConfigFileWarning.java index b81da5923fd..8f04a076b76 100644 --- a/hotspot/test/runtime/CommandLine/ConfigFileWarning.java +++ b/hotspot/test/runtime/CommandLine/ConfigFileWarning.java @@ -33,17 +33,28 @@ import com.oracle.java.testlibrary.*; public class ConfigFileWarning { public static void main(String[] args) throws Exception { - if (Platform.isDebugBuild()) { - System.out.println("Skip on debug builds since we'll always read the file there"); - return; - } + PrintWriter pw; + ProcessBuilder pb; + OutputAnalyzer output; - PrintWriter pw = new PrintWriter(".hotspotrc"); - pw.println("aa"); + pw = new PrintWriter("hs_flags.txt"); + pw.println("aaa"); pw.close(); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("warning: .hotspotrc file is present but has been ignored. Run with -XX:Flags=.hotspotrc to load the file."); + pb = ProcessTools.createJavaProcessBuilder("-XX:Flags=hs_flags.txt","-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("Unrecognized VM option 'aaa'"); + output.shouldHaveExitValue(1); + + // Skip on debug builds since we'll always read the file there + if (!Platform.isDebugBuild()) { + pw = new PrintWriter(".hotspotrc"); + pw.println("aa"); + pw.close(); + + pb = ProcessTools.createJavaProcessBuilder("-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("warning: .hotspotrc file is present but has been ignored. Run with -XX:Flags=.hotspotrc to load the file."); + } } } From ac6a099ed750caf304a01e07a071860852b1ff34 Mon Sep 17 00:00:00 2001 From: David Chase <drchase@openjdk.org> Date: Wed, 14 May 2014 22:54:45 -0400 Subject: [PATCH 082/157] 8043164: Format warning in traceStream.hpp Added cast to placate gcc Reviewed-by: kvn, zgu --- hotspot/src/share/vm/trace/traceStream.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/trace/traceStream.hpp b/hotspot/src/share/vm/trace/traceStream.hpp index 2166a75126c..14bc421115c 100644 --- a/hotspot/src/share/vm/trace/traceStream.hpp +++ b/hotspot/src/share/vm/trace/traceStream.hpp @@ -66,7 +66,7 @@ class TraceStream : public StackObj { } void print_val(const char* label, s8 val) { - _st.print("%s = "INT64_FORMAT, label, val); + _st.print("%s = "INT64_FORMAT, label, (int64_t) val); } void print_val(const char* label, bool val) { From f0baee0a2cb40204c97b4e4b122e8ba3cc1163bb Mon Sep 17 00:00:00 2001 From: Rickard Backman <rickard.backman@oracle.com> Date: Wed, 14 May 2014 20:44:33 +0200 Subject: [PATCH 083/157] 8041934: com/sun/jdi/RepStep.java fails in RT_Baseline on all platforms with assert(_cur_stack_depth == count_frames()) failed: cur_stack_depth out of sync Missing call to jvmti_method_exit from native wrapper code Reviewed-by: twisti, dcubed, sspitsyn --- .../src/cpu/sparc/vm/sharedRuntime_sparc.cpp | 24 ++++++++++++++++++ .../src/cpu/x86/vm/sharedRuntime_x86_32.cpp | 24 ++++++++++++++++++ .../src/cpu/x86/vm/sharedRuntime_x86_64.cpp | 25 +++++++++++++++++++ .../src/share/vm/runtime/sharedRuntime.cpp | 6 +++++ .../src/share/vm/runtime/sharedRuntime.hpp | 3 +++ 5 files changed, 82 insertions(+) diff --git a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp index b3c706dbef4..19a071cd213 100644 --- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp @@ -2657,6 +2657,30 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, __ bind(done); } + { + // Normally we do not post method_entry and method_exit events from + // compiled code, only from the interpreter. If method_entry/exit + // events are switched on at runtime, we will deoptimize everything + // (see VM_EnterInterpOnlyMode) on the stack and call method_entry/exit + // from the interpreter. But when we do that, we will not deoptimize + // this native wrapper frame. Thus we have an extra check here to see + // if we are now in interp_only_mode and in that case we do the jvmti + // callback. + Label skip_jvmti_method_exit; + __ ld(G2_thread, JavaThread::interp_only_mode_offset(), G3_scratch); + __ cmp_and_br_short(G3_scratch, 0, Assembler::zero, Assembler::pt, skip_jvmti_method_exit); + + save_native_result(masm, ret_type, stack_slots); + __ set_metadata_constant(method(), G3_scratch); + __ call_VM( + noreg, + CAST_FROM_FN_PTR(address, SharedRuntime::jvmti_method_exit), + G2_thread, G3_scratch, + true); + restore_native_result(masm, ret_type, stack_slots); + __ bind(skip_jvmti_method_exit); + } + // Tell dtrace about this method exit { SkipIfEqual skip_if( diff --git a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp index c97b4309782..95668394111 100644 --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp @@ -2238,6 +2238,30 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, } + { + // Normally we do not post method_entry and method_exit events from + // compiled code, only from the interpreter. If method_entry/exit + // events are switched on at runtime, we will deoptimize everything + // (see VM_EnterInterpOnlyMode) on the stack and call method_entry/exit + // from the interpreter. But when we do that, we will not deoptimize + // this native wrapper frame. Thus we have an extra check here to see + // if we are now in interp_only_mode and in that case we do the jvmti + // callback. + Label skip_jvmti_method_exit; + __ cmpl(Address(thread, JavaThread::interp_only_mode_offset()), 0); + __ jcc(Assembler::zero, skip_jvmti_method_exit, true); + + save_native_result(masm, ret_type, stack_slots); + __ mov_metadata(rax, method()); + __ call_VM( + noreg, + CAST_FROM_FN_PTR(address, SharedRuntime::jvmti_method_exit), + thread, rax, + true); + restore_native_result(masm, ret_type, stack_slots); + __ bind(skip_jvmti_method_exit); + } + { SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0); // Tell dtrace about this method exit diff --git a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp index be2bfcfa02d..1a9a18754f9 100644 --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp @@ -2484,6 +2484,31 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, __ bind(done); } + + { + // Normally we do not post method_entry and method_exit events from + // compiled code, only from the interpreter. If method_entry/exit + // events are switched on at runtime, we will deoptimize everything + // (see VM_EnterInterpOnlyMode) on the stack and call method_entry/exit + // from the interpreter. But when we do that, we will not deoptimize + // this native wrapper frame. Thus we have an extra check here to see + // if we are now in interp_only_mode and in that case we do the jvmti + // callback. + Label skip_jvmti_method_exit; + __ cmpl(Address(r15_thread, JavaThread::interp_only_mode_offset()), 0); + __ jcc(Assembler::zero, skip_jvmti_method_exit, true); + + save_native_result(masm, ret_type, stack_slots); + __ mov_metadata(c_rarg1, method()); + __ call_VM( + noreg, + CAST_FROM_FN_PTR(address, SharedRuntime::jvmti_method_exit), + r15_thread, c_rarg1, + true); + restore_native_result(masm, ret_type, stack_slots); + __ bind(skip_jvmti_method_exit); + } + { SkipIfEqual skip(masm, &DTraceMethodProbes, false); save_native_result(masm, ret_type, stack_slots); diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index fad31fd02f1..d4691c35a2e 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -993,6 +993,12 @@ JRT_LEAF(int, SharedRuntime::dtrace_method_exit( return 0; JRT_END +JRT_ENTRY(int, SharedRuntime::jvmti_method_exit( + JavaThread* thread, Method* method)) + JvmtiExport::post_method_exit(thread, method, thread->last_frame()); + return 0; +JRT_END + // Finds receiver, CallInfo (i.e. receiver method), and calling bytecode) // for a call current in progress, i.e., arguments has been pushed on stack diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.hpp b/hotspot/src/share/vm/runtime/sharedRuntime.hpp index c28c469d0e8..19bb5600372 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp @@ -263,6 +263,9 @@ class SharedRuntime: AllStatic { static int dtrace_method_entry(JavaThread* thread, Method* m); static int dtrace_method_exit(JavaThread* thread, Method* m); + // jvmti notification + static int jvmti_method_exit(JavaThread* thread, Method* m); + // Utility method for retrieving the Java thread id, returns 0 if the // thread is not a well formed Java thread. static jlong get_java_tid(Thread* thread); From d7b76028a40381a0e61e463225b4a906301ded1b Mon Sep 17 00:00:00 2001 From: Igor Veresov <iveresov@openjdk.org> Date: Wed, 14 May 2014 14:28:09 -0700 Subject: [PATCH 084/157] 8043063: Code aging should allocate MethodCounters when flushing a method Make sure that MethodCounters are present when the method is flushed for the first time to switch on code aging Reviewed-by: kvn --- hotspot/src/share/vm/runtime/sweeper.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hotspot/src/share/vm/runtime/sweeper.cpp b/hotspot/src/share/vm/runtime/sweeper.cpp index 99047609fdc..5ec575aa356 100644 --- a/hotspot/src/share/vm/runtime/sweeper.cpp +++ b/hotspot/src/share/vm/runtime/sweeper.cpp @@ -615,6 +615,11 @@ void NMethodSweeper::possibly_flush(nmethod* nm) { // flat profiles). Check the age counter for possible data. if (UseCodeAging && make_not_entrant && (nm->is_compiled_by_c2() || nm->is_compiled_by_c1())) { MethodCounters* mc = nm->method()->method_counters(); + if (mc == NULL) { + // Sometimes we can get here without MethodCounters. For example if we run with -Xcomp. + // Try to allocate them. + mc = Method::build_method_counters(nm->method(), Thread::current()); + } if (mc != NULL) { // Snapshot the value as it's changed concurrently int age = mc->nmethod_age(); From ca501f6b00600d3d4a12c89484eafe6b1f3c4bf7 Mon Sep 17 00:00:00 2001 From: Lois Foltan <lfoltan@openjdk.org> Date: Thu, 15 May 2014 09:25:27 -0400 Subject: [PATCH 085/157] 8041918: BootstrapMethods attribute cannot be empty Allow a BootstrapMethods attribute that contains an empty bootstrap_methods table where num_bootstrap_methods is equal to zero. Reviewed-by: coleenp, hseigel --- .../share/vm/classfile/classFileParser.cpp | 2 +- .../TestEmptyBootstrapMethodsAttr.java | 75 +++++++++++++++ .../emptynumbootstrapmethods.jar | Bin 0 -> 940 bytes .../emptynumbootstrapmethods1.jcod | 68 +++++++++++++ .../emptynumbootstrapmethods2.jcod | 89 ++++++++++++++++++ 5 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 hotspot/test/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java create mode 100644 hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods.jar create mode 100644 hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods1.jcod create mode 100644 hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods2.jcod diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index e78a6b2615f..61d9875c283 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -2805,7 +2805,7 @@ void ClassFileParser::parse_classfile_bootstrap_methods_attribute(u4 attribute_b "Short length on BootstrapMethods in class file %s", CHECK); - guarantee_property(attribute_byte_length > sizeof(u2), + guarantee_property(attribute_byte_length >= sizeof(u2), "Invalid BootstrapMethods attribute length %u in class file %s", attribute_byte_length, CHECK); diff --git a/hotspot/test/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java b/hotspot/test/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java new file mode 100644 index 00000000000..fa33c1e3c62 --- /dev/null +++ b/hotspot/test/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 TestEmptyBootstrapMethodsAttr + * @bug 8041918 + * @library /testlibrary + * @summary Test empty bootstrap_methods table within BootstrapMethods attribute + * @compile TestEmptyBootstrapMethodsAttr.java + * @run main TestEmptyBootstrapMethodsAttr + */ + +import java.io.File; +import com.oracle.java.testlibrary.*; + +public class TestEmptyBootstrapMethodsAttr { + + public static void main(String args[]) throws Throwable { + System.out.println("Regression test for bug 8041918"); + String jarFile = System.getProperty("test.src") + File.separator + "emptynumbootstrapmethods.jar"; + + // ====== extract the test case + ProcessBuilder pb = new ProcessBuilder(new String[] { JDKToolFinder.getJDKTool("jar"), "xvf", jarFile } ); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + + // Test case #1: + // Try loading class with empty bootstrap_methods table where no + // other attributes are following BootstrapMethods in attribute table. + String className = "emptynumbootstrapmethods1"; + + // ======= execute test case #1 + // Expect a lack of main method, this implies that the class loaded correctly + // with an empty bootstrap_methods and did not generate a ClassFormatError. + pb = ProcessTools.createJavaProcessBuilder("-cp", ".", className); + output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("java.lang.ClassFormatError"); + output.shouldContain("Main method not found in class " + className); + output.shouldHaveExitValue(1); + + // Test case #2: + // Try loading class with empty bootstrap_methods table where an + // AnnotationDefault attribute follows the BootstrapMethods in the attribute table. + className = "emptynumbootstrapmethods2"; + + // ======= execute test case #2 + // Expect a lack of main method, this implies that the class loaded correctly + // with an empty bootstrap_methods and did not generate ClassFormatError. + pb = ProcessTools.createJavaProcessBuilder("-cp", ".", className); + output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("java.lang.ClassFormatError"); + output.shouldContain("Main method not found in class " + className); + output.shouldHaveExitValue(1); + } +} diff --git a/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods.jar b/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods.jar new file mode 100644 index 0000000000000000000000000000000000000000..6ea40b970fbcd3840b3f2606199b58d70cd80336 GIT binary patch literal 940 zcmWIWW@Zs#;Nak3I2W?Qg#ih0GO#fCx`sIFdiuHP|2xINz|0Wf&CUT*!30$nfK#&w zPz7AGucM!*n`>~0p0C?y-!rFuymj?1@_OrPojY@WbCAIm;|EWR^t^m^Jbf>gu43Vg zcqRE_nVMF{4{=qs=S#FKo{Nh<5m%kYFg5#A(Z?c2up_<&v@|*ctpGU~;fTFxK9C2> zrsfuuROXfDCgtas6qghw7UZUuWaOt58|o$JBo-H2f6c#c$HvB%%qCaHrsl?W^2(j2 zNvHN)y0hfZpGl7<EjrS4=gOp>KU0#N%h<%+*c#Uy+2rzf&XGMOwf~o_x$;D)E{x4j zj;)N1&y8){l|z?~%t>-%3*?nANxe2JFox$0Pficd8-Y+!hs|>m!hSfdNl0LEN@L?l zNO{0E$%lsr?3Wuqq-NCvUAmBLzZjwW#SXt;l&RyF6oHa6r%&s9>YO}tzSz^(Tj#81 zVv4}Wg92Z+q(S|e^nh(L508z*8O|w;OmS>%U=LrKp4z(v=-Jy~4>K}}FrX$tSn2{L zKvV!vQJ~});Ek#kIZc3)9|G6{nQ*O0i4oZZP})I`2~gTWfI~ngfs}-97_u)>4eMjX XZ5T8v1H4(;K(@00p*T=^JvdAN|DzU0 literal 0 HcmV?d00001 diff --git a/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods1.jcod b/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods1.jcod new file mode 100644 index 00000000000..df1c210bee5 --- /dev/null +++ b/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods1.jcod @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +/* + * This test contains a BootstrapMethods attribute with an empty + * bootstrap_methods table. This yields a BootstrapMethods + * attribute length of 2 and should not cause a + * java.lang.ClassFormatError to be thrown. + */ +class emptynumbootstrapmethods1 { + 0xCAFEBABE; + 0; // minor version + 51; // version + [12] { // Constant Pool + ; // first element is empty + class #2; // #1 at 0x0A + Utf8 "emptynumbootstrapmethods1"; // #2 at 0x0D + class #4; // #3 at 0x1F + Utf8 "java/lang/Object"; // #4 at 0x22 + MethodHandle 5b #9; // #5 at 0x35 + NameAndType #7 #8; // #6 at 0x39 + Utf8 "equals"; // #7 at 0x3E + Utf8 "(Ljava/lang/Object;)Z"; // #8 at 0x47 + Method #3 #6; // #9 at 0x5F + Utf8 "equalsx"; // #10 at 0x3E + Utf8 "BootstrapMethods"; // #11 at 0x69 + } // Constant Pool + + 0x0001; // access + #1;// this_cpx + #3;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // fields + } // fields + + [0] { // methods + } // methods + + [1] { // Attributes + Attr(#11, 2) { // BootstrapMethods at 0x8A + [0] { // bootstrap_methods + } + } // end BootstrapMethods + } // Attributes +} // end class atrbsm00101m10p diff --git a/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods2.jcod b/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods2.jcod new file mode 100644 index 00000000000..428fad98a88 --- /dev/null +++ b/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods2.jcod @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +/* + * This test contains a BootstrapMethods attribute with an empty + * bootstrap_methods table. This yields a BootstrapMethods + * attribute length of 2 and should not cause a + * java.lang.ClassFormatError to be thrown. To ensure that an empty + * bootstrap_methods table is parsed correctly, another attribute, + * AnnotationDefault, follows the BootstrapMethods attribute in + * the attribute table. + */ + +class emptynumbootstrapmethods2 { + 0xCAFEBABE; + 0; // minor version + 51; // version + [14] { // Constant Pool + ; // first element is empty + class #2; // #1 at 0x0A + Utf8 "emptynumbootstrapmethods2"; // #2 at 0x0D + class #4; // #3 at 0x1F + Utf8 "java/lang/Object"; // #4 at 0x22 + MethodHandle 5b #9; // #5 at 0x35 + NameAndType #7 #8; // #6 at 0x39 + Utf8 "equals"; // #7 at 0x3E + Utf8 "(Ljava/lang/Object;)Z"; // #8 at 0x47 + Method #3 #6; // #9 at 0x5F + Utf8 "equalsx"; // #10 at 0x3E + Utf8 "BootstrapMethods"; // #11 at 0x69 + Utf8 "AnnotationDefault"; // #12 + Utf8 "LAnnotationDefaultI;"; // #13 + } // Constant Pool + + 0x0001; // access + #1;// this_cpx + #3;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // fields + } // fields + + [0] { // methods + } // methods + + [2] { // Attributes + Attr(#11, 2) { // BootstrapMethods at 0x8A + [0] { // bootstrap_methods + } + } // end BootstrapMethods + ; + Attr(#12) { // AnnotationDefault + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #13; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end AnnotationDefault + } // Attributes +} // end class atrbsm00101m10p From 54da05d84099388fa64414f8a761bd06b55bdf9f Mon Sep 17 00:00:00 2001 From: Ron Durbin <rdurbin@openjdk.org> Date: Thu, 15 May 2014 10:44:20 -0700 Subject: [PATCH 086/157] 8028749: java -version crashes with 'fatal error: heap walk aborted with error 1' Check_heap() should only call HeapWalk() when HeapLock() is successful. Reviewed-by: ctornqvi, sla, dcubed --- hotspot/src/os/windows/vm/os_windows.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 35c2fcfed64..04b72a9d37d 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -5005,7 +5005,11 @@ bool os::check_heap(bool force) { // wrong; at these points, eax contains the address of the offending block (I think). // To get to the exlicit error message(s) below, just continue twice. HANDLE heap = GetProcessHeap(); - { HeapLock(heap); + + // If we fail to lock the heap, then gflags.exe has been used + // or some other special heap flag has been set that prevents + // locking. We don't try to walk a heap we can't lock. + if (HeapLock(heap) != 0) { PROCESS_HEAP_ENTRY phe; phe.lpData = NULL; while (HeapWalk(heap, &phe) != 0) { From cc3c656cf1d6916619a14eb6402f5d320cd7fe37 Mon Sep 17 00:00:00 2001 From: Yuri Gaevsky <ygaevsky@azulsystems.com> Date: Thu, 15 May 2014 17:38:50 -0400 Subject: [PATCH 087/157] 8025580: Temporary flags: UseNewReflection and ReflectionWrapResolutionErrors The fix removes all UseNewReflection/ReflectionWrapResolutionErrors occurrences/logic and adds them into the list of obsolete_jvm_flags in arguments.cpp. Reviewed-by: coleenp, hseigel --- .../share/vm/classfile/systemDictionary.cpp | 2 - .../share/vm/classfile/systemDictionary.hpp | 2 +- hotspot/src/share/vm/classfile/verifier.cpp | 4 +- .../src/share/vm/interpreter/linkResolver.cpp | 1 - hotspot/src/share/vm/oops/method.cpp | 4 +- hotspot/src/share/vm/opto/library_call.cpp | 3 +- hotspot/src/share/vm/prims/jni.cpp | 4 +- hotspot/src/share/vm/prims/jvm.cpp | 9 +- hotspot/src/share/vm/runtime/arguments.cpp | 3 + hotspot/src/share/vm/runtime/globals.hpp | 16 ---- hotspot/src/share/vm/runtime/reflection.cpp | 96 +++++++------------ hotspot/src/share/vm/runtime/reflection.hpp | 6 +- hotspot/src/share/vm/runtime/vframe.cpp | 2 +- 13 files changed, 53 insertions(+), 99 deletions(-) diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp index 4a88a8c3d5d..d09de41114d 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp @@ -604,7 +604,6 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Ticks class_load_start_time = Ticks::now(); - // UseNewReflection // Fix for 4474172; see evaluation for more details class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader())); ClassLoaderData *loader_data = register_loader(class_loader, CHECK_NULL); @@ -898,7 +897,6 @@ Klass* SystemDictionary::find(Symbol* class_name, Handle protection_domain, TRAPS) { - // UseNewReflection // The result of this call should be consistent with the result // of the call to resolve_instance_class_or_null(). // See evaluation 6790209 and 4474172 for more details. diff --git a/hotspot/src/share/vm/classfile/systemDictionary.hpp b/hotspot/src/share/vm/classfile/systemDictionary.hpp index dad4b8efa66..4e1b75dc241 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.hpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp @@ -390,7 +390,7 @@ public: return k; } static Klass* check_klass_Opt_Only_JDK14NewRef(Klass* k) { - assert(JDK_Version::is_gte_jdk14x_version() && UseNewReflection, "JDK 1.4 only"); + assert(JDK_Version::is_gte_jdk14x_version(), "JDK 1.4 only"); // despite the optional loading, if you use this it must be present: return check_klass(k); } diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp index 2c1edcb6278..923a6f70d2c 100644 --- a/hotspot/src/share/vm/classfile/verifier.cpp +++ b/hotspot/src/share/vm/classfile/verifier.cpp @@ -211,9 +211,9 @@ bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool shou // reflection implementation, not just those associated with // sun/reflect/SerializationConstructorAccessor. // NOTE: this is called too early in the bootstrapping process to be - // guarded by Universe::is_gte_jdk14x_version()/UseNewReflection. + // guarded by Universe::is_gte_jdk14x_version(). // Also for lambda generated code, gte jdk8 - (!is_reflect || VerifyReflectionBytecodes)); + (!is_reflect)); } Symbol* Verifier::inference_verify( diff --git a/hotspot/src/share/vm/interpreter/linkResolver.cpp b/hotspot/src/share/vm/interpreter/linkResolver.cpp index 8ebb1ecabae..d732cb2eec5 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp @@ -950,7 +950,6 @@ void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method // reflection implementation, not just those associated with // sun/reflect/SerializationConstructorAccessor. bool is_reflect = JDK_Version::is_gte_jdk14x_version() && - UseNewReflection && klass_to_check->is_subclass_of( SystemDictionary::reflect_MagicAccessorImpl_klass()); diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index 0ce786e572f..ac2addae8ad 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -1019,13 +1019,11 @@ bool Method::should_not_be_cached() const { * security related stack walks (like Reflection.getCallerClass). */ bool Method::is_ignored_by_security_stack_walk() const { - const bool use_new_reflection = JDK_Version::is_gte_jdk14x_version() && UseNewReflection; - if (intrinsic_id() == vmIntrinsics::_invoke) { // This is Method.invoke() -- ignore it return true; } - if (use_new_reflection && + if (JDK_Version::is_gte_jdk14x_version() && method_holder()->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) { // This is an auxilary frame -- ignore it return true; diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index bf2d365a9d3..5cf1188435a 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -420,7 +420,6 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { return NULL; case vmIntrinsics::_getCallerClass: - if (!UseNewReflection) return NULL; if (!InlineReflectionGetCallerClass) return NULL; if (SystemDictionary::reflect_CallerSensitive_klass() == NULL) return NULL; break; diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index baf1cc6be21..6bbe5feb691 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -544,7 +544,7 @@ JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID meth if (m->is_initializer()) { reflection_method = Reflection::new_constructor(m, CHECK_NULL); } else { - reflection_method = Reflection::new_method(m, UseNewReflection, false, CHECK_NULL); + reflection_method = Reflection::new_method(m, false, CHECK_NULL); } ret = JNIHandles::make_local(env, reflection_method); return ret; @@ -2272,7 +2272,7 @@ JNI_ENTRY(jobject, jni_ToReflectedField(JNIEnv *env, jclass cls, jfieldID fieldI found = InstanceKlass::cast(k)->find_field_from_offset(offset, false, &fd); } assert(found, "bad fieldID passed into jni_ToReflectedField"); - oop reflected = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL); + oop reflected = Reflection::new_field(&fd, CHECK_NULL); ret = JNIHandles::make_local(env, reflected); return ret; JNI_END diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index 0fb14edfd97..5b96377b24a 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -1854,7 +1854,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, if (!publicOnly || fs.access_flags().is_public()) { fd.reinitialize(k(), fs.index()); - oop field = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL); + oop field = Reflection::new_field(&fd, CHECK_NULL); result->obj_at_put(out_idx, field); ++out_idx; } @@ -1932,7 +1932,7 @@ static jobjectArray get_class_declared_methods_helper( if (want_constructor) { m = Reflection::new_constructor(method, CHECK_NULL); } else { - m = Reflection::new_method(method, UseNewReflection, false, CHECK_NULL); + m = Reflection::new_method(method, false, CHECK_NULL); } result->obj_at_put(i, m); } @@ -2055,7 +2055,7 @@ static jobject get_method_at_helper(constantPoolHandle cp, jint index, bool forc } oop method; if (!m->is_initializer() || m->is_static()) { - method = Reflection::new_method(m, true, true, CHECK_NULL); + method = Reflection::new_method(m, true, CHECK_NULL); } else { method = Reflection::new_constructor(m, CHECK_NULL); } @@ -2105,7 +2105,7 @@ static jobject get_field_at_helper(constantPoolHandle cp, jint index, bool force if (target_klass == NULL) { THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "Unable to look up field in target class"); } - oop field = Reflection::new_field(&fd, true, CHECK_NULL); + oop field = Reflection::new_field(&fd, CHECK_NULL); return JNIHandles::make_local(field); } @@ -3521,7 +3521,6 @@ JVM_END JVM_ENTRY(jobject, JVM_LatestUserDefinedLoader(JNIEnv *env)) for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) { - // UseNewReflection vfst.skip_reflection_related_frames(); // Only needed for 1.4 reflection oop loader = vfst.method()->method_holder()->class_loader(); if (loader != NULL) { diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index e794c340a92..5bfaa639a0b 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -311,6 +311,9 @@ static ObsoleteFlag obsolete_jvm_flags[] = { { "UseBoundThreads", JDK_Version::jdk(9), JDK_Version::jdk(10) }, { "DefaultThreadPriority", JDK_Version::jdk(9), JDK_Version::jdk(10) }, { "NoYieldsInMicrolock", JDK_Version::jdk(9), JDK_Version::jdk(10) }, + { "UseNewReflection", JDK_Version::jdk(9), JDK_Version::jdk(10) }, + { "ReflectionWrapResolutionErrors",JDK_Version::jdk(9), JDK_Version::jdk(10) }, + { "VerifyReflectionBytecodes", JDK_Version::jdk(9), JDK_Version::jdk(10) }, { NULL, JDK_Version(0), JDK_Version(0) } }; diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index b3aeb1cda7c..597abcee8b2 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -3647,22 +3647,6 @@ class CommandLineFlags { \ /* New JDK 1.4 reflection implementation */ \ \ - develop(bool, UseNewReflection, true, \ - "Temporary flag for transition to reflection based on dynamic " \ - "bytecode generation in 1.4; can no longer be turned off in 1.4 " \ - "JDK, and is unneeded in 1.3 JDK, but marks most places VM " \ - "changes were needed") \ - \ - develop(bool, VerifyReflectionBytecodes, false, \ - "Force verification of 1.4 reflection bytecodes. Does not work " \ - "in situations like that described in 4486457 or for " \ - "constructors generated for serialization, so can not be enabled "\ - "in product.") \ - \ - product(bool, ReflectionWrapResolutionErrors, true, \ - "Temporary flag for transition to AbstractMethodError wrapped " \ - "in InvocationTargetException. See 6531596") \ - \ develop(intx, FastSuperclassLimit, 8, \ "Depth of hardwired instanceof accelerator array") \ \ diff --git a/hotspot/src/share/vm/runtime/reflection.cpp b/hotspot/src/share/vm/runtime/reflection.cpp index c692687a3a3..872d73c72e8 100644 --- a/hotspot/src/share/vm/runtime/reflection.cpp +++ b/hotspot/src/share/vm/runtime/reflection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -466,7 +466,6 @@ bool Reflection::verify_class_access(Klass* current_class, Klass* new_class, boo // New (1.4) reflection implementation. Allow all accesses from // sun/reflect/MagicAccessorImpl subclasses to succeed trivially. if ( JDK_Version::is_gte_jdk14x_version() - && UseNewReflection && current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) { return true; } @@ -571,7 +570,6 @@ bool Reflection::verify_field_access(Klass* current_class, // New (1.4) reflection implementation. Allow all accesses from // sun/reflect/MagicAccessorImpl subclasses to succeed trivially. if ( JDK_Version::is_gte_jdk14x_version() - && UseNewReflection && current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) { return true; } @@ -708,7 +706,7 @@ Handle Reflection::new_type(Symbol* signature, KlassHandle k, TRAPS) { } -oop Reflection::new_method(methodHandle method, bool intern_name, bool for_constant_pool_access, TRAPS) { +oop Reflection::new_method(methodHandle method, bool for_constant_pool_access, TRAPS) { // In jdk1.2.x, getMethods on an interface erroneously includes <clinit>, thus the complicated assert. // Also allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods. assert(!method()->is_initializer() || @@ -731,14 +729,8 @@ oop Reflection::new_method(methodHandle method, bool intern_name, bool for_const if (exception_types.is_null()) return NULL; Symbol* method_name = method->name(); - Handle name; - if (intern_name) { - // intern_name is only true with UseNewReflection - oop name_oop = StringTable::intern(method_name, CHECK_NULL); - name = Handle(THREAD, name_oop); - } else { - name = java_lang_String::create_from_symbol(method_name, CHECK_NULL); - } + oop name_oop = StringTable::intern(method_name, CHECK_NULL); + Handle name = Handle(THREAD, name_oop); if (name == NULL) return NULL; int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; @@ -825,16 +817,10 @@ oop Reflection::new_constructor(methodHandle method, TRAPS) { } -oop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) { +oop Reflection::new_field(fieldDescriptor* fd, TRAPS) { Symbol* field_name = fd->name(); - Handle name; - if (intern_name) { - // intern_name is only true with UseNewReflection - oop name_oop = StringTable::intern(field_name, CHECK_NULL); - name = Handle(THREAD, name_oop); - } else { - name = java_lang_String::create_from_symbol(field_name, CHECK_NULL); - } + oop name_oop = StringTable::intern(field_name, CHECK_NULL); + Handle name = Handle(THREAD, name_oop); Symbol* signature = fd->signature(); instanceKlassHandle holder (THREAD, fd->field_holder()); Handle type = new_type(signature, holder, CHECK_NULL); @@ -933,27 +919,23 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method, // resolve based on the receiver if (reflected_method->method_holder()->is_interface()) { // resolve interface call - if (ReflectionWrapResolutionErrors) { - // new default: 6531596 - // Match resolution errors with those thrown due to reflection inlining - // Linktime resolution & IllegalAccessCheck already done by Class.getMethod() - method = resolve_interface_call(klass, reflected_method, target_klass, receiver, THREAD); - if (HAS_PENDING_EXCEPTION) { - // Method resolution threw an exception; wrap it in an InvocationTargetException - oop resolution_exception = PENDING_EXCEPTION; - CLEAR_PENDING_EXCEPTION; - // JVMTI has already reported the pending exception - // JVMTI internal flag reset is needed in order to report InvocationTargetException - if (THREAD->is_Java_thread()) { - JvmtiExport::clear_detected_exception((JavaThread*) THREAD); - } - JavaCallArguments args(Handle(THREAD, resolution_exception)); - THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), - vmSymbols::throwable_void_signature(), - &args); + // + // Match resolution errors with those thrown due to reflection inlining + // Linktime resolution & IllegalAccessCheck already done by Class.getMethod() + method = resolve_interface_call(klass, reflected_method, target_klass, receiver, THREAD); + if (HAS_PENDING_EXCEPTION) { + // Method resolution threw an exception; wrap it in an InvocationTargetException + oop resolution_exception = PENDING_EXCEPTION; + CLEAR_PENDING_EXCEPTION; + // JVMTI has already reported the pending exception + // JVMTI internal flag reset is needed in order to report InvocationTargetException + if (THREAD->is_Java_thread()) { + JvmtiExport::clear_detected_exception((JavaThread*) THREAD); } - } else { - method = resolve_interface_call(klass, reflected_method, target_klass, receiver, CHECK_(NULL)); + JavaCallArguments args(Handle(THREAD, resolution_exception)); + THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), + vmSymbols::throwable_void_signature(), + &args); } } else { // if the method can be overridden, we resolve using the vtable index. @@ -970,24 +952,16 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method, // Check for abstract methods as well if (method->is_abstract()) { // new default: 6531596 - if (ReflectionWrapResolutionErrors) { - ResourceMark rm(THREAD); - Handle h_origexception = Exceptions::new_exception(THREAD, - vmSymbols::java_lang_AbstractMethodError(), - Method::name_and_sig_as_C_string(target_klass(), - method->name(), - method->signature())); - JavaCallArguments args(h_origexception); - THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), - vmSymbols::throwable_void_signature(), - &args); - } else { - ResourceMark rm(THREAD); - THROW_MSG_0(vmSymbols::java_lang_AbstractMethodError(), - Method::name_and_sig_as_C_string(target_klass(), - method->name(), - method->signature())); - } + ResourceMark rm(THREAD); + Handle h_origexception = Exceptions::new_exception(THREAD, + vmSymbols::java_lang_AbstractMethodError(), + Method::name_and_sig_as_C_string(target_klass(), + method->name(), + method->signature())); + JavaCallArguments args(h_origexception); + THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), + vmSymbols::throwable_void_signature(), + &args); } } } @@ -1006,7 +980,7 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method, // In the JDK 1.4 reflection implementation, the security check is // done at the Java level - if (!(JDK_Version::is_gte_jdk14x_version() && UseNewReflection)) { + if (!JDK_Version::is_gte_jdk14x_version()) { // Access checking (unless overridden by Method) if (!override) { @@ -1018,7 +992,7 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method, } } - } // !(Universe::is_gte_jdk14x_version() && UseNewReflection) + } // !Universe::is_gte_jdk14x_version() assert(ptypes->is_objArray(), "just checking"); int args_len = args.is_null() ? 0 : args->length(); diff --git a/hotspot/src/share/vm/runtime/reflection.hpp b/hotspot/src/share/vm/runtime/reflection.hpp index d8694948cd7..5757cfc39f5 100644 --- a/hotspot/src/share/vm/runtime/reflection.hpp +++ b/hotspot/src/share/vm/runtime/reflection.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -113,11 +113,11 @@ class Reflection: public AllStatic { // // Create a java.lang.reflect.Method object based on a method - static oop new_method(methodHandle method, bool intern_name, bool for_constant_pool_access, TRAPS); + static oop new_method(methodHandle method, bool for_constant_pool_access, TRAPS); // Create a java.lang.reflect.Constructor object based on a method static oop new_constructor(methodHandle method, TRAPS); // Create a java.lang.reflect.Field object based on a field descriptor - static oop new_field(fieldDescriptor* fd, bool intern_name, TRAPS); + static oop new_field(fieldDescriptor* fd, TRAPS); // Create a java.lang.reflect.Parameter object based on a // MethodParameterElement static oop new_parameter(Handle method, int index, Symbol* sym, diff --git a/hotspot/src/share/vm/runtime/vframe.cpp b/hotspot/src/share/vm/runtime/vframe.cpp index d5b5fa1f480..8b4d72f728e 100644 --- a/hotspot/src/share/vm/runtime/vframe.cpp +++ b/hotspot/src/share/vm/runtime/vframe.cpp @@ -473,7 +473,7 @@ void vframeStreamCommon::skip_prefixed_method_and_wrappers() { void vframeStreamCommon::skip_reflection_related_frames() { while (!at_end() && - (JDK_Version::is_gte_jdk14x_version() && UseNewReflection && + (JDK_Version::is_gte_jdk14x_version() && (method()->method_holder()->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass()) || method()->method_holder()->is_subclass_of(SystemDictionary::reflect_ConstructorAccessorImpl_klass())))) { next(); From c336175c946b5839c91487dc064fb0d767e0ccdc Mon Sep 17 00:00:00 2001 From: Coleen Phillimore <coleenp@openjdk.org> Date: Thu, 15 May 2014 18:23:26 -0400 Subject: [PATCH 088/157] 8038212: Method::is_valid_method() check has performance regression impact for stackwalking Only prune metaspace virtual spaces at safepoint so walking them is safe outside a safepoint. Reviewed-by: mgerdin, mgronlun, hseigel, stefank --- .../share/vm/classfile/classLoaderData.cpp | 29 +-------- .../share/vm/classfile/classLoaderData.hpp | 13 +++- .../concurrentMarkSweepGeneration.cpp | 4 +- .../gc_implementation/g1/g1CollectedHeap.cpp | 2 +- hotspot/src/share/vm/memory/allocation.cpp | 2 +- hotspot/src/share/vm/memory/metaspace.cpp | 60 +++++++++++-------- hotspot/src/share/vm/memory/metaspace.hpp | 5 +- hotspot/src/share/vm/oops/klass.cpp | 2 +- hotspot/src/share/vm/oops/method.cpp | 15 +++-- hotspot/src/share/vm/oops/method.hpp | 1 + hotspot/src/share/vm/runtime/os.cpp | 14 +++-- hotspot/src/share/vm/runtime/safepoint.cpp | 7 +++ .../share/vm/utilities/globalDefinitions.hpp | 2 +- 13 files changed, 84 insertions(+), 72 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classLoaderData.cpp b/hotspot/src/share/vm/classfile/classLoaderData.cpp index 4d716b9f38a..54f2225d3fe 100644 --- a/hotspot/src/share/vm/classfile/classLoaderData.cpp +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp @@ -549,6 +549,8 @@ ClassLoaderData* ClassLoaderDataGraph::_head = NULL; ClassLoaderData* ClassLoaderDataGraph::_unloading = NULL; ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL; +bool ClassLoaderDataGraph::_should_purge = false; + // Add a new class loader data node to the list. Assign the newly created // ClassLoaderData into the java/lang/ClassLoader object as a hidden field ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRAPS) { @@ -675,32 +677,6 @@ GrowableArray<ClassLoaderData*>* ClassLoaderDataGraph::new_clds() { return array; } -// For profiling and hsfind() only. Otherwise, this is unsafe (and slow). This -// is done lock free to avoid lock inversion problems. It is safe because -// new ClassLoaderData are added to the end of the CLDG, and only removed at -// safepoint. The _unloading list can be deallocated concurrently with CMS so -// this doesn't look in metaspace for classes that have been unloaded. -bool ClassLoaderDataGraph::contains(const void* x) { - if (DumpSharedSpaces) { - // There are only two metaspaces to worry about. - ClassLoaderData* ncld = ClassLoaderData::the_null_class_loader_data(); - return (ncld->ro_metaspace()->contains(x) || ncld->rw_metaspace()->contains(x)); - } - - if (UseSharedSpaces && MetaspaceShared::is_in_shared_space(x)) { - return true; - } - - for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { - if (cld->metaspace_or_null() != NULL && cld->metaspace_or_null()->contains(x)) { - return true; - } - } - - // Do not check unloading list because deallocation can be concurrent. - return false; -} - #ifndef PRODUCT bool ClassLoaderDataGraph::contains_loader_data(ClassLoaderData* loader_data) { for (ClassLoaderData* data = _head; data != NULL; data = data->next()) { @@ -759,6 +735,7 @@ bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure) { } void ClassLoaderDataGraph::purge() { + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!"); ClassLoaderData* list = _unloading; _unloading = NULL; ClassLoaderData* next = list; diff --git a/hotspot/src/share/vm/classfile/classLoaderData.hpp b/hotspot/src/share/vm/classfile/classLoaderData.hpp index e03d1625045..5be3caa6515 100644 --- a/hotspot/src/share/vm/classfile/classLoaderData.hpp +++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp @@ -66,6 +66,7 @@ class ClassLoaderDataGraph : public AllStatic { static ClassLoaderData* _unloading; // CMS support. static ClassLoaderData* _saved_head; + static bool _should_purge; static ClassLoaderData* add(Handle class_loader, bool anonymous, TRAPS); static void post_class_unload_events(void); @@ -87,12 +88,20 @@ class ClassLoaderDataGraph : public AllStatic { static void remember_new_clds(bool remember) { _saved_head = (remember ? _head : NULL); } static GrowableArray<ClassLoaderData*>* new_clds(); + static void set_should_purge(bool b) { _should_purge = b; } + static void purge_if_needed() { + // Only purge the CLDG for CMS if concurrent sweep is complete. + if (_should_purge) { + purge(); + // reset for next time. + set_should_purge(false); + } + } + static void dump_on(outputStream * const out) PRODUCT_RETURN; static void dump() { dump_on(tty); } static void verify(); - // expensive test for pointer in metaspace for debugging - static bool contains(const void* x); #ifndef PRODUCT static bool contains_loader_data(ClassLoaderData* loader_data); #endif diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index 7a4088555b3..43d6e923a7b 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -6362,7 +6362,9 @@ void CMSCollector::sweep(bool asynch) { verify_overflow_empty(); if (should_unload_classes()) { - ClassLoaderDataGraph::purge(); + // Delay purge to the beginning of the next safepoint. Metaspace::contains + // requires that the virtual spaces are stable and not deleted. + ClassLoaderDataGraph::set_should_purge(true); } _intra_sweep_timer.stop(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 575d3db9239..b29822387a2 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -5401,7 +5401,7 @@ public: if (_g1h->is_in_g1_reserved(p)) { _par_scan_state->push_on_queue(p); } else { - assert(!ClassLoaderDataGraph::contains((address)p), + assert(!Metaspace::contains((const void*)p), err_msg("Otherwise need to call _copy_metadata_obj_cl->do_oop(p) " PTR_FORMAT, p)); _copy_non_heap_obj_cl->do_oop(p); diff --git a/hotspot/src/share/vm/memory/allocation.cpp b/hotspot/src/share/vm/memory/allocation.cpp index bff2a92a1b0..2a3f4135617 100644 --- a/hotspot/src/share/vm/memory/allocation.cpp +++ b/hotspot/src/share/vm/memory/allocation.cpp @@ -75,7 +75,7 @@ bool MetaspaceObj::is_shared() const { } bool MetaspaceObj::is_metaspace_object() const { - return ClassLoaderDataGraph::contains((void*)this); + return Metaspace::contains((void*)this); } void MetaspaceObj::print_address_on(outputStream* st) const { diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index e005263aa0b..11e72d4ed27 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -316,6 +316,8 @@ class VirtualSpaceNode : public CHeapObj<mtClass> { MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); } MetaWord* end() const { return (MetaWord*) _virtual_space.high(); } + bool contains(const void* ptr) { return ptr >= low() && ptr < high(); } + size_t reserved_words() const { return _virtual_space.reserved_size() / BytesPerWord; } size_t committed_words() const { return _virtual_space.actual_committed_size() / BytesPerWord; } @@ -557,6 +559,8 @@ class VirtualSpaceList : public CHeapObj<mtClass> { void inc_virtual_space_count(); void dec_virtual_space_count(); + bool contains(const void* ptr); + // Unlink empty VirtualSpaceNodes and free it. void purge(ChunkManager* chunk_manager); @@ -641,8 +645,6 @@ class SpaceManager : public CHeapObj<mtClass> { // Accessors Metachunk* chunks_in_use(ChunkIndex index) const { return _chunks_in_use[index]; } void set_chunks_in_use(ChunkIndex index, Metachunk* v) { - // ensure lock-free iteration sees fully initialized node - OrderAccess::storestore(); _chunks_in_use[index] = v; } @@ -757,8 +759,6 @@ class SpaceManager : public CHeapObj<mtClass> { void print_on(outputStream* st) const; void locked_print_chunks_in_use_on(outputStream* st) const; - bool contains(const void *ptr); - void verify(); void verify_chunk_size(Metachunk* chunk); NOT_PRODUCT(void mangle_freed_chunks();) @@ -1078,6 +1078,7 @@ void ChunkManager::remove_chunk(Metachunk* chunk) { // nodes with a 0 container_count. Remove Metachunks in // the node from their respective freelists. void VirtualSpaceList::purge(ChunkManager* chunk_manager) { + assert(SafepointSynchronize::is_at_safepoint(), "must be called at safepoint for contains to work"); assert_lock_strong(SpaceManager::expand_lock()); // Don't use a VirtualSpaceListIterator because this // list is being changed and a straightforward use of an iterator is not safe. @@ -1111,8 +1112,8 @@ void VirtualSpaceList::purge(ChunkManager* chunk_manager) { } #ifdef ASSERT if (purged_vsl != NULL) { - // List should be stable enough to use an iterator here. - VirtualSpaceListIterator iter(virtual_space_list()); + // List should be stable enough to use an iterator here. + VirtualSpaceListIterator iter(virtual_space_list()); while (iter.repeat()) { VirtualSpaceNode* vsl = iter.get_next(); assert(vsl != purged_vsl, "Purge of vsl failed"); @@ -1121,6 +1122,23 @@ void VirtualSpaceList::purge(ChunkManager* chunk_manager) { #endif } + +// This function looks at the mmap regions in the metaspace without locking. +// The chunks are added with store ordering and not deleted except for at +// unloading time during a safepoint. +bool VirtualSpaceList::contains(const void* ptr) { + // List should be stable enough to use an iterator here because removing virtual + // space nodes is only allowed at a safepoint. + VirtualSpaceListIterator iter(virtual_space_list()); + while (iter.repeat()) { + VirtualSpaceNode* vsn = iter.get_next(); + if (vsn->contains(ptr)) { + return true; + } + } + return false; +} + void VirtualSpaceList::retire_current_virtual_space() { assert_lock_strong(SpaceManager::expand_lock()); @@ -1210,6 +1228,8 @@ bool VirtualSpaceList::create_new_virtual_space(size_t vs_word_size) { } else { assert(new_entry->reserved_words() == vs_word_size, "Reserved memory size differs from requested memory size"); + // ensure lock-free iteration sees fully initialized node + OrderAccess::storestore(); link_vs(new_entry); return true; } @@ -2434,21 +2454,6 @@ MetaWord* SpaceManager::allocate_work(size_t word_size) { return result; } -// This function looks at the chunks in the metaspace without locking. -// The chunks are added with store ordering and not deleted except for at -// unloading time. -bool SpaceManager::contains(const void *ptr) { - for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) - { - Metachunk* curr = chunks_in_use(i); - while (curr != NULL) { - if (curr->contains(ptr)) return true; - curr = curr->next(); - } - } - return false; -} - void SpaceManager::verify() { // If there are blocks in the dictionary, then // verification of chunks does not work since @@ -3538,11 +3543,15 @@ void Metaspace::print_on(outputStream* out) const { } bool Metaspace::contains(const void* ptr) { - if (vsm()->contains(ptr)) return true; - if (using_class_space()) { - return class_vsm()->contains(ptr); + if (UseSharedSpaces && MetaspaceShared::is_in_shared_space(ptr)) { + return true; } - return false; + + if (using_class_space() && get_space_list(ClassType)->contains(ptr)) { + return true; + } + + return get_space_list(NonClassType)->contains(ptr); } void Metaspace::verify() { @@ -3787,5 +3796,4 @@ void TestVirtualSpaceNode_test() { TestVirtualSpaceNodeTest::test(); TestVirtualSpaceNodeTest::test_is_available(); } - #endif diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index 1beddef8e6b..22e21b80d3d 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -232,7 +232,8 @@ class Metaspace : public CHeapObj<mtClass> { MetaWord* expand_and_allocate(size_t size, MetadataType mdtype); - bool contains(const void* ptr); + static bool contains(const void* ptr); + void dump(outputStream* const out) const; // Free empty virtualspaces diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp index 12e5b5ec708..d81dceb8f37 100644 --- a/hotspot/src/share/vm/oops/klass.cpp +++ b/hotspot/src/share/vm/oops/klass.cpp @@ -640,7 +640,7 @@ void Klass::verify_on(outputStream* st) { // This can be expensive, but it is worth checking that this klass is actually // in the CLD graph but not in production. - assert(ClassLoaderDataGraph::contains((address)this), "Should be"); + assert(Metaspace::contains((address)this), "Should be"); guarantee(this->is_klass(),"should be klass"); diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index ac2addae8ad..01ef61f2386 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -1866,6 +1866,14 @@ void Method::clear_jmethod_ids(ClassLoaderData* loader_data) { loader_data->jmethod_ids()->clear_all_methods(); } +bool Method::has_method_vptr(const void* ptr) { + Method m; + // This assumes that the vtbl pointer is the first word of a C++ object. + // This assumption is also in universe.cpp patch_klass_vtble + void* vtbl2 = dereference_vptr((const void*)&m); + void* this_vtbl = dereference_vptr(ptr); + return vtbl2 == this_vtbl; +} // Check that this pointer is valid by checking that the vtbl pointer matches bool Method::is_valid_method() const { @@ -1874,12 +1882,7 @@ bool Method::is_valid_method() const { } else if (!is_metaspace_object()) { return false; } else { - Method m; - // This assumes that the vtbl pointer is the first word of a C++ object. - // This assumption is also in universe.cpp patch_klass_vtble - void* vtbl2 = dereference_vptr((void*)&m); - void* this_vtbl = dereference_vptr((void*)this); - return vtbl2 == this_vtbl; + return has_method_vptr((const void*)this); } } diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp index 7d5afaec0b8..764264aa6dc 100644 --- a/hotspot/src/share/vm/oops/method.hpp +++ b/hotspot/src/share/vm/oops/method.hpp @@ -861,6 +861,7 @@ class Method : public Metadata { const char* internal_name() const { return "{method}"; } // Check for valid method pointer + static bool has_method_vptr(const void* ptr); bool is_valid_method() const; // Verify diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp index 70c6c064fbf..04c008431c7 100644 --- a/hotspot/src/share/vm/runtime/os.cpp +++ b/hotspot/src/share/vm/runtime/os.cpp @@ -1097,11 +1097,15 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) { } - // Check if in metaspace. - if (ClassLoaderDataGraph::contains((address)addr)) { - // Use addr->print() from the debugger instead (not here) - st->print_cr(INTPTR_FORMAT - " is pointing into metadata", addr); + // Check if in metaspace and print types that have vptrs (only method now) + if (Metaspace::contains(addr)) { + if (Method::has_method_vptr((const void*)addr)) { + ((Method*)addr)->print_value_on(st); + st->cr(); + } else { + // Use addr->print() from the debugger instead (not here) + st->print_cr(INTPTR_FORMAT " is pointing into metadata", addr); + } return; } diff --git a/hotspot/src/share/vm/runtime/safepoint.cpp b/hotspot/src/share/vm/runtime/safepoint.cpp index a2f16faa06f..e71185d431d 100644 --- a/hotspot/src/share/vm/runtime/safepoint.cpp +++ b/hotspot/src/share/vm/runtime/safepoint.cpp @@ -541,6 +541,13 @@ void SafepointSynchronize::do_cleanup_tasks() { gclog_or_tty->rotate_log(false); } + { + // CMS delays purging the CLDG until the beginning of the next safepoint and to + // make sure concurrent sweep is done + TraceTime t7("purging class loader data graph", TraceSafepointCleanupTime); + ClassLoaderDataGraph::purge_if_needed(); + } + if (MemTracker::is_on()) { MemTracker::sync(); } diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp index 50074f387b5..4c963e72808 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp @@ -1385,7 +1385,7 @@ inline intptr_t p2i(const void * p) { // All C++ compilers that we know of have the vtbl pointer in the first // word. If there are exceptions, this function needs to be made compiler // specific. -static inline void* dereference_vptr(void* addr) { +static inline void* dereference_vptr(const void* addr) { return *(void**)addr; } From ec3e742de183a38546c6009791e8f1f863b44d78 Mon Sep 17 00:00:00 2001 From: Yumin Qi <yumin.qi@oracle.com> Date: Thu, 15 May 2014 20:16:14 -0700 Subject: [PATCH 089/157] 8042885: java does not take hexadecimal number as vm option Java does not take number with hexadecimal format as options, fix enable hexadecimal format number can be used as vm option. Reviewed-by: coleenp, lfoltan, ctornqvi, hseigel, mseledtsov --- hotspot/src/share/vm/runtime/arguments.cpp | 15 ++++-- .../share/vm/utilities/globalDefinitions.hpp | 3 ++ .../runtime/CommandLine/TestHexArguments.java | 49 +++++++++++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 hotspot/test/runtime/CommandLine/TestHexArguments.java diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 5bfaa639a0b..29da2ec9034 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -583,11 +583,20 @@ char* SysClassPath::add_jars_to_path(char* path, const char* directory) { // Parses a memory size specification string. static bool atomull(const char *s, julong* result) { julong n = 0; - int args_read = sscanf(s, JULONG_FORMAT, &n); + int args_read = 0; + bool is_hex = false; + // Skip leading 0[xX] for hexadecimal + if (*s =='0' && (*(s+1) == 'x' || *(s+1) == 'X')) { + s += 2; + is_hex = true; + args_read = sscanf(s, JULONG_FORMAT_X, &n); + } else { + args_read = sscanf(s, JULONG_FORMAT, &n); + } if (args_read != 1) { return false; } - while (*s != '\0' && isdigit(*s)) { + while (*s != '\0' && (isdigit(*s) || (is_hex && isxdigit(*s)))) { s++; } // 4705540: illegal if more characters are found after the first non-digit @@ -781,7 +790,7 @@ bool Arguments::parse_argument(const char* arg, Flag::Flags origin) { } } -#define VALUE_RANGE "[-kmgtKMGT0123456789]" +#define VALUE_RANGE "[-kmgtxKMGTX0123456789abcdefABCDEF]" if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE "=" "%" XSTR(BUFLEN) VALUE_RANGE "%c", name, value, &dummy) == 2) { return set_numeric_flag(name, value, origin); } diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp index 4c963e72808..2bbd31afb76 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp @@ -1346,6 +1346,9 @@ inline intptr_t p2i(const void * p) { #ifndef JULONG_FORMAT #define JULONG_FORMAT UINT64_FORMAT #endif +#ifndef JULONG_FORMAT_X +#define JULONG_FORMAT_X UINT64_FORMAT_X +#endif // Format pointers which change size between 32- and 64-bit. #ifdef _LP64 diff --git a/hotspot/test/runtime/CommandLine/TestHexArguments.java b/hotspot/test/runtime/CommandLine/TestHexArguments.java new file mode 100644 index 00000000000..1fd33466662 --- /dev/null +++ b/hotspot/test/runtime/CommandLine/TestHexArguments.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @bug 8042885 + * @summary Make sure there is no error using hexadecimal format in vm options + * @author Yumin Qi + * @library /testlibrary + */ + +import java.io.File; +import com.oracle.java.testlibrary.*; + +public class TestHexArguments { + public static void main(String args[]) throws Exception { + String[] javaArgs = {"-XX:SharedBaseAddress=0x1D000000", "-version"}; + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, javaArgs); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("Could not create the Java Virtual Machine"); + output.shouldHaveExitValue(0); + + String[] javaArgs1 = {"-XX:SharedBaseAddress=1D000000", "-version"}; + pb = ProcessTools.createJavaProcessBuilder(true, javaArgs1); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("Could not create the Java Virtual Machine"); + } +} From 911a9fcf979659fbb1445f9391290e8d3d3e0721 Mon Sep 17 00:00:00 2001 From: Jan Lahoda <jlahoda@openjdk.org> Date: Fri, 16 May 2014 10:52:07 +0200 Subject: [PATCH 090/157] 8043186: javac test langtools/tools/javac/util/StringUtilsTest.java fails The result of String.toLowerCase.indexOf does not always point at the start of the given string in the non-lowercased text. Reviewed-by: jjg, bpatel --- .../formats/html/HtmlDocletWriter.java | 47 +++++++++---------- .../formats/html/MethodWriterImpl.java | 20 +------- .../com/sun/tools/javac/util/StringUtils.java | 19 +++++++- .../testRelativeLinks/TestRelativeLinks.java | 2 +- .../sun/javadoc/testRelativeLinks/pkg/C.java | 4 +- .../javadoc/testTopOption/TestTopOption.java | 27 ++++++++++- .../tools/javac/util/StringUtilsTest.java | 12 +++-- 7 files changed, 76 insertions(+), 55 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java index a92956eccf3..13c6637fc98 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java @@ -28,6 +28,8 @@ package com.sun.tools.doclets.formats.html; import java.io.*; import java.text.SimpleDateFormat; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import com.sun.javadoc.*; import com.sun.tools.doclets.formats.html.markup.*; @@ -139,42 +141,37 @@ public class HtmlDocletWriter extends HtmlDocWriter { if (index < 0) { return htmlstr; } - String lowerHtml = StringUtils.toLowerCase(htmlstr); - final String docroot = "{@docroot}"; - // Return index of first occurrence of {@docroot} - // Note: {@docRoot} is not case sensitive when passed in w/command line option - index = lowerHtml.indexOf(docroot, index); - if (index < 0) { + Matcher docrootMatcher = docrootPattern.matcher(htmlstr); + if (!docrootMatcher.find()) { return htmlstr; } StringBuilder buf = new StringBuilder(); - int previndex = 0; - while (true) { - // Search for lowercase version of {@docRoot} - index = lowerHtml.indexOf(docroot, previndex); - // If next {@docRoot} tag not found, append rest of htmlstr and exit loop - if (index < 0) { - buf.append(htmlstr.substring(previndex)); - break; - } - // If next {@docroot} tag found, append htmlstr up to start of tag - buf.append(htmlstr.substring(previndex, index)); - previndex = index + docroot.length(); - if (configuration.docrootparent.length() > 0 && htmlstr.startsWith("/..", previndex)) { + int prevEnd = 0; + do { + int match = docrootMatcher.start(); + // append htmlstr up to start of next {@docroot} + buf.append(htmlstr.substring(prevEnd, match)); + prevEnd = docrootMatcher.end(); + if (configuration.docrootparent.length() > 0 && htmlstr.startsWith("/..", prevEnd)) { // Insert the absolute link if {@docRoot} is followed by "/..". buf.append(configuration.docrootparent); - previndex += 3; + prevEnd += 3; } else { // Insert relative path where {@docRoot} was located buf.append(pathToRoot.isEmpty() ? "." : pathToRoot.getPath()); } // Append slash if next character is not a slash - if (previndex < htmlstr.length() && htmlstr.charAt(previndex) != '/') { + if (prevEnd < htmlstr.length() && htmlstr.charAt(prevEnd) != '/') { buf.append('/'); } - } + } while (docrootMatcher.find()); + buf.append(htmlstr.substring(prevEnd)); return buf.toString(); } + //where: + // Note: {@docRoot} is not case sensitive when passed in w/command line option: + private static final Pattern docrootPattern = + Pattern.compile(Pattern.quote("{@docroot}"), Pattern.CASE_INSENSITIVE); /** * Get the script to show or hide the All classes link. @@ -1690,13 +1687,13 @@ public class HtmlDocletWriter extends HtmlDocWriter { } //Redirect all relative links. - int end, begin = StringUtils.toLowerCase(text).indexOf("<a"); + int end, begin = StringUtils.indexOfIgnoreCase(text, "<a"); if(begin >= 0){ StringBuilder textBuff = new StringBuilder(text); while(begin >=0){ if (textBuff.length() > begin + 2 && ! Character.isWhitespace(textBuff.charAt(begin+2))) { - begin = StringUtils.toLowerCase(textBuff.toString()).indexOf("<a", begin + 1); + begin = StringUtils.indexOfIgnoreCase(textBuff.toString(), "<a", begin + 1); continue; } @@ -1736,7 +1733,7 @@ public class HtmlDocletWriter extends HtmlDocWriter { + redirectPathFromRoot.resolve(relativeLink).getPath(); textBuff.replace(begin, end, relativeLink); } - begin = StringUtils.toLowerCase(textBuff.toString()).indexOf("<a", begin + 1); + begin = StringUtils.indexOfIgnoreCase(textBuff.toString(), "<a", begin + 1); } return textBuff.toString(); } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java index a63ffac25fa..8ff82ab0ccf 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -331,24 +331,6 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter } } - /** - * Parse the <Code> tag and return the text. - */ - protected String parseCodeTag(String tag){ - if(tag == null){ - return ""; - } - - String lc = StringUtils.toLowerCase(tag); - int begin = lc.indexOf("<code>"); - int end = lc.indexOf("</code>"); - if(begin == -1 || end == -1 || end <= begin){ - return tag; - } else { - return tag.substring(begin + 6, end); - } - } - /** * {@inheritDoc} */ diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/StringUtils.java b/langtools/src/share/classes/com/sun/tools/javac/util/StringUtils.java index 4f6d36ab03e..b23af8e5f14 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/StringUtils.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/StringUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ package com.sun.tools.javac.util; import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** A collection of utilities for String manipulation. * @@ -50,4 +52,19 @@ public class StringUtils { return source.toUpperCase(Locale.US); } + /**Case insensitive version of {@link String#indexOf(java.lang.String)}. Equivalent to + * {@code text.indexOf(str)}, except the matching is case insensitive. + */ + public static int indexOfIgnoreCase(String text, String str) { + return indexOfIgnoreCase(text, str, 0); + } + + /**Case insensitive version of {@link String#indexOf(java.lang.String, int)}. Equivalent to + * {@code text.indexOf(str, startIndex)}, except the matching is case insensitive. + */ + public static int indexOfIgnoreCase(String text, String str, int startIndex) { + Matcher m = Pattern.compile(Pattern.quote(str), Pattern.CASE_INSENSITIVE).matcher(text); + return m.find(startIndex) ? m.start() : -1; + } + } diff --git a/langtools/test/com/sun/javadoc/testRelativeLinks/TestRelativeLinks.java b/langtools/test/com/sun/javadoc/testRelativeLinks/TestRelativeLinks.java index 8d53c8dc014..34bd4f5fa4f 100644 --- a/langtools/test/com/sun/javadoc/testRelativeLinks/TestRelativeLinks.java +++ b/langtools/test/com/sun/javadoc/testRelativeLinks/TestRelativeLinks.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4460354 8014636 + * @bug 4460354 8014636 8043186 * @summary Test to make sure that relative paths are redirected in the * output so that they are not broken. * @author jamieh diff --git a/langtools/test/com/sun/javadoc/testRelativeLinks/pkg/C.java b/langtools/test/com/sun/javadoc/testRelativeLinks/pkg/C.java index c899eca037b..12af871502e 100644 --- a/langtools/test/com/sun/javadoc/testRelativeLinks/pkg/C.java +++ b/langtools/test/com/sun/javadoc/testRelativeLinks/pkg/C.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ package pkg; public class C { /** - * Here is a relative link in a field: + * Here is a relative link in a field:\u0130 * <a href="relative-field-link.html">relative field link</a>. */ public C field = null; diff --git a/langtools/test/com/sun/javadoc/testTopOption/TestTopOption.java b/langtools/test/com/sun/javadoc/testTopOption/TestTopOption.java index 7d173ed24e6..35bf0337a4d 100644 --- a/langtools/test/com/sun/javadoc/testTopOption/TestTopOption.java +++ b/langtools/test/com/sun/javadoc/testTopOption/TestTopOption.java @@ -23,7 +23,7 @@ /* * @test - * @bug 6227616 + * @bug 6227616 8043186 * @summary Test the new -top option. * @author jamieh * @library ../lib @@ -43,7 +43,30 @@ public class TestTopOption extends JavadocTester { javadoc("-overview", testSrc("overview.html"), "-use", "-top", "TOP TEXT", - "-d", "out", + "-d", "out-1", + "-sourcepath", testSrc, + "pkg"); + checkExit(Exit.OK); + + checkTopText( + "pkg/AnnotationType.html", + "pkg/class-use/AnnotationType.html", + "pkg/Cl.html", + "pkg/class-use/Cl.html", + "pkg/package-summary.html", + "pkg/package-use.html", + "overview-summary.html", + "overview-tree.html", + "constant-values.html", + "help-doc.html"); + } + + @Test + void testDocRootRewrite() { + javadoc("-overview", testSrc("overview.html"), + "-use", + "-top", "\u0130{@docroot}TOP TEXT", + "-d", "out-2", "-sourcepath", testSrc, "pkg"); checkExit(Exit.OK); diff --git a/langtools/test/tools/javac/util/StringUtilsTest.java b/langtools/test/tools/javac/util/StringUtilsTest.java index ec8db20ef77..854a77381b1 100644 --- a/langtools/test/tools/javac/util/StringUtilsTest.java +++ b/langtools/test/tools/javac/util/StringUtilsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /** * @test - * @bug 8029800 + * @bug 8029800 8043186 * @summary Unit test StringUtils * @run main StringUtilsTest */ @@ -44,12 +44,14 @@ public class StringUtilsTest { assertEquals("\u0131", "I".toLowerCase()); assertEquals("\u0130", "i".toUpperCase()); - //verify the StringUtils does what it should + //verify the StringUtils.toLowerCase/toUpperCase do what they should: assertEquals("i", StringUtils.toLowerCase("I")); assertEquals("I", StringUtils.toUpperCase("i")); - //verify we can use index from indexOf of toLowerCase String in the original: - assertEquals(2, StringUtils.toLowerCase("\u0130\u0130lookFor").indexOf("lookfor")); + //verify StringUtils.caseInsensitiveIndexOf works: + assertEquals(2, StringUtils.indexOfIgnoreCase(" lookFor", "lookfor")); + assertEquals(11, StringUtils.indexOfIgnoreCase(" lookFor LOOKfor", "lookfor", 11)); + assertEquals(2, StringUtils.indexOfIgnoreCase("\u0130\u0130lookFor", "lookfor")); } void assertEquals(String expected, String actual) { From c9787c534d9193de926d0f1bd395f9cf7159320a Mon Sep 17 00:00:00 2001 From: Alexander Stepanov <alexander.v.stepanov@oracle.com> Date: Fri, 16 May 2014 17:41:47 +0400 Subject: [PATCH 091/157] 8042120: Fix doclint warnings from javax.swing.text.html.parser Reviewed-by: alexsch --- .../swing/text/html/parser/AttributeList.java | 9 +++ .../swing/text/html/parser/ContentModel.java | 23 +++++++ .../javax/swing/text/html/parser/DTD.java | 50 ++++++++++---- .../javax/swing/text/html/parser/Element.java | 33 ++++++++- .../javax/swing/text/html/parser/Parser.java | 69 ++++++++++++++++++- 5 files changed, 168 insertions(+), 16 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/text/html/parser/AttributeList.java b/jdk/src/share/classes/javax/swing/text/html/parser/AttributeList.java index 8674c7fac74..2a87568aa32 100644 --- a/jdk/src/share/classes/javax/swing/text/html/parser/AttributeList.java +++ b/jdk/src/share/classes/javax/swing/text/html/parser/AttributeList.java @@ -59,6 +59,8 @@ class AttributeList implements DTDConstants, Serializable { /** * Create an attribute list element. + * + * @param name the attribute name */ public AttributeList(String name) { this.name = name; @@ -66,6 +68,13 @@ class AttributeList implements DTDConstants, Serializable { /** * Create an attribute list element. + * + * @param name the attribute name + * @param type the attribute type + * @param modifier the attribute modifier + * @param value the default attribute value + * @param values the possible attribute values + * @param next the next attribute in the list */ public AttributeList(String name, int type, int modifier, String value, Vector<?> values, AttributeList next) { this.name = name; diff --git a/jdk/src/share/classes/javax/swing/text/html/parser/ContentModel.java b/jdk/src/share/classes/javax/swing/text/html/parser/ContentModel.java index 6dbd6e6b5a5..59a3901d493 100644 --- a/jdk/src/share/classes/javax/swing/text/html/parser/ContentModel.java +++ b/jdk/src/share/classes/javax/swing/text/html/parser/ContentModel.java @@ -62,6 +62,8 @@ public final class ContentModel implements Serializable { /** * Create a content model for an element. + * + * @param content the element */ public ContentModel(Element content) { this(0, content, null); @@ -69,6 +71,9 @@ public final class ContentModel implements Serializable { /** * Create a content model of a particular type. + * + * @param type the type + * @param content the content */ public ContentModel(int type, ContentModel content) { this(type, content, null); @@ -76,6 +81,10 @@ public final class ContentModel implements Serializable { /** * Create a content model of a particular type. + * + * @param type the type + * @param content the content + * @param next the next content model */ public ContentModel(int type, Object content, ContentModel next) { this.type = type; @@ -86,6 +95,9 @@ public final class ContentModel implements Serializable { /** * Return true if the content model could * match an empty input stream. + * + * @return {@code true} if the content model could + * match an empty input stream */ public boolean empty() { switch (type) { @@ -119,6 +131,8 @@ public final class ContentModel implements Serializable { /** * Update elemVec with the list of elements that are * part of the this contentModel. + * + * @param elemVec the list of elements */ public void getElements(Vector<Element> elemVec) { switch (type) { @@ -148,6 +162,11 @@ public final class ContentModel implements Serializable { /** * Return true if the token could potentially be the * first token in the input stream. + * + * @param token the token + * + * @return {@code true} if the token could potentially be the first token + * in the input stream */ public boolean first(Object token) { switch (type) { @@ -206,6 +225,8 @@ public final class ContentModel implements Serializable { /** * Return the element that must be next. + * + * @return the element that must be next */ public Element first() { switch (type) { @@ -226,6 +247,8 @@ public final class ContentModel implements Serializable { /** * Convert to a string. + * + * @return the string representation of this {@code ContentModel} */ public String toString() { switch (type) { diff --git a/jdk/src/share/classes/javax/swing/text/html/parser/DTD.java b/jdk/src/share/classes/javax/swing/text/html/parser/DTD.java index b0787eabbb0..2845ae49b4b 100644 --- a/jdk/src/share/classes/javax/swing/text/html/parser/DTD.java +++ b/jdk/src/share/classes/javax/swing/text/html/parser/DTD.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,6 +102,7 @@ class DTD implements DTDConstants { /** * Gets an entity by name. + * @param name the entity name * @return the <code>Entity</code> corresponding to the * <code>name</code> <code>String</code> */ @@ -111,6 +112,7 @@ class DTD implements DTDConstants { /** * Gets a character entity. + * @param ch the character * @return the <code>Entity</code> corresponding to the * <code>ch</code> character */ @@ -193,13 +195,15 @@ class DTD implements DTDConstants { * specified parameters. If one doesn't exist, a new * one is created and returned. * - * @param name the name of the <code>Element</code> - * @param type the type of the <code>Element</code> - * @param omitStart <code>true</code> if start should be omitted - * @param omitEnd <code>true</code> if end should be omitted - * @param content the <code>ContentModel</code> - * @param atts the <code>AttributeList</code> specifying the - * <code>Element</code> + * @param name the name of the <code>Element</code> + * @param type the type of the <code>Element</code> + * @param omitStart <code>true</code> if start should be omitted + * @param omitEnd <code>true</code> if end should be omitted + * @param content the <code>ContentModel</code> + * @param exclusions the set of elements that must not occur inside the element + * @param inclusions the set of elements that can occur inside the element + * @param atts the <code>AttributeList</code> specifying the + * <code>Element</code> * @return the <code>Element</code> specified */ public Element defineElement(String name, int type, @@ -231,6 +235,8 @@ class DTD implements DTDConstants { /** * Creates and returns a character <code>Entity</code>. * @param name the entity's name + * @param type the entity's type + * @param ch the entity's value (character) * @return the new character <code>Entity</code> */ public Entity defEntity(String name, int type, int ch) { @@ -241,6 +247,8 @@ class DTD implements DTDConstants { /** * Creates and returns an <code>Entity</code>. * @param name the entity's name + * @param type the entity's type + * @param str the entity's data section * @return the new <code>Entity</code> */ protected Entity defEntity(String name, int type, String str) { @@ -252,7 +260,14 @@ class DTD implements DTDConstants { /** * Creates and returns an <code>Element</code>. - * @param name the element's name + * @param name the element's name + * @param type the element's type + * @param omitStart {@code true} if the element needs no starting tag + * @param omitEnd {@code true} if the element needs no closing tag + * @param content the element's content + * @param exclusions the elements that must be excluded from the content of the element + * @param inclusions the elements that can be included as the content of the element + * @param atts the attributes of the element * @return the new <code>Element</code> */ protected Element defElement(String name, int type, @@ -280,11 +295,18 @@ class DTD implements DTDConstants { } /** - * Creates and returns an <code>AttributeList</code>. - * @param name the attribute list's name + * Creates and returns an <code>AttributeList</code> responding to a new attribute. + * @param name the attribute's name + * @param type the attribute's type + * @param modifier the attribute's modifier + * @param value the default value of the attribute + * @param values the allowed values for the attribute (multiple values could be separated by '|') + * @param atts the previous attribute of the element; to be placed to {@code AttributeList.next}, + * creating a linked list * @return the new <code>AttributeList</code> */ - protected AttributeList defAttributeList(String name, int type, int modifier, String value, String values, AttributeList atts) { + protected AttributeList defAttributeList(String name, int type, int modifier, + String value, String values, AttributeList atts) { Vector<String> vals = null; if (values != null) { vals = new Vector<String>(); @@ -301,6 +323,8 @@ class DTD implements DTDConstants { /** * Creates and returns a new content model. * @param type the type of the new content model + * @param obj the content of the content model + * @param next pointer to the next content model * @return the new <code>ContentModel</code> */ protected ContentModel defContentModel(int type, Object obj, ContentModel next) { @@ -332,6 +356,7 @@ class DTD implements DTDConstants { * * @param name the name of the DTD * @return the DTD which corresponds to <code>name</code> + * @throws IOException if an I/O error occurs */ public static DTD getDTD(String name) throws IOException { name = name.toLowerCase(); @@ -359,6 +384,7 @@ class DTD implements DTDConstants { /** * Recreates a DTD from an archived format. * @param in the <code>DataInputStream</code> to read from + * @throws IOException if an I/O error occurs */ public void read(DataInputStream in) throws IOException { if (in.readInt() != FILE_VERSION) { diff --git a/jdk/src/share/classes/javax/swing/text/html/parser/Element.java b/jdk/src/share/classes/javax/swing/text/html/parser/Element.java index 16b1943000c..283bdad73be 100644 --- a/jdk/src/share/classes/javax/swing/text/html/parser/Element.java +++ b/jdk/src/share/classes/javax/swing/text/html/parser/Element.java @@ -64,6 +64,9 @@ class Element implements DTDConstants, Serializable { /** * Create a new element. + * + * @param name the name of the element + * @param index the index */ Element(String name, int index) { this.name = name; @@ -84,6 +87,8 @@ class Element implements DTDConstants, Serializable { /** * Get the name of the element. + * + * @return the name of the element */ public String getName() { return name; @@ -91,6 +96,8 @@ class Element implements DTDConstants, Serializable { /** * Return true if the start tag can be omitted. + * + * @return {@code true} if the start tag can be omitted */ public boolean omitStart() { return oStart; @@ -98,6 +105,8 @@ class Element implements DTDConstants, Serializable { /** * Return true if the end tag can be omitted. + * + * @return {@code true} if the end tag can be omitted */ public boolean omitEnd() { return oEnd; @@ -105,6 +114,8 @@ class Element implements DTDConstants, Serializable { /** * Get type. + * + * @return the type of the element */ public int getType() { return type; @@ -112,6 +123,8 @@ class Element implements DTDConstants, Serializable { /** * Get content model + * + * @return the content model */ public ContentModel getContent() { return content; @@ -119,6 +132,8 @@ class Element implements DTDConstants, Serializable { /** * Get the attributes. + * + * @return the {@code AttributeList} specifying the element */ public AttributeList getAttributes() { return atts; @@ -126,6 +141,8 @@ class Element implements DTDConstants, Serializable { /** * Get index. + * + * @return the element index */ public int getIndex() { return index; @@ -133,6 +150,8 @@ class Element implements DTDConstants, Serializable { /** * Check if empty + * + * @return true if the current element is empty */ public boolean isEmpty() { return type == EMPTY; @@ -140,6 +159,8 @@ class Element implements DTDConstants, Serializable { /** * Convert to a string. + * + * @return a string representation for the given {@code Element} instance */ public String toString() { return name; @@ -147,6 +168,10 @@ class Element implements DTDConstants, Serializable { /** * Get an attribute by name. + * + * @param name the attribute name + * + * @return the {@code AttributeList} for the given {@code name} */ public AttributeList getAttribute(String name) { for (AttributeList a = atts ; a != null ; a = a.next) { @@ -159,10 +184,14 @@ class Element implements DTDConstants, Serializable { /** * Get an attribute by value. + * + * @param value the string representation of value + * + * @return the {@code AttributeList} for the given {@code value} */ - public AttributeList getAttributeByValue(String name) { + public AttributeList getAttributeByValue(String value) { for (AttributeList a = atts ; a != null ; a = a.next) { - if ((a.values != null) && a.values.contains(name)) { + if ((a.values != null) && a.values.contains(value)) { return a; } } diff --git a/jdk/src/share/classes/javax/swing/text/html/parser/Parser.java b/jdk/src/share/classes/javax/swing/text/html/parser/Parser.java index 79124461f9c..df02fb9d3a7 100644 --- a/jdk/src/share/classes/javax/swing/text/html/parser/Parser.java +++ b/jdk/src/share/classes/javax/swing/text/html/parser/Parser.java @@ -216,6 +216,8 @@ class Parser implements DTDConstants { * the current comment tag, text, block.... This is provided for * subclassers that wish to know the start of the current block when * called with one of the handleXXX methods. + * + * @return the start position of the current block */ int getBlockStartPosition() { return Math.max(0, lastBlockStartPos - 1); @@ -223,31 +225,55 @@ class Parser implements DTDConstants { /** * Makes a TagElement. + * + * @param elem the element storing the tag definition + * @param fictional the value of the flag "{@code fictional}" to be set for the tag + * + * @return the created {@code TagElement} */ protected TagElement makeTag(Element elem, boolean fictional) { return new TagElement(elem, fictional); } + /** + * Makes a TagElement. + * + * @param elem the element storing the tag definition + * + * @return the created {@code TagElement} + */ protected TagElement makeTag(Element elem) { return makeTag(elem, false); } + /** + * Returns attributes for the current tag. + * + * @return {@code SimpleAttributeSet} containing the attributes + */ protected SimpleAttributeSet getAttributes() { return attributes; } + /** + * Removes the current attributes. + */ protected void flushAttributes() { attributes.removeAttributes(attributes); } /** * Called when PCDATA is encountered. + * + * @param text the section text */ protected void handleText(char text[]) { } /** * Called when an HTML title tag is encountered. + * + * @param text the title text */ protected void handleTitle(char text[]) { // default behavior is to call handleText. Subclasses @@ -257,10 +283,15 @@ class Parser implements DTDConstants { /** * Called when an HTML comment is encountered. + * + * @param text the comment being handled */ protected void handleComment(char text[]) { } + /** + * Called when the content terminates without closing the HTML comment. + */ protected void handleEOFInComment() { // We've reached EOF. Our recovery strategy is to // see if we have more than one line in the comment; @@ -288,24 +319,34 @@ class Parser implements DTDConstants { /** * Called when an empty tag is encountered. + * + * @param tag the tag being handled + * @throws ChangedCharSetException if the document charset was changed */ protected void handleEmptyTag(TagElement tag) throws ChangedCharSetException { } /** * Called when a start tag is encountered. + * + * @param tag the tag being handled */ protected void handleStartTag(TagElement tag) { } /** * Called when an end tag is encountered. + * + * @param tag the tag being handled */ protected void handleEndTag(TagElement tag) { } /** * An error has occurred. + * + * @param ln the number of line containing the error + * @param msg the error message */ protected void handleError(int ln, String msg) { /* @@ -368,7 +409,12 @@ class Parser implements DTDConstants { } /** - * Invoke the error handler. + * Invokes the error handler. + * + * @param err the error type + * @param arg1 the 1st error message argument + * @param arg2 the 2nd error message argument + * @param arg3 the 3rd error message argument */ protected void error(String err, String arg1, String arg2, String arg3) { @@ -390,6 +436,9 @@ class Parser implements DTDConstants { * Handle a start tag. The new tag is pushed * onto the tag stack. The attribute list is * checked for required attributes. + * + * @param tag the tag + * @throws ChangedCharSetException if the document charset was changed */ protected void startTag(TagElement tag) throws ChangedCharSetException { Element elem = tag.getElement(); @@ -441,6 +490,9 @@ class Parser implements DTDConstants { /** * Handle an end tag. The end tag is popped * from the tag stack. + * + * @param omitted {@code true} if the tag is no actually present in the + * document, but is supposed by the parser */ protected void endTag(boolean omitted) { handleText(stack.tag); @@ -498,6 +550,8 @@ class Parser implements DTDConstants { /** * Marks the first time a tag has been seen in a document + * + * @param elem the element represented by the tag */ protected void markFirstTime(Element elem) { @@ -1478,8 +1532,11 @@ class Parser implements DTDConstants { } /** - * Parses th Document Declaration Type markup declaration. + * Parses the Document Type Declaration markup declaration. * Currently ignores it. + * + * @return the string representation of the markup declaration + * @throws IOException if an I/O error occurs */ public String parseDTDMarkup() throws IOException { @@ -1523,6 +1580,11 @@ class Parser implements DTDConstants { * Parse markup declarations. * Currently only handles the Document Type Declaration markup. * Returns true if it is a markup declaration false otherwise. + * + * @param strBuff the markup declaration + * @return {@code true} if this is a valid markup declaration; + * otherwise {@code false} + * @throws IOException if an I/O error occurs */ protected boolean parseMarkupDeclarations(StringBuffer strBuff) throws IOException { @@ -2236,6 +2298,9 @@ class Parser implements DTDConstants { /** * Parse an HTML stream, given a DTD. + * + * @param in the reader to read the source from + * @throws IOException if an I/O error occurs */ public synchronized void parse(Reader in) throws IOException { this.in = in; From 4bb7d288435d68957858240432aa6a14ff5bca4e Mon Sep 17 00:00:00 2001 From: Dmitriy Ermashov <dmitriy.ermashov@oracle.com> Date: Fri, 16 May 2014 17:45:35 +0400 Subject: [PATCH 092/157] 8042089: Fix doclint warnings from javax.swing.tree and javax.swing.undo packages Reviewed-by: alexsch --- .../javax/swing/tree/AbstractLayoutCache.java | 7 +++ .../swing/tree/DefaultMutableTreeNode.java | 7 +++ .../swing/tree/DefaultTreeCellEditor.java | 8 ++- .../swing/tree/DefaultTreeCellRenderer.java | 42 ++++++++++++++ .../javax/swing/tree/DefaultTreeModel.java | 26 +++++++++ .../swing/tree/DefaultTreeSelectionModel.java | 16 ++++++ .../javax/swing/tree/MutableTreeNode.java | 11 ++++ .../classes/javax/swing/tree/RowMapper.java | 4 ++ .../javax/swing/tree/TreeCellRenderer.java | 9 ++- .../classes/javax/swing/tree/TreeModel.java | 5 +- .../classes/javax/swing/tree/TreeNode.java | 16 ++++++ .../classes/javax/swing/tree/TreePath.java | 6 +- .../javax/swing/tree/TreeSelectionModel.java | 55 +++++++++++++++---- .../javax/swing/undo/CompoundEdit.java | 4 ++ .../javax/swing/undo/StateEditable.java | 4 ++ .../classes/javax/swing/undo/UndoManager.java | 2 + .../javax/swing/undo/UndoableEditSupport.java | 6 ++ 17 files changed, 212 insertions(+), 16 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/tree/AbstractLayoutCache.java b/jdk/src/share/classes/javax/swing/tree/AbstractLayoutCache.java index c0e474e26cd..cbb6ed09530 100644 --- a/jdk/src/share/classes/javax/swing/tree/AbstractLayoutCache.java +++ b/jdk/src/share/classes/javax/swing/tree/AbstractLayoutCache.java @@ -149,6 +149,8 @@ public abstract class AbstractLayoutCache implements RowMapper { * Returns the height of each row. If the returned value is less than * or equal to 0 the height for each row is determined by the * renderer. + * + * @return the height of each row */ public int getRowHeight() { return rowHeight; @@ -263,6 +265,9 @@ public abstract class AbstractLayoutCache implements RowMapper { /** * Returns true if the value identified by row is currently expanded. + * + * @param path TreePath to check + * @return whether TreePath is expanded */ public abstract boolean isExpanded(TreePath path); @@ -496,6 +501,8 @@ public abstract class AbstractLayoutCache implements RowMapper { /** * Returns true if the height of each row is a fixed size. + * + * @return whether the height of each row is a fixed size */ protected boolean isFixedRowHeight() { return (rowHeight > 0); diff --git a/jdk/src/share/classes/javax/swing/tree/DefaultMutableTreeNode.java b/jdk/src/share/classes/javax/swing/tree/DefaultMutableTreeNode.java index c33599064e2..2e451400d25 100644 --- a/jdk/src/share/classes/javax/swing/tree/DefaultMutableTreeNode.java +++ b/jdk/src/share/classes/javax/swing/tree/DefaultMutableTreeNode.java @@ -534,6 +534,7 @@ public class DefaultMutableTreeNode implements Cloneable, * Returns true if and only if <code>aNode</code> is in the same tree * as this node. Returns false if <code>aNode</code> is null. * + * @param aNode node to find common ancestor with * @see #getSharedAncestor * @see #getRoot * @return true if <code>aNode</code> is in the same tree as this node; @@ -638,6 +639,8 @@ public class DefaultMutableTreeNode implements Cloneable, * Returns the user object path, from the root, to get to this node. * If some of the TreeNodes in the path have null user objects, the * returned path will contain nulls. + * + * @return the user object path, from the root, to get to this node */ public Object[] getUserObjectPath() { TreeNode[] realPath = getPath(); @@ -828,6 +831,7 @@ public class DefaultMutableTreeNode implements Cloneable, * Modifying the tree by inserting, removing, or moving a node invalidates * any enumerations created before the modification. * + * @param ancestor the node to start enumeration from * @see #isNodeAncestor * @see #isNodeDescendant * @exception IllegalArgumentException if <code>ancestor</code> is @@ -848,6 +852,7 @@ public class DefaultMutableTreeNode implements Cloneable, * Returns true if <code>aNode</code> is a child of this node. If * <code>aNode</code> is null, this method returns false. * + * @param aNode the node to determinate whether it is a child * @return true if <code>aNode</code> is a child of this node; false if * <code>aNode</code> is null */ @@ -906,6 +911,7 @@ public class DefaultMutableTreeNode implements Cloneable, * <code>aChild</code> and is O(n) where n is the number of children; to * traverse the entire array of children, use an enumeration instead. * + * @param aChild the child node to look for next child after it * @see #children * @exception IllegalArgumentException if <code>aChild</code> is * null or is not a child of this node @@ -938,6 +944,7 @@ public class DefaultMutableTreeNode implements Cloneable, * performs a linear search of this node's children for <code>aChild</code> * and is O(n) where n is the number of children. * + * @param aChild the child node to look for previous child before it * @exception IllegalArgumentException if <code>aChild</code> is null * or is not a child of this node * @return the child of this node that immediately precedes diff --git a/jdk/src/share/classes/javax/swing/tree/DefaultTreeCellEditor.java b/jdk/src/share/classes/javax/swing/tree/DefaultTreeCellEditor.java index f6c2559cd99..15c645af8fd 100644 --- a/jdk/src/share/classes/javax/swing/tree/DefaultTreeCellEditor.java +++ b/jdk/src/share/classes/javax/swing/tree/DefaultTreeCellEditor.java @@ -405,7 +405,9 @@ public class DefaultTreeCellEditor implements ActionListener, TreeCellEditor, /** * Returns true if <code>event</code> is a <code>MouseEvent</code> * and the click count is 1. - * @param event the event being studied + * + * @param event the event being studied + * @return whether {@code event} should starts the editing timer */ protected boolean shouldStartEditingTimer(EventObject event) { if((event instanceof MouseEvent) && @@ -433,7 +435,9 @@ public class DefaultTreeCellEditor implements ActionListener, TreeCellEditor, * Returns true if <code>event</code> is <code>null</code>, * or it is a <code>MouseEvent</code> with a click count > 2 * and <code>inHitRegion</code> returns true. + * * @param event the event being studied + * @return whether editing can be started for the given {@code event} */ protected boolean canEditImmediately(EventObject event) { if((event instanceof MouseEvent) && @@ -513,6 +517,8 @@ public class DefaultTreeCellEditor implements ActionListener, TreeCellEditor, /** * Creates the container to manage placement of * <code>editingComponent</code>. + * + * @return new Container object */ protected Container createContainer() { return new EditorContainer(); diff --git a/jdk/src/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java b/jdk/src/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java index e24ccd978f3..c8784e93c43 100644 --- a/jdk/src/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java +++ b/jdk/src/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java @@ -234,6 +234,9 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Returns the default icon, for the current laf, that is used to * represent non-leaf nodes that are expanded. + * + * @return the default icon, for the current laf, that is used to + * represent non-leaf nodes that are expanded. */ public Icon getDefaultOpenIcon() { return DefaultLookup.getIcon(this, ui, "Tree.openIcon"); @@ -242,6 +245,9 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Returns the default icon, for the current laf, that is used to * represent non-leaf nodes that are not expanded. + * + * @return the default icon, for the current laf, that is used to + * represent non-leaf nodes that are not expanded. */ public Icon getDefaultClosedIcon() { return DefaultLookup.getIcon(this, ui, "Tree.closedIcon"); @@ -250,6 +256,9 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Returns the default icon, for the current laf, that is used to * represent leaf nodes. + * + * @return the default icon, for the current laf, that is used to + * represent leaf nodes. */ public Icon getDefaultLeafIcon() { return DefaultLookup.getIcon(this, ui, "Tree.leafIcon"); @@ -257,6 +266,8 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Sets the icon used to represent non-leaf nodes that are expanded. + * + * @param newIcon the icon to be used for expanded non-leaf nodes */ public void setOpenIcon(Icon newIcon) { openIcon = newIcon; @@ -264,6 +275,8 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Returns the icon used to represent non-leaf nodes that are expanded. + * + * @return the icon used to represent non-leaf nodes that are expanded */ public Icon getOpenIcon() { return openIcon; @@ -271,6 +284,8 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Sets the icon used to represent non-leaf nodes that are not expanded. + * + * @param newIcon the icon to be used for not expanded non-leaf nodes */ public void setClosedIcon(Icon newIcon) { closedIcon = newIcon; @@ -279,6 +294,9 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Returns the icon used to represent non-leaf nodes that are not * expanded. + * + * @return the icon used to represent non-leaf nodes that are not + * expanded */ public Icon getClosedIcon() { return closedIcon; @@ -286,6 +304,8 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Sets the icon used to represent leaf nodes. + * + * @param newIcon icon to be used for leaf nodes */ public void setLeafIcon(Icon newIcon) { leafIcon = newIcon; @@ -293,6 +313,8 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Returns the icon used to represent leaf nodes. + * + * @return the icon used to represent leaf nodes */ public Icon getLeafIcon() { return leafIcon; @@ -300,6 +322,8 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Sets the color the text is drawn with when the node is selected. + * + * @param newColor color to be used for text when the node is selected */ public void setTextSelectionColor(Color newColor) { textSelectionColor = newColor; @@ -307,6 +331,8 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Returns the color the text is drawn with when the node is selected. + * + * @return the color the text is drawn with when the node is selected */ public Color getTextSelectionColor() { return textSelectionColor; @@ -314,6 +340,8 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Sets the color the text is drawn with when the node isn't selected. + * + * @param newColor color to be used for text when the node isn't selected */ public void setTextNonSelectionColor(Color newColor) { textNonSelectionColor = newColor; @@ -321,6 +349,8 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Returns the color the text is drawn with when the node isn't selected. + * + * @return the color the text is drawn with when the node isn't selected. */ public Color getTextNonSelectionColor() { return textNonSelectionColor; @@ -328,6 +358,8 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Sets the color to use for the background if node is selected. + * + * @param newColor to be used for the background if the node is selected */ public void setBackgroundSelectionColor(Color newColor) { backgroundSelectionColor = newColor; @@ -336,6 +368,8 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Returns the color to use for the background if node is selected. + * + * @return the color to use for the background if node is selected */ public Color getBackgroundSelectionColor() { return backgroundSelectionColor; @@ -343,6 +377,8 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Sets the background color to be used for non selected nodes. + * + * @param newColor color to be used for the background for non selected nodes */ public void setBackgroundNonSelectionColor(Color newColor) { backgroundNonSelectionColor = newColor; @@ -350,6 +386,8 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Returns the background color to be used for non selected nodes. + * + * @return the background color to be used for non selected nodes. */ public Color getBackgroundNonSelectionColor() { return backgroundNonSelectionColor; @@ -357,6 +395,8 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Sets the color to use for the border. + * + * @param newColor color to be used for the border */ public void setBorderSelectionColor(Color newColor) { borderSelectionColor = newColor; @@ -364,6 +404,8 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer /** * Returns the color the border is drawn. + * + * @return the color the border is drawn */ public Color getBorderSelectionColor() { return borderSelectionColor; diff --git a/jdk/src/share/classes/javax/swing/tree/DefaultTreeModel.java b/jdk/src/share/classes/javax/swing/tree/DefaultTreeModel.java index c3b9de2d698..550d8f6062b 100644 --- a/jdk/src/share/classes/javax/swing/tree/DefaultTreeModel.java +++ b/jdk/src/share/classes/javax/swing/tree/DefaultTreeModel.java @@ -105,6 +105,9 @@ public class DefaultTreeModel implements Serializable, TreeModel { * Sets whether or not to test leafness by asking getAllowsChildren() * or isLeaf() to the TreeNodes. If newvalue is true, getAllowsChildren() * is messaged, otherwise isLeaf() is messaged. + * + * @param newValue if true, getAllowsChildren() is messaged, otherwise + * isLeaf() is messaged */ public void setAsksAllowsChildren(boolean newValue) { asksAllowsChildren = newValue; @@ -125,6 +128,8 @@ public class DefaultTreeModel implements Serializable, TreeModel { /** * Sets the root to <code>root</code>. A null <code>root</code> implies * the tree is to display nothing, and is legal. + * + * @param root new value of tree root */ public void setRoot(TreeNode root) { Object oldRoot = this.root; @@ -231,6 +236,10 @@ public class DefaultTreeModel implements Serializable, TreeModel { * This will then message nodesWereInserted to create the appropriate * event. This is the preferred way to add children as it will create * the appropriate event. + * + * @param newChild child node to be inserted + * @param parent node to which children new node will be added + * @param index index of parent's children */ public void insertNodeInto(MutableTreeNode newChild, MutableTreeNode parent, int index){ @@ -247,6 +256,8 @@ public class DefaultTreeModel implements Serializable, TreeModel { * nodesWereRemoved to create the appropriate event. This is the * preferred way to remove a node as it handles the event creation * for you. + * + * @param node the node to be removed from it's parrent */ public void removeNodeFromParent(MutableTreeNode node) { MutableTreeNode parent = (MutableTreeNode)node.getParent(); @@ -266,6 +277,8 @@ public class DefaultTreeModel implements Serializable, TreeModel { /** * Invoke this method after you've changed how node is to be * represented in the tree. + * + * @param node the changed node */ public void nodeChanged(TreeNode node) { if(listenerList != null && node != null) { @@ -303,6 +316,9 @@ public class DefaultTreeModel implements Serializable, TreeModel { * Invoke this method after you've inserted some TreeNodes into * node. childIndices should be the index of the new elements and * must be sorted in ascending order. + * + * @param node parent node which children count been incremented + * @param childIndices indexes of inserted children */ public void nodesWereInserted(TreeNode node, int[] childIndices) { if(listenerList != null && node != null && childIndices != null @@ -322,6 +338,10 @@ public class DefaultTreeModel implements Serializable, TreeModel { * node. childIndices should be the index of the removed elements and * must be sorted in ascending order. And removedChildren should be * the array of the children objects that were removed. + * + * @param node parent node which childred were removed + * @param childIndices indexes of removed childs + * @param removedChildren array of the children objects that were removed */ public void nodesWereRemoved(TreeNode node, int[] childIndices, Object[] removedChildren) { @@ -334,6 +354,9 @@ public class DefaultTreeModel implements Serializable, TreeModel { /** * Invoke this method after you've changed how the children identified by * childIndicies are to be represented in the tree. + * + * @param node changed node + * @param childIndices indexes of changed children */ public void nodesChanged(TreeNode node, int[] childIndices) { if(node != null) { @@ -360,6 +383,8 @@ public class DefaultTreeModel implements Serializable, TreeModel { * Invoke this method if you've totally changed the children of * node and its children's children... This will post a * treeStructureChanged event. + * + * @param node changed node */ public void nodeStructureChanged(TreeNode node) { if(node != null) { @@ -374,6 +399,7 @@ public class DefaultTreeModel implements Serializable, TreeModel { * tree. * * @param aNode the TreeNode to get the path for + * @return an array of TreeNodes giving the path from the root */ public TreeNode[] getPathToRoot(TreeNode aNode) { return getPathToRoot(aNode, 0); diff --git a/jdk/src/share/classes/javax/swing/tree/DefaultTreeSelectionModel.java b/jdk/src/share/classes/javax/swing/tree/DefaultTreeSelectionModel.java index 73054ad0046..d1c152f19be 100644 --- a/jdk/src/share/classes/javax/swing/tree/DefaultTreeSelectionModel.java +++ b/jdk/src/share/classes/javax/swing/tree/DefaultTreeSelectionModel.java @@ -618,6 +618,9 @@ public class DefaultTreeSelectionModel implements Cloneable, Serializable, TreeS /** * Notifies all listeners that are registered for * tree selection events on this object. + * + * @param e the event that characterizes the change + * * @see #addTreeSelectionListener * @see EventListenerList */ @@ -920,6 +923,9 @@ public class DefaultTreeSelectionModel implements Cloneable, Serializable, TreeS /** * Returns true if the paths are contiguous, * or this object has no RowMapper. + * + * @param paths array of paths to check + * @return whether the paths are contiguous, or this object has no RowMapper */ protected boolean arePathsContiguous(TreePath[] paths) { if(rowMapper == null || paths.length < 2) @@ -968,6 +974,9 @@ public class DefaultTreeSelectionModel implements Cloneable, Serializable, TreeS * or the selection mode is <code>DISCONTIGUOUS_TREE_SELECTION</code>, or * adding the paths to the current selection still results in a * contiguous set of <code>TreePath</code>s. + * + * @param paths array of {@code TreePaths} to check + * @return whether the particular set of {@code TreePaths} can be added */ protected boolean canPathsBeAdded(TreePath[] paths) { if(paths == null || paths.length == 0 || rowMapper == null || @@ -1019,6 +1028,10 @@ public class DefaultTreeSelectionModel implements Cloneable, Serializable, TreeS * Returns true if the paths can be removed without breaking the * continuity of the model. * This is rather expensive. + * + * @param paths array of {@code TreePath} to check + * @return whether the paths can be removed without breaking the + * continuity of the model */ protected boolean canPathsBeRemoved(TreePath[] paths) { if(rowMapper == null || selection == null || @@ -1072,6 +1085,9 @@ public class DefaultTreeSelectionModel implements Cloneable, Serializable, TreeS * instances of PathPlaceHolder. * * @deprecated As of JDK version 1.7 + * + * @param changedPaths the vector of the changed paths + * @param oldLeadSelection the old selection path */ @Deprecated protected void notifyPathChange(Vector<?> changedPaths, diff --git a/jdk/src/share/classes/javax/swing/tree/MutableTreeNode.java b/jdk/src/share/classes/javax/swing/tree/MutableTreeNode.java index 3c12d17e44b..98ad22ae4aa 100644 --- a/jdk/src/share/classes/javax/swing/tree/MutableTreeNode.java +++ b/jdk/src/share/classes/javax/swing/tree/MutableTreeNode.java @@ -42,22 +42,31 @@ public interface MutableTreeNode extends TreeNode /** * Adds <code>child</code> to the receiver at <code>index</code>. * <code>child</code> will be messaged with <code>setParent</code>. + * + * @param child node to be added + * @param index index of the receiver */ void insert(MutableTreeNode child, int index); /** * Removes the child at <code>index</code> from the receiver. + * + * @param index index of child to be removed */ void remove(int index); /** * Removes <code>node</code> from the receiver. <code>setParent</code> * will be messaged on <code>node</code>. + * + * @param node node to be removed from the receiver */ void remove(MutableTreeNode node); /** * Resets the user object of the receiver to <code>object</code>. + * + * @param object object to be set as a receiver */ void setUserObject(Object object); @@ -68,6 +77,8 @@ public interface MutableTreeNode extends TreeNode /** * Sets the parent of the receiver to <code>newParent</code>. + * + * @param newParent node to be set as parent of the receiver */ void setParent(MutableTreeNode newParent); } diff --git a/jdk/src/share/classes/javax/swing/tree/RowMapper.java b/jdk/src/share/classes/javax/swing/tree/RowMapper.java index 9c365dc17ea..a7b8da11738 100644 --- a/jdk/src/share/classes/javax/swing/tree/RowMapper.java +++ b/jdk/src/share/classes/javax/swing/tree/RowMapper.java @@ -41,6 +41,10 @@ public interface RowMapper * the same length as that passed in, and if one of the TreePaths * in <code>path</code> is not valid its entry in the array should * be set to -1. + * + * @param path array of TreePath to parse + * @return the rows that the TreePath instances in {@code path} are + * being displayed at */ int[] getRowsForPaths(TreePath[] path); } diff --git a/jdk/src/share/classes/javax/swing/tree/TreeCellRenderer.java b/jdk/src/share/classes/javax/swing/tree/TreeCellRenderer.java index 8ed0087dc60..8615472f777 100644 --- a/jdk/src/share/classes/javax/swing/tree/TreeCellRenderer.java +++ b/jdk/src/share/classes/javax/swing/tree/TreeCellRenderer.java @@ -67,7 +67,14 @@ public interface TreeCellRenderer { * } * </pre> * - * @return the <code>Component</code> that the renderer uses to draw the value + * @param tree the receiver is being configured for + * @param value the value to render + * @param selected whether node is selected + * @param expanded whether node is expanded + * @param leaf whether node is a lead node + * @param row row index + * @param hasFocus whether node has focus + * @return the {@code Component} that the renderer uses to draw the value */ Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, diff --git a/jdk/src/share/classes/javax/swing/tree/TreeModel.java b/jdk/src/share/classes/javax/swing/tree/TreeModel.java index 94f7d236647..435c9e51444 100644 --- a/jdk/src/share/classes/javax/swing/tree/TreeModel.java +++ b/jdk/src/share/classes/javax/swing/tree/TreeModel.java @@ -79,8 +79,9 @@ public interface TreeModel * is a valid index for <code>parent</code> (that is <code>index >= 0 && * index < getChildCount(parent</code>)). * - * @param parent a node in the tree, obtained from this data source - * @return the child of <code>parent</code> at index <code>index</code> + * @param parent a node in the tree, obtained from this data source + * @param index index of child to be returned + * @return the child of {@code parent} at index {@code index} */ public Object getChild(Object parent, int index); diff --git a/jdk/src/share/classes/javax/swing/tree/TreeNode.java b/jdk/src/share/classes/javax/swing/tree/TreeNode.java index e6dcbab292a..3633a88fb74 100644 --- a/jdk/src/share/classes/javax/swing/tree/TreeNode.java +++ b/jdk/src/share/classes/javax/swing/tree/TreeNode.java @@ -49,17 +49,24 @@ public interface TreeNode /** * Returns the child <code>TreeNode</code> at index * <code>childIndex</code>. + * + * @param childIndex index of child + * @return the child node at given index */ TreeNode getChildAt(int childIndex); /** * Returns the number of children <code>TreeNode</code>s the receiver * contains. + * + * @return the number of children the receiver contains */ int getChildCount(); /** * Returns the parent <code>TreeNode</code> of the receiver. + * + * @return the parent of the receiver */ TreeNode getParent(); @@ -67,21 +74,30 @@ public interface TreeNode * Returns the index of <code>node</code> in the receivers children. * If the receiver does not contain <code>node</code>, -1 will be * returned. + * + * @param node node to be loked for + * @return index of specified node */ int getIndex(TreeNode node); /** * Returns true if the receiver allows children. + * + * @return whether the receiver allows children */ boolean getAllowsChildren(); /** * Returns true if the receiver is a leaf. + * + * @return whether the receiver is a leaf */ boolean isLeaf(); /** * Returns the children of the receiver as an <code>Enumeration</code>. + * + * @return the children of the receiver as an {@code Enumeration} */ Enumeration children(); } diff --git a/jdk/src/share/classes/javax/swing/tree/TreePath.java b/jdk/src/share/classes/javax/swing/tree/TreePath.java index 4ed1dbafd09..1a45bca1c07 100644 --- a/jdk/src/share/classes/javax/swing/tree/TreePath.java +++ b/jdk/src/share/classes/javax/swing/tree/TreePath.java @@ -320,8 +320,10 @@ public class TreePath extends Object implements Serializable { * plus <code>child</code>. <code>child</code> is the last element * of the newly created {@code TreePath}. * - * @param child the path element to add - * @throws NullPointerException if {@code child} is {@code null} + * @param child the path element to add + * @throws NullPointerException if {@code child} is {@code null} + * @return a new path containing all the elements of this path + * plus {@code child} */ public TreePath pathByAddingChild(Object child) { if(child == null) diff --git a/jdk/src/share/classes/javax/swing/tree/TreeSelectionModel.java b/jdk/src/share/classes/javax/swing/tree/TreeSelectionModel.java index 5df7f392f2e..d0c851dc24c 100644 --- a/jdk/src/share/classes/javax/swing/tree/TreeSelectionModel.java +++ b/jdk/src/share/classes/javax/swing/tree/TreeSelectionModel.java @@ -109,6 +109,8 @@ public interface TreeSelectionModel * selected when the mode is changed to <code>SINGLE_TREE_SELECTION</code>, * only one TreePath will remain selected. It is up to the particular * implementation to decide what TreePath remains selected. + * + * @param mode selection mode to be set */ void setSelectionMode(int mode); @@ -117,6 +119,8 @@ public interface TreeSelectionModel * <code>SINGLE_TREE_SELECTION</code>, * <code>CONTIGUOUS_TREE_SELECTION</code> or * <code>DISCONTIGUOUS_TREE_SELECTION</code>. + * + * @return the current selection mode */ int getSelectionMode(); @@ -125,7 +129,7 @@ public interface TreeSelectionModel * the TreeSelectionListeners are notified. If <code>path</code> is * null, this has the same effect as invoking <code>clearSelection</code>. * - * @param path new path to select + * @param path new path to select */ void setSelectionPath(TreePath path); @@ -134,7 +138,7 @@ public interface TreeSelectionModel * the TreeSelectionListeners are notified. If <code>paths</code> is * null, this has the same effect as invoking <code>clearSelection</code>. * - * @param paths new selection + * @param paths new selection */ void setSelectionPaths(TreePath[] paths); @@ -143,7 +147,7 @@ public interface TreeSelectionModel * in the selection the TreeSelectionListeners are notified. This has * no effect if <code>path</code> is null. * - * @param path the new path to add to the current selection + * @param path the new path to add to the current selection */ void addSelectionPath(TreePath path); @@ -153,7 +157,7 @@ public interface TreeSelectionModel * are notified. This has * no effect if <code>paths</code> is null. * - * @param paths the new paths to add to the current selection + * @param paths the new paths to add to the current selection */ void addSelectionPaths(TreePath[] paths); @@ -162,7 +166,7 @@ public interface TreeSelectionModel * The TreeSelectionListeners are notified. This has no effect if * <code>path</code> is null. * - * @param path the path to remove from the selection + * @param path the path to remove from the selection */ void removeSelectionPath(TreePath path); @@ -172,7 +176,7 @@ public interface TreeSelectionModel * are in the selection, the TreeSelectionListeners are notified. * This method has no effect if <code>paths</code> is null. * - * @param paths the path to remove from the selection + * @param paths the path to remove from the selection */ void removeSelectionPaths(TreePath[] paths); @@ -181,28 +185,39 @@ public interface TreeSelectionModel * up to implementors, and may not necessarily be the TreePath with * the smallest integer value as determined from the * <code>RowMapper</code>. + * + * @return the first path in the selection */ TreePath getSelectionPath(); /** * Returns the paths in the selection. This will return null (or an * empty array) if nothing is currently selected. + * + * @return the paths in the selection */ TreePath[] getSelectionPaths(); /** * Returns the number of paths that are selected. + * + * @return the number of paths that are selected */ int getSelectionCount(); /** * Returns true if the path, <code>path</code>, is in the current * selection. + * + * @param path the path to be loked for + * @return whether the {@code path} is in the current selection */ boolean isPathSelected(TreePath path); /** * Returns true if the selection is currently empty. + * + * @return whether the selection is currently empty */ boolean isSelectionEmpty(); @@ -215,12 +230,17 @@ public interface TreeSelectionModel /** * Sets the RowMapper instance. This instance is used to determine * the row for a particular TreePath. + * + * @param newMapper RowMapper to be set */ void setRowMapper(RowMapper newMapper); /** * Returns the RowMapper instance that is able to map a TreePath to a * row. + * + * @return the RowMapper instance that is able to map a TreePath + * to a row */ RowMapper getRowMapper(); @@ -228,6 +248,8 @@ public interface TreeSelectionModel * Returns all of the currently selected rows. This will return * null (or an empty array) if there are no selected TreePaths or * a RowMapper has not been set. + * + * @return all of the currently selected rows */ int[] getSelectionRows(); @@ -235,6 +257,9 @@ public interface TreeSelectionModel * Returns the smallest value obtained from the RowMapper for the * current set of selected TreePaths. If nothing is selected, * or there is no RowMapper, this will return -1. + * + * @return the smallest value obtained from the RowMapper + * for the current set of selected TreePaths */ int getMinSelectionRow(); @@ -242,11 +267,17 @@ public interface TreeSelectionModel * Returns the largest value obtained from the RowMapper for the * current set of selected TreePaths. If nothing is selected, * or there is no RowMapper, this will return -1. + * + * @return the largest value obtained from the RowMapper + * for the current set of selected TreePaths */ int getMaxSelectionRow(); /** * Returns true if the row identified by <code>row</code> is selected. + * + * @param row row to check + * @return whether the row is selected */ boolean isRowSelected(int row); @@ -264,12 +295,16 @@ public interface TreeSelectionModel /** * Returns the lead selection index. That is the last index that was * added. + * + * @return the lead selection index */ int getLeadSelectionRow(); /** * Returns the last path that was added. This may differ from the * leadSelectionPath property maintained by the JTree. + * + * @return the last path that was added */ TreePath getLeadSelectionPath(); @@ -280,7 +315,7 @@ public interface TreeSelectionModel * A PropertyChangeEvent will get fired when the selection mode * changes. * - * @param listener the PropertyChangeListener to be added + * @param listener the PropertyChangeListener to be added */ void addPropertyChangeListener(PropertyChangeListener listener); @@ -289,7 +324,7 @@ public interface TreeSelectionModel * This removes a PropertyChangeListener that was registered * for all properties. * - * @param listener the PropertyChangeListener to be removed + * @param listener the PropertyChangeListener to be removed */ void removePropertyChangeListener(PropertyChangeListener listener); @@ -297,7 +332,7 @@ public interface TreeSelectionModel * Adds x to the list of listeners that are notified each time the * set of selected TreePaths changes. * - * @param x the new listener to be added + * @param x the new listener to be added */ void addTreeSelectionListener(TreeSelectionListener x); @@ -305,7 +340,7 @@ public interface TreeSelectionModel * Removes x from the list of listeners that are notified each time * the set of selected TreePaths changes. * - * @param x the listener to remove + * @param x the listener to remove */ void removeTreeSelectionListener(TreeSelectionListener x); } diff --git a/jdk/src/share/classes/javax/swing/undo/CompoundEdit.java b/jdk/src/share/classes/javax/swing/undo/CompoundEdit.java index 5e95f4130e4..4963262d0ac 100644 --- a/jdk/src/share/classes/javax/swing/undo/CompoundEdit.java +++ b/jdk/src/share/classes/javax/swing/undo/CompoundEdit.java @@ -82,6 +82,9 @@ public class CompoundEdit extends AbstractUndoableEdit { * Returns the last <code>UndoableEdit</code> in * <code>edits</code>, or <code>null</code> * if <code>edits</code> is empty. + * + * @return the last {@code UndoableEdit} in {@code edits}, + * or {@code null} if {@code edits} is empty. */ protected UndoableEdit lastEdit() { int count = edits.size(); @@ -182,6 +185,7 @@ public class CompoundEdit extends AbstractUndoableEdit { * received end. This generally means that edits are still being * added to it. * + * @return whether this edit is in progress * @see #end */ public boolean isInProgress() { diff --git a/jdk/src/share/classes/javax/swing/undo/StateEditable.java b/jdk/src/share/classes/javax/swing/undo/StateEditable.java index 492a2f91470..d8de2cf4871 100644 --- a/jdk/src/share/classes/javax/swing/undo/StateEditable.java +++ b/jdk/src/share/classes/javax/swing/undo/StateEditable.java @@ -43,12 +43,16 @@ public interface StateEditable { /** * Upon receiving this message the receiver should place any relevant * state into <EM>state</EM>. + * + * @param state Hashtable object to store the state */ public void storeState(Hashtable<Object,Object> state); /** * Upon receiving this message the receiver should extract any relevant * state out of <EM>state</EM>. + * + * @param state Hashtable object to restore the state from it */ public void restoreState(Hashtable<?,?> state); } // End of interface StateEditable diff --git a/jdk/src/share/classes/javax/swing/undo/UndoManager.java b/jdk/src/share/classes/javax/swing/undo/UndoManager.java index a95ebf25ce8..8f141e1d932 100644 --- a/jdk/src/share/classes/javax/swing/undo/UndoManager.java +++ b/jdk/src/share/classes/javax/swing/undo/UndoManager.java @@ -326,6 +326,7 @@ public class UndoManager extends CompoundEdit implements UndoableEditListener { * Undoes all changes from the index of the next edit to * <code>edit</code>, updating the index of the next edit appropriately. * + * @param edit the edit to be undo to * @throws CannotUndoException if one of the edits throws * <code>CannotUndoException</code> */ @@ -342,6 +343,7 @@ public class UndoManager extends CompoundEdit implements UndoableEditListener { * Redoes all changes from the index of the next edit to * <code>edit</code>, updating the index of the next edit appropriately. * + * @param edit the edit to be redo to * @throws CannotRedoException if one of the edits throws * <code>CannotRedoException</code> */ diff --git a/jdk/src/share/classes/javax/swing/undo/UndoableEditSupport.java b/jdk/src/share/classes/javax/swing/undo/UndoableEditSupport.java index a1927f34a32..21c2b61cb77 100644 --- a/jdk/src/share/classes/javax/swing/undo/UndoableEditSupport.java +++ b/jdk/src/share/classes/javax/swing/undo/UndoableEditSupport.java @@ -96,6 +96,8 @@ public class UndoableEditSupport { * Called only from <code>postEdit</code> and <code>endUpdate</code>. Calls * <code>undoableEditHappened</code> in all listeners. No synchronization * is performed here, since the two calling methods are synchronized. + * + * @param e edit to be verified */ protected void _postEdit(UndoableEdit e) { UndoableEditEvent ev = new UndoableEditEvent(realSource, e); @@ -110,6 +112,8 @@ public class UndoableEditSupport { * DEADLOCK WARNING: Calling this method may call * <code>undoableEditHappened</code> in all listeners. * It is unwise to call this method from one of its listeners. + * + * @param e edit to be posted */ public synchronized void postEdit(UndoableEdit e) { if (updateLevel == 0) { @@ -142,6 +146,8 @@ public class UndoableEditSupport { /** * Called only from <code>beginUpdate</code>. * Exposed here for subclasses' use. + * + * @return new created {@code CompoundEdit} object */ protected CompoundEdit createCompoundEdit() { return new CompoundEdit(); From 3a555f05168e75de0079df33720d0f1213c7da82 Mon Sep 17 00:00:00 2001 From: Christian Thalinger <twisti@openjdk.org> Date: Fri, 16 May 2014 09:20:56 -0700 Subject: [PATCH 093/157] 8032606: ClassValue.ClassValueMap.type is unused Reviewed-by: jrose, vlivanov --- jdk/src/share/classes/java/lang/ClassValue.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/jdk/src/share/classes/java/lang/ClassValue.java b/jdk/src/share/classes/java/lang/ClassValue.java index e58634b155d..4fc33d355bd 100644 --- a/jdk/src/share/classes/java/lang/ClassValue.java +++ b/jdk/src/share/classes/java/lang/ClassValue.java @@ -25,7 +25,6 @@ package java.lang; -import java.lang.ClassValue.ClassValueMap; import java.util.WeakHashMap; import java.lang.ref.WeakReference; import java.util.concurrent.atomic.AtomicInteger; @@ -375,10 +374,10 @@ public abstract class ClassValue<T> { synchronized (CRITICAL_SECTION) { // private object to avoid deadlocks // happens about once per type if ((map = type.classValueMap) == null) - type.classValueMap = map = new ClassValueMap(type); - } - return map; + type.classValueMap = map = new ClassValueMap(); } + return map; + } static <T> Entry<T> makeEntry(Version<T> explicitVersion, T value) { // Note that explicitVersion might be different from this.version. @@ -398,12 +397,11 @@ public abstract class ClassValue<T> { // The following class could also be top level and non-public: - /** A backing map for all ClassValues, relative a single given type. + /** A backing map for all ClassValues. * Gives a fully serialized "true state" for each pair (ClassValue cv, Class type). * Also manages an unserialized fast-path cache. */ static class ClassValueMap extends WeakHashMap<ClassValue.Identity, Entry<?>> { - private final Class<?> type; private Entry<?>[] cacheArray; private int cacheLoad, cacheLoadLimit; @@ -413,11 +411,10 @@ public abstract class ClassValue<T> { */ private static final int INITIAL_ENTRIES = 32; - /** Build a backing map for ClassValues, relative the given type. + /** Build a backing map for ClassValues. * Also, create an empty cache array and install it on the class. */ - ClassValueMap(Class<?> type) { - this.type = type; + ClassValueMap() { sizeCache(INITIAL_ENTRIES); } From ae0d3204f033464c81cd4f70f1dc2fd1a208c461 Mon Sep 17 00:00:00 2001 From: Lance Andersen <lancea@openjdk.org> Date: Fri, 16 May 2014 14:48:34 -0400 Subject: [PATCH 094/157] 8043278: Add initial unit tests for javax.sql.rowset.serial Reviewed-by: rriggs --- jdk/test/java/sql/util/BaseTest.java | 36 +- jdk/test/javax/sql/testng/TEST.properties | 2 + .../test/rowset/serial/SerialArrayTests.java | 236 +++++++++ .../test/rowset/serial/SerialBlobTests.java | 399 ++++++++++++++ .../test/rowset/serial/SerialClobTests.java | 499 ++++++++++++++++++ .../rowset/serial/SerialDataLinkTests.java | 110 ++++ .../rowset/serial/SerialExceptionTests.java | 113 ++++ .../rowset/serial/SerialJavaObjectTests.java | 100 ++++ .../test/rowset/serial/SerialRefTests.java | 131 +++++ .../test/rowset/serial/SerialStructTests.java | 140 +++++ jdk/test/javax/sql/testng/util/BaseTest.java | 91 ++++ jdk/test/javax/sql/testng/util/StubArray.java | 99 ++++ jdk/test/javax/sql/testng/util/StubBlob.java | 100 ++++ jdk/test/javax/sql/testng/util/StubClob.java | 113 ++++ jdk/test/javax/sql/testng/util/StubRef.java | 60 +++ .../javax/sql/testng/util/StubStruct.java | 55 ++ jdk/test/javax/sql/testng/util/SuperHero.java | 106 ++++ 17 files changed, 2373 insertions(+), 17 deletions(-) create mode 100644 jdk/test/javax/sql/testng/TEST.properties create mode 100644 jdk/test/javax/sql/testng/test/rowset/serial/SerialArrayTests.java create mode 100644 jdk/test/javax/sql/testng/test/rowset/serial/SerialBlobTests.java create mode 100644 jdk/test/javax/sql/testng/test/rowset/serial/SerialClobTests.java create mode 100644 jdk/test/javax/sql/testng/test/rowset/serial/SerialDataLinkTests.java create mode 100644 jdk/test/javax/sql/testng/test/rowset/serial/SerialExceptionTests.java create mode 100644 jdk/test/javax/sql/testng/test/rowset/serial/SerialJavaObjectTests.java create mode 100644 jdk/test/javax/sql/testng/test/rowset/serial/SerialRefTests.java create mode 100644 jdk/test/javax/sql/testng/test/rowset/serial/SerialStructTests.java create mode 100644 jdk/test/javax/sql/testng/util/BaseTest.java create mode 100644 jdk/test/javax/sql/testng/util/StubArray.java create mode 100644 jdk/test/javax/sql/testng/util/StubBlob.java create mode 100644 jdk/test/javax/sql/testng/util/StubClob.java create mode 100644 jdk/test/javax/sql/testng/util/StubRef.java create mode 100644 jdk/test/javax/sql/testng/util/StubStruct.java create mode 100644 jdk/test/javax/sql/testng/util/SuperHero.java diff --git a/jdk/test/java/sql/util/BaseTest.java b/jdk/test/java/sql/util/BaseTest.java index 2668c4899c7..130dae8fb4e 100644 --- a/jdk/test/java/sql/util/BaseTest.java +++ b/jdk/test/java/sql/util/BaseTest.java @@ -61,29 +61,31 @@ public class BaseTest { public void tearDownMethod() throws Exception { } - /** + /* * Take some form of SQLException, serialize and deserialize it - * - * @param <T> SQLException - * @param ex SQLException - * @return deserialized SQLException - * @throws IOException - * @throws ClassNotFoundException */ @SuppressWarnings("unchecked") protected <T extends SQLException> T createSerializedException(T ex) throws IOException, ClassNotFoundException { - T ex1; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (ObjectOutputStream oos = new ObjectOutputStream(baos) ) { - oos.writeObject(ex); - } - try (ObjectInputStream ois = - new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) { - ex1 = (T) ois.readObject(); - } - return ex1; + return (T) serializeDeserializeObject(ex); } + /* + * Utility method to serialize and deserialize an object + */ + @SuppressWarnings("unchecked") + protected <T> T serializeDeserializeObject(T o) + throws IOException, ClassNotFoundException { + T o1; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(baos)) { + oos.writeObject(o); + } + try (ObjectInputStream ois + = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) { + o1 = (T) ois.readObject(); + } + return o1; + } } diff --git a/jdk/test/javax/sql/testng/TEST.properties b/jdk/test/javax/sql/testng/TEST.properties new file mode 100644 index 00000000000..97d1bc3a5a0 --- /dev/null +++ b/jdk/test/javax/sql/testng/TEST.properties @@ -0,0 +1,2 @@ +# JDBC unit tests uses TestNG +TestNG.dirs= . \ No newline at end of file diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SerialArrayTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SerialArrayTests.java new file mode 100644 index 00000000000..077ce43da85 --- /dev/null +++ b/jdk/test/javax/sql/testng/test/rowset/serial/SerialArrayTests.java @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 test.rowset.serial; + +import java.sql.Array; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import javax.sql.rowset.serial.SerialArray; +import javax.sql.rowset.serial.SerialException; +import static org.testng.Assert.*; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import util.BaseTest; +import util.StubArray; + +public class SerialArrayTests extends BaseTest { + + private Object[] coffees; + private final String sqlType = "VARCHAR"; + private Array a; + private Map<String, Class<?>> map; + + @BeforeMethod + public void setUpMethod() throws Exception { + coffees = new Object[]{"Espresso", "Colombian", "French Roast", + "Cappuccino"}; + a = new StubArray(sqlType, coffees); + map = new HashMap<>(); + } + + /* + * Validate a SerialArray can be created from an Array + */ + @Test + public void test01() throws Exception { + SerialArray sa = new SerialArray(a); + } + + /* + * Validate a SQLException is thrown if the map is null + */ + @Test(expectedExceptions = SQLException.class) + public void test02() throws Exception { + SerialArray sa = new SerialArray(a, null); + } + + /* + * Validate a SerialException is thrown when getResultSet() is called + */ + @Test(expectedExceptions = SerialException.class) + public void test03() throws Exception { + SerialArray sa = new SerialArray(a); + sa.getResultSet(); + } + + /* + * Validate a SerialException is thrown when getResultSet() is called + */ + @Test(expectedExceptions = SerialException.class) + public void test04() throws Exception { + SerialArray sa = new SerialArray(a); + sa.getResultSet(null); + } + + /* + * Validate a SerialException is thrown when getResultSet() is called + */ + @Test(expectedExceptions = SerialException.class) + public void test05() throws Exception { + SerialArray sa = new SerialArray(a); + sa.getResultSet(1, 1); + } + + /* + * Validate a SerialException is thrown when getResultSet() is called + */ + @Test(expectedExceptions = SerialException.class) + public void test06() throws Exception { + SerialArray sa = new SerialArray(a); + sa.getResultSet(1, 1, null); + } + + /* + * Validate a SerialException is thrown when getArray() is invoked after + * free() is called + */ + @Test(expectedExceptions = SerialException.class) + public void test07() throws Exception { + SerialArray sa = new SerialArray(a); + sa.free(); + sa.getArray(); + } + + /* + * Validate a SerialException is thrown when getArray() is invoked after + * free() is called + */ + @Test(expectedExceptions = SerialException.class) + public void test08() throws Exception { + SerialArray sa = new SerialArray(a); + sa.free(); + sa.getArray(map); + } + + /* + * Validate a SerialException is thrown when getArray() is invoked after + * free() is called + */ + @Test(expectedExceptions = SerialException.class) + public void test09() throws Exception { + SerialArray sa = new SerialArray(a); + sa.free(); + sa.getArray(1, 1, map); + } + + /* + * Validate a SerialException is thrown when getArray() is invoked after + * free() is called + */ + @Test(expectedExceptions = SerialException.class) + public void test10() throws Exception { + SerialArray sa = new SerialArray(a); + sa.free(); + sa.getArray(1, 1); + } + + /* + * Validate a SerialException is thrown when getBaseType() is invoked after + * free() is called + */ + @Test(expectedExceptions = SerialException.class) + public void test11() throws Exception { + SerialArray sa = new SerialArray(a); + sa.free(); + sa.getBaseType(); + } + + /* + * Validate a SerialException is thrown when getBaseTypeName() is invoked after + * free() is called + */ + @Test(expectedExceptions = SerialException.class) + public void test12() throws Exception { + SerialArray sa = new SerialArray(a); + sa.free(); + sa.getBaseTypeName(); + } + + /* + * Validate getArray() returns the same Object[] used to create the + * SerialArray + */ + @Test + public void test13() throws Exception { + SerialArray sa = new SerialArray(a); + Object[] o = (Object[]) sa.getArray(); + assertTrue(Arrays.equals(o, coffees)); + } + + /* + * Validate getArray() returns the same Object[] used to create the + * SerialArray + */ + @Test + public void test14() throws Exception { + SerialArray sa = new SerialArray(a); + Object[] o = (Object[]) sa.getArray(map); + assertTrue(Arrays.equals(o, coffees)); + } + + /* + * Validate getArray() returns the same Object[] used to create the + * SerialArray + */ + @Test + public void test15() throws Exception { + SerialArray sa = new SerialArray(a); + Object[] o = (Object[]) sa.getArray(1, 2); + assertTrue(Arrays.equals(o, Arrays.copyOfRange(coffees, 1, 3))); + } + + /* + * Validate getArray() returns the same Object[] used to create the + * SerialArray + */ + @Test + public void test16() throws Exception { + SerialArray sa = new SerialArray(a); + Object[] o = (Object[]) sa.getArray(1, 2, map); + assertTrue(Arrays.equals(o, Arrays.copyOfRange(coffees, 1, 3))); + } + + /* + * clone() a SerialArray and check that it is equal to the + * object it was cloned from + */ + @Test + public void test17() throws Exception { + SerialArray sa = new SerialArray(a); + SerialArray sa1 = (SerialArray) sa.clone(); + assertTrue(sa.equals(sa1)); + } + + /* + * Validate that a SerialArray that is serialized & deserialized is equal to + * itself + */ + @Test + public void test18() throws Exception { + SerialArray sa = new SerialArray(a); + SerialArray sa1 = serializeDeserializeObject(sa);; + assertTrue(sa.equals(sa1)); + } +} diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SerialBlobTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SerialBlobTests.java new file mode 100644 index 00000000000..e080b1ca1b9 --- /dev/null +++ b/jdk/test/javax/sql/testng/test/rowset/serial/SerialBlobTests.java @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 test.rowset.serial; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; +import javax.sql.rowset.serial.SerialBlob; +import javax.sql.rowset.serial.SerialException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; +import util.StubBlob; + +public class SerialBlobTests extends BaseTest { + + // byte[] used to populate SerialBlob + private byte[] bytes = new byte[]{1, 2, 3, 4, 5}; + + /* + * Validate calling free() does not throw an Exception + */ + @Test + public void test() throws Exception { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + } + + /* + * Validate calling getBinaryStream() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test01() throws Exception { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.getBinaryStream(); + } + + /* + * Validate calling getBinaryStream() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test02() throws Exception { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.getBinaryStream(1, 5); + } + + /* + * Validate calling getBytes() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test03() throws Exception { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.getBytes(1, 1); + } + + /* + * Validate calling getLength() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test04() throws Exception { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.length(); + } + + /* + * Validate calling position() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test05() throws Exception { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.position(new byte[5], 1); + } + + /* + * Validate calling position() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test06() throws Exception { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.position(new StubBlob(), 1); + } + + /* + * Validate calling free() after calling setBinaryStream() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test07() throws Exception { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.setBinaryStream(5); + } + + /* + * Validate calling free() after calling setBytes() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test08() throws Exception { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.setBytes(1, new byte[5]); + } + + /* + * Validate calling setBytes() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test09() throws Exception { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.setBytes(1, new byte[10], 0, 5); + } + + /* + * Validate calling truncate() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test10() throws Exception { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.truncate(1); + } + + /* + * Validate getBinaryStream returns the correct bytes + */ + @Test + public void test11() throws Exception { + byte[] expected = new byte[]{1, 2, 3}; + SerialBlob sb = new SerialBlob(bytes); + InputStream is = sb.getBinaryStream(1, 3); + for (byte b : expected) { + byte val = (byte) is.read(); + assertTrue(b == val, val + " does not match " + b); + } + } + + /* + * Validate a SerialException is thrown if pos < 0 for getBinaryStream + */ + @Test(expectedExceptions = SerialException.class) + public void test12() throws Exception { + SerialBlob sb = new SerialBlob(bytes); + InputStream is = sb.getBinaryStream(-1, 3); + } + + /* + * Validate a SerialException is thrown if pos = 0 for getBinaryStream + */ + @Test(expectedExceptions = SerialException.class) + public void test13() throws Exception { + SerialBlob sb = new SerialBlob(bytes); + InputStream is = sb.getBinaryStream(0, 3); + } + + /* + * Validate a SerialException is thrown if len > the length of the stream + * for getBinaryStream + */ + @Test(expectedExceptions = SerialException.class) + public void test14() throws Exception { + SerialBlob sb = new SerialBlob(bytes); + InputStream is = sb.getBinaryStream(0, 3); + } + + /* + * Validate a SerialException is thrown if length < 1 + */ + @Test(expectedExceptions = SerialException.class) + public void test15() throws Exception { + SerialBlob sb = new SerialBlob(bytes); + InputStream is = sb.getBinaryStream(1, 0); + } + + /* + * Validate a SerialException is thrown if length > byte array length + */ + @Test(expectedExceptions = SerialException.class) + public void test16() throws Exception { + SerialBlob sb = new SerialBlob(bytes); + InputStream is = sb.getBinaryStream(1, 6); + } + + /* + * Validate a SerialException is thrown if pos > byte array length + */ + @Test(expectedExceptions = SerialException.class) + public void test17() throws Exception { + SerialBlob sb = new SerialBlob(bytes); + InputStream is = sb.getBinaryStream(bytes.length + 2, 6); + } + + /* + * Validate that a cloned SerializedBlob bytes match the original + */ + @Test + public void test18() throws Exception { + SerialBlob sb = new SerialBlob(bytes); + SerialBlob sb2 = (SerialBlob) sb.clone(); + assertTrue( + Arrays.equals(sb.getBytes(1, (int) sb.length()), + sb2.getBytes(1, (int) sb2.length())), + "arrays do not match "); + } + + /* + * Test clone after free has been called that the clone is not accessible + */ + @Test(expectedExceptions = SerialException.class) + public void test19() throws Exception { + SerialBlob sb = new SerialBlob(bytes); + sb.free(); + SerialBlob sb2 = (SerialBlob) sb.clone(); + InputStream is = sb2.getBinaryStream(1, 3); + } + + /* + * Validate that a SerialBlob that is serialized & deserialized is equal to + * itself + */ + @Test + public void test20() throws Exception { + SerialBlob sb = new SerialBlob(bytes); + SerialBlob sb2 = serializeDeserializeObject(sb); + assertTrue(sb.equals(sb2), "SerialBlob not equal"); + } + + /* + * Validate a SerialException is thrown if byte[] is used to + * create the SeriablBlob and setBinaryStream is called + */ + @Test(expectedExceptions = SerialException.class) + public void test21() throws Exception { + SerialBlob sb = new SerialBlob(bytes); + sb.setBinaryStream(3); + } + + /* + * Validate that setBytes will properly write a set of bytes to the + * specified location in the SerialBlob and the correct count is returned + * for bytes written + */ + @Test + public void test22() throws Exception { + byte[] diff = new byte[]{7, 8, 9}; + byte[] expected = new byte[]{1, 7, 8, 9, 5}; + SerialBlob sb = new SerialBlob(bytes); + int written = sb.setBytes(2, diff); + assertEquals(written, diff.length); + assertTrue( + Arrays.equals(sb.getBytes(1, (int) sb.length()), + expected), + "arrays do not match "); + } + + /* + * Validate that setBytes will properly write a set of bytes to the + * specified location in the SerialBlob and the correct count is returned + * for bytes written + */ + @Test + public void test23() throws Exception { + int bytesToWrite = 3; + byte[] diff = new byte[]{7, 8, 9, 0}; + byte[] expected = new byte[]{1, 8, 9, 0, 5}; + SerialBlob sb = new SerialBlob(bytes); + int written = sb.setBytes(2, diff, 1, bytesToWrite); + assertEquals(written, bytesToWrite); + assertTrue( + Arrays.equals(sb.getBytes(1, (int) sb.length()), + expected), + "arrays do not match "); + } + + /* + * Validate that truncate reduces the length of the SerlizedBlob to the + * specified value + */ + @Test + public void test24() throws Exception { + SerialBlob sb = new SerialBlob(bytes); + sb.truncate(0); + assertTrue(sb.length() == 0); + sb = new SerialBlob(bytes); + sb.truncate(3); + assertTrue(sb.length() == 3); + } + + /* + * Validate getBinaryStream returns the correct bytes + */ + @Test + public void test25() throws Exception { + byte[] expected = bytes; + SerialBlob sb = new SerialBlob(bytes); + InputStream is = sb.getBinaryStream(); + for (byte b : expected) { + byte val = (byte) is.read(); + assertTrue(b == val, val + " does not match " + b); + } + } + + /* + * Validate setBinaryStream returns an OutputStream when passed a Blob + */ + @Test + public void test26() throws Exception { + SerialBlob sb = new SerialBlob(new StubBlob()); + OutputStream os = sb.setBinaryStream(0); + assertTrue(os != null); + } + + /* + * Validate that position returns the correct starting location for a + * pattern in the SerialBlob + */ + @Test + public void test27() throws Exception { + long expectedPos = 3; // starting offset is 1 vs 0 + byte[] pattern = new byte[]{3, 4}; + SerialBlob sb = new SerialBlob(bytes); + long pos = sb.position(pattern, 1); + assertEquals(pos, expectedPos); + } + + /* + * Validate that position returns the correct starting location for a + * pattern in the SerialBlob + */ + @Test + public void test28() throws Exception { + long expectedPos = 3; // starting offset is 1 vs 0 + byte[] pattern = new byte[]{3, 4, 5}; + SerialBlob sb = new SerialBlob(bytes); + long pos = sb.position(pattern, 2); + assertEquals(pos, expectedPos); + } + + /* + * Validate that position returns the correct starting location for a + * pattern in the SerialBlob + */ + @Test + public void test29() throws Exception { + long expectedPos = 2; // starting offset is 1 vs 0 + byte[] pattern = new byte[]{4, 6}; + SerialBlob sb = new SerialBlob(new StubBlob()); + long pos = sb.position(pattern, 1); + assertEquals(pos, expectedPos); + } + + /* + * Validate that position returns the correct starting location for a + * pattern in the SerialBlob + */ + @Test + public void test30() throws Exception { + long expectedPos = 3; // starting offset is 1 vs 0 + byte[] pattern = new byte[]{6, 8}; + SerialBlob sb = new SerialBlob(new StubBlob()); + long pos = sb.position(pattern, 2); + assertEquals(pos, expectedPos); + } +} diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SerialClobTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SerialClobTests.java new file mode 100644 index 00000000000..72f42674de0 --- /dev/null +++ b/jdk/test/javax/sql/testng/test/rowset/serial/SerialClobTests.java @@ -0,0 +1,499 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 test.rowset.serial; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import javax.sql.rowset.serial.SerialClob; +import javax.sql.rowset.serial.SerialException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; +import util.StubClob; + +public class SerialClobTests extends BaseTest { + + // char[] used to populate SerialClob + private final char[] chars; + + public SerialClobTests() { + this.chars = new char[]{'h', 'e', 'l', 'l', 'o', ' ', 'w', + 'o', 'r', 'l', 'd'}; + } + + /* + * Validate calling free() does not throw an Exception + */ + @Test + public void test() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + } + + /* + * Validate calling getCharacterStream() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test01() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.getCharacterStream(); + } + + /* + * Validate calling getCharacterStream() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test02() throws Exception { + SerialClob sc = new SerialClob(chars); + sc.free(); + sc.getCharacterStream(); + } + + /* + * Validate calling getCharacterStream() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test03() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.getCharacterStream(1, 5); + } + + /* + * Validate calling getSubString() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test04() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.getSubString(1, 1); + } + + /* + * Validate calling truncate() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test05() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.truncate(1); + } + + /* + * Validate calling getAsciiStream() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test06() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.getAsciiStream(); + } + + /* + * Validate calling length() after calling free() throws an SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test07() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.length(); + } + + /* + * Validate calling position() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test08() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.position("hello", 1); + } + + /* + * Validate calling position() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test09() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.position(new StubClob(), 1); + } + + /* + * Validate calling setAsciiStream() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test10() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.setAsciiStream(5); + } + + /* + * Validate calling setCharacterStream() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test11() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.setCharacterStream(5); + } + + /* + * Validate calling setString() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test12() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.setString(1, "hello"); + } + + /* + * Validate calling setString() after calling free() throws an + * SerialException + */ + @Test(expectedExceptions = SerialException.class) + public void test13() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.setString(1, "hello", 0, 5); + } + + /* + * Test that SerialException is thrown if pos < 0 on a call to + * getCharacterStream + */ + @Test(expectedExceptions = SerialException.class) + public void test14() throws Exception { + SerialClob sc = new SerialClob(chars); + sc.getCharacterStream(-1, 5); + } + + /* + * Test that SerialException is thrown if pos = 0 on a call to + * getCharacterStream + */ + @Test(expectedExceptions = SerialException.class) + public void test15() throws Exception { + SerialClob sc = new SerialClob(chars); + sc.getCharacterStream(0, 5); + } + + /* + * Test that SerialException is thrown if pos = 0 on a call to + * getCharacterStream + */ + @Test(expectedExceptions = SerialException.class) + public void test16() throws Exception { + SerialClob sc = new SerialClob(chars); + sc.getCharacterStream(1, 100); + } + + /* + * Test that SerialException is thrown if length = 0 on a call to + * getCharacterStream + */ + @Test(expectedExceptions = SerialException.class) + public void test17() throws Exception { + SerialClob sc = new SerialClob(chars); + sc.getCharacterStream(1, 0); + } + + /* + * Test that SerialException is thrown if pos > length on a call to + * getCharacterStream + */ + @Test(expectedExceptions = SerialException.class) + public void test18() throws Exception { + SerialClob sc = new SerialClob(chars); + sc.getCharacterStream(100, 5); + } + + /* + * Clone a SerialClob and check that it is equal to itself + */ + @Test + public void test19() throws Exception { + SerialClob sc = new SerialClob(chars); + SerialClob sc1 = (SerialClob) sc.clone(); + assertTrue(sc.equals(sc1), "SerialClobs not equal"); + } + + /* + * Validate that a getAsciiStream() returns an InputStream when a Clob is + * used to create the SerialClob + */ + @Test + public void test20() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + InputStream is = sc.getAsciiStream(); + assertTrue(is != null); + } + + /* + * Validate that a getCharacterStream() returns an Reader when a Clob is + * used to create the SerialClob + */ + @Test + public void test21() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + Reader is = sc.getCharacterStream(); + assertTrue(is != null); + } + + /* + * Validate that a getCharacterStream() returns an Reader when a char[] is + * used to create the SerialClob + */ + @Test + public void test22() throws Exception { + SerialClob sc = new SerialClob(chars); + Reader is = sc.getCharacterStream(); + assertTrue(is != null); + } + + /* + * Validate that a getSubString() returns the correct value when a char[] is + * used to create the SerialClob + */ + @Test + public void test23() throws Exception { + SerialClob sc = new SerialClob(chars); + String expected = "world"; + assertEquals(expected, sc.getSubString(7, 5)); + } + + /* + * Validate that a getSubString() returns the correct value when a Clob is + * used to create the SerialClob + */ + @Test + public void test24() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + String expected = "test string"; + assertEquals(expected, sc.getSubString(5, 11)); + } + + /* + * Validate that position() returns the correct value when a Clob is used to + * create the SerialClob + */ + @Test + public void test25() throws Exception { + long expectedPos = 5; + SerialClob sc = new SerialClob(new StubClob()); + String expected = "test string"; + long pos = sc.position(expected, 1); + assertEquals(expectedPos, pos); + } + + /* + * Validate that position returned is -1 when an the search string is not + * part of the SerialClob + */ + @Test + public void test26() throws Exception { + long expectedPos = -1; + SerialClob sc = new SerialClob(chars); + String expected = "test string"; + long pos = sc.position(expected, 1); + assertEquals(expectedPos, pos); + } + + /* + * Validate that position() returned is -1 when an the search string is not + * part of the SerialClob + */ + @Test + public void test27() throws Exception { + long expectedPos = -1; + SerialClob sc = new SerialClob(new StubClob()); + String expected = "I am Batman"; + long pos = sc.position(expected, 2); + assertEquals(expectedPos, pos); + } + + /* + * Validate that position() returns the correct value when a char[] is used + * to create the SerialClob + */ + @Test + public void test28() throws Exception { + long expectedPos = 2; + SerialClob sc = new SerialClob(chars); + String expected = "ello"; + long pos = sc.position(expected, 1); + assertEquals(expectedPos, pos); + } + + /* + * Validate that position() returns the correct value when a SerialClob is + * used for the search argument + */ + @Test + public void test29() throws Exception { + long expectedPos = 21; + String expected = "Batman"; + String buf = "I am Joker, not the Batman, hahaha"; + SerialClob sc = new SerialClob(expected.toCharArray()); + SerialClob sc1 = new SerialClob(buf.toCharArray()); + long pos = sc1.position(sc, 1); + assertEquals(expectedPos, pos); + } + + /* + * Validate that position() returns the correct value when a SerialClob is + * used for the search argument + */ + @Test + public void test30() throws Exception { + long expectedPos = 17; + String expected = "012"; + SerialClob sc = new SerialClob(expected.toCharArray()); + SerialClob sc1 = new SerialClob(new StubClob()); + long pos = sc1.position(sc, 1); + assertEquals(expectedPos, pos); + } + + /* + * Check that setString() updates the appropriate characters in the + * SerialClob + */ + @Test + public void test31() throws Exception { + String val = "Hello, I am Bruce Wayne"; + String val1 = "the Batman!"; + String expected = "Hello, I am the Batman!"; + SerialClob sc = new SerialClob(val.toCharArray()); + int written = sc.setString(13, val1); + assertEquals(val1.length(), written); + assertTrue(expected.equals(sc.getSubString(1, (int) sc.length()))); + } + + /* + * Check that setString() updates the appropriate characters in the + * SerialClob + */ + @Test(enabled = false) + public void test32() throws Exception { + int expectedWritten = 9; + String val = "Hi, I am Catwoman!!!!!!"; + String val1 = "Hahaha the Joker, who are you?!"; + String expected = "Hi, I am the Joker!"; + SerialClob sc = new SerialClob(val.toCharArray()); + int written = sc.setString(10, val1, 8, expectedWritten+1); + assertEquals(written, expectedWritten); + + } + + /* + * Check that setCharacterStream() returns a non-null Writer for an + * SerialClob created from a Clob + */ + @Test + public void test33() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + Writer w = sc.setCharacterStream(1); + assertTrue(w != null); + } + + /* + * Check that setAsciiStream() returns a non-null OutputStream for an SerialClob + * created from a Clob + */ + @Test + public void test34() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + OutputStream os = sc.setAsciiStream(1); + assertTrue(os != null); + } + + /* + * Check that truncate() truncates the length of the SerialClob to the + * specified size + */ + @Test + public void test35() throws Exception { + SerialClob sc = new SerialClob(new StubClob()); + sc.truncate(0); + assertTrue(sc.length() == 0); + sc = new SerialClob(chars); + sc.truncate(5); + assertTrue(sc.length() == 5); + } + + /* + * Check that getCharacterStream() returns a Reader and that the char[] that + * was specified to create the SerialClob can be returned via the Reader + */ + @Test + public void test36() throws Exception { + SerialClob sc = new SerialClob(chars); + Reader r = sc.getCharacterStream(); + for (char c : chars) { + char val = (char) r.read(); + assertTrue(c == val, val + " does not match " + c); + } + } + + /* + * Check that getCharacterStream() returns a Reader and that the char[] that + * was specified to create the SerialClob can be returned via the Reader + */ + @Test(enabled = false) + public void test37() throws Exception { + SerialClob sc = new SerialClob(chars); + String expected = "ello w"; + Reader r = sc.getCharacterStream(2, 6); + for (char c : expected.toCharArray()) { + char val = (char) r.read(); + assertTrue(c == val, val + " does not match " + c); + } + } + + /* + * Validate that a SerialClob that is serialized & deserialized is equal to + * itself + */ + @Test + public void test38() throws Exception { + SerialClob sc = new SerialClob(chars); + SerialClob sc2 = serializeDeserializeObject(sc); + assertTrue(sc.equals(sc2), "SerialClobs not equal"); + } +} diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SerialDataLinkTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SerialDataLinkTests.java new file mode 100644 index 00000000000..8e86d4a8f3d --- /dev/null +++ b/jdk/test/javax/sql/testng/test/rowset/serial/SerialDataLinkTests.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 test.rowset.serial; + +import java.net.URL; +import javax.sql.rowset.serial.SerialDatalink; +import javax.sql.rowset.serial.SerialException; +import static org.testng.Assert.*; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SerialDataLinkTests extends BaseTest { + + private URL u; + private URL u1; + private SerialDatalink dl; + + @BeforeMethod + public void setUpMethod() throws Exception { + u = new URL("http://www.oracle.com/"); + u1 = new URL("http://www.usatoday.com/"); + dl = new SerialDatalink(u); + } + + /* + * Validate that a SerialException is thrown if the URL is null + */ + @Test(expectedExceptions = SerialException.class) + public void test() throws Exception { + SerialDatalink dl1 = new SerialDatalink(null); + } + + /* + * Validate that getDatalink() returns the same URL used to create the + * SerialDatalink object + */ + @Test + public void test01() throws Exception { + URL u2 = dl.getDatalink(); + assertTrue(u2.equals(u)); + assertTrue(u2.sameFile(u)); + } + + /* + * Validate that URL returned from getDatalink() differs from a URL that was + * not used to create the SerialDatalink + */ + @Test + public void test02() throws Exception { + URL u2 = dl.getDatalink(); + assertFalse(u2.equals(u1)); + assertFalse(u2.sameFile(u1)); + } + + /* + * Create a clone of a SerialDatalink and validate that it is equal to the + * SerialDatalink it was cloned from + */ + @Test + public void test03() throws Exception { + SerialDatalink dl2 = (SerialDatalink) dl.clone(); + assertTrue(dl.equals(dl2)); + SerialDatalink dl3 = new SerialDatalink(u1); + assertFalse(dl2.equals(dl3)); + } + + /* + * Validate that a SerialDatalink that is serialized & deserialized is + * equal to itself + */ + @Test + public void test04() throws Exception { + SerialDatalink dl2 = serializeDeserializeObject(dl); + SerialDatalink dl3 = new SerialDatalink(u); + assertTrue(dl.equals(dl2)); + assertTrue(dl3.equals(dl2)); + } + + /** + * Validate that a SerialDatalink that is serialized & deserialized is not equal + * to to a SerialDatalink created using a different URL + */ + @Test + public void test05() throws Exception { + SerialDatalink dl2 = serializeDeserializeObject(dl); + SerialDatalink d3 = new SerialDatalink(u1); + assertFalse(d3.equals(dl2)); + } +} diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SerialExceptionTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SerialExceptionTests.java new file mode 100644 index 00000000000..ff963ae7ba8 --- /dev/null +++ b/jdk/test/javax/sql/testng/test/rowset/serial/SerialExceptionTests.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 test.rowset.serial; + +import java.sql.SQLException; +import javax.sql.rowset.serial.SerialException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SerialExceptionTests extends BaseTest { + + /* + * Create SerialException with no-arg constructor + */ + @Test + public void test01() { + SerialException ex = new SerialException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /* + * Create SerialException with message + */ + @Test + public void test02() { + SerialException ex = new SerialException(reason); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /* + * Validate that the ordering of the returned Exceptions is correct using + * for-each loop + */ + @Test + public void test03() { + SerialException ex = new SerialException("Exception 1"); + ex.initCause(t1); + SerialException ex1 = new SerialException("Exception 2"); + SerialException ex2 = new SerialException("Exception 3"); + ex2.initCause(t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(msgs[num++].equals(e.getMessage())); + } + } + + /* + * Validate that the ordering of the returned Exceptions is correct using + * traditional while loop + */ + @Test + public void test04() { + SQLException ex = new SerialException("Exception 1"); + ex.initCause(t1); + SerialException ex1 = new SerialException("Exception 2"); + SerialException ex2 = new SerialException("Exception 3"); + ex2.initCause(t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + while (ex != null) { + assertTrue(msgs[num++].equals(ex.getMessage())); + Throwable c = ex.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + ex = ex.getNextException(); + } + } + + /* + * Serialize a SerialException and make sure you can read it back properly + */ + @Test + public void test05() throws Exception { + SerialException e = new SerialException(reason); + SerialException ex1 = createSerializedException(e); + assertTrue(ex1.getMessage().equals(reason) + && ex1.getSQLState() == null + && ex1.getCause() == null + && ex1.getErrorCode() == 0);; + } +} diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SerialJavaObjectTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SerialJavaObjectTests.java new file mode 100644 index 00000000000..cc2d184298d --- /dev/null +++ b/jdk/test/javax/sql/testng/test/rowset/serial/SerialJavaObjectTests.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 test.rowset.serial; + +import java.lang.reflect.Field; +import java.util.Arrays; +import javax.sql.rowset.RowSetMetaDataImpl; +import javax.sql.rowset.serial.SerialException; +import javax.sql.rowset.serial.SerialJavaObject; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SerialJavaObjectTests extends BaseTest { + + /* + * Validate that an NPE is thrown when null is specified to create + * the SerialJavaObject + */ + @Test(expectedExceptions = NullPointerException.class) + public void test() throws Exception { + SerialJavaObject sjo = new SerialJavaObject(null); + } + + /* + * Validate that an SerialExcepion is thrown when the object specified + * contains public static fields + */ + @Test(expectedExceptions = SerialException.class, enabled = false) + public void test01() throws Exception { + SerialJavaObject sjo = new SerialJavaObject(new RowSetMetaDataImpl()); + } + + /* + * Validate that an getFields()s returns the same Field[] for the object + * used to create the SerialJavaObject + */ + @Test + public void test02() throws Exception { + SerialException e = new SerialException(); + SerialJavaObject sjo = new SerialJavaObject(e); + Field[] f = e.getClass().getFields(); + assertTrue(Arrays.equals(f, sjo.getFields())); + assertFalse(Arrays.equals("hello".getClass().getFields(), + sjo.getFields())); + } + + /* + * clone() a SerialJavaObject and check that it is equal to the + * object it was cloned from + */ + @Test + public void test03() throws Exception { + SerialJavaObject sjo = new SerialJavaObject("Hello"); + SerialJavaObject sjo2 = (SerialJavaObject) sjo.clone(); + assertTrue(sjo.equals(sjo2)); + } + + /** + * Validate that a SerialJavaObject that is serialized & deserialized is + * equal to itself + */ + @Test + public void test04() throws Exception { + SerialJavaObject sjo = new SerialJavaObject("Hello"); + SerialJavaObject sjo2 = serializeDeserializeObject(sjo); + assertTrue(sjo.equals(sjo2)); + } + + /* + * Validate that a getObject() returns an object used to create the + * SerialJavaObject + */ + @Test + public void test05() throws Exception { + String s = "Hello world"; + SerialJavaObject sjo = new SerialJavaObject(s); + assertTrue(s.equals(sjo.getObject())); + } +} diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SerialRefTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SerialRefTests.java new file mode 100644 index 00000000000..8f23de70aa6 --- /dev/null +++ b/jdk/test/javax/sql/testng/test/rowset/serial/SerialRefTests.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 test.rowset.serial; + +import java.sql.Ref; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; +import javax.sql.rowset.serial.SerialRef; +import static org.testng.Assert.*; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import util.BaseTest; +import util.StubRef; +import util.SuperHero; + +public class SerialRefTests extends BaseTest { + + private static Map<String, Class<?>> map = new HashMap<>(); + private Ref ref; + private final String sqlType = "SUPERHERO"; + private SuperHero hero; + + @BeforeMethod + public void setUpMethod() throws Exception { + map.put(sqlType, Class.forName("util.SuperHero")); + hero = new SuperHero(sqlType, "Bruce", "Wayne", 1939, "Batman"); + ref = new StubRef(sqlType, hero); + } + + /* + * Validate that a SQLException() is thrown if the Ref is null + */ + @Test(expectedExceptions = SQLException.class) + public void test01() throws Exception { + SerialRef sr = new SerialRef(null); + } + + /* + * Validate that a SQLException() is thrown if the typeName is null in the + * Ref used to create the SerialRef + */ + @Test(expectedExceptions = SQLException.class) + public void test02() throws Exception { + SerialRef sr = new SerialRef(new StubRef(null, hero)); + } + + /* + * Validate that getBaseTypeName() returns the same SQLType specified + * to create the Ref + */ + @Test + public void test03() throws Exception { + SerialRef sr = new SerialRef(ref); + assertEquals(sr.getBaseTypeName(), sqlType); + } + + /* + * Validate that getObject() returns the same object used to create the Ref + */ + @Test + public void test04() throws Exception { + SerialRef sr = new SerialRef(ref); + assertTrue(hero.equals(sr.getObject())); + } + + /* + * Validate that getObject() returns the same object used to create the Ref + */ + @Test(enabled = false) + public void test05() throws Exception { + SerialRef sr = new SerialRef(ref); + assertTrue(hero.equals(sr.getObject(map))); + } + + /* + * Validate that setObject() can be used to change the value of the object + * pointed to by the SerialRef + */ + @Test + public void test06() throws Exception { + SerialRef sr = new SerialRef(ref); + assertTrue(hero.equals(sr.getObject())); + SuperHero h = new SuperHero(sqlType, "Dick", "Grayson", 1940, "Robin"); + sr.setObject(h); + assertFalse(hero.equals(sr.getObject())); + } + + /* + * clone() a SerialRef and check that it is equal to the + * object it was cloned from + */ + @Test + public void test09() throws Exception { + SerialRef sr = new SerialRef(ref); + SerialRef sr1 = (SerialRef) sr.clone(); + assertTrue(sr.equals(sr1)); + } + + /** + * Validate that a SerialRef that is serialized & deserialized is equal to + * itself for the Object & baseTypeName + */ + @Test + public void test10() throws Exception { + SerialRef sr = new SerialRef(ref); + SerialRef sr1 = serializeDeserializeObject(sr); + assertTrue(sr1.getObject().equals(sr.getObject()) + && sr1.getBaseTypeName().equals(sr.getBaseTypeName())); + } +} diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SerialStructTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SerialStructTests.java new file mode 100644 index 00000000000..84a0ff2aaaf --- /dev/null +++ b/jdk/test/javax/sql/testng/test/rowset/serial/SerialStructTests.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 test.rowset.serial; + +import java.sql.Struct; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import javax.sql.rowset.serial.SerialStruct; +import static org.testng.Assert.*; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import util.BaseTest; +import util.StubStruct; +import util.SuperHero; + +public class SerialStructTests extends BaseTest { + + private static Map<String, Class<?>> map = new HashMap<>(); + private Object[] attributes; + private Struct struct; + private final String sqlType = "SUPERHERO"; + private SuperHero hero; + + @BeforeMethod + public void setUpMethod() throws Exception { + attributes = new Object[]{"Bruce", "Wayne", 1939, + "Batman"}; + map.put(sqlType, Class.forName("util.SuperHero")); + struct = new StubStruct(sqlType, attributes); + hero = new SuperHero(sqlType, "Bruce", "Wayne", 1939, "Batman"); + } + + /* + * Validate that getSQLTypeName() returns the same SQLType specified by + * the Struct used to create the object + */ + @Test + public void test01() throws Exception { + SerialStruct ss = new SerialStruct(struct, map); + assertEquals(ss.getSQLTypeName(), sqlType); + } + + /* + * Validate that getSQLTypeName() returns the same SQLType specified by + * the Struct used to create the object + */ + @Test + public void test02() throws Exception { + SerialStruct ss = new SerialStruct(hero, map); + assertEquals(ss.getSQLTypeName(), sqlType); + } + + /* + * Validate that getAttributes() returns the same attributes specified by + * the Struct used to create the object + */ + @Test + public void test03() throws Exception { + SerialStruct ss = new SerialStruct(struct, map); + assertTrue(Arrays.equals(attributes, + ss.getAttributes())); + } + + /* + * Validate that getAttributes() returns the same attributes specified by + * the Struct used to create the object + */ + @Test + public void test04() throws Exception { + SerialStruct ss = new SerialStruct(hero, map); + assertTrue(Arrays.equals(attributes, + ss.getAttributes())); + } + + /* + * Validate that getAttributes() returns the + same attributes specified by + * the Struct used to create the object + */ + @Test + public void test05() throws Exception { + SerialStruct ss = new SerialStruct(struct, map); + assertTrue(Arrays.equals(attributes, + ss.getAttributes(map))); + } + + /* + * Validate that getAttributes() returns the same attributes specified by + * the Struct used to create the object + */ + @Test + public void test06() throws Exception { + SerialStruct ss = new SerialStruct(hero, map); + assertTrue(Arrays.equals(attributes, + ss.getAttributes(map))); + } + + /* + * clone() a SerialStruct and check that it is equal to the + * object it was cloned from + */ + @Test + public void test07() throws Exception { + SerialStruct ss = new SerialStruct(struct, map); + SerialStruct ss1 = (SerialStruct) ss.clone(); + assertTrue(ss.equals(ss1)); + } + + /** + * Validate that a SerialStruct that is serialized & deserialized is equal + * to itself + */ + @Test + public void test08() throws Exception { + SerialStruct ss = new SerialStruct(struct, map); + SerialStruct ss1 = serializeDeserializeObject(ss);; + assertTrue(ss.equals(ss1)); + } +} diff --git a/jdk/test/javax/sql/testng/util/BaseTest.java b/jdk/test/javax/sql/testng/util/BaseTest.java new file mode 100644 index 00000000000..130dae8fb4e --- /dev/null +++ b/jdk/test/javax/sql/testng/util/BaseTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.sql.SQLException; +import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; + +public class BaseTest { + + protected final String reason = "reason"; + protected final String state = "SQLState"; + protected final String cause = "java.lang.Throwable: cause"; + protected final Throwable t = new Throwable("cause"); + protected final Throwable t1 = new Throwable("cause 1"); + protected final Throwable t2 = new Throwable("cause 2"); + protected final int errorCode = 21; + protected final String[] msgs = {"Exception 1", "cause 1", "Exception 2", + "Exception 3", "cause 2"}; + + @BeforeClass + public static void setUpClass() throws Exception { + } + + @AfterClass + public static void tearDownClass() throws Exception { + } + + @BeforeMethod + public void setUpMethod() throws Exception { + } + + @AfterMethod + public void tearDownMethod() throws Exception { + } + + /* + * Take some form of SQLException, serialize and deserialize it + */ + @SuppressWarnings("unchecked") + protected <T extends SQLException> T + createSerializedException(T ex) + throws IOException, ClassNotFoundException { + return (T) serializeDeserializeObject(ex); + } + + /* + * Utility method to serialize and deserialize an object + */ + @SuppressWarnings("unchecked") + protected <T> T serializeDeserializeObject(T o) + throws IOException, ClassNotFoundException { + T o1; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(baos)) { + oos.writeObject(o); + } + try (ObjectInputStream ois + = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) { + o1 = (T) ois.readObject(); + } + return o1; + } +} diff --git a/jdk/test/javax/sql/testng/util/StubArray.java b/jdk/test/javax/sql/testng/util/StubArray.java new file mode 100644 index 00000000000..1d2ef0e5b6f --- /dev/null +++ b/jdk/test/javax/sql/testng/util/StubArray.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 util; + +import java.sql.Array; +import java.sql.JDBCType; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Map; + +public class StubArray implements Array { + + private String typeName; + Object[] elements; + + public StubArray(String name, Object[] values) { + typeName = name; + elements = Arrays.copyOf(values, values.length); + + } + + @Override + public String getBaseTypeName() throws SQLException { + return typeName; + } + + @Override + public int getBaseType() throws SQLException { + return JDBCType.valueOf(typeName).getVendorTypeNumber(); + } + + @Override + public Object getArray() throws SQLException { + return Arrays.copyOf(elements, elements.length); + } + + @Override + public Object getArray(Map<String, Class<?>> map) throws SQLException { + return getArray(); + } + + @Override + public Object getArray(long index, int count) throws SQLException { + return getArray(); + } + + @Override + public Object getArray(long index, int count, Map<String, Class<?>> map) throws SQLException { + return getArray(); + } + + @Override + public ResultSet getResultSet() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ResultSet getResultSet(Map<String, Class<?>> map) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ResultSet getResultSet(long index, int count) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ResultSet getResultSet(long index, int count, Map<String, Class<?>> map) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void free() throws SQLException { + elements = null; + typeName = null; + } + +} diff --git a/jdk/test/javax/sql/testng/util/StubBlob.java b/jdk/test/javax/sql/testng/util/StubBlob.java new file mode 100644 index 00000000000..727e8a926d5 --- /dev/null +++ b/jdk/test/javax/sql/testng/util/StubBlob.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.sql.Blob; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class StubBlob implements Blob { + + private byte[] bytes; + + public StubBlob() { + bytes = new byte[]{2, 4, 6, 8}; + } + + public long length() throws SQLException { + return bytes.length; + } + + public byte[] getBytes(long pos, int length) + throws SQLException { + return Arrays.copyOfRange(bytes, (int) pos - 1, length); + } + + public InputStream getBinaryStream() + throws SQLException { + return null; + } + + public long position(byte[] pattern, long start) + throws SQLException { + return 0; + } + + public long position(Blob pattern, long start) + throws SQLException { + return 0; + } + + public int setBytes(long pos, byte[] bytes) + throws SQLException { + return 0; + } + + public int setBytes(long pos, byte[] bytes, int offset, int len) + throws SQLException { + return 0; + } + + public OutputStream setBinaryStream(long pos) + throws SQLException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = null; + try { + oos = new ObjectOutputStream(baos); + } catch (IOException ex) { + Logger.getLogger(StubBlob.class.getName()).log(Level.SEVERE, null, ex); + } + return oos; + } + + public void truncate(long len) + throws SQLException { + } + + public void free() throws SQLException { + } + + public InputStream getBinaryStream(long pos, long length) throws SQLException { + return null; + } +} diff --git a/jdk/test/javax/sql/testng/util/StubClob.java b/jdk/test/javax/sql/testng/util/StubClob.java new file mode 100644 index 00000000000..cb1e0c0a62a --- /dev/null +++ b/jdk/test/javax/sql/testng/util/StubClob.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import java.sql.Clob; +import java.sql.SQLException; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class StubClob implements Clob { + + public String buf = "The test string 0123456789"; + + @Override + public String getSubString(long pos, int length) throws SQLException { + return buf; + } + + @Override + public long length() throws SQLException { + return buf.length(); + } + + @Override + public Reader getCharacterStream() throws SQLException { + return new StringReader(buf); + } + + @Override + public InputStream getAsciiStream() throws SQLException { + return new java.io.StringBufferInputStream(buf); + } + + @Override + public int setString(long pos, String str) throws SQLException { + return str.length(); + } + + @Override + public int setString(long pos, String str, int offset, int len) throws SQLException { + return len; + } + + @Override + public long position(String searchstr, long start) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public long position(Clob searchstr, long start) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public OutputStream setAsciiStream(long pos) throws SQLException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = null; + try { + oos = new ObjectOutputStream(baos); + } catch (IOException ex) { + Logger.getLogger(StubBlob.class.getName()).log(Level.SEVERE, null, ex); + } + return oos; + } + + @Override + public Writer setCharacterStream(long pos) throws SQLException { + return new StringWriter(); + } + + @Override + public void truncate(long len) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void free() throws SQLException { + } + + @Override + public Reader getCharacterStream(long pos, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/jdk/test/javax/sql/testng/util/StubRef.java b/jdk/test/javax/sql/testng/util/StubRef.java new file mode 100644 index 00000000000..052bd92c740 --- /dev/null +++ b/jdk/test/javax/sql/testng/util/StubRef.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 util; + +import java.io.Serializable; +import java.sql.Ref; +import java.sql.SQLException; +import java.util.Map; + +public class StubRef implements Ref, Serializable { + + private final String baseTypeName; + private Object obj; + + public StubRef(String type, Object o) { + baseTypeName = type; + obj = o; + } + + @Override + public String getBaseTypeName() throws SQLException { + return baseTypeName; + } + + @Override + public Object getObject(Map<String, Class<?>> map) throws SQLException { + return obj; + } + + @Override + public Object getObject() throws SQLException { + return getObject(null); + } + + @Override + public void setObject(Object value) throws SQLException { + obj = value; + } + +} diff --git a/jdk/test/javax/sql/testng/util/StubStruct.java b/jdk/test/javax/sql/testng/util/StubStruct.java new file mode 100644 index 00000000000..1dee8028a2c --- /dev/null +++ b/jdk/test/javax/sql/testng/util/StubStruct.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 util; + +import java.sql.SQLException; +import java.sql.Struct; +import java.util.Arrays; +import java.util.Map; + +public class StubStruct implements Struct { + + private final String type; + private final Object[] attribs; + + public StubStruct(String type, Object[] o) { + this.type = type; + this.attribs = Arrays.copyOf(o, o.length); + } + + @Override + public String getSQLTypeName() throws SQLException { + return type; + } + + @Override + public Object[] getAttributes() throws SQLException { + return attribs; + } + + @Override + public Object[] getAttributes(Map<String, Class<?>> map) throws SQLException { + return attribs; + } + +} diff --git a/jdk/test/javax/sql/testng/util/SuperHero.java b/jdk/test/javax/sql/testng/util/SuperHero.java new file mode 100644 index 00000000000..8588f5006f1 --- /dev/null +++ b/jdk/test/javax/sql/testng/util/SuperHero.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 util; + +import java.io.Serializable; +import java.sql.SQLData; +import java.sql.SQLException; +import java.sql.SQLInput; +import java.sql.SQLOutput; + +public class SuperHero implements SQLData, Serializable { + + private String first; + private String last; + private final String type; + private Integer firstYear; + private String secretIdentity; + + public SuperHero(String sqlType, String fname, String lname, Integer year, + String identity) { + first = fname; + last = lname; + type = sqlType; + firstYear = year; + secretIdentity = identity; + } + + @Override + public String getSQLTypeName() throws SQLException { + return type; + } + + @Override + public void readSQL(SQLInput stream, String typeName) throws SQLException { + first = stream.readString(); + last = stream.readString(); + firstYear = stream.readInt(); + secretIdentity = stream.readString(); + } + + @Override + public void writeSQL(SQLOutput stream) throws SQLException { + stream.writeString(first); + stream.writeString(last); + stream.writeInt(firstYear); + stream.writeString(secretIdentity); + } + + @Override + public String toString() { + return "[ name =" + first + " " + last + " " + + firstYear + " " + secretIdentity + " ]"; + } + + public void setIdentity(String identity) { + secretIdentity = identity; + } + + public String getIdentity() { + return secretIdentity; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof SuperHero) { + SuperHero ss = (SuperHero) obj; + return first.equals(ss.first) && last.equals(ss.last) + && firstYear.equals(ss.firstYear) + && type.equals(ss.type) + && secretIdentity.equals(ss.secretIdentity); + } + return false; + } + + @Override + public int hashCode() { + return ((31 + first.hashCode()) * 31) * 31 + + ((31 + last.hashCode()) * 31) * 31 + + ((31 + firstYear.hashCode()) * 31) * 31 + + ((31 + type.hashCode()) * 31) * 31 + + secretIdentity.hashCode(); + } +} From 31e6340f5437b5c78087b33e131eb3f76b71cfc1 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons <jjg@openjdk.org> Date: Sun, 18 May 2014 19:59:10 -0700 Subject: [PATCH 095/157] 8041422: Split javac ClassReader into ClassReader+ClassFinder Reviewed-by: jfranck --- .../com/sun/tools/javac/code/ClassFinder.java | 537 ++++++++++++++++++ .../com/sun/tools/javac/code/Symtab.java | 5 +- .../com/sun/tools/javac/code/Types.java | 5 +- .../com/sun/tools/javac/comp/Check.java | 2 +- .../com/sun/tools/javac/comp/Enter.java | 2 - .../com/sun/tools/javac/comp/Lower.java | 30 +- .../com/sun/tools/javac/comp/MemberEnter.java | 6 +- .../com/sun/tools/javac/comp/Resolve.java | 8 +- .../com/sun/tools/javac/jvm/ClassReader.java | 527 ++--------------- .../sun/tools/javac/main/JavaCompiler.java | 40 +- .../JavacProcessingEnvironment.java | 8 +- .../classes/com/sun/tools/javadoc/DocEnv.java | 28 +- ...assReader.java => JavadocClassFinder.java} | 22 +- .../com/sun/tools/javadoc/JavadocEnter.java | 4 +- .../com/sun/tools/javadoc/JavadocTool.java | 18 +- .../test/tools/javac/6330997/T6330997.java | 4 +- .../tools/javac/MethodParametersTest.java | 10 +- .../test/tools/javac/T6435291/T6435291.java | 4 +- .../javac/defaultMethods/BadClassfile.java | 4 +- 19 files changed, 696 insertions(+), 568 deletions(-) create mode 100644 langtools/src/share/classes/com/sun/tools/javac/code/ClassFinder.java rename langtools/src/share/classes/com/sun/tools/javadoc/{JavadocClassReader.java => JavadocClassFinder.java} (82%) diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/ClassFinder.java b/langtools/src/share/classes/com/sun/tools/javac/code/ClassFinder.java new file mode 100644 index 00000000000..4c19370386d --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/javac/code/ClassFinder.java @@ -0,0 +1,537 @@ +/* + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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.tools.javac.code; + +import java.io.*; +import java.util.EnumSet; +import java.util.Set; +import javax.lang.model.SourceVersion; +import javax.tools.JavaFileObject; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileManager.Location; +import javax.tools.StandardJavaFileManager; + +import static javax.tools.StandardLocation.*; + +import com.sun.tools.javac.comp.Annotate; +import com.sun.tools.javac.code.Symbol.*; +import com.sun.tools.javac.jvm.ClassReader; +import com.sun.tools.javac.util.*; + +import static com.sun.tools.javac.code.Flags.*; +import static com.sun.tools.javac.code.Kinds.*; + +import static com.sun.tools.javac.main.Option.*; + +/** + * This class provides operations to locate class definitions + * from the source and class files on the paths provided to javac. + * + * <p><b>This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice.</b> + */ +public class ClassFinder { + /** The context key for the class finder. */ + protected static final Context.Key<ClassFinder> classFinderKey = new Context.Key<>(); + + ClassReader reader; + + Annotate annotate; + + /** Switch: verbose output. + */ + boolean verbose; + + /** + * Switch: cache completion failures unless -XDdev is used + */ + private boolean cacheCompletionFailure; + + /** + * Switch: prefer source files instead of newer when both source + * and class are available + **/ + protected boolean preferSource; + + /** + * Switch: Search classpath and sourcepath for classes before the + * bootclasspath + */ + protected boolean userPathsFirst; + + /** The log to use for verbose output + */ + final Log log; + + /** The symbol table. */ + Symtab syms; + + /** The name table. */ + final Names names; + + /** Force a completion failure on this name + */ + final Name completionFailureName; + + /** Access to files + */ + private final JavaFileManager fileManager; + + /** Factory for diagnostics + */ + JCDiagnostic.Factory diagFactory; + + /** Can be reassigned from outside: + * the completer to be used for ".java" files. If this remains unassigned + * ".java" files will not be loaded. + */ + public Completer sourceCompleter = null; + + /** The path name of the class file currently being read. + */ + protected JavaFileObject currentClassFile = null; + + /** The class or method currently being read. + */ + protected Symbol currentOwner = null; + + /** + * Completer that delegates to the complete-method of this class. + */ + private final Completer thisCompleter = new Completer() { + @Override + public void complete(Symbol sym) throws CompletionFailure { + ClassFinder.this.complete(sym); + } + }; + + public Completer getCompleter() { + return thisCompleter; + } + + /** Get the ClassFinder instance for this invocation. */ + public static ClassFinder instance(Context context) { + ClassFinder instance = context.get(classFinderKey); + if (instance == null) + instance = new ClassFinder(context); + return instance; + } + + /** Construct a new class reader. */ + protected ClassFinder(Context context) { + context.put(classFinderKey, this); + reader = ClassReader.instance(context); + names = Names.instance(context); + syms = Symtab.instance(context); + fileManager = context.get(JavaFileManager.class); + if (fileManager == null) + throw new AssertionError("FileManager initialization error"); + diagFactory = JCDiagnostic.Factory.instance(context); + + log = Log.instance(context); + annotate = Annotate.instance(context); + + Options options = Options.instance(context); + verbose = options.isSet(VERBOSE); + cacheCompletionFailure = options.isUnset("dev"); + preferSource = "source".equals(options.get("-Xprefer")); + userPathsFirst = options.isSet(XXUSERPATHSFIRST); + + + completionFailureName = + options.isSet("failcomplete") + ? names.fromString(options.get("failcomplete")) + : null; + } + +/************************************************************************ + * Loading Classes + ***********************************************************************/ + + /** Completion for classes to be loaded. Before a class is loaded + * we make sure its enclosing class (if any) is loaded. + */ + private void complete(Symbol sym) throws CompletionFailure { + if (sym.kind == TYP) { + ClassSymbol c = (ClassSymbol)sym; + c.members_field = new Scope.ErrorScope(c); // make sure it's always defined + annotate.enterStart(); + try { + completeOwners(c.owner); + completeEnclosing(c); + } finally { + // The flush needs to happen only after annotations + // are filled in. + annotate.enterDoneWithoutFlush(); + } + fillIn(c); + } else if (sym.kind == PCK) { + PackageSymbol p = (PackageSymbol)sym; + try { + fillIn(p); + } catch (IOException ex) { + throw new CompletionFailure(sym, ex.getLocalizedMessage()).initCause(ex); + } + } + if (!reader.filling) + annotate.flush(); // finish attaching annotations + } + + /** complete up through the enclosing package. */ + private void completeOwners(Symbol o) { + if (o.kind != PCK) completeOwners(o.owner); + o.complete(); + } + + /** + * Tries to complete lexically enclosing classes if c looks like a + * nested class. This is similar to completeOwners but handles + * the situation when a nested class is accessed directly as it is + * possible with the Tree API or javax.lang.model.*. + */ + private void completeEnclosing(ClassSymbol c) { + if (c.owner.kind == PCK) { + Symbol owner = c.owner; + for (Name name : Convert.enclosingCandidates(Convert.shortName(c.name))) { + Symbol encl = owner.members().lookup(name).sym; + if (encl == null) + encl = syms.classes.get(TypeSymbol.formFlatName(name, owner)); + if (encl != null) + encl.complete(); + } + } + } + + /** Fill in definition of class `c' from corresponding class or + * source file. + */ + private void fillIn(ClassSymbol c) { + if (completionFailureName == c.fullname) { + throw new CompletionFailure(c, "user-selected completion failure by class name"); + } + currentOwner = c; + JavaFileObject classfile = c.classfile; + if (classfile != null) { + JavaFileObject previousClassFile = currentClassFile; + try { + if (reader.filling) { + Assert.error("Filling " + classfile.toUri() + " during " + previousClassFile); + } + currentClassFile = classfile; + if (verbose) { + log.printVerbose("loading", currentClassFile.toString()); + } + if (classfile.getKind() == JavaFileObject.Kind.CLASS) { + reader.readClassFile(c); + } else { + if (sourceCompleter != null) { + sourceCompleter.complete(c); + } else { + throw new IllegalStateException("Source completer required to read " + + classfile.toUri()); + } + } + return; + } finally { + currentClassFile = previousClassFile; + } + } else { + JCDiagnostic diag = + diagFactory.fragment("class.file.not.found", c.flatname); + throw + newCompletionFailure(c, diag); + } + } + // where + /** Static factory for CompletionFailure objects. + * In practice, only one can be used at a time, so we share one + * to reduce the expense of allocating new exception objects. + */ + private CompletionFailure newCompletionFailure(TypeSymbol c, + JCDiagnostic diag) { + if (!cacheCompletionFailure) { + // log.warning("proc.messager", + // Log.getLocalizedString("class.file.not.found", c.flatname)); + // c.debug.printStackTrace(); + return new CompletionFailure(c, diag); + } else { + CompletionFailure result = cachedCompletionFailure; + result.sym = c; + result.diag = diag; + return result; + } + } + private CompletionFailure cachedCompletionFailure = + new CompletionFailure(null, (JCDiagnostic) null); + { + cachedCompletionFailure.setStackTrace(new StackTraceElement[0]); + } + + + /** Load a toplevel class with given fully qualified name + * The class is entered into `classes' only if load was successful. + */ + public ClassSymbol loadClass(Name flatname) throws CompletionFailure { + boolean absent = syms.classes.get(flatname) == null; + ClassSymbol c = syms.enterClass(flatname); + if (c.members_field == null && c.completer != null) { + try { + c.complete(); + } catch (CompletionFailure ex) { + if (absent) syms.classes.remove(flatname); + throw ex; + } + } + return c; + } + +/************************************************************************ + * Loading Packages + ***********************************************************************/ + + /** Include class corresponding to given class file in package, + * unless (1) we already have one the same kind (.class or .java), or + * (2) we have one of the other kind, and the given class file + * is older. + */ + protected void includeClassFile(PackageSymbol p, JavaFileObject file) { + if ((p.flags_field & EXISTS) == 0) + for (Symbol q = p; q != null && q.kind == PCK; q = q.owner) + q.flags_field |= EXISTS; + JavaFileObject.Kind kind = file.getKind(); + int seen; + if (kind == JavaFileObject.Kind.CLASS) + seen = CLASS_SEEN; + else + seen = SOURCE_SEEN; + String binaryName = fileManager.inferBinaryName(currentLoc, file); + int lastDot = binaryName.lastIndexOf("."); + Name classname = names.fromString(binaryName.substring(lastDot + 1)); + boolean isPkgInfo = classname == names.package_info; + ClassSymbol c = isPkgInfo + ? p.package_info + : (ClassSymbol) p.members_field.lookup(classname).sym; + if (c == null) { + c = syms.enterClass(classname, p); + if (c.classfile == null) // only update the file if's it's newly created + c.classfile = file; + if (isPkgInfo) { + p.package_info = c; + } else { + if (c.owner == p) // it might be an inner class + p.members_field.enter(c); + } + } else if (!preferCurrent && c.classfile != null && (c.flags_field & seen) == 0) { + // if c.classfile == null, we are currently compiling this class + // and no further action is necessary. + // if (c.flags_field & seen) != 0, we have already encountered + // a file of the same kind; again no further action is necessary. + if ((c.flags_field & (CLASS_SEEN | SOURCE_SEEN)) != 0) + c.classfile = preferredFileObject(file, c.classfile); + } + c.flags_field |= seen; + } + + /** Implement policy to choose to derive information from a source + * file or a class file when both are present. May be overridden + * by subclasses. + */ + protected JavaFileObject preferredFileObject(JavaFileObject a, + JavaFileObject b) { + + if (preferSource) + return (a.getKind() == JavaFileObject.Kind.SOURCE) ? a : b; + else { + long adate = a.getLastModified(); + long bdate = b.getLastModified(); + // 6449326: policy for bad lastModifiedTime in ClassReader + //assert adate >= 0 && bdate >= 0; + return (adate > bdate) ? a : b; + } + } + + /** + * specifies types of files to be read when filling in a package symbol + */ + protected EnumSet<JavaFileObject.Kind> getPackageFileKinds() { + return EnumSet.of(JavaFileObject.Kind.CLASS, JavaFileObject.Kind.SOURCE); + } + + /** + * this is used to support javadoc + */ + protected void extraFileActions(PackageSymbol pack, JavaFileObject fe) { + } + + protected Location currentLoc; // FIXME + + private boolean verbosePath = true; + + // Set to true when the currently selected file should be kept + private boolean preferCurrent; + + /** Load directory of package into members scope. + */ + private void fillIn(PackageSymbol p) throws IOException { + if (p.members_field == null) + p.members_field = new Scope(p); + + preferCurrent = false; + if (userPathsFirst) { + scanUserPaths(p); + preferCurrent = true; + scanPlatformPath(p); + } else { + scanPlatformPath(p); + scanUserPaths(p); + } + verbosePath = false; + } + + /** + * Scans class path and source path for files in given package. + */ + private void scanUserPaths(PackageSymbol p) throws IOException { + Set<JavaFileObject.Kind> kinds = getPackageFileKinds(); + + Set<JavaFileObject.Kind> classKinds = EnumSet.copyOf(kinds); + classKinds.remove(JavaFileObject.Kind.SOURCE); + boolean wantClassFiles = !classKinds.isEmpty(); + + Set<JavaFileObject.Kind> sourceKinds = EnumSet.copyOf(kinds); + sourceKinds.remove(JavaFileObject.Kind.CLASS); + boolean wantSourceFiles = !sourceKinds.isEmpty(); + + boolean haveSourcePath = fileManager.hasLocation(SOURCE_PATH); + + if (verbose && verbosePath) { + if (fileManager instanceof StandardJavaFileManager) { + StandardJavaFileManager fm = (StandardJavaFileManager)fileManager; + if (haveSourcePath && wantSourceFiles) { + List<File> path = List.nil(); + for (File file : fm.getLocation(SOURCE_PATH)) { + path = path.prepend(file); + } + log.printVerbose("sourcepath", path.reverse().toString()); + } else if (wantSourceFiles) { + List<File> path = List.nil(); + for (File file : fm.getLocation(CLASS_PATH)) { + path = path.prepend(file); + } + log.printVerbose("sourcepath", path.reverse().toString()); + } + if (wantClassFiles) { + List<File> path = List.nil(); + for (File file : fm.getLocation(PLATFORM_CLASS_PATH)) { + path = path.prepend(file); + } + for (File file : fm.getLocation(CLASS_PATH)) { + path = path.prepend(file); + } + log.printVerbose("classpath", path.reverse().toString()); + } + } + } + + String packageName = p.fullname.toString(); + if (wantSourceFiles && !haveSourcePath) { + fillIn(p, CLASS_PATH, + fileManager.list(CLASS_PATH, + packageName, + kinds, + false)); + } else { + if (wantClassFiles) + fillIn(p, CLASS_PATH, + fileManager.list(CLASS_PATH, + packageName, + classKinds, + false)); + if (wantSourceFiles) + fillIn(p, SOURCE_PATH, + fileManager.list(SOURCE_PATH, + packageName, + sourceKinds, + false)); + } + } + + /** + * Scans platform class path for files in given package. + */ + private void scanPlatformPath(PackageSymbol p) throws IOException { + fillIn(p, PLATFORM_CLASS_PATH, + fileManager.list(PLATFORM_CLASS_PATH, + p.fullname.toString(), + EnumSet.of(JavaFileObject.Kind.CLASS), + false)); + } + // where + private void fillIn(PackageSymbol p, + Location location, + Iterable<JavaFileObject> files) + { + currentLoc = location; + for (JavaFileObject fo : files) { + switch (fo.getKind()) { + case CLASS: + case SOURCE: { + // TODO pass binaryName to includeClassFile + String binaryName = fileManager.inferBinaryName(currentLoc, fo); + String simpleName = binaryName.substring(binaryName.lastIndexOf(".") + 1); + if (SourceVersion.isIdentifier(simpleName) || + simpleName.equals("package-info")) + includeClassFile(p, fo); + break; + } + default: + extraFileActions(p, fo); + } + } + } + + /** + * Used for bad class definition files, such as bad .class files or + * for .java files with unexpected package or class names. + */ + public static class BadClassFile extends CompletionFailure { + private static final long serialVersionUID = 0; + + public BadClassFile(TypeSymbol sym, JavaFileObject file, JCDiagnostic diag, + JCDiagnostic.Factory diagFactory) { + super(sym, createBadClassFileDiagnostic(file, diag, diagFactory)); + } + // where + private static JCDiagnostic createBadClassFileDiagnostic( + JavaFileObject file, JCDiagnostic diag, JCDiagnostic.Factory diagFactory) { + String key = (file.getKind() == JavaFileObject.Kind.SOURCE + ? "bad.source.file.header" : "bad.class.file.header"); + return diagFactory.fragment(key, file, diag); + } + } +} diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java index 59e2e19d7d9..9ced8f07d83 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java @@ -50,7 +50,6 @@ import com.sun.tools.javac.code.Type.JCVoidType; import com.sun.tools.javac.code.Type.MethodType; import com.sun.tools.javac.code.Type.UnknownType; import com.sun.tools.javac.jvm.ByteCodes; -import com.sun.tools.javac.jvm.ClassReader; import com.sun.tools.javac.jvm.Target; import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Context; @@ -470,8 +469,8 @@ public class Symtab { Scope scope = new Scope(predefClass); predefClass.members_field = scope; - // Get the initial completer for Symbols from the ClassReader - initialCompleter = ClassReader.instance(context).getCompleter(); + // Get the initial completer for Symbols from the ClassFinder + initialCompleter = ClassFinder.instance(context).getCompleter(); rootPackage.completer = initialCompleter; unnamedPackage.completer = initialCompleter; diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index 2184d0c1490..15b79180844 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -42,9 +42,8 @@ import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.Check; import com.sun.tools.javac.comp.Enter; import com.sun.tools.javac.comp.Env; -import com.sun.tools.javac.jvm.ClassReader; -import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.util.*; + import static com.sun.tools.javac.code.BoundKind.*; import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Scope.*; @@ -84,7 +83,6 @@ public class Types { final boolean allowBoxing; final boolean allowCovariantReturns; final boolean allowObjectToPrimitiveCast; - final ClassReader reader; final Check chk; final Enter enter; JCDiagnostic.Factory diags; @@ -110,7 +108,6 @@ public class Types { allowBoxing = source.allowBoxing(); allowCovariantReturns = source.allowCovariantReturns(); allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast(); - reader = ClassReader.instance(context); chk = Check.instance(context); enter = Enter.instance(context); capturedName = names.fromString("<captured wildcard>"); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 1b412e39405..1283d87d27b 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -282,7 +282,7 @@ public class Check { */ public Type completionError(DiagnosticPosition pos, CompletionFailure ex) { log.error(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE, pos, "cant.access", ex.sym, ex.getDetailValue()); - if (ex instanceof ClassReader.BadClassFile + if (ex instanceof ClassFinder.BadClassFile && !suppressAbortOnBadClassFile) throw new Abort(); else return syms.errType; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java index bd189b3b696..65df77a2cc5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java @@ -96,7 +96,6 @@ public class Enter extends JCTree.Visitor { Symtab syms; Check chk; TreeMaker make; - ClassReader reader; Annotate annotate; MemberEnter memberEnter; Types types; @@ -118,7 +117,6 @@ public class Enter extends JCTree.Visitor { context.put(enterKey, this); log = Log.instance(context); - reader = ClassReader.instance(context); make = TreeMaker.instance(context); syms = Symtab.instance(context); chk = Check.instance(context); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java index bf3e3c122d4..33762e0d9d4 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java @@ -67,25 +67,24 @@ public class Lower extends TreeTranslator { return instance; } - private Names names; - private Log log; - private Symtab syms; - private Resolve rs; - private Check chk; - private Attr attr; + private final Names names; + private final Log log; + private final Symtab syms; + private final Resolve rs; + private final Check chk; + private final Attr attr; private TreeMaker make; private DiagnosticPosition make_pos; - private ClassWriter writer; - private ClassReader reader; - private ConstFold cfolder; - private Target target; - private Source source; - private boolean allowEnums; + private final ClassWriter writer; + private final ConstFold cfolder; + private final Target target; + private final Source source; + private final boolean allowEnums; private final Name dollarAssertionsDisabled; private final Name classDollar; - private Types types; - private boolean debugLower; - private PkgInfo pkginfoOpt; + private final Types types; + private final boolean debugLower; + private final PkgInfo pkginfoOpt; protected Lower(Context context) { context.put(lowerKey, this); @@ -97,7 +96,6 @@ public class Lower extends TreeTranslator { attr = Attr.instance(context); make = TreeMaker.instance(context); writer = ClassWriter.instance(context); - reader = ClassReader.instance(context); cfolder = ConstFold.instance(context); target = Target.instance(context); source = Source.instance(context); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index ab6e894b739..4fddfb10f85 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -25,10 +25,7 @@ package com.sun.tools.javac.comp; -import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; import java.util.Set; import javax.tools.JavaFileObject; @@ -49,6 +46,7 @@ import static com.sun.tools.javac.code.TypeTag.CLASS; import static com.sun.tools.javac.code.TypeTag.ERROR; import static com.sun.tools.javac.code.TypeTag.TYPEVAR; import static com.sun.tools.javac.tree.JCTree.Tag.*; + import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; @@ -75,7 +73,6 @@ public class MemberEnter extends JCTree.Visitor implements Completer { private final Attr attr; private final Symtab syms; private final TreeMaker make; - private final ClassReader reader; private final Todo todo; private final Annotate annotate; private final TypeAnnotations typeAnnotations; @@ -102,7 +99,6 @@ public class MemberEnter extends JCTree.Visitor implements Completer { attr = Attr.instance(context); syms = Symtab.instance(context); make = TreeMaker.instance(context); - reader = ClassReader.instance(context); todo = Todo.instance(context); annotate = Annotate.instance(context); typeAnnotations = TypeAnnotations.instance(context); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index dc79bfd780a..a058f4a742b 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -87,7 +87,7 @@ public class Resolve { DeferredAttr deferredAttr; Check chk; Infer infer; - ClassReader reader; + ClassFinder finder; TreeInfo treeinfo; Types types; JCDiagnostic.Factory diags; @@ -121,7 +121,7 @@ public class Resolve { deferredAttr = DeferredAttr.instance(context); chk = Check.instance(context); infer = Infer.instance(context); - reader = ClassReader.instance(context); + finder = ClassFinder.instance(context); treeinfo = TreeInfo.instance(context); types = Types.instance(context); diags = JCDiagnostic.Factory.instance(context); @@ -1886,9 +1886,9 @@ public class Resolve { */ Symbol loadClass(Env<AttrContext> env, Name name) { try { - ClassSymbol c = reader.loadClass(name); + ClassSymbol c = finder.loadClass(name); return isAccessible(env, c) ? c : new AccessError(c); - } catch (ClassReader.BadClassFile err) { + } catch (ClassFinder.BadClassFile err) { throw err; } catch (CompletionFailure ex) { return typeNotFound; diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index ed560d52355..311857f521c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -35,13 +35,8 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import javax.lang.model.SourceVersion; import javax.tools.JavaFileObject; import javax.tools.JavaFileManager; -import javax.tools.JavaFileManager.Location; -import javax.tools.StandardJavaFileManager; - -import static javax.tools.StandardLocation.*; import com.sun.tools.javac.comp.Annotate; import com.sun.tools.javac.code.*; @@ -119,23 +114,6 @@ public class ClassReader { */ public boolean saveParameterNames; - /** - * Switch: cache completion failures unless -XDdev is used - */ - private boolean cacheCompletionFailure; - - /** - * Switch: prefer source files instead of newer when both source - * and class are available - **/ - public boolean preferSource; - - /** - * Switch: Search classpath and sourcepath for classes before the - * bootclasspath - */ - public boolean userPathsFirst; - /** * The currently selected profile. */ @@ -153,10 +131,6 @@ public class ClassReader { /** The name table. */ final Names names; - /** Force a completion failure on this name - */ - final Name completionFailureName; - /** Access to files */ private final JavaFileManager fileManager; @@ -165,12 +139,6 @@ public class ClassReader { */ JCDiagnostic.Factory diagFactory; - /** Can be reassigned from outside: - * the completer to be used for ".java" files. If this remains unassigned - * ".java" files will not be loaded. - */ - public SourceCompleter sourceCompleter = null; - /** The current scope where type variables are entered. */ protected Scope typevars; @@ -227,20 +195,6 @@ public class ClassReader { */ Set<Name> warnedAttrs = new HashSet<>(); - /** - * Completer that delegates to the complete-method of this class. - */ - private final Completer thisCompleter = new Completer() { - @Override - public void complete(Symbol sym) throws CompletionFailure { - ClassReader.this.complete(sym); - } - }; - - public Completer getCompleter() { - return thisCompleter; - } - /** Get the ClassReader instance for this invocation. */ public static ClassReader instance(Context context) { ClassReader instance = context.get(classReaderKey); @@ -274,17 +228,9 @@ public class ClassReader { allowSimplifiedVarargs = source.allowSimplifiedVarargs(); saveParameterNames = options.isSet("save-parameter-names"); - cacheCompletionFailure = options.isUnset("dev"); - preferSource = "source".equals(options.get("-Xprefer")); - userPathsFirst = options.isSet(XXUSERPATHSFIRST); profile = Profile.instance(context); - completionFailureName = - options.isSet("failcomplete") - ? names.fromString(options.get("failcomplete")) - : null; - typevars = new Scope(syms.noSymbol); lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE); @@ -305,26 +251,12 @@ public class ClassReader { * Error Diagnoses ***********************************************************************/ - - public class BadClassFile extends CompletionFailure { - private static final long serialVersionUID = 0; - - public BadClassFile(TypeSymbol sym, JavaFileObject file, JCDiagnostic diag) { - super(sym, createBadClassFileDiagnostic(file, diag)); - } - } - // where - private JCDiagnostic createBadClassFileDiagnostic(JavaFileObject file, JCDiagnostic diag) { - String key = (file.getKind() == JavaFileObject.Kind.SOURCE - ? "bad.source.file.header" : "bad.class.file.header"); - return diagFactory.fragment(key, file, diag); - } - - public BadClassFile badClassFile(String key, Object... args) { - return new BadClassFile ( + public ClassFinder.BadClassFile badClassFile(String key, Object... args) { + return new ClassFinder.BadClassFile ( currentOwner.enclClass(), currentClassFile, - diagFactory.fragment(key, args)); + diagFactory.fragment(key, args), + diagFactory); } /************************************************************************ @@ -1501,7 +1433,7 @@ public class ClassReader { int tag = nextByte(); // TargetType tag is a byte if (!TargetType.isValidTargetTypeValue(tag)) - throw this.badClassFile("bad.type.annotation.value", String.format("0x%02X", tag)); + throw badClassFile("bad.type.annotation.value", String.format("0x%02X", tag)); TargetType type = TargetType.fromTargetTypeValue(tag); @@ -2353,9 +2285,9 @@ public class ClassReader { } } - /** Read a class file. + /** Read a class definition from the bytes in buf. */ - private void readClassFile(ClassSymbol c) throws IOException { + private void readClassBuffer(ClassSymbol c) throws IOException { int magic = nextInt(); if (magic != JAVA_MAGIC) throw badClassFile("illegal.start.of.class.file"); @@ -2395,162 +2327,39 @@ public class ClassReader { readClass(c); } -/************************************************************************ - * Adjusting flags - ***********************************************************************/ - - long adjustFieldFlags(long flags) { - return flags; - } - long adjustMethodFlags(long flags) { - if ((flags & ACC_BRIDGE) != 0) { - flags &= ~ACC_BRIDGE; - flags |= BRIDGE; - if (!allowGenerics) - flags &= ~SYNTHETIC; - } - if ((flags & ACC_VARARGS) != 0) { - flags &= ~ACC_VARARGS; - flags |= VARARGS; - } - return flags; - } - long adjustClassFlags(long flags) { - return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded - } - -/************************************************************************ - * Loading Classes - ***********************************************************************/ - - /** Completion for classes to be loaded. Before a class is loaded - * we make sure its enclosing class (if any) is loaded. - */ - private void complete(Symbol sym) throws CompletionFailure { - if (sym.kind == TYP) { - ClassSymbol c = (ClassSymbol)sym; - c.members_field = new Scope.ErrorScope(c); // make sure it's always defined - annotate.enterStart(); - try { - completeOwners(c.owner); - completeEnclosing(c); - } finally { - // The flush needs to happen only after annotations - // are filled in. - annotate.enterDoneWithoutFlush(); - } - fillIn(c); - } else if (sym.kind == PCK) { - PackageSymbol p = (PackageSymbol)sym; - try { - fillIn(p); - } catch (IOException ex) { - throw new CompletionFailure(sym, ex.getLocalizedMessage()).initCause(ex); - } - } - if (!filling) - annotate.flush(); // finish attaching annotations - } - - /** complete up through the enclosing package. */ - private void completeOwners(Symbol o) { - if (o.kind != PCK) completeOwners(o.owner); - o.complete(); - } - - /** - * Tries to complete lexically enclosing classes if c looks like a - * nested class. This is similar to completeOwners but handles - * the situation when a nested class is accessed directly as it is - * possible with the Tree API or javax.lang.model.*. - */ - private void completeEnclosing(ClassSymbol c) { - if (c.owner.kind == PCK) { - Symbol owner = c.owner; - for (Name name : Convert.enclosingCandidates(Convert.shortName(c.name))) { - Symbol encl = owner.members().lookup(name).sym; - if (encl == null) - encl = syms.classes.get(TypeSymbol.formFlatName(name, owner)); - if (encl != null) - encl.complete(); - } - } - } - - /** We can only read a single class file at a time; this - * flag keeps track of when we are currently reading a class - * file. - */ - private boolean filling = false; - - /** Fill in definition of class `c' from corresponding class or - * source file. - */ - private void fillIn(ClassSymbol c) { - if (completionFailureName == c.fullname) { - throw new CompletionFailure(c, "user-selected completion failure by class name"); - } + public void readClassFile(ClassSymbol c) { currentOwner = c; + currentClassFile = c.classfile; warnedAttrs.clear(); - JavaFileObject classfile = c.classfile; - if (classfile != null) { - JavaFileObject previousClassFile = currentClassFile; - try { - if (filling) { - Assert.error("Filling " + classfile.toUri() + " during " + previousClassFile); - } - currentClassFile = classfile; - if (verbose) { - log.printVerbose("loading", currentClassFile.toString()); - } - if (classfile.getKind() == JavaFileObject.Kind.CLASS) { - filling = true; - try { - bp = 0; - buf = readInputStream(buf, classfile.openInputStream()); - readClassFile(c); - if (!missingTypeVariables.isEmpty() && !foundTypeVariables.isEmpty()) { - List<Type> missing = missingTypeVariables; - List<Type> found = foundTypeVariables; - missingTypeVariables = List.nil(); - foundTypeVariables = List.nil(); - filling = false; - ClassType ct = (ClassType)currentOwner.type; - ct.supertype_field = - types.subst(ct.supertype_field, missing, found); - ct.interfaces_field = - types.subst(ct.interfaces_field, missing, found); - } else if (missingTypeVariables.isEmpty() != - foundTypeVariables.isEmpty()) { - Name name = missingTypeVariables.head.tsym.name; - throw badClassFile("undecl.type.var", name); - } - } finally { - missingTypeVariables = List.nil(); - foundTypeVariables = List.nil(); - filling = false; - } - } else { - if (sourceCompleter != null) { - sourceCompleter.complete(c); - } else { - throw new IllegalStateException("Source completer required to read " - + classfile.toUri()); - } - } - return; - } catch (IOException ex) { - throw badClassFile("unable.to.access.file", ex.getMessage()); - } catch (ArrayIndexOutOfBoundsException ex) { - throw badClassFile("bad.class.file", c.flatname); - } finally { - currentClassFile = previousClassFile; + filling = true; + try { + bp = 0; + buf = readInputStream(buf, c.classfile.openInputStream()); + readClassBuffer(c); + if (!missingTypeVariables.isEmpty() && !foundTypeVariables.isEmpty()) { + List<Type> missing = missingTypeVariables; + List<Type> found = foundTypeVariables; + missingTypeVariables = List.nil(); + foundTypeVariables = List.nil(); + filling = false; + ClassType ct = (ClassType)currentOwner.type; + ct.supertype_field = + types.subst(ct.supertype_field, missing, found); + ct.interfaces_field = + types.subst(ct.interfaces_field, missing, found); + } else if (missingTypeVariables.isEmpty() != + foundTypeVariables.isEmpty()) { + Name name = missingTypeVariables.head.tsym.name; + throw badClassFile("undecl.type.var", name); } - } else { - JCDiagnostic diag = - diagFactory.fragment("class.file.not.found", c.flatname); - throw - newCompletionFailure(c, diag); + } catch (IOException ex) { + throw badClassFile("unable.to.access.file", ex.getMessage()); + } catch (ArrayIndexOutOfBoundsException ex) { + throw badClassFile("bad.class.file", c.flatname); + } finally { + missingTypeVariables = List.nil(); + foundTypeVariables = List.nil(); + filling = false; } } // where @@ -2590,253 +2399,39 @@ public class ClassReader { } return buf; } - /** Static factory for CompletionFailure objects. - * In practice, only one can be used at a time, so we share one - * to reduce the expense of allocating new exception objects. - */ - private CompletionFailure newCompletionFailure(TypeSymbol c, - JCDiagnostic diag) { - if (!cacheCompletionFailure) { - // log.warning("proc.messager", - // Log.getLocalizedString("class.file.not.found", c.flatname)); - // c.debug.printStackTrace(); - return new CompletionFailure(c, diag); - } else { - CompletionFailure result = cachedCompletionFailure; - result.sym = c; - result.diag = diag; - return result; - } - } - private CompletionFailure cachedCompletionFailure = - new CompletionFailure(null, (JCDiagnostic) null); - { - cachedCompletionFailure.setStackTrace(new StackTraceElement[0]); - } - - /** Load a toplevel class with given fully qualified name - * The class is entered into `classes' only if load was successful. + /** We can only read a single class file at a time; this + * flag keeps track of when we are currently reading a class + * file. */ - public ClassSymbol loadClass(Name flatname) throws CompletionFailure { - boolean absent = syms.classes.get(flatname) == null; - ClassSymbol c = syms.enterClass(flatname); - if (c.members_field == null && c.completer != null) { - try { - c.complete(); - } catch (CompletionFailure ex) { - if (absent) syms.classes.remove(flatname); - throw ex; - } - } - return c; - } + public boolean filling = false; /************************************************************************ - * Loading Packages + * Adjusting flags ***********************************************************************/ - /** Include class corresponding to given class file in package, - * unless (1) we already have one the same kind (.class or .java), or - * (2) we have one of the other kind, and the given class file - * is older. - */ - protected void includeClassFile(PackageSymbol p, JavaFileObject file) { - if ((p.flags_field & EXISTS) == 0) - for (Symbol q = p; q != null && q.kind == PCK; q = q.owner) - q.flags_field |= EXISTS; - JavaFileObject.Kind kind = file.getKind(); - int seen; - if (kind == JavaFileObject.Kind.CLASS) - seen = CLASS_SEEN; - else - seen = SOURCE_SEEN; - String binaryName = fileManager.inferBinaryName(currentLoc, file); - int lastDot = binaryName.lastIndexOf("."); - Name classname = names.fromString(binaryName.substring(lastDot + 1)); - boolean isPkgInfo = classname == names.package_info; - ClassSymbol c = isPkgInfo - ? p.package_info - : (ClassSymbol) p.members_field.lookup(classname).sym; - if (c == null) { - c = syms.enterClass(classname, p); - if (c.classfile == null) // only update the file if's it's newly created - c.classfile = file; - if (isPkgInfo) { - p.package_info = c; - } else { - if (c.owner == p) // it might be an inner class - p.members_field.enter(c); - } - } else if (!preferCurrent && c.classfile != null && (c.flags_field & seen) == 0) { - // if c.classfile == null, we are currently compiling this class - // and no further action is necessary. - // if (c.flags_field & seen) != 0, we have already encountered - // a file of the same kind; again no further action is necessary. - if ((c.flags_field & (CLASS_SEEN | SOURCE_SEEN)) != 0) - c.classfile = preferredFileObject(file, c.classfile); + long adjustFieldFlags(long flags) { + return flags; + } + + long adjustMethodFlags(long flags) { + if ((flags & ACC_BRIDGE) != 0) { + flags &= ~ACC_BRIDGE; + flags |= BRIDGE; + if (!allowGenerics) + flags &= ~SYNTHETIC; } - c.flags_field |= seen; - } - - /** Implement policy to choose to derive information from a source - * file or a class file when both are present. May be overridden - * by subclasses. - */ - protected JavaFileObject preferredFileObject(JavaFileObject a, - JavaFileObject b) { - - if (preferSource) - return (a.getKind() == JavaFileObject.Kind.SOURCE) ? a : b; - else { - long adate = a.getLastModified(); - long bdate = b.getLastModified(); - // 6449326: policy for bad lastModifiedTime in ClassReader - //assert adate >= 0 && bdate >= 0; - return (adate > bdate) ? a : b; + if ((flags & ACC_VARARGS) != 0) { + flags &= ~ACC_VARARGS; + flags |= VARARGS; } + return flags; } - /** - * specifies types of files to be read when filling in a package symbol - */ - protected EnumSet<JavaFileObject.Kind> getPackageFileKinds() { - return EnumSet.of(JavaFileObject.Kind.CLASS, JavaFileObject.Kind.SOURCE); + long adjustClassFlags(long flags) { + return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded } - /** - * this is used to support javadoc - */ - protected void extraFileActions(PackageSymbol pack, JavaFileObject fe) { - } - - protected Location currentLoc; // FIXME - - private boolean verbosePath = true; - - // Set to true when the currently selected file should be kept - private boolean preferCurrent; - - /** Load directory of package into members scope. - */ - private void fillIn(PackageSymbol p) throws IOException { - if (p.members_field == null) - p.members_field = new Scope(p); - - preferCurrent = false; - if (userPathsFirst) { - scanUserPaths(p); - preferCurrent = true; - scanPlatformPath(p); - } else { - scanPlatformPath(p); - scanUserPaths(p); - } - verbosePath = false; - } - - /** - * Scans class path and source path for files in given package. - */ - private void scanUserPaths(PackageSymbol p) throws IOException { - Set<JavaFileObject.Kind> kinds = getPackageFileKinds(); - - Set<JavaFileObject.Kind> classKinds = EnumSet.copyOf(kinds); - classKinds.remove(JavaFileObject.Kind.SOURCE); - boolean wantClassFiles = !classKinds.isEmpty(); - - Set<JavaFileObject.Kind> sourceKinds = EnumSet.copyOf(kinds); - sourceKinds.remove(JavaFileObject.Kind.CLASS); - boolean wantSourceFiles = !sourceKinds.isEmpty(); - - boolean haveSourcePath = fileManager.hasLocation(SOURCE_PATH); - - if (verbose && verbosePath) { - if (fileManager instanceof StandardJavaFileManager) { - StandardJavaFileManager fm = (StandardJavaFileManager)fileManager; - if (haveSourcePath && wantSourceFiles) { - List<File> path = List.nil(); - for (File file : fm.getLocation(SOURCE_PATH)) { - path = path.prepend(file); - } - log.printVerbose("sourcepath", path.reverse().toString()); - } else if (wantSourceFiles) { - List<File> path = List.nil(); - for (File file : fm.getLocation(CLASS_PATH)) { - path = path.prepend(file); - } - log.printVerbose("sourcepath", path.reverse().toString()); - } - if (wantClassFiles) { - List<File> path = List.nil(); - for (File file : fm.getLocation(PLATFORM_CLASS_PATH)) { - path = path.prepend(file); - } - for (File file : fm.getLocation(CLASS_PATH)) { - path = path.prepend(file); - } - log.printVerbose("classpath", path.reverse().toString()); - } - } - } - - String packageName = p.fullname.toString(); - if (wantSourceFiles && !haveSourcePath) { - fillIn(p, CLASS_PATH, - fileManager.list(CLASS_PATH, - packageName, - kinds, - false)); - } else { - if (wantClassFiles) - fillIn(p, CLASS_PATH, - fileManager.list(CLASS_PATH, - packageName, - classKinds, - false)); - if (wantSourceFiles) - fillIn(p, SOURCE_PATH, - fileManager.list(SOURCE_PATH, - packageName, - sourceKinds, - false)); - } - } - - /** - * Scans platform class path for files in given package. - */ - private void scanPlatformPath(PackageSymbol p) throws IOException { - fillIn(p, PLATFORM_CLASS_PATH, - fileManager.list(PLATFORM_CLASS_PATH, - p.fullname.toString(), - EnumSet.of(JavaFileObject.Kind.CLASS), - false)); - } - // where - private void fillIn(PackageSymbol p, - Location location, - Iterable<JavaFileObject> files) - { - currentLoc = location; - for (JavaFileObject fo : files) { - switch (fo.getKind()) { - case CLASS: - case SOURCE: { - // TODO pass binaryName to includeClassFile - String binaryName = fileManager.inferBinaryName(currentLoc, fo); - String simpleName = binaryName.substring(binaryName.lastIndexOf(".") + 1); - if (SourceVersion.isIdentifier(simpleName) || - simpleName.equals("package-info")) - includeClassFile(p, fo); - break; - } - default: - extraFileActions(p, fo); - } - } - } - /** Output for "-checkclassfile" option. * @param key The key to look up the correct internationalized string. * @param arg An argument for substitution into the output string. @@ -2845,12 +2440,6 @@ public class ClassReader { log.printLines(key, arg); } - - public interface SourceCompleter { - void complete(ClassSymbol sym) - throws CompletionFailure; - } - /** * A subclass of JavaFileObject for the sourcefile attribute found in a classfile. * The attribute is only the last component of the original filename, so is unlikely diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java index 6c7ccc11ffa..ff8ff35581a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -219,6 +219,10 @@ public class JavaCompiler { */ protected TreeMaker make; + /** The class finder. + */ + protected ClassFinder finder; + /** The class reader. */ protected ClassReader reader; @@ -296,13 +300,13 @@ public class JavaCompiler { protected MultiTaskListener taskListener; /** - * SourceCompleter that delegates to the complete-method of this class. + * SourceCompleter that delegates to the readSourceFile method of this class. */ - protected final ClassReader.SourceCompleter thisCompleter = - new ClassReader.SourceCompleter() { + protected final Symbol.Completer sourceCompleter = + new Symbol.Completer() { @Override - public void complete(ClassSymbol sym) throws CompletionFailure { - JavaCompiler.this.complete(sym); + public void complete(Symbol sym) throws CompletionFailure { + readSourceFile((ClassSymbol) sym); } }; @@ -338,6 +342,7 @@ public class JavaCompiler { names = Names.instance(context); log = Log.instance(context); diagFactory = JCDiagnostic.Factory.instance(context); + finder = ClassFinder.instance(context); reader = ClassReader.instance(context); make = TreeMaker.instance(context); writer = ClassWriter.instance(context); @@ -355,7 +360,7 @@ public class JavaCompiler { } catch (CompletionFailure ex) { // inlined Check.completionError as it is not initialized yet log.error("cant.access", ex.sym, ex.getDetailValue()); - if (ex instanceof ClassReader.BadClassFile) + if (ex instanceof ClassFinder.BadClassFile) throw new Abort(); } source = Source.instance(context); @@ -370,7 +375,7 @@ public class JavaCompiler { types = Types.instance(context); taskListener = MultiTaskListener.instance(context); - reader.sourceCompleter = thisCompleter; + finder.sourceCompleter = sourceCompleter; options = Options.instance(context); @@ -663,7 +668,7 @@ public class JavaCompiler { public Symbol resolveBinaryNameOrIdent(String name) { try { Name flatname = names.fromString(name.replace("/", ".")); - return reader.loadClass(flatname); + return finder.loadClass(flatname); } catch (CompletionFailure ignore) { return resolveIdent(name); } @@ -737,22 +742,20 @@ public class JavaCompiler { return null; } - /** Complete compiling a source file that has been accessed - * by the class file reader. + /** Compile a source file that has been accessed by the class finder. * @param c The class the source file of which needs to be compiled. */ - public void complete(ClassSymbol c) throws CompletionFailure { - complete(null, c); + private void readSourceFile(ClassSymbol c) throws CompletionFailure { + readSourceFile(null, c); } - /** Complete a ClassSymbol from source, optionally using the given compilation unit as + /** Compile a ClassSymbol from source, optionally using the given compilation unit as * the source tree. - * @param tree the compilation unit int which the given ClassSymbol resides, + * @param tree the compilation unit in which the given ClassSymbol resides, * or null if should be parsed from source * @param c the ClassSymbol to complete */ - public void complete(JCCompilationUnit tree, ClassSymbol c) throws CompletionFailure { -// System.err.println("completing " + c);//DEBUG + public void readSourceFile(JCCompilationUnit tree, ClassSymbol c) throws CompletionFailure { if (completionFailureName == c.fullname) { throw new CompletionFailure(c, "user-selected completion failure by class name"); } @@ -791,13 +794,13 @@ public class JavaCompiler { JCDiagnostic diag = diagFactory.fragment("file.does.not.contain.package", c.location()); - throw reader.new BadClassFile(c, filename, diag); + throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory); } } else { JCDiagnostic diag = diagFactory.fragment("file.doesnt.contain.class", c.getQualifiedName()); - throw reader.new BadClassFile(c, filename, diag); + throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory); } } @@ -1663,6 +1666,7 @@ public class JavaCompiler { */ public void close() { rootClasses = null; + finder = null; reader = null; make = null; writer = null; diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java index 5ffe456db60..4e3be1145b7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java @@ -54,8 +54,6 @@ import com.sun.tools.javac.comp.Check; import com.sun.tools.javac.comp.Enter; import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.file.JavacFileManager; -import com.sun.tools.javac.jvm.*; -import com.sun.tools.javac.jvm.ClassReader.BadClassFile; import com.sun.tools.javac.main.JavaCompiler; import com.sun.tools.javac.model.JavacElements; import com.sun.tools.javac.model.JavacTypes; @@ -203,7 +201,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea symtab = Symtab.instance(context); names = Names.instance(context); enter = Enter.instance(context); - initialCompleter = ClassReader.instance(context).getCompleter(); + initialCompleter = ClassFinder.instance(context).getCompleter(); chk = Check.instance(context); initProcessorClassLoader(); } @@ -799,7 +797,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea RoundEnvironment renv) { try { return proc.process(tes, renv); - } catch (BadClassFile ex) { + } catch (ClassFinder.BadClassFile ex) { log.error("proc.cant.access.1", ex.sym, ex.getDetailValue()); return false; } catch (CompletionFailure ex) { @@ -1308,7 +1306,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea } @Override public void complete(Symbol sym) throws CompletionFailure { - compiler.complete(topLevel, (ClassSymbol) sym); + compiler.readSourceFile(topLevel, (ClassSymbol) sym); } } diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java index dfe014ca1fc..17a08f958e4 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java @@ -37,11 +37,19 @@ import com.sun.tools.doclint.DocLint; import com.sun.tools.javac.api.BasicJavacTask; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Symbol.*; +import com.sun.tools.javac.code.Symbol.ClassSymbol; +import com.sun.tools.javac.code.Symbol.CompletionFailure; +import com.sun.tools.javac.code.Symbol.MethodSymbol; +import com.sun.tools.javac.code.Symbol.PackageSymbol; +import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Type.ClassType; import com.sun.tools.javac.comp.Check; +import com.sun.tools.javac.comp.Enter; import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.JCTree.*; +import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.tree.JCTree.JCPackageDecl; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Names; @@ -71,21 +79,21 @@ public class DocEnv { return instance; } - private Messager messager; - DocLocale doclocale; + private final Messager messager; + /** Predefined symbols known to the compiler. */ - Symtab syms; + final Symtab syms; /** Referenced directly in RootDocImpl. */ - JavadocClassReader reader; + private final ClassFinder finder; /** Javadoc's own version of the compiler's enter phase. */ - JavadocEnter enter; + final Enter enter; /** The name table. */ - Names names; + private Names names; /** The encoding name. */ private String encoding; @@ -139,8 +147,8 @@ public class DocEnv { messager = Messager.instance0(context); syms = Symtab.instance(context); - reader = JavadocClassReader.instance0(context); - enter = JavadocEnter.instance0(context); + finder = JavadocClassFinder.instance(context); + enter = JavadocEnter.instance(context); names = Names.instance(context); externalizableSym = syms.enterClass(names.fromString("java.io.Externalizable")); chk = Check.instance(context); @@ -176,7 +184,7 @@ public class DocEnv { */ public ClassDocImpl loadClass(String name) { try { - ClassSymbol c = reader.loadClass(names.fromString(name)); + ClassSymbol c = finder.loadClass(names.fromString(name)); return getClassDoc(c); } catch (CompletionFailure ex) { chk.completionError(null, ex); diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassFinder.java similarity index 82% rename from langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java rename to langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassFinder.java index d9a1e7392b4..ecb3659f174 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassFinder.java @@ -29,10 +29,10 @@ import java.util.EnumSet; import javax.tools.JavaFileObject; import com.sun.tools.javac.code.Symbol.PackageSymbol; -import com.sun.tools.javac.jvm.ClassReader; +import com.sun.tools.javac.code.ClassFinder; import com.sun.tools.javac.util.Context; -/** Javadoc uses an extended class reader that records package.html entries +/** Javadoc uses an extended class finder that records package.html entries * * <p><b>This is NOT part of any supported API. * If you write code that depends on this, you do so at your own risk. @@ -41,19 +41,19 @@ import com.sun.tools.javac.util.Context; * * @author Neal Gafter */ -public class JavadocClassReader extends ClassReader { +public class JavadocClassFinder extends ClassFinder { - public static JavadocClassReader instance0(Context context) { - ClassReader instance = context.get(classReaderKey); + public static JavadocClassFinder instance(Context context) { + ClassFinder instance = context.get(classFinderKey); if (instance == null) - instance = new JavadocClassReader(context); - return (JavadocClassReader)instance; + instance = new JavadocClassFinder(context); + return (JavadocClassFinder)instance; } public static void preRegister(Context context) { - context.put(classReaderKey, new Context.Factory<ClassReader>() { - public ClassReader make(Context c) { - return new JavadocClassReader(c); + context.put(classFinderKey, new Context.Factory<ClassFinder>() { + public ClassFinder make(Context c) { + return new JavadocClassFinder(c); } }); } @@ -65,7 +65,7 @@ public class JavadocClassReader extends ClassReader { private EnumSet<JavaFileObject.Kind> noSource = EnumSet.of(JavaFileObject.Kind.CLASS, JavaFileObject.Kind.HTML); - public JavadocClassReader(Context context) { + public JavadocClassFinder(Context context) { super(context); docenv = DocEnv.instance(context); preferSource = true; diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java index 5215edcb894..50386acabe2 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ import com.sun.tools.javac.util.List; * @author Neal Gafter */ public class JavadocEnter extends Enter { - public static JavadocEnter instance0(Context context) { + public static JavadocEnter instance(Context context) { Enter instance = context.get(enterKey); if (instance == null) instance = new JavadocEnter(context); diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java index 17d12b864a5..3937ff95720 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java @@ -33,12 +33,15 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; + import javax.tools.JavaFileManager.Location; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; +import com.sun.tools.javac.code.ClassFinder; import com.sun.tools.javac.code.Symbol.CompletionFailure; +import com.sun.tools.javac.comp.Enter; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; @@ -66,8 +69,8 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { DocEnv docenv; final Messager messager; - final JavadocClassReader javadocReader; - final JavadocEnter javadocEnter; + final ClassFinder javadocFinder; + final Enter javadocEnter; final Set<JavaFileObject> uniquefiles; /** @@ -77,8 +80,8 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { protected JavadocTool(Context context) { super(context); messager = Messager.instance0(context); - javadocReader = JavadocClassReader.instance0(context); - javadocEnter = JavadocEnter.instance0(context); + javadocFinder = JavadocClassFinder.instance(context); + javadocEnter = JavadocEnter.instance(context); uniquefiles = new HashSet<>(); } @@ -95,8 +98,8 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { public static JavadocTool make0(Context context) { Messager messager = null; try { - // force the use of Javadoc's class reader - JavadocClassReader.preRegister(context); + // force the use of Javadoc's class finder + JavadocClassFinder.preRegister(context); // force the use of Javadoc's own enter phase JavadocEnter.preRegister(context); @@ -137,7 +140,8 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { docenv.setEncoding(encoding); docenv.docClasses = docClasses; docenv.legacyDoclet = legacyDoclet; - javadocReader.sourceCompleter = docClasses ? null : thisCompleter; + + javadocFinder.sourceCompleter = docClasses ? null : sourceCompleter; ListBuffer<String> names = new ListBuffer<>(); ListBuffer<JCCompilationUnit> classTrees = new ListBuffer<>(); diff --git a/langtools/test/tools/javac/6330997/T6330997.java b/langtools/test/tools/javac/6330997/T6330997.java index 98c76e22828..8995c1b32a1 100644 --- a/langtools/test/tools/javac/6330997/T6330997.java +++ b/langtools/test/tools/javac/6330997/T6330997.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ import java.nio.*; import java.io.*; import java.nio.channels.*; import com.sun.tools.javac.api.JavacTaskImpl; -import com.sun.tools.javac.jvm.ClassReader.BadClassFile; +import com.sun.tools.javac.code.ClassFinder.BadClassFile; import com.sun.tools.javac.main.JavaCompiler; import javax.tools.ToolProvider; diff --git a/langtools/test/tools/javac/MethodParametersTest.java b/langtools/test/tools/javac/MethodParametersTest.java index 515eee34e23..c2570b7bed1 100644 --- a/langtools/test/tools/javac/MethodParametersTest.java +++ b/langtools/test/tools/javac/MethodParametersTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -129,14 +129,14 @@ public class MethodParametersTest { if (out.length() > 0) System.err.println(out); - // Now get the class reader, construct a name for Baz, and load it. - com.sun.tools.javac.jvm.ClassReader cr = - com.sun.tools.javac.jvm.ClassReader.instance(context); + // Now get the class finder, construct a name for Baz, and load it. + com.sun.tools.javac.code.ClassFinder cf = + com.sun.tools.javac.code.ClassFinder.instance(context); Name name = Names.instance(context).fromString(Baz_name); // Now walk down the language model and check the name of the // parameter. - final Element baz = cr.loadClass(name); + final Element baz = cf.loadClass(name); for (Element e : baz.getEnclosedElements()) { if (e instanceof ExecutableElement) { final ExecutableElement ee = (ExecutableElement) e; diff --git a/langtools/test/tools/javac/T6435291/T6435291.java b/langtools/test/tools/javac/T6435291/T6435291.java index d710f9c4fc5..73985a635f2 100644 --- a/langtools/test/tools/javac/T6435291/T6435291.java +++ b/langtools/test/tools/javac/T6435291/T6435291.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ */ import com.sun.tools.javac.api.JavacTaskImpl; -import com.sun.tools.javac.jvm.ClassReader.BadClassFile; +import com.sun.tools.javac.code.ClassFinder.BadClassFile; import com.sun.tools.javac.main.JavaCompiler; import javax.tools.ToolProvider; diff --git a/langtools/test/tools/javac/defaultMethods/BadClassfile.java b/langtools/test/tools/javac/defaultMethods/BadClassfile.java index 424d3acf102..28d0dcf6d41 100644 --- a/langtools/test/tools/javac/defaultMethods/BadClassfile.java +++ b/langtools/test/tools/javac/defaultMethods/BadClassfile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,8 +32,8 @@ import com.sun.tools.classfile.*; import com.sun.tools.javac.api.JavacTaskImpl; +import com.sun.tools.javac.code.ClassFinder.BadClassFile; import com.sun.tools.javac.code.Symbol; -import com.sun.tools.javac.jvm.ClassReader.BadClassFile; import com.sun.tools.javac.jvm.Target; import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.JCDiagnostic; From c212c43f70a9c258e197dfaf799c9fc13e68907b Mon Sep 17 00:00:00 2001 From: Paul Govereau <pgovereau@openjdk.org> Date: Fri, 16 May 2014 17:08:42 -0400 Subject: [PATCH 096/157] 8015927: Class reference duplicates in constant pool Reviewed-by: jjg --- .../com/sun/tools/javac/jvm/ClassWriter.java | 4 +- .../classes/com/sun/tools/javac/jvm/Pool.java | 10 ++- .../jvm/ClassRefDupInConstantPoolTest.java | 63 +++++++++++++++++++ 3 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 langtools/test/tools/javac/jvm/ClassRefDupInConstantPoolTest.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java index 5580d06831f..d86644d864b 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java @@ -459,11 +459,11 @@ public class ClassWriter extends ClassFile { poolbuf.appendChar(pool.put(names.fromString((String)value))); } else if (value instanceof UniqueType) { Type type = ((UniqueType)value).type; - if (type instanceof MethodType) { + if (type.hasTag(METHOD)) { poolbuf.appendByte(CONSTANT_MethodType); poolbuf.appendChar(pool.put(typeSig((MethodType)type))); } else { - if (type.hasTag(CLASS)) enterInner((ClassSymbol)type.tsym); + Assert.check(type.hasTag(ARRAY)); poolbuf.appendByte(CONSTANT_Class); poolbuf.appendChar(pool.put(xClassName(type))); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java index cef21cf52e1..9c9a93df143 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java @@ -28,6 +28,7 @@ package com.sun.tools.javac.jvm; import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.*; +import com.sun.tools.javac.code.TypeTag; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Types; import com.sun.tools.javac.code.Types.UniqueType; @@ -127,7 +128,14 @@ public class Pool { } else if (o instanceof VarSymbol) { return new Variable((VarSymbol)o, types); } else if (o instanceof Type) { - return new UniqueType((Type)o, types); + Type t = (Type)o; + // ClassRefs can come from ClassSymbols or from Types. + // Return the symbol for these types to avoid duplicates + // in the constant pool + if (t.hasTag(TypeTag.CLASS)) + return t.tsym; + else + return new UniqueType(t, types); } else { return o; } diff --git a/langtools/test/tools/javac/jvm/ClassRefDupInConstantPoolTest.java b/langtools/test/tools/javac/jvm/ClassRefDupInConstantPoolTest.java new file mode 100644 index 00000000000..98c7cf8dabb --- /dev/null +++ b/langtools/test/tools/javac/jvm/ClassRefDupInConstantPoolTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @bug 8015927 + * @summary Class reference duplicates in constant pool + * @clean ClassRefDupInConstantPoolTest$Duplicates.class + * @run main ClassRefDupInConstantPoolTest + */ + +import java.util.TreeSet; + +import com.sun.tools.classfile.*; +import com.sun.tools.classfile.ConstantPool.*; + +public class ClassRefDupInConstantPoolTest { + public static void main(String[] args) throws Exception { + ClassFile cls = ClassFile.read(ClassRefDupInConstantPoolTest.class. + getResourceAsStream("ClassRefDupInConstantPoolTest$Duplicates.class")); + ConstantPool pool = cls.constant_pool; + + int duplicates = 0; + TreeSet<Integer> set = new TreeSet<>(); + for (CPInfo i : pool.entries()) { + if (i.getTag() == ConstantPool.CONSTANT_Class) { + CONSTANT_Class_info ci = (CONSTANT_Class_info)i; + if (!set.add(ci.name_index)) { + duplicates++; + System.out.println("DUPLICATE CLASS REF " + ci.getName()); + } + } + } + if (duplicates > 0) + throw new Exception("Test Failed"); + } + + class Duplicates { + String concat(String s1, String s2) { + return s1 + (s2 == s1 ? " " : s2); + } + } +} From 7f2b064e439227ac00c27521fb7973321bc0690e Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn <serguei.spitsyn@oracle.com> Date: Fri, 16 May 2014 15:05:44 -0700 Subject: [PATCH 097/157] 8042796: jvmtiRedefineClasses.cpp: guarantee(false) failed: OLD and/or OBSOLETE method(s) found Relax the guaranty for deleted methods Reviewed-by: dcubed, coleenp --- hotspot/src/share/vm/oops/cpCache.cpp | 5 +++-- hotspot/src/share/vm/oops/method.hpp | 2 ++ hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp | 5 +++-- hotspot/src/share/vm/utilities/accessFlags.hpp | 5 ++++- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/hotspot/src/share/vm/oops/cpCache.cpp b/hotspot/src/share/vm/oops/cpCache.cpp index 4b6459ee33f..527b771fd68 100644 --- a/hotspot/src/share/vm/oops/cpCache.cpp +++ b/hotspot/src/share/vm/oops/cpCache.cpp @@ -498,9 +498,10 @@ bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() { // _f1 == NULL || !_f1->is_method() are OK here return true; } - // return false if _f1 refers to an old or an obsolete method + // return false if _f1 refers to a non-deleted old or obsolete method return (NOT_PRODUCT(_f1->is_valid() &&) _f1->is_method() && - !((Method*)_f1)->is_old() && !((Method*)_f1)->is_obsolete()); + (f1_as_method()->is_deleted() || + (!f1_as_method()->is_old() && !f1_as_method()->is_obsolete()))); } bool ConstantPoolCacheEntry::is_interesting_method_entry(Klass* k) { diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp index 764264aa6dc..67fc34ed0ed 100644 --- a/hotspot/src/share/vm/oops/method.hpp +++ b/hotspot/src/share/vm/oops/method.hpp @@ -669,6 +669,8 @@ class Method : public Metadata { void set_is_old() { _access_flags.set_is_old(); } bool is_obsolete() const { return access_flags().is_obsolete(); } void set_is_obsolete() { _access_flags.set_is_obsolete(); } + bool is_deleted() const { return access_flags().is_deleted(); } + void set_is_deleted() { _access_flags.set_is_deleted(); } bool on_stack() const { return access_flags().on_stack(); } void set_on_stack(const bool value); diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index 5f3d05478f6..2d4ce07e247 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -2970,7 +2970,8 @@ void VM_RedefineClasses::check_methods_and_mark_as_obsolete( assert(!old_method->has_vtable_index(), "cannot delete methods with vtable entries");; - // Mark all deleted methods as old and obsolete + // Mark all deleted methods as old, obsolete and deleted + old_method->set_is_deleted(); old_method->set_is_old(); old_method->set_is_obsolete(); ++obsolete_count; @@ -3576,7 +3577,7 @@ void VM_RedefineClasses::CheckClass::do_klass(Klass* k) { no_old_methods = false; } - // the constant pool cache should never contain old or obsolete methods + // the constant pool cache should never contain non-deleted old or obsolete methods if (ik->constants() != NULL && ik->constants()->cache() != NULL && !ik->constants()->cache()->check_no_old_or_obsolete_entries()) { diff --git a/hotspot/src/share/vm/utilities/accessFlags.hpp b/hotspot/src/share/vm/utilities/accessFlags.hpp index a3d3de99c91..5b1ff17322b 100644 --- a/hotspot/src/share/vm/utilities/accessFlags.hpp +++ b/hotspot/src/share/vm/utilities/accessFlags.hpp @@ -54,7 +54,8 @@ enum { JVM_ACC_IS_OLD = 0x00010000, // RedefineClasses() has replaced this method JVM_ACC_IS_OBSOLETE = 0x00020000, // RedefineClasses() has made method obsolete JVM_ACC_IS_PREFIXED_NATIVE = 0x00040000, // JVMTI has prefixed this native method - JVM_ACC_ON_STACK = 0x00080000, // RedefinedClasses() is used on the stack + JVM_ACC_ON_STACK = 0x00080000, // RedefineClasses() was used on the stack + JVM_ACC_IS_DELETED = 0x00008000, // RedefineClasses() has deleted this method // Klass* flags JVM_ACC_HAS_MIRANDA_METHODS = 0x10000000, // True if this class has miranda methods in it's vtable @@ -131,6 +132,7 @@ class AccessFlags VALUE_OBJ_CLASS_SPEC { bool has_jsrs () const { return (_flags & JVM_ACC_HAS_JSRS ) != 0; } bool is_old () const { return (_flags & JVM_ACC_IS_OLD ) != 0; } bool is_obsolete () const { return (_flags & JVM_ACC_IS_OBSOLETE ) != 0; } + bool is_deleted () const { return (_flags & JVM_ACC_IS_DELETED ) != 0; } bool is_prefixed_native () const { return (_flags & JVM_ACC_IS_PREFIXED_NATIVE ) != 0; } // Klass* flags @@ -195,6 +197,7 @@ class AccessFlags VALUE_OBJ_CLASS_SPEC { void set_has_jsrs() { atomic_set_bits(JVM_ACC_HAS_JSRS); } void set_is_old() { atomic_set_bits(JVM_ACC_IS_OLD); } void set_is_obsolete() { atomic_set_bits(JVM_ACC_IS_OBSOLETE); } + void set_is_deleted() { atomic_set_bits(JVM_ACC_IS_DELETED); } void set_is_prefixed_native() { atomic_set_bits(JVM_ACC_IS_PREFIXED_NATIVE); } void clear_not_c1_compilable() { atomic_clear_bits(JVM_ACC_NOT_C1_COMPILABLE); } From e8c1213b23da72ace88cd1b05598132d35ef41b2 Mon Sep 17 00:00:00 2001 From: Krystal Mok <krismo@azulsystems.com> Date: Sat, 17 May 2014 01:59:43 -0700 Subject: [PATCH 098/157] 8043264: hsdis library not picked up correctly on expected paths Fix file separator issue on Windows Reviewed-by: sla, sspitsyn --- hotspot/src/share/vm/compiler/disassembler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/compiler/disassembler.cpp b/hotspot/src/share/vm/compiler/disassembler.cpp index 0e9c14c1549..a0b2b49903c 100644 --- a/hotspot/src/share/vm/compiler/disassembler.cpp +++ b/hotspot/src/share/vm/compiler/disassembler.cpp @@ -86,7 +86,7 @@ bool Disassembler::load_library() { { // Match "jvm[^/]*" in jvm_path. const char* base = buf; - const char* p = strrchr(buf, '/'); + const char* p = strrchr(buf, *os::file_separator()); if (p != NULL) lib_offset = p - base + 1; p = strstr(p ? p : base, "jvm"); if (p != NULL) jvm_offset = p - base; @@ -111,7 +111,7 @@ bool Disassembler::load_library() { if (_library == NULL) { // 3. <home>/jre/lib/<arch>/hsdis-<arch>.so buf[lib_offset - 1] = '\0'; - const char* p = strrchr(buf, '/'); + const char* p = strrchr(buf, *os::file_separator()); if (p != NULL) { lib_offset = p - buf + 1; strcpy(&buf[lib_offset], hsdis_library_name); From 192bd8a421c7431a6af35e15e95535bbb9565eb5 Mon Sep 17 00:00:00 2001 From: Staffan Larsen <sla@openjdk.org> Date: Sun, 18 May 2014 20:42:10 +0200 Subject: [PATCH 099/157] 8043382: TempDirTest.java times out Remove explicit timeout Reviewed-by: alanb --- jdk/test/com/sun/tools/attach/TempDirTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/com/sun/tools/attach/TempDirTest.java b/jdk/test/com/sun/tools/attach/TempDirTest.java index e60f9ce46ca..9f8fafd2c7e 100644 --- a/jdk/test/com/sun/tools/attach/TempDirTest.java +++ b/jdk/test/com/sun/tools/attach/TempDirTest.java @@ -39,7 +39,7 @@ import jdk.testlibrary.ProcessThread; * @summary Test to make sure attach and jvmstat works correctly when java.io.tmpdir is set * @library /lib/testlibrary * @run build Application Shutdown RunnerUtil - * @run main/timeout=10 TempDirTest + * @run main TempDirTest */ public class TempDirTest { From 764a4758cb63679dd413ff54aba5b159ab2c4e8e Mon Sep 17 00:00:00 2001 From: Steven Sides <steve.sides@oracle.com> Date: Mon, 19 May 2014 10:34:42 +0400 Subject: [PATCH 100/157] 8039966: Add @return and @param block tags in colorchooser and filechooser swing classes Reviewed-by: malenkov, alexsch --- .../AbstractColorChooserPanel.java | 5 +++- .../javax/swing/filechooser/FileFilter.java | 5 ++++ .../swing/filechooser/FileSystemView.java | 23 ++++++++++++++++++ .../javax/swing/filechooser/FileView.java | 24 ++++++++++++++++++- 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/colorchooser/AbstractColorChooserPanel.java b/jdk/src/share/classes/javax/swing/colorchooser/AbstractColorChooserPanel.java index c75d08b89ff..5568fd6161a 100644 --- a/jdk/src/share/classes/javax/swing/colorchooser/AbstractColorChooserPanel.java +++ b/jdk/src/share/classes/javax/swing/colorchooser/AbstractColorChooserPanel.java @@ -145,7 +145,8 @@ public abstract class AbstractColorChooserPanel extends JPanel { /** * Invoked when the panel is added to the chooser. * If you override this, be sure to call <code>super</code>. - * @param enclosingChooser the panel to be added + * + * @param enclosingChooser the chooser to which the panel is to be added * @exception RuntimeException if the chooser panel has already been * installed */ @@ -163,6 +164,8 @@ public abstract class AbstractColorChooserPanel extends JPanel { /** * Invoked when the panel is removed from the chooser. * If override this, be sure to call <code>super</code>. + * + * @param enclosingChooser the chooser from which the panel is to be removed */ public void uninstallChooserPanel(JColorChooser enclosingChooser) { chooser.removePropertyChangeListener("enabled", enabledListener); diff --git a/jdk/src/share/classes/javax/swing/filechooser/FileFilter.java b/jdk/src/share/classes/javax/swing/filechooser/FileFilter.java index 1bdc9d4d8e7..170e4c8b891 100644 --- a/jdk/src/share/classes/javax/swing/filechooser/FileFilter.java +++ b/jdk/src/share/classes/javax/swing/filechooser/FileFilter.java @@ -51,11 +51,16 @@ import java.io.File; public abstract class FileFilter { /** * Whether the given file is accepted by this filter. + * + * @param f the File to test + * @return true if the file is to be accepted */ public abstract boolean accept(File f); /** * The description of this filter. For example: "JPG and GIF Images" + * + * @return the description of this filter * @see FileView#getName */ public abstract String getDescription(); diff --git a/jdk/src/share/classes/javax/swing/filechooser/FileSystemView.java b/jdk/src/share/classes/javax/swing/filechooser/FileSystemView.java index 4ab5dea5cac..26f09eac229 100644 --- a/jdk/src/share/classes/javax/swing/filechooser/FileSystemView.java +++ b/jdk/src/share/classes/javax/swing/filechooser/FileSystemView.java @@ -324,11 +324,18 @@ public abstract class FileSystemView { /** * Creates a new folder with a default folder name. + * + * @param containingDir a {@code File} object denoting directory to contain the new folder + * @return a {@code File} object denoting the newly created folder + * @throws IOException if new folder could not be created */ public abstract File createNewFolder(File containingDir) throws IOException; /** * Returns whether a file is hidden or not. + * + * @param f a {@code File} object + * @return true if the given {@code File} denotes a hidden file */ public boolean isHiddenFile(File f) { return f.isHidden(); @@ -395,6 +402,9 @@ public abstract class FileSystemView { * Returns all root partitions on this system. For example, on * Windows, this would be the "Desktop" folder, while on DOS this * would be the A: through Z: drives. + * + * @return an array of {@code File} objects representing all root partitions + * on this system */ public File[] getRoots() { // Don't cache this array, because filesystem might change @@ -435,6 +445,10 @@ public abstract class FileSystemView { /** * Returns a File object constructed in dir from the given filename. + * + * @param dir an abstract pathname denoting a directory + * @param filename a {@code String} representation of a pathname + * @return a {@code File} object created from {@code dir} and {@code filename} */ public File createFileObject(File dir, String filename) { if(dir == null) { @@ -446,6 +460,9 @@ public abstract class FileSystemView { /** * Returns a File object constructed from the given path string. + * + * @param path {@code String} representation of path + * @return a {@code File} object created from the given {@code path} */ public File createFileObject(String path) { File f = new File(path); @@ -458,6 +475,12 @@ public abstract class FileSystemView { /** * Gets the list of shown (i.e. not hidden) files. + * + * @param dir the root directory of files to be returned + * @param useFileHiding determine if hidden files are returned + * @return an array of {@code File} objects representing files and + * directories in the given {@code dir}. It includes hidden + * files if {@code useFileHiding} is false. */ public File[] getFiles(File dir, boolean useFileHiding) { List<File> files = new ArrayList<File>(); diff --git a/jdk/src/share/classes/javax/swing/filechooser/FileView.java b/jdk/src/share/classes/javax/swing/filechooser/FileView.java index 5e04ca4c69e..b628d5dbc51 100644 --- a/jdk/src/share/classes/javax/swing/filechooser/FileView.java +++ b/jdk/src/share/classes/javax/swing/filechooser/FileView.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,6 +69,9 @@ public abstract class FileView { /** * The name of the file. Normally this would be simply * <code>f.getName()</code>. + * + * @param f a {@code File} object + * @return a {@code String} representing the name of the file */ public String getName(File f) { return null; @@ -78,6 +81,11 @@ public abstract class FileView { * A human readable description of the file. For example, * a file named <i>jag.jpg</i> might have a description that read: * "A JPEG image file of James Gosling's face". + * + * @param f a {@code File} object + * @return a {@code String} containing a description of the file or + * {@code null} if it is not available. + * */ public String getDescription(File f) { return null; @@ -87,6 +95,10 @@ public abstract class FileView { * A human readable description of the type of the file. For * example, a <code>jpg</code> file might have a type description of: * "A JPEG Compressed Image File" + * + * @param f a {@code File} object + * @return a {@code String} containing a description of the type of the file + * or {@code null} if it is not available . */ public String getTypeDescription(File f) { return null; @@ -94,6 +106,10 @@ public abstract class FileView { /** * The icon that represents this file in the <code>JFileChooser</code>. + * + * @param f a {@code File} object + * @return an {@code Icon} which represents the specified {@code File} or + * {@code null} if it is not available. */ public Icon getIcon(File f) { return null; @@ -103,6 +119,12 @@ public abstract class FileView { * Whether the directory is traversable or not. This might be * useful, for example, if you want a directory to represent * a compound document and don't want the user to descend into it. + * + * @param f a {@code File} object representing a directory + * @return {@code true} if the directory is traversable, + * {@code false} if it is not, and {@code null} if the + * file system should be checked. + * @see FileSystemView#isTraversable */ public Boolean isTraversable(File f) { return null; From 31726139548f5bd5949d5fe467704c46ebda177c Mon Sep 17 00:00:00 2001 From: Steven Sides <steve.sides@oracle.com> Date: Mon, 19 May 2014 10:43:09 +0400 Subject: [PATCH 101/157] 8040893: Add block tags for @return and @param to swing border classes Reviewed-by: malenkov, alexsch --- .../javax/swing/border/BevelBorder.java | 27 ++++++++++++++++++- .../classes/javax/swing/border/Border.java | 6 +++++ .../javax/swing/border/CompoundBorder.java | 4 +++ .../javax/swing/border/EmptyBorder.java | 3 +++ .../javax/swing/border/EtchedBorder.java | 20 ++++++++++++++ .../javax/swing/border/LineBorder.java | 27 ++++++++++++++++--- .../javax/swing/border/MatteBorder.java | 10 ++++++- 7 files changed, 91 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/border/BevelBorder.java b/jdk/src/share/classes/javax/swing/border/BevelBorder.java index dd18a88245d..0c023fa6e63 100644 --- a/jdk/src/share/classes/javax/swing/border/BevelBorder.java +++ b/jdk/src/share/classes/javax/swing/border/BevelBorder.java @@ -134,7 +134,9 @@ public class BevelBorder extends AbstractBorder * when rendered on the specified component. If no highlight * color was specified at instantiation, the highlight color * is derived from the specified component's background color. + * * @param c the component for which the highlight may be derived + * @return the outer highlight {@code Color} * @since 1.3 */ public Color getHighlightOuterColor(Component c) { @@ -148,7 +150,9 @@ public class BevelBorder extends AbstractBorder * when rendered on the specified component. If no highlight * color was specified at instantiation, the highlight color * is derived from the specified component's background color. + * * @param c the component for which the highlight may be derived + * @return the inner highlight {@code Color} * @since 1.3 */ public Color getHighlightInnerColor(Component c) { @@ -162,7 +166,9 @@ public class BevelBorder extends AbstractBorder * when rendered on the specified component. If no shadow * color was specified at instantiation, the shadow color * is derived from the specified component's background color. + * * @param c the component for which the shadow may be derived + * @return the inner shadow {@code Color} * @since 1.3 */ public Color getShadowInnerColor(Component c) { @@ -176,7 +182,9 @@ public class BevelBorder extends AbstractBorder * when rendered on the specified component. If no shadow * color was specified at instantiation, the shadow color * is derived from the specified component's background color. + * * @param c the component for which the shadow may be derived + * @return the outer shadow {@code Color} * @since 1.3 */ public Color getShadowOuterColor(Component c) { @@ -189,6 +197,9 @@ public class BevelBorder extends AbstractBorder * Returns the outer highlight color of the bevel border. * Will return null if no highlight color was specified * at instantiation. + * + * @return the outer highlight {@code Color} or {@code null} if no highlight + * color was specified * @since 1.3 */ public Color getHighlightOuterColor() { @@ -199,6 +210,9 @@ public class BevelBorder extends AbstractBorder * Returns the inner highlight color of the bevel border. * Will return null if no highlight color was specified * at instantiation. + * + * @return the inner highlight {@code Color} or {@code null} if no highlight + * color was specified * @since 1.3 */ public Color getHighlightInnerColor() { @@ -209,6 +223,9 @@ public class BevelBorder extends AbstractBorder * Returns the inner shadow color of the bevel border. * Will return null if no shadow color was specified * at instantiation. + * + * @return the inner shadow {@code Color} or {@code null} if no shadow color + * was specified * @since 1.3 */ public Color getShadowInnerColor() { @@ -219,6 +236,9 @@ public class BevelBorder extends AbstractBorder * Returns the outer shadow color of the bevel border. * Will return null if no shadow color was specified * at instantiation. + * + * @return the outer shadow {@code Color} or {@code null} if no shadow color + * was specified * @since 1.3 */ public Color getShadowOuterColor() { @@ -227,13 +247,18 @@ public class BevelBorder extends AbstractBorder /** * Returns the type of the bevel border. + * + * @return the bevel border type, either {@code RAISED} or {@code LOWERED} */ public int getBevelType() { return bevelType; } /** - * Returns whether or not the border is opaque. + * Returns whether or not the border is opaque. This implementation + * returns {@code true}. + * + * @return true */ public boolean isBorderOpaque() { return true; } diff --git a/jdk/src/share/classes/javax/swing/border/Border.java b/jdk/src/share/classes/javax/swing/border/Border.java index ca58d0d7327..cbc0f6b6546 100644 --- a/jdk/src/share/classes/javax/swing/border/Border.java +++ b/jdk/src/share/classes/javax/swing/border/Border.java @@ -66,6 +66,7 @@ public interface Border /** * Paints the border for the specified component with the specified * position and size. + * * @param c the component for which this border is being painted * @param g the paint graphics * @param x the x position of the painted border @@ -77,7 +78,10 @@ public interface Border /** * Returns the insets of the border. + * * @param c the component for which this border insets value applies + * @return an {@code Insets} object containing the insets from top, left, + * bottom and right of this {@code Border} */ Insets getBorderInsets(Component c); @@ -85,6 +89,8 @@ public interface Border * Returns whether or not the border is opaque. If the border * is opaque, it is responsible for filling in it's own * background when painting. + * + * @return true if this {@code Border} is opaque */ boolean isBorderOpaque(); } diff --git a/jdk/src/share/classes/javax/swing/border/CompoundBorder.java b/jdk/src/share/classes/javax/swing/border/CompoundBorder.java index b62ecc9965b..162b30fc94c 100644 --- a/jdk/src/share/classes/javax/swing/border/CompoundBorder.java +++ b/jdk/src/share/classes/javax/swing/border/CompoundBorder.java @@ -155,6 +155,8 @@ public class CompoundBorder extends AbstractBorder { /** * Returns the outside border object. + * + * @return the outside {@code Border} object */ public Border getOutsideBorder() { return outsideBorder; @@ -162,6 +164,8 @@ public class CompoundBorder extends AbstractBorder { /** * Returns the inside border object. + * + * @return the inside {@code Border} object */ public Border getInsideBorder() { return insideBorder; diff --git a/jdk/src/share/classes/javax/swing/border/EmptyBorder.java b/jdk/src/share/classes/javax/swing/border/EmptyBorder.java index 1875ee354f0..82d2599611a 100644 --- a/jdk/src/share/classes/javax/swing/border/EmptyBorder.java +++ b/jdk/src/share/classes/javax/swing/border/EmptyBorder.java @@ -98,6 +98,9 @@ public class EmptyBorder extends AbstractBorder implements Serializable /** * Returns the insets of the border. + * + * @return an {@code Insets} object containing the insets from top, left, + * bottom and right * @since 1.3 */ public Insets getBorderInsets() { diff --git a/jdk/src/share/classes/javax/swing/border/EtchedBorder.java b/jdk/src/share/classes/javax/swing/border/EtchedBorder.java index 2850b60db7b..59ea6bb414e 100644 --- a/jdk/src/share/classes/javax/swing/border/EtchedBorder.java +++ b/jdk/src/share/classes/javax/swing/border/EtchedBorder.java @@ -77,6 +77,7 @@ public class EtchedBorder extends AbstractBorder * whose colors will be derived * from the background color of the component passed into * the paintBorder method. + * * @param etchType the type of etch to be drawn by the border */ public EtchedBorder(int etchType) { @@ -86,6 +87,7 @@ public class EtchedBorder extends AbstractBorder /** * Creates a lowered etched border with the specified highlight and * shadow colors. + * * @param highlight the color to use for the etched highlight * @param shadow the color to use for the etched shadow */ @@ -96,6 +98,7 @@ public class EtchedBorder extends AbstractBorder /** * Creates an etched border with the specified etch-type, * highlight and shadow colors. + * * @param etchType the type of etch to be drawn by the border * @param highlight the color to use for the etched highlight * @param shadow the color to use for the etched shadow @@ -110,6 +113,7 @@ public class EtchedBorder extends AbstractBorder /** * Paints the border for the specified component with the * specified position and size. + * * @param c the component for which this border is being painted * @param g the paint graphics * @param x the x position of the painted border @@ -138,6 +142,7 @@ public class EtchedBorder extends AbstractBorder /** * Reinitialize the insets parameter with this Border's current Insets. + * * @param c the component for which this border insets value applies * @param insets the object to be reinitialized */ @@ -148,11 +153,16 @@ public class EtchedBorder extends AbstractBorder /** * Returns whether or not the border is opaque. + * This implementation returns true. + * + * @return true */ public boolean isBorderOpaque() { return true; } /** * Returns which etch-type is set on the etched border. + * + * @return the etched border type, either {@code RAISED} or {@code LOWERED} */ public int getEtchType() { return etchType; @@ -163,7 +173,9 @@ public class EtchedBorder extends AbstractBorder * when rendered on the specified component. If no highlight * color was specified at instantiation, the highlight color * is derived from the specified component's background color. + * * @param c the component for which the highlight may be derived + * @return the highlight {@code Color} of this {@code EtchedBorder} * @since 1.3 */ public Color getHighlightColor(Component c) { @@ -175,6 +187,9 @@ public class EtchedBorder extends AbstractBorder * Returns the highlight color of the etched border. * Will return null if no highlight color was specified * at instantiation. + * + * @return the highlight {@code Color} of this {@code EtchedBorder} or null + * if none was specified * @since 1.3 */ public Color getHighlightColor() { @@ -186,7 +201,9 @@ public class EtchedBorder extends AbstractBorder * when rendered on the specified component. If no shadow * color was specified at instantiation, the shadow color * is derived from the specified component's background color. + * * @param c the component for which the shadow may be derived + * @return the shadow {@code Color} of this {@code EtchedBorder} * @since 1.3 */ public Color getShadowColor(Component c) { @@ -197,6 +214,9 @@ public class EtchedBorder extends AbstractBorder * Returns the shadow color of the etched border. * Will return null if no shadow color was specified * at instantiation. + * + * @return the shadow {@code Color} of this {@code EtchedBorder} or null + * if none was specified * @since 1.3 */ public Color getShadowColor() { diff --git a/jdk/src/share/classes/javax/swing/border/LineBorder.java b/jdk/src/share/classes/javax/swing/border/LineBorder.java index 1e083c1164f..c03183292f7 100644 --- a/jdk/src/share/classes/javax/swing/border/LineBorder.java +++ b/jdk/src/share/classes/javax/swing/border/LineBorder.java @@ -60,8 +60,11 @@ public class LineBorder extends AbstractBorder protected Color lineColor; protected boolean roundedCorners; - /** Convenience method for getting the Color.black LineBorder of thickness 1. - */ + /** + * Convenience method for getting the Color.black LineBorder of thickness 1. + * + * @return a {@code LineBorder} with {@code Color.black} and thickness of 1 + */ public static Border createBlackLineBorder() { if (blackLine == null) { blackLine = new LineBorder(Color.black, 1); @@ -69,8 +72,11 @@ public class LineBorder extends AbstractBorder return blackLine; } - /** Convenience method for getting the Color.gray LineBorder of thickness 1. - */ + /** + * Convenience method for getting the Color.gray LineBorder of thickness 1. + * + * @return a {@code LineBorder} with {@code Color.gray} and thickness of 1 + */ public static Border createGrayLineBorder() { if (grayLine == null) { grayLine = new LineBorder(Color.gray, 1); @@ -81,6 +87,7 @@ public class LineBorder extends AbstractBorder /** * Creates a line border with the specified color and a * thickness = 1. + * * @param color the color for the border */ public LineBorder(Color color) { @@ -89,6 +96,7 @@ public class LineBorder extends AbstractBorder /** * Creates a line border with the specified color and thickness. + * * @param color the color of the border * @param thickness the thickness of the border */ @@ -99,6 +107,7 @@ public class LineBorder extends AbstractBorder /** * Creates a line border with the specified color, thickness, * and corner shape. + * * @param color the color of the border * @param thickness the thickness of the border * @param roundedCorners whether or not border corners should be round @@ -114,6 +123,7 @@ public class LineBorder extends AbstractBorder /** * Paints the border for the specified component with the * specified position and size. + * * @param c the component for which this border is being painted * @param g the paint graphics * @param x the x position of the painted border @@ -152,6 +162,7 @@ public class LineBorder extends AbstractBorder /** * Reinitialize the insets parameter with this Border's current Insets. + * * @param c the component for which this border insets value applies * @param insets the object to be reinitialized */ @@ -162,6 +173,8 @@ public class LineBorder extends AbstractBorder /** * Returns the color of the border. + * + * @return a {@code Color} object representing the color of this object */ public Color getLineColor() { return lineColor; @@ -169,6 +182,8 @@ public class LineBorder extends AbstractBorder /** * Returns the thickness of the border. + * + * @return the thickness of this border */ public int getThickness() { return thickness; @@ -176,6 +191,8 @@ public class LineBorder extends AbstractBorder /** * Returns whether this border will be drawn with rounded corners. + * + * @return {@code true} if this border should have rounded corners * @since 1.3 */ public boolean getRoundedCorners() { @@ -184,6 +201,8 @@ public class LineBorder extends AbstractBorder /** * Returns whether or not the border is opaque. + * + * @return {@code true} if the border is opaque, {@code false} otherwise */ public boolean isBorderOpaque() { return !roundedCorners; diff --git a/jdk/src/share/classes/javax/swing/border/MatteBorder.java b/jdk/src/share/classes/javax/swing/border/MatteBorder.java index e8491f59850..b1501ff932f 100644 --- a/jdk/src/share/classes/javax/swing/border/MatteBorder.java +++ b/jdk/src/share/classes/javax/swing/border/MatteBorder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -196,6 +196,9 @@ public class MatteBorder extends EmptyBorder /** * Returns the color used for tiling the border or null * if a tile icon is being used. + * + * @return the {@code Color} object used to render the border or {@code null} + * if a tile icon is used * @since 1.3 */ public Color getMatteColor() { @@ -205,6 +208,9 @@ public class MatteBorder extends EmptyBorder /** * Returns the icon used for tiling the border or null * if a solid color is being used. + * + * @return the {@code Icon} used to tile the border or {@code null} if a + * solid color is used to fill the border * @since 1.3 */ public Icon getTileIcon() { @@ -213,6 +219,8 @@ public class MatteBorder extends EmptyBorder /** * Returns whether or not the border is opaque. + * + * @return {@code true} if the border is opaque, {@code false} otherwise */ public boolean isBorderOpaque() { // If a tileIcon is set, then it may contain transparent bits From 4b44e25310033f2ee79694ba59cf05aac112222e Mon Sep 17 00:00:00 2001 From: Rob McKenna <robm@openjdk.org> Date: Mon, 19 May 2014 14:28:08 +0100 Subject: [PATCH 102/157] 8028627: Unsynchronized code path from javax.crypto.Cipher to the WeakHashMap used by JceSecurity to store codebase mappings Reviewed-by: mullan --- .../classes/javax/crypto/JceSecurity.java | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/jdk/src/share/classes/javax/crypto/JceSecurity.java b/jdk/src/share/classes/javax/crypto/JceSecurity.java index 7e062462211..fb7052d244d 100644 --- a/jdk/src/share/classes/javax/crypto/JceSecurity.java +++ b/jdk/src/share/classes/javax/crypto/JceSecurity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -216,26 +216,28 @@ final class JceSecurity { new WeakHashMap<>(); /* - * Retuns the CodeBase for the given class. + * Returns the CodeBase for the given class. */ static URL getCodeBase(final Class<?> clazz) { - URL url = codeBaseCacheRef.get(clazz); - if (url == null) { - url = AccessController.doPrivileged(new PrivilegedAction<URL>() { - public URL run() { - ProtectionDomain pd = clazz.getProtectionDomain(); - if (pd != null) { - CodeSource cs = pd.getCodeSource(); - if (cs != null) { - return cs.getLocation(); + synchronized (codeBaseCacheRef) { + URL url = codeBaseCacheRef.get(clazz); + if (url == null) { + url = AccessController.doPrivileged(new PrivilegedAction<URL>() { + public URL run() { + ProtectionDomain pd = clazz.getProtectionDomain(); + if (pd != null) { + CodeSource cs = pd.getCodeSource(); + if (cs != null) { + return cs.getLocation(); + } } + return NULL_URL; } - return NULL_URL; - } - }); - codeBaseCacheRef.put(clazz, url); + }); + codeBaseCacheRef.put(clazz, url); + } + return (url == NULL_URL) ? null : url; } - return (url == NULL_URL) ? null : url; } private static void setupJurisdictionPolicies() throws Exception { From db62a418b31bd0b6642aba36cccd59661269e72b Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan <sundar@openjdk.org> Date: Tue, 20 May 2014 08:32:09 +0530 Subject: [PATCH 103/157] 8043443: Test framework changes to run script tests without security manager Reviewed-by: attila --- nashorn/make/build.xml | 19 +++++++++++ nashorn/make/project.properties | 6 ++++ nashorn/test/script/nosecurity/nosecurity.js | 34 ++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 nashorn/test/script/nosecurity/nosecurity.js diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml index e8058a32f9b..88c4e9cf379 100644 --- a/nashorn/make/build.xml +++ b/nashorn/make/build.xml @@ -360,6 +360,10 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" { <include name="**/framework/*Test.class"/> </fileset> + <fileset id="test.nosecurity.classes" dir="${build.test.classes.dir}"> + <include name="**/framework/ScriptTest.class"/> + </fileset> + <testng outputdir="${build.test.results.dir}" classfilesetref="test.classes" verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}"> <jvmarg line="${ext.class.path}"/> @@ -376,6 +380,21 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" { <pathelement path="${run.test.classpath}"/> </classpath> </testng> + <testng outputdir="${build.nosecurity.test.results.dir}" classfilesetref="test.nosecurity.classes" + verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}"> + <jvmarg line="${ext.class.path}"/> + <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx}"/> + <propertyset> + <propertyref prefix="nashorn."/> + </propertyset> + <propertyset> + <propertyref prefix="test-sys-prop-no-security."/> + <mapper from="test-sys-prop-no-security.*" to="*" type="glob"/> + </propertyset> + <classpath> + <pathelement path="${run.test.classpath}"/> + </classpath> + </testng> </target> <target name="test-basicparallel" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file"> diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties index 5af728794e2..8210e250ad2 100644 --- a/nashorn/make/project.properties +++ b/nashorn/make/project.properties @@ -59,6 +59,7 @@ nashorn.api.tests.jar=${build.dir}/nashorn-api-tests.jar # test results directory build.test.results.dir=${build.dir}/test/reports +build.nosecurity.test.results.dir=${build.dir}/test/nosecurity/reports # This directory is removed when the project is cleaned: dist.dir=dist @@ -113,6 +114,7 @@ run.classpath=\ # test scripts to run test.dir=test +test.nosecurity.dir=test/script/nosecurity test.script.dir=test/script test.basic.dir=test/script/basic test.maptests.dir=test/script/maptests @@ -131,8 +133,12 @@ test-sys-prop.test262.suite.dir=${test262.suite.dir} test-sys-prop.es5conform.testcases.dir=${test.external.dir}/ES5Conform/TestCases test-sys-prop.test.basic.dir=${test.basic.dir} +test-sys-prop-no-security.test.dir=${test.dir} +test-sys-prop-no-security.test.js.roots=${test.nosecurity.dir} + # framework root for our script tests test-sys-prop.test.js.framework=${test.script.dir}/assert.js +test-sys-prop-no-security.test.js.framework=${test.script.dir}/assert.js # Control the verbosity of ParserTest test-sys-prop.parsertest.verbose=false diff --git a/nashorn/test/script/nosecurity/nosecurity.js b/nashorn/test/script/nosecurity/nosecurity.js new file mode 100644 index 00000000000..688af8cf6a0 --- /dev/null +++ b/nashorn/test/script/nosecurity/nosecurity.js @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +/** + * 8043443: Test framework changes to run script tests without security manager + * @test + * @run + */ + +var System = Java.type("java.lang.System"); + +if (System.securityManager != null) { + fail("SecurityManager is set!"); +} From 56436ec3c3f0bf7f865c99915d55adc633a2d6b4 Mon Sep 17 00:00:00 2001 From: Ivan Gerasimov <igerasim@openjdk.org> Date: Tue, 20 May 2014 10:11:23 +0400 Subject: [PATCH 104/157] 7195480: javax.smartcardio does not detect cards on Mac OS X Reviewed-by: valeriep --- .../security/smartcardio/MUSCLE/pcsclite.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/jdk/src/solaris/native/sun/security/smartcardio/MUSCLE/pcsclite.h b/jdk/src/solaris/native/sun/security/smartcardio/MUSCLE/pcsclite.h index e17cf8061e3..02e7035b31c 100644 --- a/jdk/src/solaris/native/sun/security/smartcardio/MUSCLE/pcsclite.h +++ b/jdk/src/solaris/native/sun/security/smartcardio/MUSCLE/pcsclite.h @@ -62,6 +62,8 @@ typedef SCARDHANDLE *LPSCARDHANDLE; #define MAX_ATR_SIZE 33 /* Maximum ATR size */ +#ifndef __APPLE__ + typedef struct { const char *szReader; @@ -73,6 +75,23 @@ typedef struct } SCARD_READERSTATE_A; +#else // __APPLE__ + +#pragma pack(1) +typedef struct +{ + const char *szReader; + void *pvUserData; + uint32_t dwCurrentState; + uint32_t dwEventState; + uint32_t cbAtr; + unsigned char rgbAtr[MAX_ATR_SIZE]; +} +SCARD_READERSTATE_A; +#pragma pack() + +#endif // __APPLE__ + typedef SCARD_READERSTATE_A SCARD_READERSTATE, *PSCARD_READERSTATE_A, *LPSCARD_READERSTATE_A; From eddf95338d43475403daa788e631edad9c6afff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Lid=C3=A9n?= <pliden@openjdk.org> Date: Tue, 20 May 2014 10:24:30 +0200 Subject: [PATCH 105/157] 8039042: G1: Phantom zeros in cardtable Reviewed-by: tschatzl, mgerdin --- .../gc_implementation/g1/g1SATBCardTableModRefBS.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp index 756ea3e233b..e741a0f7951 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp @@ -96,7 +96,15 @@ void G1SATBCardTableModRefBS::g1_mark_as_young(const MemRegion& mr) { jbyte *const first = byte_for(mr.start()); jbyte *const last = byte_after(mr.last()); - memset(first, g1_young_gen, last - first); + // Below we may use an explicit loop instead of memset() because on + // certain platforms memset() can give concurrent readers phantom zeros. + if (UseMemSetInBOT) { + memset(first, g1_young_gen, last - first); + } else { + for (jbyte* i = first; i < last; i++) { + *i = g1_young_gen; + } + } } #ifndef PRODUCT From 878ab77469cf4e5239f2b046851836785edc3dfb Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff <dsamersoff@openjdk.org> Date: Tue, 20 May 2014 06:11:05 -0700 Subject: [PATCH 106/157] 8041435: Make JDWP socket connector accept only local connections by default Bind to localhost only if no address specified. Require * to bind to all available addresses Reviewed-by: dcubed, sspitsyn --- .../share/transport/socket/socketTransport.c | 81 ++++++++++++++++--- jdk/test/com/sun/jdi/OptionTest.java | 31 +++++++ 2 files changed, 102 insertions(+), 10 deletions(-) diff --git a/jdk/src/share/transport/socket/socketTransport.c b/jdk/src/share/transport/socket/socketTransport.c index c76fd1085d5..b8de834a9eb 100644 --- a/jdk/src/share/transport/socket/socketTransport.c +++ b/jdk/src/share/transport/socket/socketTransport.c @@ -31,6 +31,11 @@ #include "jdwpTransport.h" #include "sysSocket.h" +#ifdef _WIN32 + #include <winsock2.h> + #include <ws2tcpip.h> +#endif + /* * The Socket Transport Library. * @@ -189,23 +194,81 @@ handshake(int fd, jlong timeout) { return JDWPTRANSPORT_ERROR_NONE; } +static uint32_t +getLocalHostAddress() { + // Simple routine to guess localhost address. + // it looks up "localhost" and returns 127.0.0.1 if lookup + // fails. + struct addrinfo hints = {0}, *res = NULL; + int err; + + hints.ai_family = AF_INET; + + err = getaddrinfo("localhost", NULL, &hints, &res); + if (err < 0 || res == NULL) { + return dbgsysHostToNetworkLong(INADDR_LOOPBACK); + } + + // getaddrinfo might return more than one address + // but we are using first one only + return ((struct sockaddr_in *)(res->ai_addr))->sin_addr.s_addr; +} + +static int +getPortNumber(const char *s_port) { + u_long n; + char *eptr; + + if (*s_port == 0) { + // bad address - colon with no port number in parameters + return -1; + } + + n = strtoul(s_port, &eptr, 10); + if (eptr != s_port + strlen(s_port)) { + // incomplete conversion - port number contains non-digit + return -1; + } + + if (n > (u_short) -1) { + // check that value supplied by user is less than + // maximum possible u_short value (65535) and + // will not be truncated later. + return -1; + } + + return n; +} + static jdwpTransportError -parseAddress(const char *address, struct sockaddr_in *sa, uint32_t defaultHost) { +parseAddress(const char *address, struct sockaddr_in *sa) { char *colon; + int port; memset((void *)sa,0,sizeof(struct sockaddr_in)); sa->sin_family = AF_INET; /* check for host:port or port */ colon = strchr(address, ':'); + port = getPortNumber((colon == NULL) ? address : colon +1); + if (port < 0) { + RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "invalid port number specified"); + } + sa->sin_port = dbgsysHostToNetworkShort((u_short)port); + if (colon == NULL) { - u_short port = (u_short)atoi(address); - sa->sin_port = dbgsysHostToNetworkShort(port); - sa->sin_addr.s_addr = dbgsysHostToNetworkLong(defaultHost); - } else { + // bind to localhost only if no address specified + sa->sin_addr.s_addr = getLocalHostAddress(); + } else if (strncmp(address,"localhost:",10) == 0) { + // optimize for common case + sa->sin_addr.s_addr = getLocalHostAddress(); + } else if (*address == '*' && *(address+1) == ':') { + // we are explicitly asked to bind server to all available IP addresses + // has no meaning for client. + sa->sin_addr.s_addr = dbgsysHostToNetworkLong(INADDR_ANY); + } else { char *buf; char *hostname; - u_short port; uint32_t addr; buf = (*callback->alloc)((int)strlen(address)+1); @@ -215,8 +278,6 @@ parseAddress(const char *address, struct sockaddr_in *sa, uint32_t defaultHost) strcpy(buf, address); buf[colon - address] = '\0'; hostname = buf; - port = atoi(colon + 1); - sa->sin_port = dbgsysHostToNetworkShort(port); /* * First see if the host is a literal IP address. @@ -277,7 +338,7 @@ socketTransport_startListening(jdwpTransportEnv* env, const char* address, address = "0"; } - err = parseAddress(address, &sa, INADDR_ANY); + err = parseAddress(address, &sa); if (err != JDWPTRANSPORT_ERROR_NONE) { return err; } @@ -437,7 +498,7 @@ socketTransport_attach(jdwpTransportEnv* env, const char* addressString, jlong a RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "address is missing"); } - err = parseAddress(addressString, &sa, 0x7f000001); + err = parseAddress(addressString, &sa); if (err != JDWPTRANSPORT_ERROR_NONE) { return err; } diff --git a/jdk/test/com/sun/jdi/OptionTest.java b/jdk/test/com/sun/jdi/OptionTest.java index 55e74133993..b5ea8e708cc 100644 --- a/jdk/test/com/sun/jdi/OptionTest.java +++ b/jdk/test/com/sun/jdi/OptionTest.java @@ -157,6 +157,37 @@ public class OptionTest extends Object { throw new Exception("Test failed: jdwp doesn't like " + cmds[1]); } } + + System.out.println("Testing invalid address string"); + + // Test invalid addresses + String badAddresses[] = { + ":", + "localhost:", + "localhost:abc", + "localhost:65536", + "localhost:65F" + }; + + for (String badAddress : badAddresses) { + + String badOptions = "transport=dt_socket" + + ",address=" + badAddress + + ",server=y" + + ",suspend=n"; + String cmds[] = {javaExe, "-agentlib:jdwp=" + badOptions, targetClass}; + OptionTest myTest = new OptionTest(); + String results[] = myTest.run(VMConnection.insertDebuggeeVMOptions(cmds)); + + if (!results[RETSTAT].equals("0") && results[STDERR].startsWith("ERROR:")) { + // We got expected error, test passed + } + else { + throw new Exception("Test failed: jdwp accept invalid address '" + badAddress + "'"); + } + } + System.out.println("Test passed: status = 0"); } } + From a7f214e7156ca66dc592ee529501383e16b1132e Mon Sep 17 00:00:00 2001 From: John Coomes <jcoomes@openjdk.org> Date: Tue, 20 May 2014 10:04:03 -0700 Subject: [PATCH 107/157] 8042255: make gc src file exclusion more automatic Reviewed-by: brutisso, stefank, dholmes, rdurbin --- hotspot/make/excludeSrc.make | 58 +++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/hotspot/make/excludeSrc.make b/hotspot/make/excludeSrc.make index dcaa3a11a0c..55495e6bef2 100644 --- a/hotspot/make/excludeSrc.make +++ b/hotspot/make/excludeSrc.make @@ -77,30 +77,40 @@ ifeq ($(INCLUDE_ALL_GCS), false) CXXFLAGS += -DINCLUDE_ALL_GCS=0 CFLAGS += -DINCLUDE_ALL_GCS=0 - Src_Files_EXCLUDE += \ - cmsAdaptiveSizePolicy.cpp cmsCollectorPolicy.cpp \ - cmsGCAdaptivePolicyCounters.cpp cmsLockVerifier.cpp compactibleFreeListSpace.cpp \ - concurrentMarkSweepGeneration.cpp concurrentMarkSweepThread.cpp \ - freeChunk.cpp adaptiveFreeList.cpp promotionInfo.cpp vmCMSOperations.cpp \ - collectionSetChooser.cpp concurrentG1Refine.cpp concurrentG1RefineThread.cpp \ - concurrentMark.cpp concurrentMarkThread.cpp dirtyCardQueue.cpp g1AllocRegion.cpp \ - g1BlockOffsetTable.cpp g1CardCounts.cpp g1CollectedHeap.cpp g1CollectorPolicy.cpp \ - g1ErgoVerbose.cpp g1GCPhaseTimes.cpp g1HRPrinter.cpp g1HotCardCache.cpp g1Log.cpp \ - g1MMUTracker.cpp g1MarkSweep.cpp g1MemoryPool.cpp g1MonitoringSupport.cpp g1OopClosures.cpp \ - g1RemSet.cpp g1RemSetSummary.cpp g1SATBCardTableModRefBS.cpp g1StringDedup.cpp g1StringDedupStat.cpp \ - g1StringDedupTable.cpp g1StringDedupThread.cpp g1StringDedupQueue.cpp g1_globals.cpp heapRegion.cpp \ - g1BiasedArray.cpp heapRegionRemSet.cpp heapRegionSeq.cpp heapRegionSet.cpp heapRegionSets.cpp \ - ptrQueue.cpp satbQueue.cpp sparsePRT.cpp survRateGroup.cpp vm_operations_g1.cpp g1CodeCacheRemSet.cpp \ - adjoiningGenerations.cpp adjoiningVirtualSpaces.cpp asPSOldGen.cpp asPSYoungGen.cpp \ - cardTableExtension.cpp gcTaskManager.cpp gcTaskThread.cpp objectStartArray.cpp \ - parallelScavengeHeap.cpp parMarkBitMap.cpp pcTasks.cpp psAdaptiveSizePolicy.cpp \ - psCompactionManager.cpp psGCAdaptivePolicyCounters.cpp psGenerationCounters.cpp \ - psMarkSweep.cpp psMarkSweepDecorator.cpp psMemoryPool.cpp psOldGen.cpp \ - psParallelCompact.cpp psPromotionLAB.cpp psPromotionManager.cpp psScavenge.cpp \ - psTasks.cpp psVirtualspace.cpp psYoungGen.cpp vmPSOperations.cpp asParNewGeneration.cpp \ - parCardTableModRefBS.cpp parGCAllocBuffer.cpp parNewGeneration.cpp mutableSpace.cpp \ - gSpaceCounters.cpp allocationStats.cpp spaceCounters.cpp gcAdaptivePolicyCounters.cpp \ - mutableNUMASpace.cpp immutableSpace.cpp yieldingWorkGroup.cpp hSpaceCounters.cpp + gc_impl := $(GAMMADIR)/src/share/vm/gc_implementation + gc_exclude := \ + $(notdir $(wildcard $(gc_impl)/concurrentMarkSweep/*.cpp)) \ + $(notdir $(wildcard $(gc_impl)/g1/*.cpp)) \ + $(notdir $(wildcard $(gc_impl)/parallelScavenge/*.cpp)) \ + $(notdir $(wildcard $(gc_impl)/parNew/*.cpp)) + Src_Files_EXCLUDE += $(gc_exclude) + + # Exclude everything in $(gc_impl)/shared except the files listed + # in $(gc_shared_keep). + gc_shared_all := $(notdir $(wildcard $(gc_impl)/shared/*.cpp)) + gc_shared_keep := \ + adaptiveSizePolicy.cpp \ + ageTable.cpp \ + collectorCounters.cpp \ + cSpaceCounters.cpp \ + gcPolicyCounters.cpp \ + gcStats.cpp \ + gcTimer.cpp \ + gcTrace.cpp \ + gcTraceSend.cpp \ + gcTraceTime.cpp \ + gcUtil.cpp \ + generationCounters.cpp \ + markSweep.cpp \ + objectCountEventSender.cpp \ + spaceDecorator.cpp \ + vmGCOperations.cpp + Src_Files_EXCLUDE += $(filter-out $(gc_shared_keep),$(gc_shared_all)) + + # src/share/vm/services + Src_Files_EXCLUDE += \ + g1MemoryPool.cpp \ + psMemoryPool.cpp endif ifeq ($(INCLUDE_NMT), false) From 049c4994231fea0305182e8610f1473bbde0b4c3 Mon Sep 17 00:00:00 2001 From: Dmitry Fazunenko <dmitry.fazunenko@oracle.com> Date: Tue, 20 May 2014 18:25:14 +0400 Subject: [PATCH 108/157] 8039489: Refactor test framework for dynamic VM options Reviewed-by: jmasa, ehelin, jwilhelm --- .../gc/arguments/TestDynMaxHeapFreeRatio.java | 68 +++++--- .../gc/arguments/TestDynMinHeapFreeRatio.java | 66 ++++--- .../parallelScavenge/TestDynShrinkHeap.java | 11 +- .../java/testlibrary/DynamicVMOption.java | 165 ++++++++++++++++++ .../testlibrary/DynamicVMOptionChecker.java | 121 ------------- .../java/testlibrary/TestDynamicVMOption.java | 104 ----------- 6 files changed, 255 insertions(+), 280 deletions(-) create mode 100644 hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOption.java delete mode 100644 hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOptionChecker.java delete mode 100644 hotspot/test/testlibrary/com/oracle/java/testlibrary/TestDynamicVMOption.java diff --git a/hotspot/test/gc/arguments/TestDynMaxHeapFreeRatio.java b/hotspot/test/gc/arguments/TestDynMaxHeapFreeRatio.java index 6d36106c43b..53728b8187b 100644 --- a/hotspot/test/gc/arguments/TestDynMaxHeapFreeRatio.java +++ b/hotspot/test/gc/arguments/TestDynMaxHeapFreeRatio.java @@ -21,6 +21,11 @@ * questions. */ +import static com.oracle.java.testlibrary.Asserts.assertEQ; +import static com.oracle.java.testlibrary.Asserts.assertFalse; +import static com.oracle.java.testlibrary.Asserts.assertTrue; +import com.oracle.java.testlibrary.DynamicVMOption; + /** * @test TestDynMaxHeapFreeRatio * @bug 8028391 @@ -33,32 +38,45 @@ * @run main/othervm -XX:MinHeapFreeRatio=51 -XX:MaxHeapFreeRatio=52 TestDynMaxHeapFreeRatio * @run main/othervm -XX:MinHeapFreeRatio=75 -XX:MaxHeapFreeRatio=100 TestDynMaxHeapFreeRatio */ -import com.oracle.java.testlibrary.TestDynamicVMOption; -import com.oracle.java.testlibrary.DynamicVMOptionChecker; - -public class TestDynMaxHeapFreeRatio extends TestDynamicVMOption { - - public static final String MinFreeRatioFlagName = "MinHeapFreeRatio"; - public static final String MaxFreeRatioFlagName = "MaxHeapFreeRatio"; - - public TestDynMaxHeapFreeRatio() { - super(MaxFreeRatioFlagName); - } - - public void test() { - - int minHeapFreeValue = DynamicVMOptionChecker.getIntValue(MinFreeRatioFlagName); - System.out.println(MinFreeRatioFlagName + " = " + minHeapFreeValue); - - testPercentageValues(); - - checkInvalidValue(Integer.toString(minHeapFreeValue - 1)); - checkValidValue(Integer.toString(minHeapFreeValue)); - checkValidValue("100"); - } +public class TestDynMaxHeapFreeRatio { public static void main(String args[]) throws Exception { - new TestDynMaxHeapFreeRatio().test(); - } + // low boundary value + int minValue = DynamicVMOption.getInt("MinHeapFreeRatio"); + System.out.println("MinHeapFreeRatio= " + minValue); + + String badValues[] = { + null, + "", + "not a number", + "8.5", "-0.01", + Integer.toString(Integer.MIN_VALUE), + Integer.toString(Integer.MAX_VALUE), + Integer.toString(minValue - 1), + "-1024", "-1", "101", "1997" + }; + + String goodValues[] = { + Integer.toString(minValue), + Integer.toString(minValue + 1), + Integer.toString((minValue + 100) / 2), + "99", "100" + }; + + DynamicVMOption option = new DynamicVMOption("MaxHeapFreeRatio"); + + assertTrue(option.isWriteable(), "Option " + option.name + + " is expected to be writable"); + + for (String v : badValues) { + assertFalse(option.isValidValue(v), + "'" + v + "' is expected to be illegal for flag " + option.name); + } + for (String v : goodValues) { + option.setValue(v); + String newValue = option.getValue(); + assertEQ(v, newValue); + } + } } diff --git a/hotspot/test/gc/arguments/TestDynMinHeapFreeRatio.java b/hotspot/test/gc/arguments/TestDynMinHeapFreeRatio.java index 13132f04d38..bbf0ecf3f5f 100644 --- a/hotspot/test/gc/arguments/TestDynMinHeapFreeRatio.java +++ b/hotspot/test/gc/arguments/TestDynMinHeapFreeRatio.java @@ -33,30 +33,52 @@ * @run main/othervm -XX:MinHeapFreeRatio=51 -XX:MaxHeapFreeRatio=52 TestDynMinHeapFreeRatio * @run main/othervm -XX:MinHeapFreeRatio=75 -XX:MaxHeapFreeRatio=100 TestDynMinHeapFreeRatio */ -import com.oracle.java.testlibrary.TestDynamicVMOption; -import com.oracle.java.testlibrary.DynamicVMOptionChecker; +import static com.oracle.java.testlibrary.Asserts.assertEQ; +import static com.oracle.java.testlibrary.Asserts.assertFalse; +import static com.oracle.java.testlibrary.Asserts.assertTrue; +import com.oracle.java.testlibrary.DynamicVMOption; -public class TestDynMinHeapFreeRatio extends TestDynamicVMOption { - - public static final String MinFreeRatioFlagName = "MinHeapFreeRatio"; - public static final String MaxFreeRatioFlagName = "MaxHeapFreeRatio"; - - public TestDynMinHeapFreeRatio() { - super(MinFreeRatioFlagName); - } - - public void test() { - int maxHeapFreeValue = DynamicVMOptionChecker.getIntValue(MaxFreeRatioFlagName); - System.out.println(MaxFreeRatioFlagName + " = " + maxHeapFreeValue); - - testPercentageValues(); - - checkInvalidValue(Integer.toString(maxHeapFreeValue + 1)); - checkValidValue(Integer.toString(maxHeapFreeValue)); - checkValidValue("0"); - } +public class TestDynMinHeapFreeRatio { public static void main(String args[]) throws Exception { - new TestDynMinHeapFreeRatio().test(); + + // high boundary value + int maxValue = DynamicVMOption.getInt("MaxHeapFreeRatio"); + System.out.println("MaxHeapFreeRatio= " + maxValue); + + String badValues[] = { + null, + "", + "not a number", + "8.5", "-0.01", + Integer.toString(Integer.MIN_VALUE), + Integer.toString(Integer.MAX_VALUE), + Integer.toString(maxValue + 1), + "-1024", "-1", "101", "1997" + }; + + String goodValues[] = { + Integer.toString(maxValue), + Integer.toString(maxValue - 1), + Integer.toString(maxValue / 2), + "0", "1" + }; + + // option under test + DynamicVMOption option = new DynamicVMOption("MinHeapFreeRatio"); + + assertTrue(option.isWriteable(), "Option " + option.name + + " is expected to be writable"); + + for (String v : badValues) { + assertFalse(option.isValidValue(v), + "'" + v + "' is expected to be illegal for flag " + option.name); + } + + for (String v : goodValues) { + option.setValue(v); + String newValue = option.getValue(); + assertEQ(v, newValue); + } } } diff --git a/hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java b/hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java index 14755075d3b..944efcc3956 100644 --- a/hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java +++ b/hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java @@ -28,8 +28,7 @@ * @library /testlibrary * @run main/othervm -XX:+UseAdaptiveSizePolicyWithSystemGC -XX:+UseParallelGC -XX:MinHeapFreeRatio=0 -XX:MaxHeapFreeRatio=100 -verbose:gc TestDynShrinkHeap */ - -import com.oracle.java.testlibrary.TestDynamicVMOption; +import com.oracle.java.testlibrary.DynamicVMOption; import java.lang.management.ManagementFactory; import java.lang.management.MemoryUsage; import java.util.ArrayList; @@ -44,12 +43,7 @@ public class TestDynShrinkHeap { private static ArrayList<byte[]> list = new ArrayList<>(0); private static final int M = 1024 * 1024; // to make heap more manageable by test code - private final TestDynamicVMOption maxRatioOption; - private final TestDynamicVMOption minRatioOption; - public TestDynShrinkHeap() { - minRatioOption = new TestDynamicVMOption(MIN_FREE_RATIO_FLAG_NAME); - maxRatioOption = new TestDynamicVMOption(MAX_FREE_RATIO_FLAG_NAME); } private final void test() { @@ -86,7 +80,8 @@ public class TestDynShrinkHeap { } private void free() { - maxRatioOption.setIntValue(minRatioOption.getIntValue() + 1); + int min = DynamicVMOption.getInt(MIN_FREE_RATIO_FLAG_NAME); + DynamicVMOption.setInt(MAX_FREE_RATIO_FLAG_NAME, min); System.gc(); MemoryUsagePrinter.printMemoryUsage("under pressure"); } diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOption.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOption.java new file mode 100644 index 00000000000..49671ef54fa --- /dev/null +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOption.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 com.oracle.java.testlibrary; + +import com.sun.management.HotSpotDiagnosticMXBean; +import java.lang.management.ManagementFactory; + +/** + * A utility class to work with VM options which could be altered during + * execution. + * + * This class is a wrapper around {@code com.sun.management.VMOption}. + * It provides more convenient interface to read/write the values. + * + */ +public class DynamicVMOption { + + private final HotSpotDiagnosticMXBean mxBean; + + /** + * VM option name, like "MinHeapFreeRatio". + */ + public final String name; + + /** + * Creates an instance of DynamicVMOption. + * + * @param name the VM option name + */ + public DynamicVMOption(String name) { + this.name = name; + mxBean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); + } + + /** + * Sets a new value for the option. + * Trying to set not applicable value will cause IllegalArgumentException. + * Behavior with null is undefined, most likely NPE will be thrown. + * + * @param newValue the value to be set + * @see #getValue() + * @throws IllegalArgumentException if newValue is not applicable to the option + */ + public final void setValue(String newValue) { + mxBean.setVMOption(name, newValue); + } + + /** + * Returns the value of option. + * + * @return the current option value + * @see #setValue(java.lang.String) + */ + public final String getValue() { + return mxBean.getVMOption(name).getValue(); + } + + /** + * Returns true, if option is writable, false otherwise. + * + * @return true, if option is writable, false otherwise + */ + public final boolean isWriteable() { + return mxBean.getVMOption(name).isWriteable(); + } + + /** + * Checks if the given value is applicable for the option. + * + * This method tries to set the option to the new value. If no exception + * has been thrown the value is treated as valid. + * + * Calling this method will not change the option value. After an attempt + * to set a new value, the option will be restored to its previous value. + * + * @param value the value to verify + * @return true if option could be set to the given value + */ + public boolean isValidValue(String value) { + boolean isValid = true; + String oldValue = getValue(); + try { + setValue(value); + } catch (NullPointerException e) { + if (value == null) { + isValid = false; + } + } catch (IllegalArgumentException e) { + isValid = false; + } finally { + setValue(oldValue); + } + return isValid; + } + + /** + * Returns the value of the given VM option as String. + * + * This is a simple shortcut for {@code new DynamicVMOption(name).getValue()} + * + * @param name the name of VM option + * @return value as a string + * @see #getValue() + */ + public static String getString(String name) { + return new DynamicVMOption(name).getValue(); + } + + /** + * Returns the value of the given option as int. + * + * @param name the name of VM option + * @return value parsed as integer + * @see #getString(java.lang.String) + * + */ + public static int getInt(String name) { + return Integer.parseInt(getString(name)); + } + + /** + * Sets the VM option to a new value. + * + * This is a simple shortcut for {@code new DynamicVMOption(name).setValue(value)} + * + * @param name the name of VM option + * @param value the value to be set + * @see #setValue(java.lang.String) + */ + public static void setString(String name, String value) { + new DynamicVMOption(name).setValue(value); + } + + /** + * Sets the VM option value to a new integer value. + * + * @param name the name of VM option + * @param value the integer value to be set + * @see #setString(java.lang.String, java.lang.String) + */ + public static void setInt(String name, int value) { + new DynamicVMOption(name).setValue(Integer.toString(value)); + } + +} diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOptionChecker.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOptionChecker.java deleted file mode 100644 index baa717d46aa..00000000000 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOptionChecker.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * 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 com.oracle.java.testlibrary; - -import com.sun.management.HotSpotDiagnosticMXBean; -import com.sun.management.VMOption; -import java.lang.management.ManagementFactory; - -/** - * Simple class to check writeability, invalid and valid values for VMOption - */ -public class DynamicVMOptionChecker { - - /** - * Reads VM option from PlatformMXBean and parse it to integer value - * - * @param name of option - * @return parsed value - */ - public static int getIntValue(String name) { - - VMOption option = ManagementFactory. - getPlatformMXBean(HotSpotDiagnosticMXBean.class). - getVMOption(name); - - return Integer.parseInt(option.getValue()); - } - - /** - * Sets VM option value - * - * @param name of option - * @param value to set - */ - public static void setIntValue(String name, int value) { - ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class).setVMOption(name, Integer.toString(value)); - } - - /** - * Checks that VM option is dynamically writable - * - * @param name - * @throws RuntimeException if option if not writable - * @return always true - */ - public static boolean checkIsWritable(String name) { - VMOption option = ManagementFactory. - getPlatformMXBean(HotSpotDiagnosticMXBean.class). - getVMOption(name); - - if (!option.isWriteable()) { - throw new RuntimeException(name + " is not writable"); - } - - return true; - } - - /** - * Checks that value cannot be set - * - * @param name of flag - * @param value string representation of value to set - * @throws RuntimeException on error - when expected exception hasn't been thrown - */ - public static void checkInvalidValue(String name, String value) { - // should throw - try { - ManagementFactory. - getPlatformMXBean(HotSpotDiagnosticMXBean.class). - setVMOption(name, value); - - } catch (IllegalArgumentException e) { - return; - } - - throw new RuntimeException("Expected IllegalArgumentException was not thrown, " + name + "= " + value); - } - - /** - * Checks that value can be set - * - * @param name of flag to set - * @param value string representation of value to set - * @throws RuntimeException on error - when value in VM is not equal to origin - */ - public static void checkValidValue(String name, String value) { - ManagementFactory. - getPlatformMXBean(HotSpotDiagnosticMXBean.class). - setVMOption(name, value); - - VMOption option = ManagementFactory. - getPlatformMXBean(HotSpotDiagnosticMXBean.class). - getVMOption(name); - - if (!option.getValue().equals(value)) { - throw new RuntimeException("Actual value of " + name + " \"" + option.getValue() - + "\" not equal origin \"" + value + "\""); - } - } - -} diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/TestDynamicVMOption.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/TestDynamicVMOption.java deleted file mode 100644 index 2c164596924..00000000000 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/TestDynamicVMOption.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * 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 com.oracle.java.testlibrary; - -/** - * Simple class to check writeability, invalid and valid values for concrete VMOption - */ -public class TestDynamicVMOption { - - private final String name; - private final int value; - - /** - * Constructor - * - * @param name of VM option to test - */ - public TestDynamicVMOption(String name) { - this.name = name; - this.value = DynamicVMOptionChecker.getIntValue(name); - System.out.println(this.name + " = " + this.value); - } - - /** - * Checks that this value can accept valid percentage values and cannot accept invalid percentage values - * - * @throws RuntimeException - */ - public void testPercentageValues() { - checkInvalidValue(Integer.toString(Integer.MIN_VALUE)); - checkInvalidValue(Integer.toString(Integer.MAX_VALUE)); - checkInvalidValue("-10"); - checkInvalidValue("190"); - } - - /** - * Reads VM option from PlatformMXBean and parse it to integer value - * - * @return value - */ - public int getIntValue() { - return DynamicVMOptionChecker.getIntValue(this.name); - } - - /** - * Sets VM option value - * - * @param value to set - */ - public void setIntValue(int value) { - DynamicVMOptionChecker.setIntValue(this.name, value); - } - - /** - * Checks that this VM option is dynamically writable - * - * @throws RuntimeException if option if not writable - * @return true - */ - public boolean checkIsWritable() throws RuntimeException { - return DynamicVMOptionChecker.checkIsWritable(this.name); - } - - /** - * Checks that value for this VM option cannot be set - * - * @param value to check - * @throws RuntimeException on error - when expected exception hasn't been thrown - */ - public void checkInvalidValue(String value) { - DynamicVMOptionChecker.checkInvalidValue(this.name, value); - } - - /** - * Checks that value for this VM option can be set - * - * @param value to check - * @throws RuntimeException on error - when value in VM is not equal to origin - */ - public void checkValidValue(String value) { - DynamicVMOptionChecker.checkValidValue(this.name, value); - } - -} From 7f721c111bc24eb6d3a2a682fb46fc59c67f64b4 Mon Sep 17 00:00:00 2001 From: Staffan Larsen <sla@openjdk.org> Date: Tue, 20 May 2014 20:35:39 +0200 Subject: [PATCH 109/157] 8043314: Fix for JDK-8041934 causes assert(is_interpreted_frame()) failed: interpreted frame expected Back out fix for JDK-8041934 Reviewed-by: coleenp, sspitsyn --- .../src/cpu/sparc/vm/sharedRuntime_sparc.cpp | 24 ------------------ .../src/cpu/x86/vm/sharedRuntime_x86_32.cpp | 24 ------------------ .../src/cpu/x86/vm/sharedRuntime_x86_64.cpp | 25 ------------------- .../src/share/vm/runtime/sharedRuntime.cpp | 6 ----- .../src/share/vm/runtime/sharedRuntime.hpp | 3 --- 5 files changed, 82 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp index 19a071cd213..b3c706dbef4 100644 --- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp @@ -2657,30 +2657,6 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, __ bind(done); } - { - // Normally we do not post method_entry and method_exit events from - // compiled code, only from the interpreter. If method_entry/exit - // events are switched on at runtime, we will deoptimize everything - // (see VM_EnterInterpOnlyMode) on the stack and call method_entry/exit - // from the interpreter. But when we do that, we will not deoptimize - // this native wrapper frame. Thus we have an extra check here to see - // if we are now in interp_only_mode and in that case we do the jvmti - // callback. - Label skip_jvmti_method_exit; - __ ld(G2_thread, JavaThread::interp_only_mode_offset(), G3_scratch); - __ cmp_and_br_short(G3_scratch, 0, Assembler::zero, Assembler::pt, skip_jvmti_method_exit); - - save_native_result(masm, ret_type, stack_slots); - __ set_metadata_constant(method(), G3_scratch); - __ call_VM( - noreg, - CAST_FROM_FN_PTR(address, SharedRuntime::jvmti_method_exit), - G2_thread, G3_scratch, - true); - restore_native_result(masm, ret_type, stack_slots); - __ bind(skip_jvmti_method_exit); - } - // Tell dtrace about this method exit { SkipIfEqual skip_if( diff --git a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp index 95668394111..c97b4309782 100644 --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp @@ -2238,30 +2238,6 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, } - { - // Normally we do not post method_entry and method_exit events from - // compiled code, only from the interpreter. If method_entry/exit - // events are switched on at runtime, we will deoptimize everything - // (see VM_EnterInterpOnlyMode) on the stack and call method_entry/exit - // from the interpreter. But when we do that, we will not deoptimize - // this native wrapper frame. Thus we have an extra check here to see - // if we are now in interp_only_mode and in that case we do the jvmti - // callback. - Label skip_jvmti_method_exit; - __ cmpl(Address(thread, JavaThread::interp_only_mode_offset()), 0); - __ jcc(Assembler::zero, skip_jvmti_method_exit, true); - - save_native_result(masm, ret_type, stack_slots); - __ mov_metadata(rax, method()); - __ call_VM( - noreg, - CAST_FROM_FN_PTR(address, SharedRuntime::jvmti_method_exit), - thread, rax, - true); - restore_native_result(masm, ret_type, stack_slots); - __ bind(skip_jvmti_method_exit); - } - { SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0); // Tell dtrace about this method exit diff --git a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp index 1a9a18754f9..be2bfcfa02d 100644 --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp @@ -2484,31 +2484,6 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, __ bind(done); } - - { - // Normally we do not post method_entry and method_exit events from - // compiled code, only from the interpreter. If method_entry/exit - // events are switched on at runtime, we will deoptimize everything - // (see VM_EnterInterpOnlyMode) on the stack and call method_entry/exit - // from the interpreter. But when we do that, we will not deoptimize - // this native wrapper frame. Thus we have an extra check here to see - // if we are now in interp_only_mode and in that case we do the jvmti - // callback. - Label skip_jvmti_method_exit; - __ cmpl(Address(r15_thread, JavaThread::interp_only_mode_offset()), 0); - __ jcc(Assembler::zero, skip_jvmti_method_exit, true); - - save_native_result(masm, ret_type, stack_slots); - __ mov_metadata(c_rarg1, method()); - __ call_VM( - noreg, - CAST_FROM_FN_PTR(address, SharedRuntime::jvmti_method_exit), - r15_thread, c_rarg1, - true); - restore_native_result(masm, ret_type, stack_slots); - __ bind(skip_jvmti_method_exit); - } - { SkipIfEqual skip(masm, &DTraceMethodProbes, false); save_native_result(masm, ret_type, stack_slots); diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index d4691c35a2e..fad31fd02f1 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -993,12 +993,6 @@ JRT_LEAF(int, SharedRuntime::dtrace_method_exit( return 0; JRT_END -JRT_ENTRY(int, SharedRuntime::jvmti_method_exit( - JavaThread* thread, Method* method)) - JvmtiExport::post_method_exit(thread, method, thread->last_frame()); - return 0; -JRT_END - // Finds receiver, CallInfo (i.e. receiver method), and calling bytecode) // for a call current in progress, i.e., arguments has been pushed on stack diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.hpp b/hotspot/src/share/vm/runtime/sharedRuntime.hpp index 19bb5600372..c28c469d0e8 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp @@ -263,9 +263,6 @@ class SharedRuntime: AllStatic { static int dtrace_method_entry(JavaThread* thread, Method* m); static int dtrace_method_exit(JavaThread* thread, Method* m); - // jvmti notification - static int jvmti_method_exit(JavaThread* thread, Method* m); - // Utility method for retrieving the Java thread id, returns 0 if the // thread is not a well formed Java thread. static jlong get_java_tid(Thread* thread); From 24c1439f3635133d01ed3c948ae97170a0c1b5f5 Mon Sep 17 00:00:00 2001 From: Alexander Zuev <kizune@openjdk.org> Date: Tue, 20 May 2014 23:17:01 +0400 Subject: [PATCH 110/157] 8037398: integer overflow in jdk/src/share/bin/java.c Reviewed-by: ksrini --- jdk/src/share/bin/java.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/bin/java.c b/jdk/src/share/bin/java.c index 79912d52d0a..1db708c90d8 100644 --- a/jdk/src/share/bin/java.c +++ b/jdk/src/share/bin/java.c @@ -739,6 +739,9 @@ SetClassPath(const char *s) if (s == NULL) return; s = JLI_WildcardExpandClasspath(s); + if (sizeof(format) - 2 + JLI_StrLen(s) < JLI_StrLen(s)) + // s is became corrupted after expanding wildcards + return; def = JLI_MemAlloc(sizeof(format) - 2 /* strlen("%s") */ + JLI_StrLen(s)); @@ -1358,9 +1361,11 @@ AddApplicationOptions(int cpathc, const char **cpathv) if (s) { s = (char *) JLI_WildcardExpandClasspath(s); /* 40 for -Denv.class.path= */ - envcp = (char *)JLI_MemAlloc(JLI_StrLen(s) + 40); - sprintf(envcp, "-Denv.class.path=%s", s); - AddOption(envcp, NULL); + if (JLI_StrLen(s) + 40 > JLI_StrLen(s)) { // Safeguard from overflow + envcp = (char *)JLI_MemAlloc(JLI_StrLen(s) + 40); + sprintf(envcp, "-Denv.class.path=%s", s); + AddOption(envcp, NULL); + } } } From ac4c2fe57a577f2ebeed9909fa1f34b9f8873d91 Mon Sep 17 00:00:00 2001 From: Neil Toda <ntoda@openjdk.org> Date: Tue, 20 May 2014 15:50:17 -0700 Subject: [PATCH 111/157] 8042406: javac.jvm.ClassReader.readClassFile() is using Target to verify valid major versions Reviewed-by: jjg --- .../classes/com/sun/tools/javac/jvm/ClassFile.java | 12 +++++++++++- .../classes/com/sun/tools/javac/jvm/ClassReader.java | 10 +++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java index e1ff3ac274e..60f12fc4784 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,11 +108,21 @@ public class ClassFile { V50(50, 0), // JDK 1.6: stackmaps V51(51, 0), // JDK 1.7 V52(52, 0); // JDK 1.8: lambda, type annos, param names + // JDK9 still marked as V52 // V53(53, 0); // JDK 1.9 + Version(int major, int minor) { this.major = major; this.minor = minor; } public final int major, minor; + + private static final Version MIN = values()[0]; + /** Return the least version supported, MIN */ + public static Version MIN() { return MIN; } + + private static final Version MAX = values()[values().length-1]; + /** Return the largest version supported, MAX */ + public static Version MAX() { return MAX; } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index 311857f521c..0a585735ba7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -2012,8 +2012,8 @@ public class ClassReader { Type type = readType(nextChar()); if (currentOwner.isInterface() && (flags & ABSTRACT) == 0 && !name.equals(names.clinit)) { - if (majorVersion > Target.JDK1_8.majorVersion || - (majorVersion == Target.JDK1_8.majorVersion && minorVersion >= Target.JDK1_8.minorVersion)) { + if (majorVersion > Version.V52.major || + (majorVersion == Version.V52.major && minorVersion >= Version.V52.minor)) { if ((flags & STATIC) == 0) { currentOwner.flags_field |= DEFAULT; flags |= DEFAULT | ABSTRACT; @@ -2294,11 +2294,11 @@ public class ClassReader { minorVersion = nextChar(); majorVersion = nextChar(); - int maxMajor = Target.MAX().majorVersion; - int maxMinor = Target.MAX().minorVersion; + int maxMajor = Version.MAX().major; + int maxMinor = Version.MAX().minor; if (majorVersion > maxMajor || majorVersion * 1000 + minorVersion < - Target.MIN().majorVersion * 1000 + Target.MIN().minorVersion) + Version.MIN().major * 1000 + Version.MIN().minor) { if (majorVersion == (maxMajor + 1)) log.warning("big.major.version", From 9e710c30f7cdbc0dda5414d614b3599ee47525ea Mon Sep 17 00:00:00 2001 From: Staffan Larsen <sla@openjdk.org> Date: Wed, 21 May 2014 10:22:20 +0200 Subject: [PATCH 112/157] 8043551: [TESTBUG] sun/tools/jcmd/TestJcmdSanity.java failure in nightly jdk9-dev fastdebug build Add -XX:+UsePerfData to the test Reviewed-by: dholmes --- jdk/test/sun/tools/jcmd/TestJcmdSanity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/sun/tools/jcmd/TestJcmdSanity.java b/jdk/test/sun/tools/jcmd/TestJcmdSanity.java index d32fb18d2c1..89152216010 100644 --- a/jdk/test/sun/tools/jcmd/TestJcmdSanity.java +++ b/jdk/test/sun/tools/jcmd/TestJcmdSanity.java @@ -41,7 +41,7 @@ import jdk.testlibrary.Utils; * @bug 7104647 7154822 * @library /lib/testlibrary * @build jdk.testlibrary.* - * @run main TestJcmdSanity + * @run main/othervm -XX:+UsePerfData TestJcmdSanity */ public class TestJcmdSanity { From 53cb60f14886b23564ff030504316ebaa8eadc16 Mon Sep 17 00:00:00 2001 From: Weijun Wang <weijun@openjdk.org> Date: Thu, 22 May 2014 07:04:57 +0800 Subject: [PATCH 113/157] 8043537: Changes for JDK-8039951 introduced circular dependency between Kerberos and com.sun.security.auth Reviewed-by: alanb --- jdk/make/mapfiles/libjava/mapfile-vers | 5 ++- jdk/src/share/classes/sun/misc/VM.java | 32 ++++++++++++++++++- .../krb5/internal/rcache/DflCache.java | 14 ++------ jdk/src/solaris/native/sun/misc/VM_md.c | 28 ++++++++++++---- jdk/src/windows/native/sun/misc/VM_md.c | 29 ++++++++++++++--- .../krb5/auto/ReplayCacheTestProc.java | 9 +----- 6 files changed, 85 insertions(+), 32 deletions(-) diff --git a/jdk/make/mapfiles/libjava/mapfile-vers b/jdk/make/mapfiles/libjava/mapfile-vers index aeb1588e70d..ca99cc5c03b 100644 --- a/jdk/make/mapfiles/libjava/mapfile-vers +++ b/jdk/make/mapfiles/libjava/mapfile-vers @@ -270,7 +270,10 @@ SUNWprivate_1.1 { Java_sun_misc_Version_getJvmVersionInfo; Java_sun_misc_Version_getJvmSpecialVersion; Java_sun_misc_VM_latestUserDefinedLoader; - Java_sun_misc_VM_isSetUID; + Java_sun_misc_VM_getuid; + Java_sun_misc_VM_geteuid; + Java_sun_misc_VM_getgid; + Java_sun_misc_VM_getegid; Java_sun_misc_VM_initialize; Java_sun_misc_VMSupport_initAgentProperties; Java_sun_misc_VMSupport_getVMTemporaryDirectory; diff --git a/jdk/src/share/classes/sun/misc/VM.java b/jdk/src/share/classes/sun/misc/VM.java index 5c5a3e83641..9ddff0e2f87 100644 --- a/jdk/src/share/classes/sun/misc/VM.java +++ b/jdk/src/share/classes/sun/misc/VM.java @@ -370,7 +370,37 @@ public class VM { /** * Returns {@code true} if we are in a set UID program. */ - public static native boolean isSetUID(); + public static boolean isSetUID() { + long uid = getuid(); + long euid = geteuid(); + long gid = getgid(); + long egid = getegid(); + return uid != euid || gid != egid; + } + + /** + * Returns the real user ID of the calling process, + * or -1 if the value is not available. + */ + public static native long getuid(); + + /** + * Returns the effective user ID of the calling process, + * or -1 if the value is not available. + */ + public static native long geteuid(); + + /** + * Returns the real group ID of the calling process, + * or -1 if the value is not available. + */ + public static native long getgid(); + + /** + * Returns the effective group ID of the calling process, + * or -1 if the value is not available. + */ + public static native long getegid(); static { initialize(); diff --git a/jdk/src/share/classes/sun/security/krb5/internal/rcache/DflCache.java b/jdk/src/share/classes/sun/security/krb5/internal/rcache/DflCache.java index 4756ce7f064..cbae7026cec 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/rcache/DflCache.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/rcache/DflCache.java @@ -39,7 +39,6 @@ import java.nio.file.attribute.PosixFilePermission; import java.security.AccessController; import java.util.*; -import com.sun.security.auth.module.UnixSystem; import sun.security.action.GetPropertyAction; import sun.security.krb5.internal.KerberosTime; import sun.security.krb5.internal.Krb5; @@ -61,8 +60,7 @@ import sun.security.krb5.internal.ReplayCache; * * service_euid * - * Java does not have a method to get euid, so uid is used instead. This - * should normally to be since a Java program is seldom used as a setuid app. + * in which euid is available as sun.misc.VM.geteuid(). * * The file has a header: * @@ -108,14 +106,8 @@ public class DflCache extends ReplayCache { private static long uid; static { - try { - // Available on Solaris, Linux and Mac. Otherwise, no _euid suffix - UnixSystem us = new com.sun.security.auth.module.UnixSystem(); - uid = us.getUid(); - } catch (Throwable e) { - // Cannot be only Exception, might be UnsatisfiedLinkError - uid = -1; - } + // Available on Solaris, Linux and Mac. Otherwise, -1 and no _euid suffix + uid = sun.misc.VM.geteuid(); } public DflCache (String source) { diff --git a/jdk/src/solaris/native/sun/misc/VM_md.c b/jdk/src/solaris/native/sun/misc/VM_md.c index 7fe336274a4..48a8e4a954b 100644 --- a/jdk/src/solaris/native/sun/misc/VM_md.c +++ b/jdk/src/solaris/native/sun/misc/VM_md.c @@ -27,12 +27,26 @@ #include "jni_util.h" -JNIEXPORT jboolean JNICALL -Java_sun_misc_VM_isSetUID(JNIEnv *env, jclass thisclass) { +JNIEXPORT jlong JNICALL +Java_sun_misc_VM_getuid(JNIEnv *env, jclass thisclass) { - /* Return true if we are in a set UID or set GID process. */ - if (getuid() != geteuid() || getgid() != getegid()) { - return JNI_TRUE; - } - return JNI_FALSE; + return getuid(); +} + +JNIEXPORT jlong JNICALL +Java_sun_misc_VM_geteuid(JNIEnv *env, jclass thisclass) { + + return geteuid(); +} + +JNIEXPORT jlong JNICALL +Java_sun_misc_VM_getgid(JNIEnv *env, jclass thisclass) { + + return getgid(); +} + +JNIEXPORT jlong JNICALL +Java_sun_misc_VM_getegid(JNIEnv *env, jclass thisclass) { + + return getegid(); } diff --git a/jdk/src/windows/native/sun/misc/VM_md.c b/jdk/src/windows/native/sun/misc/VM_md.c index 165ad2713ea..2b13ffc4f37 100644 --- a/jdk/src/windows/native/sun/misc/VM_md.c +++ b/jdk/src/windows/native/sun/misc/VM_md.c @@ -26,9 +26,30 @@ #include "jni_util.h" -JNIEXPORT jboolean JNICALL -Java_sun_misc_VM_isSetUID(JNIEnv *env, jclass thisclass) { +JNIEXPORT jlong JNICALL +Java_sun_misc_VM_getuid(JNIEnv *env, jclass thisclass) { - /* There is no set UID on Windows. */ - return JNI_FALSE; + /* -1 means function not available. */ + return -1; +} + +JNIEXPORT jlong JNICALL +Java_sun_misc_VM_geteuid(JNIEnv *env, jclass thisclass) { + + /* -1 means function not available. */ + return -1; +} + +JNIEXPORT jlong JNICALL +Java_sun_misc_VM_getgid(JNIEnv *env, jclass thisclass) { + + /* -1 means function not available. */ + return -1; +} + +JNIEXPORT jlong JNICALL +Java_sun_misc_VM_getegid(JNIEnv *env, jclass thisclass) { + + /* -1 means function not available. */ + return -1; } diff --git a/jdk/test/sun/security/krb5/auto/ReplayCacheTestProc.java b/jdk/test/sun/security/krb5/auto/ReplayCacheTestProc.java index 1e69486fba7..5275b69b594 100644 --- a/jdk/test/sun/security/krb5/auto/ReplayCacheTestProc.java +++ b/jdk/test/sun/security/krb5/auto/ReplayCacheTestProc.java @@ -40,7 +40,6 @@ import java.nio.file.StandardOpenOption; import java.security.MessageDigest; import java.util.*; -import com.sun.security.auth.module.UnixSystem; import sun.security.jgss.GSSUtil; import sun.security.krb5.internal.APReq; import sun.security.krb5.internal.rcache.AuthTime; @@ -79,13 +78,7 @@ public class ReplayCacheTestProc { mode = -1; } - try { - UnixSystem us = new com.sun.security.auth.module.UnixSystem(); - uid = us.getUid(); - } catch (Throwable e) { - // Cannot be only Exception, might be UnsatisfiedLinkError - uid = -1; - } + uid = sun.misc.VM.geteuid(); KDC kdc = KDC.create(OneKDC.REALM, HOST, 0, true); for (int i=0; i<nu; i++) { From 393ceefdc7e9c1df2bd6c9d336479ecfacf81462 Mon Sep 17 00:00:00 2001 From: Valerie Peng <valeriep@openjdk.org> Date: Wed, 21 May 2014 23:30:17 +0000 Subject: [PATCH 114/157] 8037745: Consider re-enabling PKCS11 mechanisms previously disabled due to Solaris bug 7050617 Remove digest mechanisms from the disabled mechanisms section Reviewed-by: ascarpino, wetmore --- jdk/src/share/lib/security/sunpkcs11-solaris.cfg | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/jdk/src/share/lib/security/sunpkcs11-solaris.cfg b/jdk/src/share/lib/security/sunpkcs11-solaris.cfg index a2233d8cef1..74096efea5f 100644 --- a/jdk/src/share/lib/security/sunpkcs11-solaris.cfg +++ b/jdk/src/share/lib/security/sunpkcs11-solaris.cfg @@ -18,16 +18,6 @@ attributes = compatibility disabledMechanisms = { CKM_DSA_KEY_PAIR_GEN -# the following mechanisms are disabled due to CKR_SAVED_STATE_INVALID bug -# (Solaris bug 7058108) - CKM_MD2 - CKM_MD5 - CKM_SHA_1 -# the following mechanisms are disabled due to no cloning support -# (Solaris bug 7050617) - CKM_SHA256 - CKM_SHA384 - CKM_SHA512 # the following mechanisms are disabled due to performance issues # (Solaris bug 6337157) CKM_DSA_SHA1 From c05f339b0ccc96ea1bcb0c3590c700f5807f397d Mon Sep 17 00:00:00 2001 From: Masayoshi Okutsu <okutsu@openjdk.org> Date: Thu, 22 May 2014 13:21:47 +0900 Subject: [PATCH 115/157] 8032650: [parfait] warning from b124 for jdk/src/share/native/java/util: jni exception pending Reviewed-by: naoto --- jdk/src/share/classes/java/util/TimeZone.java | 9 ++--- jdk/src/share/native/java/util/TimeZone.c | 34 +++++------------ .../solaris/native/java/util/TimeZone_md.c | 4 +- .../solaris/native/java/util/TimeZone_md.h | 4 +- .../windows/native/java/util/TimeZone_md.c | 38 +++++++------------ .../windows/native/java/util/TimeZone_md.h | 4 +- 6 files changed, 32 insertions(+), 61 deletions(-) diff --git a/jdk/src/share/classes/java/util/TimeZone.java b/jdk/src/share/classes/java/util/TimeZone.java index 96497939fad..356f33be3e1 100644 --- a/jdk/src/share/classes/java/util/TimeZone.java +++ b/jdk/src/share/classes/java/util/TimeZone.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -591,8 +591,7 @@ abstract public class TimeZone implements Serializable, Cloneable { /** * Gets the platform defined TimeZone ID. **/ - private static native String getSystemTimeZoneID(String javaHome, - String country); + private static native String getSystemTimeZoneID(String javaHome); /** * Gets the custom time zone ID based on the GMT offset of the @@ -650,12 +649,10 @@ abstract public class TimeZone implements Serializable, Cloneable { // if the time zone ID is not set (yet), perform the // platform to Java time zone ID mapping. if (zoneID == null || zoneID.isEmpty()) { - String country = AccessController.doPrivileged( - new GetPropertyAction("user.country")); String javaHome = AccessController.doPrivileged( new GetPropertyAction("java.home")); try { - zoneID = getSystemTimeZoneID(javaHome, country); + zoneID = getSystemTimeZoneID(javaHome); if (zoneID == null) { zoneID = GMT_ID; } diff --git a/jdk/src/share/native/java/util/TimeZone.c b/jdk/src/share/native/java/util/TimeZone.c index d061b334a84..95e4e0a5425 100644 --- a/jdk/src/share/native/java/util/TimeZone.c +++ b/jdk/src/share/native/java/util/TimeZone.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,42 +38,28 @@ */ JNIEXPORT jstring JNICALL Java_java_util_TimeZone_getSystemTimeZoneID(JNIEnv *env, jclass ign, - jstring java_home, jstring country) + jstring java_home) { - const char *cname; const char *java_home_dir; char *javaTZ; + jstring jstrJavaTZ = NULL; - if (java_home == NULL) - return NULL; + CHECK_NULL_RETURN(java_home, NULL); java_home_dir = JNU_GetStringPlatformChars(env, java_home, 0); - if (java_home_dir == NULL) - return NULL; - - if (country != NULL) { - cname = JNU_GetStringPlatformChars(env, country, 0); - /* ignore error cases for cname */ - } else { - cname = NULL; - } + CHECK_NULL_RETURN(java_home_dir, NULL); /* * Invoke platform dependent mapping function */ - javaTZ = findJavaTZ_md(java_home_dir, cname); - - free((void *)java_home_dir); - if (cname != NULL) { - free((void *)cname); - } - + javaTZ = findJavaTZ_md(java_home_dir); if (javaTZ != NULL) { - jstring jstrJavaTZ = JNU_NewStringPlatform(env, javaTZ); + jstrJavaTZ = JNU_NewStringPlatform(env, javaTZ); free((void *)javaTZ); - return jstrJavaTZ; } - return NULL; + + JNU_ReleaseStringPlatformChars(env, java_home, java_home_dir); + return jstrJavaTZ; } /* diff --git a/jdk/src/solaris/native/java/util/TimeZone_md.c b/jdk/src/solaris/native/java/util/TimeZone_md.c index c90fcee25ba..76c3f394b2d 100644 --- a/jdk/src/solaris/native/java/util/TimeZone_md.c +++ b/jdk/src/solaris/native/java/util/TimeZone_md.c @@ -652,11 +652,11 @@ static char *mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz * using <java_home>/lib/tzmappings. If the TZ value is not found, it * trys some libc implementation dependent mappings. If it still * can't map to a Java time zone ID, it falls back to the GMT+/-hh:mm - * form. `country', which can be null, is not used for UNIX platforms. + * form. */ /*ARGSUSED1*/ char * -findJavaTZ_md(const char *java_home_dir, const char *country) +findJavaTZ_md(const char *java_home_dir) { char *tz; char *javatz = NULL; diff --git a/jdk/src/solaris/native/java/util/TimeZone_md.h b/jdk/src/solaris/native/java/util/TimeZone_md.h index 9d20bcaf95b..99e01920f2a 100644 --- a/jdk/src/solaris/native/java/util/TimeZone_md.h +++ b/jdk/src/solaris/native/java/util/TimeZone_md.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #ifndef _TIMEZONE_MD_H #define _TIMEZONE_MD_H -char *findJavaTZ_md(const char *java_home_dir, const char *region); +char *findJavaTZ_md(const char *java_home_dir); char *getGMTOffsetID(); #endif diff --git a/jdk/src/windows/native/java/util/TimeZone_md.c b/jdk/src/windows/native/java/util/TimeZone_md.c index 57d4b526ba6..7cb23e098a6 100644 --- a/jdk/src/windows/native/java/util/TimeZone_md.c +++ b/jdk/src/windows/native/java/util/TimeZone_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -394,31 +394,34 @@ static int getWinTimeZone(char *winZoneName, char *winMapID) * * value_type is one of the following values: * VALUE_KEY for exact key matching - * VALUE_MAPID for MapID and country-based mapping (this is + * VALUE_MAPID for MapID (this is * required for the old Windows, such as NT 4.0 SP3). */ static char *matchJavaTZ(const char *java_home_dir, int value_type, char *tzName, - char *mapID, const char *country) + char *mapID) { int line; int IDmatched = 0; FILE *fp; char *javaTZName = NULL; char *items[TZ_NITEMS]; - char mapFileName[_MAX_PATH + 1]; + char *mapFileName; char lineBuffer[MAX_ZONE_CHAR * 4]; - char bestMatch[MAX_ZONE_CHAR]; - int noMapID = *mapID == '\0'; /* no mapID on Vista */ - - bestMatch[0] = '\0'; + int noMapID = *mapID == '\0'; /* no mapID on Vista and later */ + mapFileName = malloc(strlen(java_home_dir) + strlen(MAPPINGS_FILE) + 1); + if (mapFileName == NULL) { + return NULL; + } strcpy(mapFileName, java_home_dir); strcat(mapFileName, MAPPINGS_FILE); if ((fp = fopen(mapFileName, "r")) == NULL) { jio_fprintf(stderr, "can't open %s.\n", mapFileName); + free((void *) mapFileName); return NULL; } + free((void *) mapFileName); line = 0; while (fgets(lineBuffer, sizeof(lineBuffer), fp) != NULL) { @@ -469,18 +472,6 @@ static char *matchJavaTZ(const char *java_home_dir, int value_type, char *tzName javaTZName = _strdup(items[TZ_JAVA_NAME]); break; } - /* - * Try to find the most likely time zone. - */ - if (*items[TZ_REGION] == '\0') { - strncpy(bestMatch, items[TZ_JAVA_NAME], MAX_ZONE_CHAR); - } else if (country != NULL && strcmp(items[TZ_REGION], country) == 0) { - if (value_type == VALUE_MAPID) { - javaTZName = _strdup(items[TZ_JAVA_NAME]); - break; - } - strncpy(bestMatch, items[TZ_JAVA_NAME], MAX_ZONE_CHAR); - } } else { if (IDmatched == 1) { /* @@ -492,9 +483,6 @@ static char *matchJavaTZ(const char *java_home_dir, int value_type, char *tzName } fclose(fp); - if (javaTZName == NULL && bestMatch[0] != '\0') { - javaTZName = _strdup(bestMatch); - } return javaTZName; illegal_format: @@ -506,7 +494,7 @@ static char *matchJavaTZ(const char *java_home_dir, int value_type, char *tzName /* * Detects the platform time zone which maps to a Java time zone ID. */ -char *findJavaTZ_md(const char *java_home_dir, const char *country) +char *findJavaTZ_md(const char *java_home_dir) { char winZoneName[MAX_ZONE_CHAR]; char winMapID[MAX_MAPID_LENGTH]; @@ -521,7 +509,7 @@ char *findJavaTZ_md(const char *java_home_dir, const char *country) std_timezone = _strdup(winZoneName); } else { std_timezone = matchJavaTZ(java_home_dir, result, - winZoneName, winMapID, country); + winZoneName, winMapID); } } diff --git a/jdk/src/windows/native/java/util/TimeZone_md.h b/jdk/src/windows/native/java/util/TimeZone_md.h index 9d20bcaf95b..99e01920f2a 100644 --- a/jdk/src/windows/native/java/util/TimeZone_md.h +++ b/jdk/src/windows/native/java/util/TimeZone_md.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #ifndef _TIMEZONE_MD_H #define _TIMEZONE_MD_H -char *findJavaTZ_md(const char *java_home_dir, const char *region); +char *findJavaTZ_md(const char *java_home_dir); char *getGMTOffsetID(); #endif From c3d3305c76a73660c970fe517252a4453d0b9c2a Mon Sep 17 00:00:00 2001 From: Katja Kantserova <ykantser@openjdk.org> Date: Thu, 22 May 2014 11:05:36 +0200 Subject: [PATCH 116/157] 8043520: Serviceability tests using @library failing with java.lang.NoClassDefFoundError Reviewed-by: sla, egahlin --- jdk/test/com/sun/jdi/BadHandshakeTest.java | 2 +- jdk/test/com/sun/jdi/ExclusiveBind.java | 3 +-- jdk/test/com/sun/tools/attach/TempDirTest.java | 2 +- .../lang/instrument/DaemonThread/TestDaemonThread.java | 2 +- .../lang/management/MemoryMXBean/ResetPeakMemoryUsage.java | 2 +- jdk/test/sun/management/jdp/JdpDefaultsTest.java | 2 +- jdk/test/sun/management/jdp/JdpOffTest.java | 2 +- jdk/test/sun/management/jdp/JdpSpecificAddressTest.java | 2 +- .../jmxremote/bootstrap/LocalManagementTest.java | 4 +--- .../jmxremote/bootstrap/PasswordFilePermissionTest.java | 6 +----- .../sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh | 6 +----- .../management/jmxremote/bootstrap/RmiRegistrySslTest.java | 5 +---- .../management/jmxremote/bootstrap/RmiSslBootstrapTest.sh | 5 +---- .../jmxremote/bootstrap/SSLConfigFilePermissionTest.java | 7 +------ .../management/jmxremote/startstop/JMXStartStopTest.java | 5 +---- jdk/test/sun/tools/jstat/JStatInterval.java | 3 +-- jdk/test/sun/tools/jstatd/TestJstatdDefaults.java | 2 +- jdk/test/sun/tools/jstatd/TestJstatdExternalRegistry.java | 2 +- jdk/test/sun/tools/jstatd/TestJstatdPort.java | 2 +- jdk/test/sun/tools/jstatd/TestJstatdPortAndServer.java | 2 +- jdk/test/sun/tools/jstatd/TestJstatdServer.java | 2 +- jdk/test/sun/tools/jstatd/TestJstatdUsage.java | 2 +- 22 files changed, 22 insertions(+), 48 deletions(-) diff --git a/jdk/test/com/sun/jdi/BadHandshakeTest.java b/jdk/test/com/sun/jdi/BadHandshakeTest.java index 35afb33567a..7e35ce3fdd6 100644 --- a/jdk/test/com/sun/jdi/BadHandshakeTest.java +++ b/jdk/test/com/sun/jdi/BadHandshakeTest.java @@ -26,7 +26,7 @@ * @summary Check that a bad handshake doesn't cause a debuggee to abort * @library /lib/testlibrary * - * @build VMConnection BadHandshakeTest Exit0 + * @build jdk.testlibrary.* VMConnection BadHandshakeTest Exit0 * @run main BadHandshakeTest * */ diff --git a/jdk/test/com/sun/jdi/ExclusiveBind.java b/jdk/test/com/sun/jdi/ExclusiveBind.java index d53efd8d585..b5ca807d8f9 100644 --- a/jdk/test/com/sun/jdi/ExclusiveBind.java +++ b/jdk/test/com/sun/jdi/ExclusiveBind.java @@ -27,8 +27,7 @@ * at the same time. * @library /lib/testlibrary * - * @build jdk.testlibrary.ProcessTools jdk.testlibrary.JDKToolLauncher jdk.testlibrary.Utils - * @build VMConnection ExclusiveBind HelloWorld + * @build jdk.testlibrary.* VMConnection ExclusiveBind HelloWorld * @run main ExclusiveBind */ import java.net.ServerSocket; diff --git a/jdk/test/com/sun/tools/attach/TempDirTest.java b/jdk/test/com/sun/tools/attach/TempDirTest.java index 9f8fafd2c7e..9f0beb698e2 100644 --- a/jdk/test/com/sun/tools/attach/TempDirTest.java +++ b/jdk/test/com/sun/tools/attach/TempDirTest.java @@ -38,7 +38,7 @@ import jdk.testlibrary.ProcessThread; * @bug 8033104 * @summary Test to make sure attach and jvmstat works correctly when java.io.tmpdir is set * @library /lib/testlibrary - * @run build Application Shutdown RunnerUtil + * @run build jdk.testlibrary.* Application Shutdown RunnerUtil * @run main TempDirTest */ diff --git a/jdk/test/java/lang/instrument/DaemonThread/TestDaemonThread.java b/jdk/test/java/lang/instrument/DaemonThread/TestDaemonThread.java index 20c9077d02f..12246b1a676 100644 --- a/jdk/test/java/lang/instrument/DaemonThread/TestDaemonThread.java +++ b/jdk/test/java/lang/instrument/DaemonThread/TestDaemonThread.java @@ -26,7 +26,7 @@ * @summary Assert in java.lang.instrument agents during shutdown when classloading occurs after shutdown * @library /lib/testlibrary * - * @build DummyAgent DummyClass TestDaemonThreadLauncher TestDaemonThread + * @build jdk.testlibrary.* DummyAgent DummyClass TestDaemonThreadLauncher TestDaemonThread * @run shell ../MakeJAR3.sh DummyAgent * @run main TestDaemonThreadLauncher /timeout=240 * diff --git a/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java b/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java index f15fd2b007d..c0d5ad57e46 100644 --- a/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java +++ b/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java @@ -33,7 +33,7 @@ * @author Mandy Chung * * @library /lib/testlibrary/ - * @build ResetPeakMemoryUsage MemoryUtil RunUtil + * @build jdk.testlibrary.* ResetPeakMemoryUsage MemoryUtil RunUtil * @run main ResetPeakMemoryUsage */ diff --git a/jdk/test/sun/management/jdp/JdpDefaultsTest.java b/jdk/test/sun/management/jdp/JdpDefaultsTest.java index 9067be7cc05..35a145fd330 100644 --- a/jdk/test/sun/management/jdp/JdpDefaultsTest.java +++ b/jdk/test/sun/management/jdp/JdpDefaultsTest.java @@ -28,7 +28,7 @@ * @test JdpDefaultsTest * @summary Assert that we can read JDP packets from a multicast socket connection, on default IP and port. * @library /lib/testlibrary - * @build ClientConnection JdpTestUtil JdpTestCase JdpOnTestCase DynamicLauncher + * @build jdk.testlibrary.* ClientConnection JdpTestUtil JdpTestCase JdpOnTestCase DynamicLauncher * @run main JdpDefaultsTest */ diff --git a/jdk/test/sun/management/jdp/JdpOffTest.java b/jdk/test/sun/management/jdp/JdpOffTest.java index 7810400abbe..15b082e01ef 100644 --- a/jdk/test/sun/management/jdp/JdpOffTest.java +++ b/jdk/test/sun/management/jdp/JdpOffTest.java @@ -29,7 +29,7 @@ * @test JdpOffTest.java * @summary Assert that no JDP packets are sent to the default address and port. * @library /lib/testlibrary - * @build ClientConnection JdpTestUtil JdpTestCase JdpOffTestCase DynamicLauncher + * @build jdk.testlibrary.* ClientConnection JdpTestUtil JdpTestCase JdpOffTestCase DynamicLauncher * @run main JdpOffTest */ diff --git a/jdk/test/sun/management/jdp/JdpSpecificAddressTest.java b/jdk/test/sun/management/jdp/JdpSpecificAddressTest.java index 8a791766d85..0b9d8e02328 100644 --- a/jdk/test/sun/management/jdp/JdpSpecificAddressTest.java +++ b/jdk/test/sun/management/jdp/JdpSpecificAddressTest.java @@ -28,7 +28,7 @@ * @test JdpSpecificAddressTest * @summary Assert that we can read JDP packets from a multicast socket connection, on specific IP and port. * @library /lib/testlibrary - * @build ClientConnection JdpTestUtil JdpTestCase JdpOnTestCase DynamicLauncher + * @build jdk.testlibrary.* ClientConnection JdpTestUtil JdpTestCase JdpOnTestCase DynamicLauncher * @run main JdpSpecificAddressTest */ diff --git a/jdk/test/sun/management/jmxremote/bootstrap/LocalManagementTest.java b/jdk/test/sun/management/jmxremote/bootstrap/LocalManagementTest.java index d02d43e68de..1828d867bfc 100644 --- a/jdk/test/sun/management/jmxremote/bootstrap/LocalManagementTest.java +++ b/jdk/test/sun/management/jmxremote/bootstrap/LocalManagementTest.java @@ -42,9 +42,7 @@ import java.util.concurrent.atomic.AtomicReference; * without connection or username/password details. * TestManager will attempt a connection to the address obtained from * both agent properties and jvmstat buffer. - * @build jdk.testlibrary.ProcessTools - * @build jdk.testlibrary.Utils - * @build TestManager TestApplication + * @build jdk.testlibrary.* TestManager TestApplication * @run main/othervm/timeout=300 -XX:+UsePerfData LocalManagementTest */ diff --git a/jdk/test/sun/management/jmxremote/bootstrap/PasswordFilePermissionTest.java b/jdk/test/sun/management/jmxremote/bootstrap/PasswordFilePermissionTest.java index cce5bc2c8a0..e53cbc9eaaf 100644 --- a/jdk/test/sun/management/jmxremote/bootstrap/PasswordFilePermissionTest.java +++ b/jdk/test/sun/management/jmxremote/bootstrap/PasswordFilePermissionTest.java @@ -28,11 +28,7 @@ import java.io.IOException; * @library /lib/testlibrary * @bug 6557093 * @summary Check SSL config file permission for out-of-the-box management - * @build jdk.testlibrary.Utils - * @build jdk.testlibrary.ProcessTools - * @build jdk.testlibrary.OutputAnalyzer - * @build AbstractFilePermissionTest - * @build Dummy + * @build jdk.testlibrary.* AbstractFilePermissionTest Dummy * @run main/timeout=300 PasswordFilePermissionTest * * @author Taras Ledkov diff --git a/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh b/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh index 50c4262e48b..10835558713 100644 --- a/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh +++ b/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh @@ -27,11 +27,7 @@ # @summary Test RMI Bootstrap # # @library /lib/testlibrary -# @library /lib/testlibrary -# @build jdk.testlibrary.Utils -# @build TestLogger -# @build Utils -# @build RmiBootstrapTest +# @build jdk.testlibrary.* TestLogger Utils RmiBootstrapTest # @run shell/timeout=300 RmiBootstrapTest.sh # Define the Java class test name diff --git a/jdk/test/sun/management/jmxremote/bootstrap/RmiRegistrySslTest.java b/jdk/test/sun/management/jmxremote/bootstrap/RmiRegistrySslTest.java index 3648ca6ad11..eaeaa392936 100644 --- a/jdk/test/sun/management/jmxremote/bootstrap/RmiRegistrySslTest.java +++ b/jdk/test/sun/management/jmxremote/bootstrap/RmiRegistrySslTest.java @@ -42,10 +42,7 @@ import java.util.regex.Pattern; * @library /lib/testlibrary * @bug 6228231 * @summary Test that RMI registry uses SSL. - * @build jdk.testlibrary.Utils - * @build jdk.testlibrary.ProcessTools - * @build jdk.testlibrary.OutputAnalyzer - * @build RmiRegistrySslTestApp + * @build jdk.testlibrary.* RmiRegistrySslTestApp * @run main/timeout=300 RmiRegistrySslTest * @author Luis-Miguel Alventosa, Taras Ledkov */ diff --git a/jdk/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh b/jdk/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh index 7a786a357ad..a74fdd63622 100644 --- a/jdk/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh +++ b/jdk/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh @@ -27,10 +27,7 @@ # @summary Test RMI Bootstrap with SSL # # @library /lib/testlibrary -# @build jdk.testlibrary.Utils -# @build TestLogger -# @build Utils -# @build RmiBootstrapTest +# @build jdk.testlibrary.* TestLogger Utils RmiBootstrapTest # @run shell/timeout=300 RmiSslBootstrapTest.sh # Define the Java class test name diff --git a/jdk/test/sun/management/jmxremote/bootstrap/SSLConfigFilePermissionTest.java b/jdk/test/sun/management/jmxremote/bootstrap/SSLConfigFilePermissionTest.java index 149e9c4ef38..cbe158c0858 100644 --- a/jdk/test/sun/management/jmxremote/bootstrap/SSLConfigFilePermissionTest.java +++ b/jdk/test/sun/management/jmxremote/bootstrap/SSLConfigFilePermissionTest.java @@ -27,12 +27,7 @@ import java.io.IOException; * @test * @library /lib/testlibrary * @bug 6557093 - * @bug 6557093 - * @build jdk.testlibrary.Utils - * @build jdk.testlibrary.ProcessTools - * @build jdk.testlibrary.OutputAnalyzer - * @build Dummy - * @build AbstractFilePermissionTest + * @build jdk.testlibrary.* Dummy AbstractFilePermissionTest * @summary Check SSL config file permission for out-of-the-box management * @run main/timeout=300 SSLConfigFilePermissionTest * diff --git a/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java index c6d539e5465..a1518b9cbe3 100644 --- a/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java +++ b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java @@ -54,10 +54,7 @@ import jdk.testlibrary.JDKToolLauncher; * @test * @bug 7110104 * @library /lib/testlibrary - * @build jdk.testlibrary.ProcessTools - * @build jdk.testlibrary.JDKToolLauncher - * @build jdk.testlibrary.Utils - * @build JMXStartStopTest JMXStartStopDoSomething + * @build jdk.testlibrary.* JMXStartStopTest JMXStartStopDoSomething * @run main/othervm JMXStartStopTest * @summary Makes sure that enabling/disabling the management agent through * JCMD achieves the desired results diff --git a/jdk/test/sun/tools/jstat/JStatInterval.java b/jdk/test/sun/tools/jstat/JStatInterval.java index 0d39df23e10..8c1203be4c8 100644 --- a/jdk/test/sun/tools/jstat/JStatInterval.java +++ b/jdk/test/sun/tools/jstat/JStatInterval.java @@ -28,8 +28,7 @@ * @summary Test checks case when target application finishes execution and jstat didn't complete work. jstat is started with interval = 100 (jstat -compiler 100) and monitored application finishes after 500ms. This shouldn't cause crash or hang in target application or in jstat. - * @build jdk.testlibrary.ProcessTools jdk.testlibrary.JDKToolLauncher - * @build JStatInterval + * @build jdk.testlibrary.* JStatInterval * @run main JStatInterval */ diff --git a/jdk/test/sun/tools/jstatd/TestJstatdDefaults.java b/jdk/test/sun/tools/jstatd/TestJstatdDefaults.java index d68f384c35c..c3973f824e9 100644 --- a/jdk/test/sun/tools/jstatd/TestJstatdDefaults.java +++ b/jdk/test/sun/tools/jstatd/TestJstatdDefaults.java @@ -25,7 +25,7 @@ * @test * @bug 4990825 * @library /lib/testlibrary - * @build JstatdTest JstatGCUtilParser + * @build jdk.testlibrary.* JstatdTest JstatGCUtilParser * @run main/timeout=60 TestJstatdDefaults */ public class TestJstatdDefaults { diff --git a/jdk/test/sun/tools/jstatd/TestJstatdExternalRegistry.java b/jdk/test/sun/tools/jstatd/TestJstatdExternalRegistry.java index da81db13bc9..fdf2e484c46 100644 --- a/jdk/test/sun/tools/jstatd/TestJstatdExternalRegistry.java +++ b/jdk/test/sun/tools/jstatd/TestJstatdExternalRegistry.java @@ -25,7 +25,7 @@ * @test * @bug 4990825 7092186 * @library /lib/testlibrary - * @build JstatdTest JstatGCUtilParser + * @build jdk.testlibrary.* JstatdTest JstatGCUtilParser * @run main/timeout=60 TestJstatdExternalRegistry */ public class TestJstatdExternalRegistry { diff --git a/jdk/test/sun/tools/jstatd/TestJstatdPort.java b/jdk/test/sun/tools/jstatd/TestJstatdPort.java index f2d479b6e30..bba8732bad9 100644 --- a/jdk/test/sun/tools/jstatd/TestJstatdPort.java +++ b/jdk/test/sun/tools/jstatd/TestJstatdPort.java @@ -25,7 +25,7 @@ * @test * @bug 4990825 * @library /lib/testlibrary - * @build JstatdTest JstatGCUtilParser + * @build jdk.testlibrary.* JstatdTest JstatGCUtilParser * @run main/timeout=60 TestJstatdPort */ public class TestJstatdPort { diff --git a/jdk/test/sun/tools/jstatd/TestJstatdPortAndServer.java b/jdk/test/sun/tools/jstatd/TestJstatdPortAndServer.java index e771561e99c..6b516f9140d 100644 --- a/jdk/test/sun/tools/jstatd/TestJstatdPortAndServer.java +++ b/jdk/test/sun/tools/jstatd/TestJstatdPortAndServer.java @@ -25,7 +25,7 @@ * @test * @bug 4990825 * @library /lib/testlibrary - * @build JstatdTest JstatGCUtilParser + * @build jdk.testlibrary.* JstatdTest JstatGCUtilParser * @run main/timeout=60 TestJstatdPortAndServer */ public class TestJstatdPortAndServer { diff --git a/jdk/test/sun/tools/jstatd/TestJstatdServer.java b/jdk/test/sun/tools/jstatd/TestJstatdServer.java index f8e87a668fc..fbf1c56026f 100644 --- a/jdk/test/sun/tools/jstatd/TestJstatdServer.java +++ b/jdk/test/sun/tools/jstatd/TestJstatdServer.java @@ -25,7 +25,7 @@ * @test * @bug 4990825 * @library /lib/testlibrary - * @build JstatdTest JstatGCUtilParser + * @build jdk.testlibrary.* JstatdTest JstatGCUtilParser * @run main/timeout=60 TestJstatdServer */ public class TestJstatdServer { diff --git a/jdk/test/sun/tools/jstatd/TestJstatdUsage.java b/jdk/test/sun/tools/jstatd/TestJstatdUsage.java index 3fd5efc19f3..abec798df6f 100644 --- a/jdk/test/sun/tools/jstatd/TestJstatdUsage.java +++ b/jdk/test/sun/tools/jstatd/TestJstatdUsage.java @@ -28,7 +28,7 @@ import jdk.testlibrary.OutputAnalyzer; * @test * @bug 4990825 * @library /lib/testlibrary - * @build jdk.testlibrary.JDKToolLauncher jdk.testlibrary.OutputAnalyzer + * @build jdk.testlibrary.* * @run main TestJstatdUsage */ public class TestJstatdUsage { From 85ac546ee7b90917274637c8929698f57459ffd3 Mon Sep 17 00:00:00 2001 From: Pavel Rappo <pavel.rappo@oracle.com> Date: Wed, 21 May 2014 14:33:33 +0100 Subject: [PATCH 117/157] 8042887: Remove serialver -show, this tool does not need a GUI Reviewed-by: alanb, chegar --- .../sun/tools/serialver/SerialVer.java | 240 ++---------------- .../serialver/resources/serialver.properties | 10 +- 2 files changed, 29 insertions(+), 221 deletions(-) diff --git a/jdk/src/share/classes/sun/tools/serialver/SerialVer.java b/jdk/src/share/classes/sun/tools/serialver/SerialVer.java index 85c7373c4f1..bf9ff893f62 100644 --- a/jdk/src/share/classes/sun/tools/serialver/SerialVer.java +++ b/jdk/src/share/classes/sun/tools/serialver/SerialVer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,8 +26,6 @@ package sun.tools.serialver; import java.io.*; -import java.awt.*; -import java.applet.*; import java.io.ObjectStreamClass; import java.util.Properties; import java.text.MessageFormat; @@ -39,106 +37,7 @@ import java.net.MalformedURLException; import java.util.StringTokenizer; import sun.net.www.ParseUtil; -public class SerialVer extends Applet { - GridBagLayout gb; - TextField classname_t; - Button show_b; - TextField serialversion_t; - Label footer_l; - - private static final long serialVersionUID = 7666909783837760853L; - - public synchronized void init() { - gb = new GridBagLayout(); - setLayout(gb); - - GridBagConstraints c = new GridBagConstraints(); - c.fill = GridBagConstraints.BOTH; - - Label l1 = new Label(Res.getText("FullClassName")); - l1.setAlignment(Label.RIGHT); - gb.setConstraints(l1, c); - add(l1); - - classname_t = new TextField(20); - c.gridwidth = GridBagConstraints.RELATIVE; - c.weightx = 1.0; - gb.setConstraints(classname_t, c); - add(classname_t); - - show_b = new Button(Res.getText("Show")); - c.gridwidth = GridBagConstraints.REMAINDER; - c.weightx = 0.0; /* Don't grow the button */ - gb.setConstraints(show_b, c); - add(show_b); - - Label l2 = new Label(Res.getText("SerialVersion")); - l2.setAlignment(Label.RIGHT); - c.gridwidth = 1; - gb.setConstraints(l2, c); - add(l2); - - serialversion_t = new TextField(50); - serialversion_t.setEditable(false); - c.gridwidth = GridBagConstraints.REMAINDER; - gb.setConstraints(serialversion_t, c); - add(serialversion_t); - - footer_l = new Label(); - c.gridwidth = GridBagConstraints.REMAINDER; - gb.setConstraints(footer_l, c); - add(footer_l); - - /* Give the focus to the type-in area */ - classname_t.requestFocus(); - } - - public void start() { - /* Give the focus to the type-in area */ - classname_t.requestFocus(); - } - - @SuppressWarnings("deprecation") - public boolean action(Event ev, Object obj) { - if (ev.target == classname_t) { - show((String)ev.arg); - return true; - } else if (ev.target == show_b) { - show(classname_t.getText()); - return true; - } - return false; - } - - - @SuppressWarnings("deprecation") - public boolean handleEvent(Event ev) { - boolean rc = super.handleEvent(ev); - return rc; - } - - /** - * Lookup the specified classname and display it. - */ - void show(String classname) { - try { - footer_l.setText(""); // Clear the message - serialversion_t.setText(""); // clear the last value - - if (classname.equals("")) { - return; - } - - String s = serialSyntax(classname); - if (s != null) { - serialversion_t.setText(s); - } else { - footer_l.setText(Res.getText("NotSerializable", classname)); - } - } catch (ClassNotFoundException cnf) { - footer_l.setText(Res.getText("ClassNotFound", classname)); - } - } +public class SerialVer { /* * A class loader that will load from the CLASSPATH environment @@ -218,13 +117,7 @@ public class SerialVer extends Applet { } } - @SuppressWarnings("deprecation") - private static void showWindow(Window w) { - w.show(); - } - public static void main(String[] args) { - boolean show = false; String envcp = null; int i = 0; @@ -234,9 +127,7 @@ public class SerialVer extends Applet { } for (i = 0; i < args.length; i++) { - if (args[i].equals("-show")) { - show = true; - } else if (args[i].equals("-classpath")) { + if (args[i].equals("-classpath")) { if ((i+1 == args.length) || args[i+1].startsWith("-")) { System.err.println(Res.getText("error.missing.classpath")); usage(); @@ -278,51 +169,35 @@ public class SerialVer extends Applet { System.exit(3); } - if (!show) { - /* - * Check if there are any class names specified, if it is not a - * invocation with the -show option. - */ - if (i == args.length) { - usage(); - System.exit(1); - } + /* + * Check if there are any class names specified + */ + if (i == args.length) { + usage(); + System.exit(1); + } - /* - * The rest of the parameters are classnames. - */ - boolean exitFlag = false; - for (i = i; i < args.length; i++ ) { - try { - String syntax = serialSyntax(args[i]); - if (syntax != null) - System.out.println(args[i] + ":" + syntax); - else { - System.err.println(Res.getText("NotSerializable", - args[i])); - exitFlag = true; - } - } catch (ClassNotFoundException cnf) { - System.err.println(Res.getText("ClassNotFound", args[i])); + /* + * The rest of the parameters are classnames. + */ + boolean exitFlag = false; + for (i = i; i < args.length; i++ ) { + try { + String syntax = serialSyntax(args[i]); + if (syntax != null) + System.out.println(args[i] + ":" + syntax); + else { + System.err.println(Res.getText("NotSerializable", + args[i])); exitFlag = true; } + } catch (ClassNotFoundException cnf) { + System.err.println(Res.getText("ClassNotFound", args[i])); + exitFlag = true; } - if (exitFlag) { - System.exit(1); - } - } else { - if (i < args.length) { - System.err.println(Res.getText("ignoring.classes")); - System.exit(1); - } - Frame f = new SerialVerFrame(); - // f.setLayout(new FlowLayout()); - SerialVer sv = new SerialVer(); - sv.init(); - - f.add("Center", sv); - f.pack(); - showWindow(f); + } + if (exitFlag) { + System.exit(1); } } @@ -336,65 +211,6 @@ public class SerialVer extends Applet { } -/** - * Top level frame so serialVer can be run as an main program - * and have an exit menu item. - */ -class SerialVerFrame extends Frame { - MenuBar menu_mb; - Menu file_m; - MenuItem exit_i; - - private static final long serialVersionUID = -7248105987187532533L; - - /* - * Construct a new Frame with title and menu. - */ - SerialVerFrame() { - super(Res.getText("SerialVersionInspector")); - - /* Create the file menu */ - file_m = new Menu(Res.getText("File")); - file_m.add(exit_i = new MenuItem(Res.getText("Exit"))); - - /* Now add the file menu to the menu bar */ - menu_mb = new MenuBar(); - menu_mb.add(file_m); - - /* Add the menubar to the frame */ - // Bug in JDK1.1 setMenuBar(menu_mb); - } - - /* - * Handle a window destroy event by exiting. - */ - @SuppressWarnings("deprecation") - public boolean handleEvent(Event e) { - if (e.id == Event.WINDOW_DESTROY) { - exit(0); - } - return super.handleEvent(e); - } - /* - * Handle an Exit event by exiting. - */ - @SuppressWarnings("deprecation") - public boolean action(Event ev, Object obj) { - if (ev.target == exit_i) { - exit(0); - } - return false; - } - - /* - * Cleanup and exit. - */ - void exit(int ret) { - System.exit(ret); - } - -} - /** * Utility for integrating with serialver and for localization. * Handle Resources. Access to error and warning counts. diff --git a/jdk/src/share/classes/sun/tools/serialver/resources/serialver.properties b/jdk/src/share/classes/sun/tools/serialver/resources/serialver.properties index 3d0ed602f8a..12213d0ecb8 100644 --- a/jdk/src/share/classes/sun/tools/serialver/resources/serialver.properties +++ b/jdk/src/share/classes/sun/tools/serialver/resources/serialver.properties @@ -1,9 +1,3 @@ -SerialVersionInspector=Serial Version Inspector -File=File -Exit=Exit -Show=Show -FullClassName=Full Class Name: -SerialVersion=Serial Version: NotSerializable=\ Class {0} is not Serializable. ClassNotFound=\ @@ -14,7 +8,5 @@ error.missing.classpath=\ Missing argument for -classpath option invalid.flag=\ Invalid flag {0}. -ignoring.classes=\ - Cannot specify class arguments with the -show option usage=\ - use: serialver [-classpath classpath] [-show] [classname...] + use: serialver [-classpath classpath] [classname...] From 8876554e3c0c20b1bb086bac90e53105f615b925 Mon Sep 17 00:00:00 2001 From: Erik Helin <ehelin@openjdk.org> Date: Wed, 21 May 2014 16:11:04 +0200 Subject: [PATCH 118/157] 8043639: Backout JDK-8034852: Shrinking of Metaspace high-water-mark causes incorrect OutOfMemoryErrors or back-to-back GCs Reviewed-by: stefank, tschatzl --- hotspot/src/share/vm/memory/metaspace.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 18c1d900ab8..e005263aa0b 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -1433,9 +1433,10 @@ size_t MetaspaceGC::allowed_expansion() { } size_t capacity_until_gc = capacity_until_GC(); - assert(capacity_until_gc >= committed_bytes, - err_msg("capacity_until_gc: " SIZE_FORMAT " < committed_bytes: " SIZE_FORMAT, - capacity_until_gc, committed_bytes)); + + if (capacity_until_gc <= committed_bytes) { + return 0; + } size_t left_until_GC = capacity_until_gc - committed_bytes; size_t left_to_commit = MIN2(left_until_GC, left_until_max); @@ -1448,15 +1449,7 @@ void MetaspaceGC::compute_new_size() { uint current_shrink_factor = _shrink_factor; _shrink_factor = 0; - // Using committed_bytes() for used_after_gc is an overestimation, since the - // chunk free lists are included in committed_bytes() and the memory in an - // un-fragmented chunk free list is available for future allocations. - // However, if the chunk free lists becomes fragmented, then the memory may - // not be available for future allocations and the memory is therefore "in use". - // Including the chunk free lists in the definition of "in use" is therefore - // necessary. Not including the chunk free lists can cause capacity_until_GC to - // shrink below committed_bytes() and this has caused serious bugs in the past. - const size_t used_after_gc = MetaspaceAux::committed_bytes(); + const size_t used_after_gc = MetaspaceAux::capacity_bytes(); const size_t capacity_until_GC = MetaspaceGC::capacity_until_GC(); const double minimum_free_percentage = MinMetaspaceFreeRatio / 100.0; From 1bf7f2b9a634d67a9120f8acd67779fb59c428b4 Mon Sep 17 00:00:00 2001 From: Chuck Rasbold <rasbold@openjdk.org> Date: Wed, 21 May 2014 10:54:59 -0700 Subject: [PATCH 119/157] 8043354: 8043354: Make is_return_allocated() respect allocated objects than can method-escape In bcEscapeAnalyzer update the _allocated_escapes flag if a var escapes the method. Reviewed-by: kvn --- hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp | 3 + .../TestAllocatedEscapesPtrComparison.java | 107 ++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 hotspot/test/compiler/EscapeAnalysis/TestAllocatedEscapesPtrComparison.java diff --git a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp index c2943e98edb..ae9def38b26 100644 --- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp +++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp @@ -158,6 +158,9 @@ void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, VectorSet &bm) { void BCEscapeAnalyzer::set_method_escape(ArgumentMap vars) { clear_bits(vars, _arg_local); + if (vars.contains_allocated()) { + _allocated_escapes = true; + } } void BCEscapeAnalyzer::set_global_escape(ArgumentMap vars, bool merge) { diff --git a/hotspot/test/compiler/EscapeAnalysis/TestAllocatedEscapesPtrComparison.java b/hotspot/test/compiler/EscapeAnalysis/TestAllocatedEscapesPtrComparison.java new file mode 100644 index 00000000000..04dea1e3934 --- /dev/null +++ b/hotspot/test/compiler/EscapeAnalysis/TestAllocatedEscapesPtrComparison.java @@ -0,0 +1,107 @@ +/* + * Copyright 2014 Google, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @bug 8043354 + * @summary bcEscapeAnalyzer allocated_escapes not conservative enough + * @run main/othervm -XX:CompileOnly=.visitAndPop TestAllocatedEscapesPtrComparison + * @author Chuck Rasbold rasbold@google.com + */ + +/* + * Test always passes with -XX:-OptmimizePtrCompare + */ + +import java.util.ArrayList; +import java.util.List; + +public class TestAllocatedEscapesPtrComparison { + + static TestAllocatedEscapesPtrComparison dummy; + + class Marker { + } + + List<Marker> markerList = new ArrayList<>(); + + // Suppress compilation of this method, it must be processed + // by the bytecode escape analyzer. + + // Make a new marker and put it on the List + Marker getMarker() { + // result escapes through markerList + final Marker result = new Marker(); + markerList.add(result); + return result; + } + + void visit(int depth) { + // Make a new marker + getMarker(); + + // Call visitAndPop every once in a while + // Cap the depth of our recursive visits + if (depth % 10 == 2) { + visitAndPop(depth + 1); + } else if (depth < 15) { + visit(depth + 1); + } + } + + void visitAndPop(int depth) { + // Random dummy allocation to force EscapeAnalysis to process this method + dummy = new TestAllocatedEscapesPtrComparison(); + + // Make a new marker + Marker marker = getMarker(); + + visit(depth + 1); + + // Walk and pop the marker list up to the current marker + boolean found = false; + for (int i = markerList.size() - 1; i >= 0; i--) { + Marker removed = markerList.remove(i); + + // In the failure, EA mistakenly converts this comparison to false + if (removed == marker) { + found = true; + break; + } + } + + if (!found) { + throw new RuntimeException("test fails"); + } + } + + + public static void main(String args[]) { + TestAllocatedEscapesPtrComparison tc = new TestAllocatedEscapesPtrComparison(); + + // Warmup and run enough times + for (int i = 0; i < 20000; i++) { + tc.visit(0); + } + } +} From 638b464ed3c09428be5c88fa7b378855c1bfb7ac Mon Sep 17 00:00:00 2001 From: Shrinivas Joshi <shrinivas.joshi@oracle.com> Date: Wed, 21 May 2014 12:16:41 -0700 Subject: [PATCH 120/157] 8043274: Test compiler/7184394/TestAESMain.java gets NPE on solaris Save cipher len after registers are saved Reviewed-by: kvn --- .../src/cpu/sparc/vm/stubGenerator_sparc.cpp | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp index 7cac116fada..231d1f7d932 100644 --- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp @@ -3653,9 +3653,9 @@ class StubGenerator: public StubCodeGenerator { const Register len_reg = I4; // cipher length const Register keylen = I5; // reg for storing expanded key array length - // save cipher len before save_frame, to return in the end - __ mov(O4, L0); __ save_frame(0); + // save cipher len to return in the end + __ mov(len_reg, L0); // read expanded key length __ ldsw(Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)), keylen, 0); @@ -3778,9 +3778,9 @@ class StubGenerator: public StubCodeGenerator { // re-init intial vector for next block, 8-byte alignment is guaranteed __ stf(FloatRegisterImpl::D, F60, rvec, 0); __ stf(FloatRegisterImpl::D, F62, rvec, 8); - __ restore(); - __ retl(); - __ delayed()->mov(L0, O0); + __ mov(L0, I0); + __ ret(); + __ delayed()->restore(); __ align(OptoLoopAlignment); __ BIND(L_cbcenc192); @@ -3869,9 +3869,9 @@ class StubGenerator: public StubCodeGenerator { // re-init intial vector for next block, 8-byte alignment is guaranteed __ stf(FloatRegisterImpl::D, F60, rvec, 0); __ stf(FloatRegisterImpl::D, F62, rvec, 8); - __ restore(); - __ retl(); - __ delayed()->mov(L0, O0); + __ mov(L0, I0); + __ ret(); + __ delayed()->restore(); __ align(OptoLoopAlignment); __ BIND(L_cbcenc256); @@ -3962,9 +3962,9 @@ class StubGenerator: public StubCodeGenerator { // re-init intial vector for next block, 8-byte alignment is guaranteed __ stf(FloatRegisterImpl::D, F60, rvec, 0); __ stf(FloatRegisterImpl::D, F62, rvec, 8); - __ restore(); - __ retl(); - __ delayed()->mov(L0, O0); + __ mov(L0, I0); + __ ret(); + __ delayed()->restore(); return start; } @@ -3992,9 +3992,9 @@ class StubGenerator: public StubCodeGenerator { const Register original_key = I5; // original key array only required during decryption const Register keylen = L6; // reg for storing expanded key array length - // save cipher len before save_frame, to return in the end - __ mov(O4, L0); __ save_frame(0); //args are read from I* registers since we save the frame in the beginning + // save cipher len to return in the end + __ mov(len_reg, L7); // load original key from SunJCE expanded decryption key // Since we load original key buffer starting first element, 8-byte alignment is guaranteed @@ -4568,10 +4568,9 @@ class StubGenerator: public StubCodeGenerator { // re-init intial vector for next block, 8-byte alignment is guaranteed __ stx(L0, rvec, 0); __ stx(L1, rvec, 8); - __ restore(); - __ mov(L0, O0); - __ retl(); - __ delayed()->nop(); + __ mov(L7, I0); + __ ret(); + __ delayed()->restore(); return start; } From c1d46ac98580578ef40af4c8388a5568f0e75eac Mon Sep 17 00:00:00 2001 From: Sergey Lugovoy <sergey.lugovoy@oracle.com> Date: Thu, 22 May 2014 11:12:29 +0200 Subject: [PATCH 121/157] 8028615: jdk.nashorn.x3::some.serious.failure needs more memory to run Reviewed-by: attila, sundar --- nashorn/make/project.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties index 8210e250ad2..ba4e57a1003 100644 --- a/nashorn/make/project.properties +++ b/nashorn/make/project.properties @@ -265,7 +265,7 @@ src.dir=src test.src.dir=test/src # -Xmx is used for all tests, -Xms only for octane benchmark -run.test.xmx=3G +run.test.xmx=2G run.test.xms=2G run.test.user.language=tr From a8c4f42722c4d4e8626e87fea358b941fccf237b Mon Sep 17 00:00:00 2001 From: Sandipan Razzaque <me@sandipan.net> Date: Thu, 22 May 2014 08:13:14 -0700 Subject: [PATCH 122/157] 8037343: Wrong dateformat for locale es_DO Reviewed-by: okutsu --- .../text/resources/es/FormatData_es_DO.java | 4 +- .../sun/text/resources/Format/Bug8037343.java | 71 +++++++++++++++++++ jdk/test/sun/text/resources/LocaleData | 8 ++- .../sun/text/resources/LocaleDataTest.java | 1 + 4 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 jdk/test/sun/text/resources/Format/Bug8037343.java diff --git a/jdk/src/share/classes/sun/text/resources/es/FormatData_es_DO.java b/jdk/src/share/classes/sun/text/resources/es/FormatData_es_DO.java index c8f1345b29d..4224a3a69b9 100644 --- a/jdk/src/share/classes/sun/text/resources/es/FormatData_es_DO.java +++ b/jdk/src/share/classes/sun/text/resources/es/FormatData_es_DO.java @@ -75,8 +75,8 @@ public class FormatData_es_DO extends ParallelListResourceBundle { new String[] { "EEEE d' de 'MMMM' de 'yyyy", // full date pattern "d' de 'MMMM' de 'yyyy", // long date pattern - "MM/dd/yyyy", // medium date pattern - "MM/dd/yy", // short date pattern + "dd/MM/yyyy", // medium date pattern + "dd/MM/yy", // short date pattern } }, { "DateTimePatterns", diff --git a/jdk/test/sun/text/resources/Format/Bug8037343.java b/jdk/test/sun/text/resources/Format/Bug8037343.java new file mode 100644 index 00000000000..80735f74236 --- /dev/null +++ b/jdk/test/sun/text/resources/Format/Bug8037343.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @bug 8037343 + * @summary updating dateformat for es_DO + */ + +import java.text.DateFormat; +import java.util.Calendar; +import java.util.Locale; + +public class Bug8037343 +{ + + public static void main(String[] arg) + { + final Locale esDO = new Locale("es", "DO"); + final String expectedShort = "31/03/12"; + final String expectedMedium = "31/03/2012"; + + int errors = 0; + DateFormat format; + String result; + + Calendar cal = Calendar.getInstance(esDO); + cal.set(Calendar.DAY_OF_MONTH, 31); + cal.set(Calendar.MONTH, Calendar.MARCH); + cal.set(Calendar.YEAR, 2012); + + format = DateFormat.getDateInstance(DateFormat.SHORT, esDO); + result = format.format(cal.getTime()); + if (!expectedShort.equals(result)) { + System.out.println(String.format("Short Date format for es_DO is not as expected. Expected: [%s] Actual: [%s]", expectedShort, result)); + errors++; + } + + format = DateFormat.getDateInstance(DateFormat.MEDIUM, esDO); + result = format.format(cal.getTime()); + if (!expectedMedium.equals(result)) { + System.out.println(String.format("Medium Date format for es_DO is not as expected. Expected: [%s] Actual: [%s]", expectedMedium, result)); + errors++; + } + + if (errors > 0) { + throw new RuntimeException(); + } + } + +} diff --git a/jdk/test/sun/text/resources/LocaleData b/jdk/test/sun/text/resources/LocaleData index fbea26741fd..6be5a4c1111 100644 --- a/jdk/test/sun/text/resources/LocaleData +++ b/jdk/test/sun/text/resources/LocaleData @@ -483,8 +483,8 @@ FormatData/es_DO/TimePatterns/2=hh:mm:ss a FormatData/es_DO/TimePatterns/3=hh:mm a FormatData/es_DO/DatePatterns/0=EEEE d' de 'MMMM' de 'yyyy FormatData/es_DO/DatePatterns/1=d' de 'MMMM' de 'yyyy -FormatData/es_DO/DatePatterns/2=MM/dd/yyyy -FormatData/es_DO/DatePatterns/3=MM/dd/yy +# FormatData/es_DO/DatePatterns/2=MM/dd/yyyy # Changed: see bug 8037343 +# FormatData/es_DO/DatePatterns/3=MM/dd/yy # Changed: see bug 8037343 FormatData/es_DO/DateTimePatterns/0={1} {0} FormatData/es_DO/NumberElements/0=. FormatData/es_DO/NumberElements/1=, @@ -7692,3 +7692,7 @@ FormatData/es_EC/TimePatterns/0=HH:mm:ss zzzz FormatData/es_EC/TimePatterns/1=H:mm:ss z FormatData/es_EC/TimePatterns/2=H:mm:ss FormatData/es_EC/TimePatterns/3=H:mm + +# bug 8037343 +FormatData/es_DO/DatePatterns/2=dd/MM/yyyy +FormatData/es_DO/DatePatterns/3=dd/MM/yy diff --git a/jdk/test/sun/text/resources/LocaleDataTest.java b/jdk/test/sun/text/resources/LocaleDataTest.java index 1c31cc9ad3b..9b44eec236b 100644 --- a/jdk/test/sun/text/resources/LocaleDataTest.java +++ b/jdk/test/sun/text/resources/LocaleDataTest.java @@ -36,6 +36,7 @@ * 6919624 6998391 7019267 7020960 7025837 7020583 7036905 7066203 7101495 * 7003124 7085757 7028073 7171028 7189611 8000983 7195759 8004489 8006509 * 7114053 7074882 7040556 8013836 8021121 6192407 6931564 8027695 8017142 + * 8037343 * @summary Verify locale data * */ From 67d65fd0dfe1a75bd1da84752900e1447d224795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= <hannesw@openjdk.org> Date: Thu, 22 May 2014 17:51:56 +0200 Subject: [PATCH 123/157] 8030202: Nashorn: Multiple RegExp#ignoreCase issues Reviewed-by: sundar, jlaskey --- .../runtime/regexp/joni/Analyser.java | 4 +- .../runtime/regexp/joni/ApplyCaseFold.java | 72 +++++------------ .../runtime/regexp/joni/ByteCodeMachine.java | 10 +-- .../runtime/regexp/joni/EncodingHelper.java | 81 ++++++++++++++----- .../runtime/regexp/joni/SearchAlgorithm.java | 2 +- nashorn/test/script/basic/JDK-8030202.js | 57 +++++++++++++ .../test/script/basic/JDK-8030202.js.EXPECTED | 22 +++++ 7 files changed, 168 insertions(+), 80 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8030202.js create mode 100644 nashorn/test/script/basic/JDK-8030202.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java index a75e84cafee..eb612cd3d36 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java @@ -771,7 +771,7 @@ final class Analyser extends Parser { while (value < end) { int ovalue = value; - buf = Character.toLowerCase(chars[value++]); + buf = EncodingHelper.toLowerCase(chars[value++]); if (chars[ovalue] != buf) { @@ -779,7 +779,7 @@ final class Analyser extends Parser { System.arraycopy(chars, sn.p, sbuf, 0, ovalue - sn.p); value = ovalue; while (value < end) { - buf = Character.toLowerCase(chars[value++]); + buf = EncodingHelper.toLowerCase(chars[value++]); if (sp >= sbuf.length) { char[]tmp = new char[sbuf.length << 1]; System.arraycopy(sbuf, 0, tmp, 0, sbuf.length); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFold.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFold.java index 397b05cef47..dda5b733e27 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFold.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFold.java @@ -20,70 +20,42 @@ package jdk.nashorn.internal.runtime.regexp.joni; import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode; -import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode; -import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode; final class ApplyCaseFold { // i_apply_case_fold - public void apply(int from, int[]to, int length, Object o) { + public void apply(int from, int to, Object o) { ApplyCaseFoldArg arg = (ApplyCaseFoldArg)o; ScanEnvironment env = arg.env; CClassNode cc = arg.cc; BitSet bs = cc.bs; - if (length == 1) { - boolean inCC = cc.isCodeInCC(from); + boolean inCC = cc.isCodeInCC(from); - if (Config.CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS) { - if ((inCC && !cc.isNot()) || (!inCC && cc.isNot())) { - if (to[0] >= BitSet.SINGLE_BYTE_SIZE) { - cc.addCodeRange(env, to[0], to[0]); - } else { - /* /(?i:[^A-C])/.match("a") ==> fail. */ - bs.set(to[0]); - } - } - } else { - if (inCC) { - if (to[0] >= BitSet.SINGLE_BYTE_SIZE) { - if (cc.isNot()) cc.clearNotFlag(); - cc.addCodeRange(env, to[0], to[0]); - } else { - if (cc.isNot()) { - bs.clear(to[0]); - } else { - bs.set(to[0]); - } - } - } - } // CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS - - } else { - if (cc.isCodeInCC(from) && (!Config.CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS || !cc.isNot())) { - StringNode node = null; - for (int i=0; i<length; i++) { - if (i == 0) { - node = new StringNode(); - /* char-class expanded multi-char only - compare with string folded at match time. */ - node.setAmbig(); - } - node.catCode(to[i]); - } - - ConsAltNode alt = ConsAltNode.newAltNode(node, null); - - if (arg.tail == null) { - arg.altRoot = alt; + if (Config.CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS) { + if ((inCC && !cc.isNot()) || (!inCC && cc.isNot())) { + if (to >= BitSet.SINGLE_BYTE_SIZE) { + cc.addCodeRange(env, to, to); } else { - arg.tail.setCdr(alt); + /* /(?i:[^A-C])/.match("a") ==> fail. */ + bs.set(to); } - arg.tail = alt; } - - } + } else { + if (inCC) { + if (to >= BitSet.SINGLE_BYTE_SIZE) { + if (cc.isNot()) cc.clearNotFlag(); + cc.addCodeRange(env, to, to); + } else { + if (cc.isNot()) { + bs.clear(to); + } else { + bs.set(to); + } + } + } + } // CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java index df4b125bcee..b897a8cbf19 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java @@ -58,8 +58,8 @@ class ByteCodeMachine extends StackMachine { int end1 = s1 + mbLen; while (s1 < end1) { - char c1 = Character.toLowerCase(chars[s1++]); - char c2 = Character.toLowerCase(chars[s2++]); + char c1 = EncodingHelper.toLowerCase(chars[s1++]); + char c2 = EncodingHelper.toLowerCase(chars[s2++]); if (c1 != c2) { return false; @@ -367,7 +367,7 @@ class ByteCodeMachine extends StackMachine { } private void opExact1IC() { - if (s >= range || code[ip] != Character.toLowerCase(chars[s++])) {opFail(); return;} + if (s >= range || code[ip] != EncodingHelper.toLowerCase(chars[s++])) {opFail(); return;} ip++; sprev = sbegin; // break; } @@ -380,10 +380,10 @@ class ByteCodeMachine extends StackMachine { char[] bs = regex.templates[code[ip++]]; int ps = code[ip++]; - while (tlen-- > 0) if (bs[ps++] != Character.toLowerCase(chars[s++])) {opFail(); return;} + while (tlen-- > 0) if (bs[ps++] != EncodingHelper.toLowerCase(chars[s++])) {opFail(); return;} } else { - while (tlen-- > 0) if (code[ip++] != Character.toLowerCase(chars[s++])) {opFail(); return;} + while (tlen-- > 0) if (code[ip++] != EncodingHelper.toLowerCase(chars[s++])) {opFail(); return;} } sprev = s - 1; } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java index afbb1b20bd1..0c9c8ab410c 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java @@ -93,41 +93,78 @@ public final class EncodingHelper { return s; } - public static int mbcToCode(byte[] bytes, int p, int end) { - int code = 0; - for (int i = p; i < end; i++) { - code = (code << 8) | (bytes[i] & 0xff); - } - return code; - } - public static int mbcodeStartPosition() { return 0x80; } public static char[] caseFoldCodesByString(int flag, char c) { - if (Character.isUpperCase(c)) { - return new char[] {Character.toLowerCase(c)}; - } else if (Character.isLowerCase(c)) { - return new char[] {Character.toUpperCase(c)}; - } else { - return EMPTYCHARS; + char[] codes = EMPTYCHARS; + final char upper = toUpperCase(c); + + if (upper != toLowerCase(upper)) { + int count = 0; + char ch = 0; + + do { + final char u = toUpperCase(ch); + if (u == upper && ch != c) { + // Almost all characters will return array of length 1, very few 2 or 3, so growing by one is fine. + codes = count == 0 ? new char[1] : Arrays.copyOf(codes, count + 1); + codes[count++] = ch; + } + } while (ch++ < 0xffff); } + return codes; } public static void applyAllCaseFold(int flag, ApplyCaseFold fun, Object arg) { - int[] code = new int[1]; - for (int c = 0; c < 0xffff; c++) { - if (Character.getType(c) == Character.LOWERCASE_LETTER) { + if (Character.isLowerCase(c)) { + final int upper = toUpperCase(c); - int upper = code[0] = Character.toUpperCase(c); - fun.apply(c, code, 1, arg); - - code[0] = c; - fun.apply(upper, code, 1, arg); + if (upper != c) { + fun.apply(c, upper, arg); + } } } + + // Some characters have multiple lower case variants, hence we need to do a second run + for (int c = 0; c < 0xffff; c++) { + if (Character.isLowerCase(c)) { + final int upper = toUpperCase(c); + + if (upper != c) { + fun.apply(upper, c, arg); + } + } + } + } + + public static char toLowerCase(char c) { + return (char)toLowerCase((int)c); + } + + public static int toLowerCase(int c) { + if (c < 128) { + return ('A' <= c && c <= 'Z') ? (c + ('a' - 'A')) : c; + } + // Do not convert non-ASCII upper case character to ASCII lower case. + int lower = Character.toLowerCase(c); + return (lower < 128) ? c : lower; + + } + + public static char toUpperCase(char c) { + return (char)toUpperCase((int)c); + } + + public static int toUpperCase(int c) { + if (c < 128) { + return ('a' <= c && c <= 'z') ? c + ('A' - 'a') : c; + } + // Do not convert non-ASCII lower case character to ASCII upper case. + int upper = Character.toUpperCase(c); + return (upper < 128) ? c : upper; } public static int[] ctypeCodeRange(int ctype, IntHolder sbOut) { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java index 758679a267b..5b2eac97142 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java @@ -168,7 +168,7 @@ public abstract class SearchAlgorithm { char[] chars, int p, int end) { while (tP < tEnd) { - if (t[tP++] != Character.toLowerCase(chars[p++])) return false; + if (t[tP++] != EncodingHelper.toLowerCase(chars[p++])) return false; } return true; } diff --git a/nashorn/test/script/basic/JDK-8030202.js b/nashorn/test/script/basic/JDK-8030202.js new file mode 100644 index 00000000000..6cf5647513b --- /dev/null +++ b/nashorn/test/script/basic/JDK-8030202.js @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +/** + * JDK-8030202: Nashorn: Multiple RegExp#ignoreCase issues + * + * @test + * @run + */ + +print(/\u2160/i.test("\u2170")); +print(/[\u2160]/i.test("\u2170")); +print(/\u2170/i.test("\u2160")); +print(/[\u2170]/i.test("\u2160")); + +print(/\u0130/i.test("\u0069")); +print(/[\u0130]/i.test("\u0069")); +print(/\u0069/i.test("\u0130")); +print(/[\u0069]/i.test("\u0130")); + +print(/\u1e9e/i.test("\u00df")); +print(/[\u1e9e]/i.test("\u00df")); +print(/\u00df/i.test("\u1e9e")); +print(/[\u00df]/i.test("\u1e9e")); + +print(/[^\u1e9e]/i.test("\u00df")); +print(/[^\u00df]/i.test("\u1e9e")); + +print(/\u0345{4}/i.test("\u0345\u0399\u03b9\u1fbe")); +print(/\u0399{4}/i.test("\u0345\u0399\u03b9\u1fbe")); +print(/\u03b9{4}/i.test("\u0345\u0399\u03b9\u1fbe")); +print(/\u1fbe{4}/i.test("\u0345\u0399\u03b9\u1fbe")); + +print(/[\u0345]{4}/i.test("\u0345\u0399\u03b9\u1fbe")); +print(/[\u0399]{4}/i.test("\u0345\u0399\u03b9\u1fbe")); +print(/[\u03b9]{4}/i.test("\u0345\u0399\u03b9\u1fbe")); +print(/[\u1fbe]{4}/i.test("\u0345\u0399\u03b9\u1fbe")); diff --git a/nashorn/test/script/basic/JDK-8030202.js.EXPECTED b/nashorn/test/script/basic/JDK-8030202.js.EXPECTED new file mode 100644 index 00000000000..7c73d8c04b1 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8030202.js.EXPECTED @@ -0,0 +1,22 @@ +true +true +true +true +false +false +false +false +false +false +false +false +true +true +true +true +true +true +true +true +true +true From ccdd942921a0e074947f397c840521627e9e5733 Mon Sep 17 00:00:00 2001 From: Ivan Gerasimov <igerasim@openjdk.org> Date: Thu, 22 May 2014 20:19:08 +0400 Subject: [PATCH 124/157] 8043772: Typos in Double/Int/LongSummaryStatistics.java Reviewed-by: rriggs --- jdk/src/share/classes/java/util/DoubleSummaryStatistics.java | 2 +- jdk/src/share/classes/java/util/IntSummaryStatistics.java | 2 +- jdk/src/share/classes/java/util/LongSummaryStatistics.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/java/util/DoubleSummaryStatistics.java b/jdk/src/share/classes/java/util/DoubleSummaryStatistics.java index 222d9672d29..569c35899bc 100644 --- a/jdk/src/share/classes/java/util/DoubleSummaryStatistics.java +++ b/jdk/src/share/classes/java/util/DoubleSummaryStatistics.java @@ -54,7 +54,7 @@ import java.util.stream.Collector; * * @implNote This implementation is not thread safe. However, it is safe to use * {@link java.util.stream.Collectors#summarizingDouble(java.util.function.ToDoubleFunction) - * Collectors.toDoubleStatistics()} on a parallel stream, because the parallel + * Collectors.summarizingDouble()} on a parallel stream, because the parallel * implementation of {@link java.util.stream.Stream#collect Stream.collect()} * provides the necessary partitioning, isolation, and merging of results for * safe and efficient parallel execution. diff --git a/jdk/src/share/classes/java/util/IntSummaryStatistics.java b/jdk/src/share/classes/java/util/IntSummaryStatistics.java index f93436e7017..3a38b91f981 100644 --- a/jdk/src/share/classes/java/util/IntSummaryStatistics.java +++ b/jdk/src/share/classes/java/util/IntSummaryStatistics.java @@ -54,7 +54,7 @@ import java.util.stream.Collector; * * @implNote This implementation is not thread safe. However, it is safe to use * {@link java.util.stream.Collectors#summarizingInt(java.util.function.ToIntFunction) - * Collectors.toIntStatistics()} on a parallel stream, because the parallel + * Collectors.summarizingInt()} on a parallel stream, because the parallel * implementation of {@link java.util.stream.Stream#collect Stream.collect()} * provides the necessary partitioning, isolation, and merging of results for * safe and efficient parallel execution. diff --git a/jdk/src/share/classes/java/util/LongSummaryStatistics.java b/jdk/src/share/classes/java/util/LongSummaryStatistics.java index 085aa298075..d1a7de7aa36 100644 --- a/jdk/src/share/classes/java/util/LongSummaryStatistics.java +++ b/jdk/src/share/classes/java/util/LongSummaryStatistics.java @@ -42,7 +42,7 @@ import java.util.stream.Collector; * }</pre> * * <p>{@code LongSummaryStatistics} can be used as a - * {@linkplain java.util.stream.Stream#collect(Collector)} reduction} + * {@linkplain java.util.stream.Stream#collect(Collector) reduction} * target for a {@linkplain java.util.stream.Stream stream}. For example: * * <pre> {@code @@ -55,7 +55,7 @@ import java.util.stream.Collector; * * @implNote This implementation is not thread safe. However, it is safe to use * {@link java.util.stream.Collectors#summarizingLong(java.util.function.ToLongFunction) - * Collectors.toLongStatistics()} on a parallel stream, because the parallel + * Collectors.summarizingLong()} on a parallel stream, because the parallel * implementation of {@link java.util.stream.Stream#collect Stream.collect()} * provides the necessary partitioning, isolation, and merging of results for * safe and efficient parallel execution. From 4560a6cb3d3d586f55f304470b4a076e40251c51 Mon Sep 17 00:00:00 2001 From: David Katleman <katleman@openjdk.org> Date: Thu, 22 May 2014 12:53:41 -0700 Subject: [PATCH 125/157] Added tag jdk9-b14 for changeset 4009a00151e2 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 18cf4e05c86..3f510f7c8a2 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -256,3 +256,4 @@ a4bf701ac316946c2e5e83138ad8e687da6a4b30 jdk9-b06 77ea0a2503582a28e4e66be7239a49a0d1dd313f jdk9-b11 e212cdcc8c11f0ba5acf6f5ddb596c4c545a93f9 jdk9-b12 088eec4c36f4d7f250fcd19c4969bf698e3d2cdc jdk9-b13 +a2b82f863ba95a596da555a4c1b871c404863e7e jdk9-b14 From b6a3e971bbf2fd80e88aa49b2ecb23e258b4f024 Mon Sep 17 00:00:00 2001 From: David Katleman <katleman@openjdk.org> Date: Thu, 22 May 2014 12:53:50 -0700 Subject: [PATCH 126/157] Added tag jdk9-b14 for changeset 631682a70d8a --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 97ea5ccc8bc..00898012217 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -416,3 +416,4 @@ ebc44d040cd149d2120d69fe183a3dae7840f4b4 jdk9-b10 783309c3a1a629a452673399dcfa83ef7eca94d8 jdk9-b11 1c383bb39e2849ca62cb763f4e182a29b421d60a jdk9-b12 456ad9c99133803d4e1433124c85a6fd141b9ac9 jdk9-b13 +bd333491bb6c012d7b606939406d0fa9a5ac7ffd jdk9-b14 From 9fe74fcd0fa60bb9349339671ae9cfc581138145 Mon Sep 17 00:00:00 2001 From: David Katleman <katleman@openjdk.org> Date: Thu, 22 May 2014 12:53:57 -0700 Subject: [PATCH 127/157] Added tag jdk9-b14 for changeset d122674e5ed7 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index f631e59bbe0..7cda4470598 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -256,3 +256,4 @@ f93a792fe37279d4d37aea86a99f3abbdc6fe79b jdk9-b09 6b4280dceb00642f54d5bc1c2cb7d34c99a04992 jdk9-b11 e88cecf5a21b760ff7d7761c2db6bb8c82bc9f0c jdk9-b12 5eaf717f6e36037a6d3744ffeee0e4c88e64a0d2 jdk9-b13 +32b3fc4bc7374a34d52b7f4e2391b4b4b0c084e8 jdk9-b14 From 9b4dd883bb595c262e733e7630ccc7e5ac3a3d62 Mon Sep 17 00:00:00 2001 From: David Katleman <katleman@openjdk.org> Date: Thu, 22 May 2014 12:54:01 -0700 Subject: [PATCH 128/157] Added tag jdk9-b14 for changeset 334fc8abb249 --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index b2197334dde..c7dda23a67d 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -259,3 +259,4 @@ c9e8bb8c1144a966ca7b481142c6b5e55d14a29c jdk9-b09 1f953ba7db2b535e19f0354abfee6d67605e0684 jdk9-b11 779f8b21c75f83e3918dac8499e4d0ecb3a54ed7 jdk9-b12 3d42204854c9f703e3ccdc8891248e73057713ab jdk9-b13 +02e58850b7062825308413d420f2b02c1f25a724 jdk9-b14 From 2af1faabc9a4cd0236939091fc777225942cf339 Mon Sep 17 00:00:00 2001 From: David Katleman <katleman@openjdk.org> Date: Thu, 22 May 2014 12:54:02 -0700 Subject: [PATCH 129/157] Added tag jdk9-b14 for changeset 2e754d3dbdf2 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 7a9bbb24e71..fdf62aef521 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -256,3 +256,4 @@ ab06ba2894313a47e4969ca37792ff119c49e711 jdk9-b10 47feccd164b7187a0147693a922ee47c6629643c jdk9-b11 83d9bc20973de232cae45b139fdff8a4549c130f jdk9-b12 c7c8002d02721e02131d104549ebeb8b379fb8d2 jdk9-b13 +5c7a17a81afd0906b53ee31d95a3211c96ff6b25 jdk9-b14 From 5d455cb4827dd438bc651c7bf4f84c2e5b1f37ce Mon Sep 17 00:00:00 2001 From: David Katleman <katleman@openjdk.org> Date: Thu, 22 May 2014 12:54:10 -0700 Subject: [PATCH 130/157] Added tag jdk9-b14 for changeset 076ae2d12410 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index 7020c726d31..d59728d0fb2 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -256,3 +256,4 @@ ea02d24b3f1dd1417132d6587dd38b056cca0be2 jdk9-b08 f04fccfbd880c819affc3ef33e0083aab9556409 jdk9-b11 72efbe612e494f98b9c3ede1b4a3d02304e1e9cc jdk9-b12 2c8bb81b5d48161019218c7604fa88c67edc6105 jdk9-b13 +1df3f53b9d980b66739f05e14053381ffb0f38ee jdk9-b14 From 80e612127070e716644f962f859722acf4154dbc Mon Sep 17 00:00:00 2001 From: David Katleman <katleman@openjdk.org> Date: Thu, 22 May 2014 12:54:12 -0700 Subject: [PATCH 131/157] Added tag jdk9-b14 for changeset 2187cb29a50c --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index 4eb279cc390..f5e58e3f192 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -247,3 +247,4 @@ b3517e51f40477f10db8bc30a557aa0ea712c274 jdk9-b02 4d60c3292e14aac90dc3b8232496ba4af4254cc3 jdk9-b11 282e9a675e079cc84dbfaa4c10050f08397faab0 jdk9-b12 be4580ae56e2ef0ce521d3f840753eaa83cacf33 jdk9-b13 +806df06b6ac58d3e9c9c6a680dbdd7a6c94ca700 jdk9-b14 From c82d0f24182df1adc14422db8a6a43c705630d44 Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff <dsamersoff@openjdk.org> Date: Thu, 22 May 2014 13:03:10 -0700 Subject: [PATCH 132/157] 8043716: JDI test com/sun/jdi/ProcessAttachTest.sh and other 3 jdi tests failed in nightly InetAddress.getLocalHost() returns configured host name instead of localhost. Reviewed-by: dcubed --- .../com/sun/tools/jdi/SocketAttachingConnector.java | 7 +------ .../classes/com/sun/tools/jdi/SocketTransportService.java | 7 +++++-- jdk/src/share/transport/socket/socketTransport.c | 4 +++- jdk/test/com/sun/jdi/BadHandshakeTest.java | 4 ++-- jdk/test/com/sun/jdi/RunToExit.java | 3 +++ 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/jdk/src/share/classes/com/sun/tools/jdi/SocketAttachingConnector.java b/jdk/src/share/classes/com/sun/tools/jdi/SocketAttachingConnector.java index a8c2bed6549..2fe565bcc01 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/SocketAttachingConnector.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/SocketAttachingConnector.java @@ -44,12 +44,7 @@ public class SocketAttachingConnector extends GenericAttachingConnector { public SocketAttachingConnector() { super(new SocketTransportService()); - String defaultHostName; - try { - defaultHostName = InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException e) { - defaultHostName = ""; - } + String defaultHostName = "localhost"; addStringArgument( ARG_HOST, diff --git a/jdk/src/share/classes/com/sun/tools/jdi/SocketTransportService.java b/jdk/src/share/classes/com/sun/tools/jdi/SocketTransportService.java index 5585a003110..e1c0e5a0256 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/SocketTransportService.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/SocketTransportService.java @@ -198,13 +198,17 @@ public class SocketTransportService extends TransportService { String host; String portStr; if (splitIndex < 0) { - host = InetAddress.getLocalHost().getHostName(); + host = "localhost"; portStr = address; } else { host = address.substring(0, splitIndex); portStr = address.substring(splitIndex+1); } + if (host.equals("*")) { + host = InetAddress.getLocalHost().getHostName(); + } + int port; try { port = Integer.decode(portStr).intValue(); @@ -215,7 +219,6 @@ public class SocketTransportService extends TransportService { // open TCP connection to VM - InetSocketAddress sa = new InetSocketAddress(host, port); Socket s = new Socket(); try { diff --git a/jdk/src/share/transport/socket/socketTransport.c b/jdk/src/share/transport/socket/socketTransport.c index b8de834a9eb..bcd21400ad2 100644 --- a/jdk/src/share/transport/socket/socketTransport.c +++ b/jdk/src/share/transport/socket/socketTransport.c @@ -199,9 +199,11 @@ getLocalHostAddress() { // Simple routine to guess localhost address. // it looks up "localhost" and returns 127.0.0.1 if lookup // fails. - struct addrinfo hints = {0}, *res = NULL; + struct addrinfo hints, *res = NULL; int err; + // Use portable way to initialize the structure + memset((void *)&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; err = getaddrinfo("localhost", NULL, &hints, &res); diff --git a/jdk/test/com/sun/jdi/BadHandshakeTest.java b/jdk/test/com/sun/jdi/BadHandshakeTest.java index 7e35ce3fdd6..eb17d7c3e81 100644 --- a/jdk/test/com/sun/jdi/BadHandshakeTest.java +++ b/jdk/test/com/sun/jdi/BadHandshakeTest.java @@ -110,12 +110,12 @@ public class BadHandshakeTest { } // Connect to the debuggee and handshake with garbage - Socket s = new Socket(InetAddress.getLocalHost(), port); + Socket s = new Socket("localhost", port); s.getOutputStream().write("Here's a poke in the eye".getBytes("UTF-8")); s.close(); // Re-connect and to a partial handshake - don't disconnect - s = new Socket(InetAddress.getLocalHost(), port); + s = new Socket("localhost", port); s.getOutputStream().write("JDWP-".getBytes("UTF-8")); diff --git a/jdk/test/com/sun/jdi/RunToExit.java b/jdk/test/com/sun/jdi/RunToExit.java index 95d6256862c..54b05a47078 100644 --- a/jdk/test/com/sun/jdi/RunToExit.java +++ b/jdk/test/com/sun/jdi/RunToExit.java @@ -161,6 +161,9 @@ public class RunToExit { Connector.IntegerArgument port_arg = (Connector.IntegerArgument)conn_args.get("port"); port_arg.setValue(port); + + System.out.println("Connection arguments: " + conn_args); + VirtualMachine vm = conn.attach(conn_args); // The first event is always a VMStartEvent, and it is always in From ec539d90649acc85c94892227e41278502f8b28f Mon Sep 17 00:00:00 2001 From: Otavio Goncalves de Santana <otaviopolianasantana@gmail.com> Date: Thu, 22 May 2014 20:24:42 +0000 Subject: [PATCH 133/157] 8043342: Replace uses of StringBuffer with StringBuilder within crypto code JCE components of 8041679 here due to code signing process. Reviewed-by: xuelei, wetmore --- .../classes/com/sun/crypto/provider/DHParameters.java | 10 +++++----- .../classes/com/sun/crypto/provider/DHPublicKey.java | 10 +++++----- .../com/sun/crypto/provider/OAEPParameters.java | 4 ++-- jdk/src/share/classes/sun/security/pkcs11/P11Util.java | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/jdk/src/share/classes/com/sun/crypto/provider/DHParameters.java b/jdk/src/share/classes/com/sun/crypto/provider/DHParameters.java index 57b0e7c3a0c..f8de6b43ff5 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/DHParameters.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/DHParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -131,14 +131,14 @@ public final class DHParameters extends AlgorithmParametersSpi { protected String engineToString() { String LINE_SEP = System.getProperty("line.separator"); - StringBuffer strbuf - = new StringBuffer("SunJCE Diffie-Hellman Parameters:" + StringBuilder sb + = new StringBuilder("SunJCE Diffie-Hellman Parameters:" + LINE_SEP + "p:" + LINE_SEP + Debug.toHexString(this.p) + LINE_SEP + "g:" + LINE_SEP + Debug.toHexString(this.g)); if (this.l != 0) - strbuf.append(LINE_SEP + "l:" + LINE_SEP + " " + this.l); - return strbuf.toString(); + sb.append(LINE_SEP + "l:" + LINE_SEP + " " + this.l); + return sb.toString(); } } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/DHPublicKey.java b/jdk/src/share/classes/com/sun/crypto/provider/DHPublicKey.java index 7293c945768..037589c8d53 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/DHPublicKey.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/DHPublicKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -260,8 +260,8 @@ javax.crypto.interfaces.DHPublicKey, Serializable { public String toString() { String LINE_SEP = System.getProperty("line.separator"); - StringBuffer strbuf - = new StringBuffer("SunJCE Diffie-Hellman Public Key:" + StringBuilder sb + = new StringBuilder("SunJCE Diffie-Hellman Public Key:" + LINE_SEP + "y:" + LINE_SEP + Debug.toHexString(this.y) + LINE_SEP + "p:" + LINE_SEP @@ -269,8 +269,8 @@ javax.crypto.interfaces.DHPublicKey, Serializable { + LINE_SEP + "g:" + LINE_SEP + Debug.toHexString(this.g)); if (this.l != 0) - strbuf.append(LINE_SEP + "l:" + LINE_SEP + " " + this.l); - return strbuf.toString(); + sb.append(LINE_SEP + "l:" + LINE_SEP + " " + this.l); + return sb.toString(); } private void parseKeyBits() throws InvalidKeyException { diff --git a/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java b/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java index 74b3cc408d9..1ea16cc62e1 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -238,7 +238,7 @@ public final class OAEPParameters extends AlgorithmParametersSpi { } protected String engineToString() { - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); sb.append("MD: " + mdName + "\n"); sb.append("MGF: MGF1" + mgfSpec.getDigestAlgorithm() + "\n"); sb.append("PSource: PSpecified " + diff --git a/jdk/src/share/classes/sun/security/pkcs11/P11Util.java b/jdk/src/share/classes/sun/security/pkcs11/P11Util.java index 38da9401f33..b5787a712f9 100644 --- a/jdk/src/share/classes/sun/security/pkcs11/P11Util.java +++ b/jdk/src/share/classes/sun/security/pkcs11/P11Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -166,7 +166,7 @@ public final class P11Util { if (b == null) { return "(null)"; } - StringBuffer sb = new StringBuffer(b.length * 3); + StringBuilder sb = new StringBuilder(b.length * 3); for (int i = 0; i < b.length; i++) { int k = b[i] & 0xff; if (i != 0) { From 378c3fe62f8efe8d3a4e11376bb7fd65f5b5fc65 Mon Sep 17 00:00:00 2001 From: Sonali Goel <sogoel@openjdk.org> Date: Thu, 22 May 2014 15:42:10 -0700 Subject: [PATCH 134/157] 8043336: Missing bug id in test/tools/javac/lambda/TargetType23.java Reviewed-by: jjg, vromero, dlsmith --- langtools/test/tools/javac/lambda/TargetType23.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langtools/test/tools/javac/lambda/TargetType23.java b/langtools/test/tools/javac/lambda/TargetType23.java index bac45e9351e..4f20232a3cc 100644 --- a/langtools/test/tools/javac/lambda/TargetType23.java +++ b/langtools/test/tools/javac/lambda/TargetType23.java @@ -1,6 +1,6 @@ /* * @test /nodynamiccopyright/ - * @bug 8003280 + * @bug 8003280 8034223 * @summary Add lambda tests * check case of ambiguous method call with lambda whose body cannot complete normally From 26e2d0e0968a642ce2581e18d319389adef112a0 Mon Sep 17 00:00:00 2001 From: Ivan Gerasimov <igerasim@openjdk.org> Date: Fri, 23 May 2014 07:07:33 +0400 Subject: [PATCH 135/157] 8043507: javax.smartcardio.CardTerminals.list() fails on MacOSX Reviewed-by: valeriep --- jdk/src/share/native/sun/security/smartcardio/pcsc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/native/sun/security/smartcardio/pcsc.c b/jdk/src/share/native/sun/security/smartcardio/pcsc.c index 8c33f2a03d2..ab30e138120 100644 --- a/jdk/src/share/native/sun/security/smartcardio/pcsc.c +++ b/jdk/src/share/native/sun/security/smartcardio/pcsc.c @@ -108,7 +108,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEXPORT jlong JNICALL Java_sun_security_smartcardio_PCSC_SCardEstablishContext (JNIEnv *env, jclass thisClass, jint dwScope) { - SCARDCONTEXT context; + SCARDCONTEXT context = 0; LONG rv; dprintf("-establishContext\n"); rv = CALL_SCardEstablishContext(dwScope, NULL, NULL, &context); @@ -180,7 +180,7 @@ JNIEXPORT jobjectArray JNICALL Java_sun_security_smartcardio_PCSC_SCardListReade SCARDCONTEXT context = (SCARDCONTEXT)jContext; LONG rv; LPTSTR mszReaders; - DWORD size; + DWORD size = 0; jobjectArray result; dprintf1("-context: %x\n", context); @@ -215,8 +215,8 @@ JNIEXPORT jlong JNICALL Java_sun_security_smartcardio_PCSC_SCardConnect SCARDCONTEXT context = (SCARDCONTEXT)jContext; LONG rv; LPCTSTR readerName; - SCARDHANDLE card; - DWORD proto; + SCARDHANDLE card = 0; + DWORD proto = 0; readerName = (*env)->GetStringUTFChars(env, jReaderName, NULL); if (readerName == NULL) { @@ -280,8 +280,8 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_smartcardio_PCSC_SCardStatus DWORD readerLen = READERNAME_BUFFER_SIZE; unsigned char atr[ATR_BUFFER_SIZE]; DWORD atrLen = ATR_BUFFER_SIZE; - DWORD state; - DWORD protocol; + DWORD state = 0; + DWORD protocol = 0; jbyteArray jArray; jbyte status[2]; From 264825d4bf627d3f356f8b23c731be9cd499a1f2 Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik <jbachorik@openjdk.org> Date: Fri, 23 May 2014 15:07:22 +0200 Subject: [PATCH 136/157] 8043572: demo/jvmti/mtrace/TraceJFrame.java fails with AWTError: Can't connect to X11 window server using '$DISPLAY_SITE' as the value of the DISPLAY variable Reviewed-by: sla --- .../demo/jvmti/mtrace/JFrameCreateTime.java | 24 +++++++++++-------- jdk/test/demo/jvmti/mtrace/TraceJFrame.java | 2 +- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/jdk/test/demo/jvmti/mtrace/JFrameCreateTime.java b/jdk/test/demo/jvmti/mtrace/JFrameCreateTime.java index c31e5237b2e..b08206ef3e9 100644 --- a/jdk/test/demo/jvmti/mtrace/JFrameCreateTime.java +++ b/jdk/test/demo/jvmti/mtrace/JFrameCreateTime.java @@ -32,24 +32,28 @@ * was very slow (VisualMust debugger people reported this). */ +import java.awt.GraphicsEnvironment; import javax.swing.*; public class JFrameCreateTime { public static void main(String[] args) { JFrame f; long start, end; + if (GraphicsEnvironment.isHeadless()) { + System.out.println("JFrameCreateTime test was skipped due to headless mode"); + } else { + start = System.currentTimeMillis(); + f = new JFrame("JFrame"); + end = System.currentTimeMillis(); - start = System.currentTimeMillis(); - f = new JFrame("JFrame"); - end = System.currentTimeMillis(); + System.out.println("JFrame first creation took " + (end - start) + " ms"); - System.out.println("JFrame first creation took " + (end - start) + " ms"); + start = System.currentTimeMillis(); + f = new JFrame("JFrame"); + end = System.currentTimeMillis(); - start = System.currentTimeMillis(); - f = new JFrame("JFrame"); - end = System.currentTimeMillis(); - - System.out.println("JFrame second creation took " + (end - start) + " ms"); - System.exit(0); + System.out.println("JFrame second creation took " + (end - start) + " ms"); + System.exit(0); + } } } diff --git a/jdk/test/demo/jvmti/mtrace/TraceJFrame.java b/jdk/test/demo/jvmti/mtrace/TraceJFrame.java index 2a69f688990..c0dbe0ba960 100644 --- a/jdk/test/demo/jvmti/mtrace/TraceJFrame.java +++ b/jdk/test/demo/jvmti/mtrace/TraceJFrame.java @@ -37,7 +37,7 @@ import java.awt.GraphicsEnvironment; public class TraceJFrame { public static void main(String args[]) throws Exception { if (GraphicsEnvironment.isHeadless()) { - System.out.println("JFrame test was skipped due to headless mode"); + System.out.println("TraceJFrame test was skipped due to headless mode"); } else { DemoRun demo; From 81760b349894fedcded270be1af658730645ed65 Mon Sep 17 00:00:00 2001 From: Miroslav Kos <mkos@openjdk.org> Date: Fri, 23 May 2014 16:24:18 +0200 Subject: [PATCH 137/157] 8039210: Fix type error in DefaultResourceInjector Adding generic types to method call; blocker for fixing javac issue Reviewed-by: chegar --- .../sun/xml/internal/ws/server/DefaultResourceInjector.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/server/DefaultResourceInjector.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/server/DefaultResourceInjector.java index 73cd2c46cd5..8600d0184a7 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/server/DefaultResourceInjector.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/server/DefaultResourceInjector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ import javax.xml.ws.WebServiceContext; */ public final class DefaultResourceInjector extends ResourceInjector { public void inject(@NotNull WSWebServiceContext context, @NotNull Object instance) { - InjectionPlan.buildInjectionPlan( + InjectionPlan.<Object, WebServiceContext>buildInjectionPlan( instance.getClass(),WebServiceContext.class,false).inject(instance,context); } From a6da88c8ad0993d499a934d24cc2d9493586962b Mon Sep 17 00:00:00 2001 From: Miroslav Kos <mkos@openjdk.org> Date: Fri, 23 May 2014 16:25:43 +0200 Subject: [PATCH 138/157] 8043129: JAF initialisation in SAAJ clashing with the one in javax.mail Reviewed-by: chegar --- .../xml/internal/messaging/saaj/soap/AttachmentPartImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/AttachmentPartImpl.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/AttachmentPartImpl.java index bc35f38f8da..ead4533885d 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/AttachmentPartImpl.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/AttachmentPartImpl.java @@ -582,7 +582,8 @@ public class AttachmentPartImpl extends AttachmentPart { mailMap.addMailcap("text/xml;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.XmlDataContentHandler"); mailMap.addMailcap("application/xml;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.XmlDataContentHandler"); mailMap.addMailcap("application/fastinfoset;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.FastInfosetDataContentHandler"); - mailMap.addMailcap("multipart/*;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.MultipartDataContentHandler"); + // this handler seems to be not used according VCS history ... + // mailMap.addMailcap("multipart/*;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.MultipartDataContentHandler"); mailMap.addMailcap("image/*;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.ImageDataContentHandler"); mailMap.addMailcap("text/plain;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.StringDataContentHandler"); } From 4cac8137e0a3171ab8d74adaad2b20cf42132697 Mon Sep 17 00:00:00 2001 From: Miroslav Kos <mkos@openjdk.org> Date: Fri, 23 May 2014 16:35:10 +0200 Subject: [PATCH 139/157] 8043129: JAF initialisation in SAAJ clashing with the one in javax.mail Reviewed-by: chegar --- jdk/test/javax/xml/ws/8043129/MailTest.java | 148 +++++++++++++++++++ jdk/test/javax/xml/ws/8043129/javax.mail.jar | Bin 0 -> 571102 bytes 2 files changed, 148 insertions(+) create mode 100644 jdk/test/javax/xml/ws/8043129/MailTest.java create mode 100644 jdk/test/javax/xml/ws/8043129/javax.mail.jar diff --git a/jdk/test/javax/xml/ws/8043129/MailTest.java b/jdk/test/javax/xml/ws/8043129/MailTest.java new file mode 100644 index 00000000000..3d32a7d4dd8 --- /dev/null +++ b/jdk/test/javax/xml/ws/8043129/MailTest.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @bug 8043129 + * @summary JAF initialisation in SAAJ clashing with the one in javax.mail + * @author mkos + * @library javax.mail.jar + * @build MailTest + * @run main MailTest + */ + +import javax.activation.CommandMap; +import javax.activation.MailcapCommandMap; +import javax.mail.BodyPart; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Multipart; +import javax.mail.Session; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; +import javax.xml.soap.AttachmentPart; +import javax.xml.soap.MessageFactory; +import javax.xml.soap.SOAPException; +import javax.xml.soap.SOAPMessage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Properties; + +public class MailTest { + + String host = null; + String user = ""; + String password = null; + String from = null; + String to = null; + + public static void main(String[] args) { + MailTest t = new MailTest(); + + t.user = "somebody@somewhere.com"; + t.from = "somebody@somewhere.com"; + t.to = "somebody@somewhere.com"; + + t.user = "somebody@somewhere.com"; + t.password = "somepassword"; + t.host = "somehost"; + + t.sendMail(); //this works + + t.addSoapAttachement(); + t.sendMail(); //after addAttachmentPart to soapmessage it do not work + + // workaroundJAFSetup(); + // t.sendMail(); //after workaround works again + } + + void addSoapAttachement() { + try { + MessageFactory messageFactory = MessageFactory.newInstance(); + SOAPMessage message = messageFactory.createMessage(); + AttachmentPart a = message.createAttachmentPart(); + a.setContentType("binary/octet-stream"); + message.addAttachmentPart(a); + } catch (SOAPException e) { + e.printStackTrace(); + } + } + + void sendMail() { + + try { + Properties props = new Properties(); + props.put("mail.smtp.host", host); + props.put("mail.smtp.auth", "true"); + + Session session = Session.getInstance(props); + session.setDebug(true); + + // Define message + MimeMessage message = new MimeMessage(session); + message.setFrom(new InternetAddress(from)); + message.addRecipients(Message.RecipientType.TO, to); + message.setSubject("this is a multipart test"); + + Multipart multipart = new MimeMultipart(); + + BodyPart messageBodyPart1 = new MimeBodyPart(); + messageBodyPart1.setText("please send also this Content\n ciao!"); + multipart.addBodyPart(messageBodyPart1); + + BodyPart messageBodyPart2 = new MimeBodyPart(); + messageBodyPart2.setContent("<b>please</b> send also this Content <br>ciao!", "text/html; charset=UTF-8"); + multipart.addBodyPart(messageBodyPart2); + + message.setContent(multipart); + + /* + Transport tr = session.getTransport("smtp"); + tr.connect(host,user, password); + tr.sendMessage(message,InternetAddress.parse(to)); + tr.close(); + */ + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + message.writeTo(baos); + String output = baos.toString(); + System.out.println("output = " + output); + if (output.contains("also this Content")) { + System.out.println("Test PASSED."); + } else { + System.out.println("Test FAILED, missing content."); + throw new IllegalStateException("Test FAILED, missing content."); + } + } catch (MessagingException ignored) { + } catch (IOException ignored) { + } + } + + // this is how the error can be worked around ... + static void workaroundJAFSetup() { + MailcapCommandMap mailMap = (MailcapCommandMap) CommandMap.getDefaultCommandMap(); + mailMap.addMailcap("multipart/mixed;;x-java-content-handler=com.sun.mail.handlers.multipart_mixed"); + } +} diff --git a/jdk/test/javax/xml/ws/8043129/javax.mail.jar b/jdk/test/javax/xml/ws/8043129/javax.mail.jar new file mode 100644 index 0000000000000000000000000000000000000000..7da28712d88504c45494db4e02278b12f60c5c0f GIT binary patch literal 571102 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ⅈ#hAO%=&<jCE_CbLMH2n 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	YddO5%m3;&JQ{_%m;~6#O@R|Z5 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Π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 literal 0 HcmV?d00001 From 9be082f40218196392e111c132c0f77dc212a7d7 Mon Sep 17 00:00:00 2001 From: Rob McKenna <robm@openjdk.org> Date: Fri, 23 May 2014 16:24:43 +0100 Subject: [PATCH 140/157] 8042857: 14 stuck threads waiting for notification on LDAPRequest Reviewed-by: vinnie --- .../classes/com/sun/jndi/ldap/Connection.java | 4 +- .../com/sun/jndi/ldap/LdapTimeoutTest.java | 45 +++++++++++++++---- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java index 65a675ffdf5..a0643a6ad29 100644 --- a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java +++ b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -459,10 +459,10 @@ public final class Connection implements Runnable { // will be woken up before readTimeout only if reply is // available ldr.wait(readTimeout); - waited = true; } else { ldr.wait(15 * 1000); // 15 second timeout } + waited = true; } else { break; } diff --git a/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java b/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java index 0db3ab9239c..39270374488 100644 --- a/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java +++ b/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,11 +64,12 @@ public class LdapTimeoutTest { env.put(Context.SECURITY_PRINCIPAL, "user"); env.put(Context.SECURITY_CREDENTIALS, "password"); - env.put("com.sun.jndi.ldap.connect.timeout", "10"); - env.put("com.sun.jndi.ldap.read.timeout", "3000"); - InitialContext ctx = null; try { + new LdapTimeoutTest().deadServerNoTimeout(env); + + env.put("com.sun.jndi.ldap.connect.timeout", "10"); + env.put("com.sun.jndi.ldap.read.timeout", "3000"); new LdapTimeoutTest().ldapReadTimeoutTest(env, false); new LdapTimeoutTest().ldapReadTimeoutTest(env, true); new LdapTimeoutTest().simpleAuthConnectTest(env); @@ -84,7 +85,7 @@ public class LdapTimeoutTest { void ldapReadTimeoutTest(Hashtable env, boolean ssl) { InitialContext ctx = null; if (ssl) env.put(Context.SECURITY_PROTOCOL, "ssl"); - ScheduledFuture killer = killSwitch(); + ScheduledFuture killer = killSwitch(5000); long start = System.nanoTime(); try { ctx = new InitialDirContext(env); @@ -112,7 +113,7 @@ public class LdapTimeoutTest { void simpleAuthConnectTest(Hashtable env) { InitialContext ctx = null; - ScheduledFuture killer = killSwitch(); + ScheduledFuture killer = killSwitch(5000); long start = System.nanoTime(); try { ctx = new InitialDirContext(env); @@ -139,6 +140,32 @@ public class LdapTimeoutTest { } } + void deadServerNoTimeout(Hashtable env) { + InitialContext ctx = null; + ScheduledFuture killer = killSwitch(30000); + long start = System.nanoTime(); + try { + ctx = new InitialDirContext(env); + SearchControls scl = new SearchControls(); + scl.setSearchScope(SearchControls.SUBTREE_SCOPE); + NamingEnumeration<SearchResult> answer = ((InitialDirContext)ctx) + .search("ou=People,o=JNDITutorial", "(objectClass=*)", scl); + // shouldn't reach here + fail(); + } catch (NamingException e) { + long end = System.nanoTime(); + if (TimeUnit.NANOSECONDS.toMillis(end - start) < 14000) { + System.err.println("fail: timeout should be at least 15 seconds, actual time: " + + TimeUnit.NANOSECONDS.toMillis(end - start)); + fail(); + } else { + pass(); + } + } finally { + if (!shutItDown(killer, ctx)) fail(); + } + } + boolean shutItDown(ScheduledFuture killer, InitialContext ctx) { killer.cancel(true); try { @@ -149,15 +176,15 @@ public class LdapTimeoutTest { } } - ScheduledFuture killSwitch() { + ScheduledFuture killSwitch(int ms) { final Thread current = Thread.currentThread(); return LdapTimeoutTest.pool.schedule(new Callable<Void>() { public Void call() throws Exception { System.err.println("Fail: killSwitch()"); - current.interrupt(); + System.exit(0); return null; } - }, 5000, TimeUnit.MILLISECONDS); + }, ms, TimeUnit.MILLISECONDS); } static class Server extends Thread { From 659ff66142f2cd6227eb3a8f009cc1e71081750b Mon Sep 17 00:00:00 2001 From: Joe Wang <joehw@openjdk.org> Date: Fri, 23 May 2014 09:06:34 -0700 Subject: [PATCH 141/157] 8043666: Remove unused files from jaxp repository Reviewed-by: alanb --- .../internal/xsltc/compiler/Makefile.inc | 60 ------------------- .../javax.xml.transform.TransformerFactory | 1 - ...che.xerces.dom.DOMImplementationSourceImpl | 1 - .../org.w3c.dom.DOMImplementationSourceList | 1 - .../javax.xml.datatype.DatatypeFactory | 1 - .../javax.xml.parsers.DocumentBuilderFactory | 1 - .../jaxp/javax.xml.parsers.SAXParserFactory | 1 - .../javax.xml.validation.SchemaFactory | 1 - ....apache.xerces.xni.parser.DTDConfiguration | 1 - ...pache.xerces.xni.parser.XML11Configuration | 1 - ...e.xerces.xni.parser.XMLParserConfiguration | 1 - .../internal/parsers/org.xml.sax.driver | 2 - .../stream/javax.xml.stream.XMLEventFactory | 1 - .../stream/javax.xml.stream.XMLInputFactory | 1 - .../stream/javax.xml.stream.XMLOutputFactory | 1 - jaxp/src/org/xml/sax/COPYING | 12 ---- jaxp/src/org/xml/sax/COPYING.txt | 39 ------------ 17 files changed, 126 deletions(-) delete mode 100644 jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Makefile.inc delete mode 100644 jaxp/src/com/sun/org/apache/xalan/internal/xsltc/javax.xml.transform.TransformerFactory delete mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/dom/org.apache.xerces.dom.DOMImplementationSourceImpl delete mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/dom/org.w3c.dom.DOMImplementationSourceList delete mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/jaxp/datatype/javax.xml.datatype.DatatypeFactory delete mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/jaxp/javax.xml.parsers.DocumentBuilderFactory delete mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/jaxp/javax.xml.parsers.SAXParserFactory delete mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/javax.xml.validation.SchemaFactory delete mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.DTDConfiguration delete mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.XML11Configuration delete mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.XMLParserConfiguration delete mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.xml.sax.driver delete mode 100644 jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLEventFactory delete mode 100644 jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLInputFactory delete mode 100644 jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLOutputFactory delete mode 100644 jaxp/src/org/xml/sax/COPYING delete mode 100644 jaxp/src/org/xml/sax/COPYING.txt diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Makefile.inc b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Makefile.inc deleted file mode 100644 index 8c1f57a8b18..00000000000 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Makefile.inc +++ /dev/null @@ -1,60 +0,0 @@ -########################################################################### -# reserved comment block -# DO NOT REMOVE OR ALTER! -########################################################################### -########################################################################## -# Copyright 2001-2004 The Apache Software Foundation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################## -# -# $Id: Makefile.inc,v 1.2 2004/02/17 16:32:49 minchau Exp $ -# -#################################################################### -# # -# Makefile.inc for XSLT compiler # -# # -#################################################################### - -#################################################################### -# Useful macros # -#################################################################### - -JAVAC = javac -#JAVAC_FLAGS = -g -d $(XSLT)/src/classes -JAVAC_FLAGS = -sourcepath $(XSLT)/src -JAVACC = javacc -JAVACC_FLAGS = -static=FALSE -JAVACUP = javacup -JAVACUP_FLAGS = -JAVALEX = jlex -JAVALEX_FLAGS = - -#################################################################### -# Explicit rules # -#################################################################### - -.SUFFIXES: .java .class .jj .lex .cup - -.java.class: - $(JAVAC) $(JAVAC_FLAGS) $< - -.jj.java: - $(JAVACC) $(JAVACC_FLAGS) $< - -.cup.java: - $(JAVACUP) $(JAVACUP_FLAGS) $< - -.lex.java: - $(JAVALEX) $(JAVALEX_FLAGS) $< - diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/javax.xml.transform.TransformerFactory b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/javax.xml.transform.TransformerFactory deleted file mode 100644 index a607891fefd..00000000000 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/javax.xml.transform.TransformerFactory +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/dom/org.apache.xerces.dom.DOMImplementationSourceImpl b/jaxp/src/com/sun/org/apache/xerces/internal/dom/org.apache.xerces.dom.DOMImplementationSourceImpl deleted file mode 100644 index 79c33dd2078..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/dom/org.apache.xerces.dom.DOMImplementationSourceImpl +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.dom.DOMImplementationSourceImpl diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/dom/org.w3c.dom.DOMImplementationSourceList b/jaxp/src/com/sun/org/apache/xerces/internal/dom/org.w3c.dom.DOMImplementationSourceList deleted file mode 100644 index 814f03139f0..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/dom/org.w3c.dom.DOMImplementationSourceList +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.dom.DOMXSImplementationSourceImpl diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/datatype/javax.xml.datatype.DatatypeFactory b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/datatype/javax.xml.datatype.DatatypeFactory deleted file mode 100644 index 4a5c28226b5..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/datatype/javax.xml.datatype.DatatypeFactory +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/javax.xml.parsers.DocumentBuilderFactory b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/javax.xml.parsers.DocumentBuilderFactory deleted file mode 100644 index dc39440e898..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/javax.xml.parsers.DocumentBuilderFactory +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/javax.xml.parsers.SAXParserFactory b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/javax.xml.parsers.SAXParserFactory deleted file mode 100644 index cd8406950db..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/javax.xml.parsers.SAXParserFactory +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/javax.xml.validation.SchemaFactory b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/javax.xml.validation.SchemaFactory deleted file mode 100644 index 51d33a674c7..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/javax.xml.validation.SchemaFactory +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.DTDConfiguration b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.DTDConfiguration deleted file mode 100644 index 8f6ac8baba9..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.DTDConfiguration +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.parsers.DTDConfiguration diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.XML11Configuration b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.XML11Configuration deleted file mode 100644 index af1926488fd..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.XML11Configuration +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.parsers.XML11Configuration diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.XMLParserConfiguration b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.XMLParserConfiguration deleted file mode 100644 index ca8bc3e7232..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.XMLParserConfiguration +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.xml.sax.driver b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.xml.sax.driver deleted file mode 100644 index e1a387435c4..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.xml.sax.driver +++ /dev/null @@ -1,2 +0,0 @@ -com.sun.org.apache.xerces.internal.parsers.SAXParser - diff --git a/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLEventFactory b/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLEventFactory deleted file mode 100644 index adc26b34340..00000000000 --- a/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLEventFactory +++ /dev/null @@ -1 +0,0 @@ -com.sun.xml.internal.stream.events.XMLEventFactoryImpl diff --git a/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLInputFactory b/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLInputFactory deleted file mode 100644 index 456882c2cb3..00000000000 --- a/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLInputFactory +++ /dev/null @@ -1 +0,0 @@ -com.sun.xml.internal.stream.XMLInputFactoryImpl diff --git a/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLOutputFactory b/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLOutputFactory deleted file mode 100644 index 3de51905314..00000000000 --- a/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLOutputFactory +++ /dev/null @@ -1 +0,0 @@ -com.sun.xml.internal.stream.XMLOutputFactoryImpl diff --git a/jaxp/src/org/xml/sax/COPYING b/jaxp/src/org/xml/sax/COPYING deleted file mode 100644 index dd0b9813dbc..00000000000 --- a/jaxp/src/org/xml/sax/COPYING +++ /dev/null @@ -1,12 +0,0 @@ -SAX IS FREE ------------ - -I hereby abandon any property rights to SAX 2.0 (the Simple API for -XML), and release all of the SAX 2.0 source code, compiled code, and -documentation contained in this distribution into the Public Domain. -SAX comes with NO WARRANTY or guarantee of fitness for any purpose. - - -David Megginson -david@megginson.com -2000-01-14 diff --git a/jaxp/src/org/xml/sax/COPYING.txt b/jaxp/src/org/xml/sax/COPYING.txt deleted file mode 100644 index 27518b4b9cc..00000000000 --- a/jaxp/src/org/xml/sax/COPYING.txt +++ /dev/null @@ -1,39 +0,0 @@ - SAX COPYRIGHT STATUS - -Version 1.0 of the Simple API for XML (SAX), created collectively by -the membership of the XML-DEV mailing list, is hereby released into -the public domain. - -No one owns SAX: you may use it freely in both commercial and -non-commercial applications, bundle it with your software -distribution, include it on a CD-ROM, list the source code in a book, -mirror the documentation at your own web site, or use it in any other -way you see fit. - - - NO WARRANTY - -Because SAX is released to the public domain, there is no warranty for -the design or for the software implementation, to the extent permitted -by applicable law. Except when otherwise stated in writing the -copyright holders and/or other parties provide SAX "as is" without -warranty of any kind, either expressed or implied, including, but not -limited to, the implied warranties of merchantability and fitness for -a particular purpose. The entire risk as to the quality and -performance of SAX is with you. Should SAX prove defective, you -assume the cost of all necessary servicing, repair or correction. - -In no event unless required by applicable law or agreed to in writing -will any copyright holder, or any other party who may modify and/or -redistribute SAX, be liable to you for damages, including any general, -special, incidental or consequential damages arising out of the use or -inability to use SAX (including but not limited to loss of data or -data being rendered inaccurate or losses sustained by you or third -parties or a failure of the SAX to operate with any other programs), -even if such holder or other party has been advised of the possibility -of such damages. - - -David Megginson <sax@megginson.com> -1998-05-11 - From 7f334fe1a10fdc7b5a830f5740602ff3e63bfeca Mon Sep 17 00:00:00 2001 From: Rob McKenna <robm@openjdk.org> Date: Fri, 23 May 2014 19:42:16 +0100 Subject: [PATCH 142/157] 8041451: com.sun.jndi.ldap.Connection:ReadTimeout should abandon ldap request Reviewed-by: vinnie --- jdk/src/share/classes/com/sun/jndi/ldap/Connection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java index a0643a6ad29..d41c94480e9 100644 --- a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java +++ b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java @@ -474,7 +474,7 @@ public final class Connection implements Runnable { } if ((rber == null) && waited) { - removeRequest(ldr); + abandonRequest(ldr, null); throw new NamingException("LDAP response read timed out, timeout used:" + readTimeout + "ms." ); From f7940fec73be71e6a5ea2c80d7087438c548db33 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan <sundar@openjdk.org> Date: Mon, 26 May 2014 15:48:25 +0530 Subject: [PATCH 143/157] 8043930: TypeError when attemping to create an instance of non-public class could be better Reviewed-by: attila, lagergren --- .../linker/NashornStaticClassLinker.java | 6 +++ .../runtime/resources/Messages.properties | 1 + nashorn/test/script/basic/JDK-8043930.js | 37 +++++++++++++++++++ .../test/script/basic/JDK-8043930.js.EXPECTED | 1 + 4 files changed, 45 insertions(+) create mode 100644 nashorn/test/script/basic/JDK-8043930.js create mode 100644 nashorn/test/script/basic/JDK-8043930.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java index 272b4ec0ac4..f8ea9916041 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java @@ -25,6 +25,7 @@ package jdk.nashorn.internal.runtime.linker; +import java.lang.reflect.Modifier; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.beans.BeansLinker; import jdk.internal.dynalink.beans.StaticClass; @@ -65,10 +66,15 @@ final class NashornStaticClassLinker implements TypeBasedGuardingDynamicLinker { return null; } final Class<?> receiverClass = ((StaticClass) self).getRepresentedClass(); + Bootstrap.checkReflectionAccess(receiverClass, true); final CallSiteDescriptor desc = request.getCallSiteDescriptor(); // We intercept "new" on StaticClass instances to provide additional capabilities if ("new".equals(desc.getNameToken(CallSiteDescriptor.OPERATOR))) { + if (! Modifier.isPublic(receiverClass.getModifiers())) { + throw ECMAErrors.typeError("new.on.nonpublic.javatype", receiverClass.getName()); + } + // make sure new is on accessible Class Context.checkPackageAccess(receiverClass); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties index 47248fce715..c98c1c7c84a 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties @@ -138,6 +138,7 @@ type.error.no.method.matches.args=Can not invoke method {0} with the passed argu type.error.method.not.constructor=Java method {0} can't be used as a constructor. type.error.env.not.object=$ENV must be an Object. type.error.unsupported.java.to.type=Unsupported Java.to target type {0}. +type.error.new.on.nonpublic.javatype=new cannot be used with non-public java type {0}. range.error.dataview.constructor.offset=Wrong offset or length in DataView constructor range.error.dataview.offset=Offset is outside the bounds of the DataView diff --git a/nashorn/test/script/basic/JDK-8043930.js b/nashorn/test/script/basic/JDK-8043930.js new file mode 100644 index 00000000000..a89b3541e37 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8043930.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8043930: TypeError when attemping to create an instance of non-public class could be better + * + * @test + * @run + */ + +var NonPublicClass = Java.type("jdk.nashorn.test.models.NonPublicClass"); +try { + var obj = new NonPublicClass(); + fail("Expected TypeError to be thrown!"); +} catch (e) { + print(e); +} diff --git a/nashorn/test/script/basic/JDK-8043930.js.EXPECTED b/nashorn/test/script/basic/JDK-8043930.js.EXPECTED new file mode 100644 index 00000000000..ee5cf9dc81c --- /dev/null +++ b/nashorn/test/script/basic/JDK-8043930.js.EXPECTED @@ -0,0 +1 @@ +TypeError: new cannot be used with non-public java type jdk.nashorn.test.models.NonPublicClass. From 9de45895e7150984d299a81e4a380ccca6b0ecde Mon Sep 17 00:00:00 2001 From: Miroslav Kos <mkos@openjdk.org> Date: Mon, 26 May 2014 14:59:14 +0200 Subject: [PATCH 144/157] 8043762: Remove unused files from jaxws repository Reviewed-by: alanb --- ...l.internal.ws.spi.db.BindingContextFactory | 2 - .../tools/internal/jxc/gen/config/config.rng | 131 -- .../xjc/reader/dtd/bindinfo/bindingfile.rng | 317 --- .../xjc/reader/xmlschema/bindinfo/binding.rng | 913 -------- .../xmlschema/xmlschema-for-jaxb.rng | 1579 ------------- .../rngom/parse/compact/CompactSyntax.jj | 1963 ----------------- .../{pacakge-info.java => package-info.java} | 2 +- 7 files changed, 1 insertion(+), 4906 deletions(-) delete mode 100644 jaxws/src/share/jaxws_classes/com/sun/tools/etc/META-INF/services/com.sun.xml.internal.ws.spi.db.BindingContextFactory delete mode 100644 jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/config.rng delete mode 100644 jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/dtd/bindinfo/bindingfile.rng delete mode 100644 jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/xmlschema/bindinfo/binding.rng delete mode 100644 jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/schemagen/xmlschema/xmlschema-for-jaxb.rng delete mode 100644 jaxws/src/share/jaxws_classes/com/sun/xml/internal/rngom/parse/compact/CompactSyntax.jj rename jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/{pacakge-info.java => package-info.java} (95%) diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/etc/META-INF/services/com.sun.xml.internal.ws.spi.db.BindingContextFactory b/jaxws/src/share/jaxws_classes/com/sun/tools/etc/META-INF/services/com.sun.xml.internal.ws.spi.db.BindingContextFactory deleted file mode 100644 index 36ea2a98abe..00000000000 --- a/jaxws/src/share/jaxws_classes/com/sun/tools/etc/META-INF/services/com.sun.xml.internal.ws.spi.db.BindingContextFactory +++ /dev/null @@ -1,2 +0,0 @@ -com.sun.xml.internal.ws.db.glassfish.JAXBRIContextFactory -# com.sun.xml.internal.ws.db.toplink.JAXBContextFactory diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/config.rng b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/config.rng deleted file mode 100644 index 59bcb4e49bc..00000000000 --- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/config.rng +++ /dev/null @@ -1,131 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright (c) 1997, 2012, 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. ---> - -<grammar - xmlns="http://relaxng.org/ns/structure/1.0" - xmlns:r="http://relaxng.org/ns/structure/1.0" - xmlns:a="http://relaxng.org/ns/annotation/1.0" - xmlns:ref="urn:crossreference" - xmlns:c="http://www.xml.gr.jp/xmlns/relaxngcc" - c:runtime-type="com.sun.tools.internal.jxc.NGCCRuntimeEx" - datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" - c:package="com.sun.tools.internal.jxc.gen.config"> - - -<start c:class="Config" c:access="public"> - - <c:java-import> - import java.util.List; - import java.util.ArrayList; - import java.io.File; - </c:java-import> - -<c:java-body> - private File baseDir; - private Classes classes; - private List schema = new ArrayList(); - public Classes getClasses() { return this.classes;} - public File getBaseDir() { return baseDir;} - public List getSchema() { return this.schema;} -</c:java-body> - - <element name="config"> - <attribute name="baseDir"> - bd = <data type="string"/> - baseDir = $runtime.getBaseDir(bd); - </attribute> - <ref name="Classes" c:alias="classes"/> - <zeroOrMore> - <ref name="Schema" c:alias="_schema" />(baseDir); - this.schema.add (_schema); - </zeroOrMore> - </element> - </start> - - - <define name="Classes" c:access="public"> - <c:java-import> - import java.util.List; - import java.util.ArrayList; - </c:java-import> - <c:java-body> - private List includes = new ArrayList(); - public List getIncludes() { return $runtime.getIncludePatterns(this.includes);} - private List excludes = new ArrayList(); - public List getExcludes() { return $runtime.getExcludePatterns(this.excludes);} - </c:java-body> - <element name="classes"> - - <element name="includes"> - <list> - <oneOrMore> - <data type="string" c:alias="include_content"/> - <c:java> this.includes.add(include_content); </c:java> - </oneOrMore> - </list> - - </element> - <optional> - <element name="excludes"> - <list> - <zeroOrMore> - <data type="string" c:alias="exclude_content"/> - <c:java> this.excludes.add(exclude_content); </c:java> - </zeroOrMore> - </list> - - </element> - </optional> - </element> - </define> - - - <define name="Schema" c:access="public" c:params="File baseDir"> - <c:java-import> - import java.io.File; - </c:java-import> - <c:java-body> - private File location; - private String namespace; - public String getNamespace() { return this.namespace;} - public File getLocation() { return this.location;} - </c:java-body> - <element name="schema"> - <optional> - <attribute name="namespace"> - namespace = <data type="string" /> - </attribute> - </optional> - - <optional> - <attribute name="location"> - loc = <data type="string" /> - location = new File(baseDir,loc); - </attribute> - </optional> - </element> - </define> -</grammar> diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/dtd/bindinfo/bindingfile.rng b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/dtd/bindinfo/bindingfile.rng deleted file mode 100644 index 41c18ff0d1d..00000000000 --- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/dtd/bindinfo/bindingfile.rng +++ /dev/null @@ -1,317 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright (c) 1997, 2012, 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. ---> - -<!-- -DTD binding information file which is supported by this version of XJC. - -- Changes from the EA1 is marked by "CHANGE:" -- "ref:key" and "ref:keyref" are used to specify cross-reference - information. -- "a:defaultValue" is used to specify the default behavior. - Note that default behaviors are hard-coded to the source code. - Values specified in this schema is not used in the actual processing. ---> -<grammar - xmlns="http://relaxng.org/ns/structure/1.0" - xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" - xmlns:a="http://relaxng.org/ns/annotation/1.0" - xmlns:ref="urn:crossreference" - datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> - - <start> - <element name="xml-java-binding-schema"> - <optional> - <attribute name="version"> - <value>1.0ea2</value> - </attribute> - </optional> - - <interleave> - <optional> - <element name="options"> - <optional> - <attribute name="package"/> - </optional> - </element> - </optional> - <optional> - <element name="xjc:serializable"> - <optional> - <attribute name="uid"> - <data type="long"/> - </attribute> - </optional> - </element> - </optional> - <optional> - <element name="xjc:superClass"> - <attribute name="name"/> - </element> - </optional> - <!-- light-weight runtime --> - <optional> - <element name="xjc:noMarshaller"> - <empty/> - </element> - </optional> - <optional> - <element name="xjc:noUnmarshaller"> - <empty/> - </element> - </optional> - <optional> - <element name="xjc:noValidator"> - <empty/> - </element> - </optional> - <optional> - <element name="xjc:noValidatingUnmarshaller"> - <empty/> - </element> - </optional> - <zeroOrMore> - <choice> - <ref name="toplevel.declaration"/> - <ref name="global.or.local.declaration"/> - </choice> - </zeroOrMore> - </interleave> - </element> - </start> - - - - - <!-- element-class declaration --> - <define name="toplevel.declaration" combine="choice"> - <element name="element"> - <attribute name="name"/> - <attribute name="type"> - <value>class</value> - </attribute> - <optional> - <attribute name="class"> - <ref name="java.classname.datatype"/> - </attribute> - </optional> - <optional> - <attribute name="root" a:defaultValue="false"> - <choice> - <value>true</value> - <value>false</value> - </choice> - </attribute> - </optional> - - <interleave> - <!-- attribute-property declaration --> - <zeroOrMore> - <element name="attribute"> - <attribute name="name"/> - <optional> - <attribute name="property"/> - </optional> - <optional> - <ref name="collection.att"/> - </optional> - <optional> - <attribute name="convert"> - <text ref:keyref="conversion"/> - </attribute> - </optional> - </element> - </zeroOrMore> - - <zeroOrMore> - <ref name="global.or.local.declaration"/> - </zeroOrMore> - - <!-- element-local declarations --> - <zeroOrMore> - <element name="constructor"> - <attribute name="properties"> - <list> - <oneOrMore> - <!-- point to a property defined in this element --> - <data type="token"/> - </oneOrMore> - </list> - </attribute> - </element> - </zeroOrMore> - - <optional> - <element name="content"> - <interleave> - <choice> - <!-- general content-property declaration --> - <ref name="collection.particle.decl"/> - - <!-- model-based content property declaration --> - <group> - <zeroOrMore> - <choice> - <element name="element-ref"> - <attribute name="name"/> - <optional> - <attribute name="property"/> - </optional> - <optional> - <ref name="collection.att"/> - </optional> - </element> - <element> - <choice> - <name>sequence</name> - <name>choice</name> - </choice> - <ref name="collection.particle.decl"/> - </element> - </choice> - </zeroOrMore> - <optional><!-- followed by an optional <rest> --> - <element name="rest"> - <ref name="collection.particle.decl"/> - </element> - </optional> - </group> - </choice> - </interleave> - </element> - </optional> - </interleave> - </element> - </define> - - <define name="collection.particle.decl"> - <attribute name="property"/> - <optional> - <ref name="collection.att"/> - </optional> - <optional> - <attribute name="supertype"/> - </optional> - </define> - - <define name="collection.att"> - <attribute name="collection"> - <!-- CHANGE: array is removed and set,vector are added --> - <choice> - <value>list</value> - <value>set</value> - <value>vector</value> - </choice> - </attribute> - </define> - - - - <!-- conversion declaration --> - <define name="global.or.local.declaration" combine="choice"> - <element name="conversion"> - <attribute name="name" ref:key="conversion"/> - <optional> - <!-- defaults to @name --> - <attribute name="type"/> - </optional> - <optional> - <attribute name="parse" a:defaultValue="new"/> - </optional> - <optional> - <attribute name="print" a:defaultValue="toString"/> - </optional> - <optional> - <attribute name="whitespace" a:defaultValue="collapse"> - <choice> - <value>preserve</value> - <value>replace</value><!-- CHANGE: it was normalize --> - <value>collapse</value> - </choice> - </attribute> - </optional> - </element> - </define> - - <!-- element-value declaration --> - <define name="toplevel.declaration" combine="choice"> - <element name="element"> - <attribute name="name"/> - <attribute name="type"> - <value>value</value> - </attribute> - <optional> - <attribute name="convert"> - <text ref:keyref="conversion"/> - </attribute> - </optional> - </element> - </define> - - <!-- interface declaration --> - <define name="toplevel.declaration" combine="choice"> - <element name="interface"> - <attribute name="name"> - <ref name="java.classname.datatype"/> - </attribute> - <attribute name="members"> - <list> - <oneOrMore> - <ref name="java.classname.datatype"/> - </oneOrMore> - </list> - </attribute> - <!-- CHANGE: TODO: @properties is not supported yet --> - </element> - </define> - - <!-- enumeration declaration --> - <define name="global.or.local.declaration" combine="choice"> - <element name="enumeration"> - <attribute name="name"> - <ref name="java.classname.datatype"/> - </attribute> - <attribute name="members"> - <list> - <oneOrMore> - <data type="token"/> - </oneOrMore> - </list> - </attribute> - </element> - </define> - - - - <!-- valid Java name --> - <define name="java.name.datatype"> - <!-- TODO: add pattern facet or implement a custom datatype --> - <data type="token"/> - </define> - - <define name="java.classname.datatype"> - <ref name="java.name.datatype"/> - </define> -</grammar> diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/xmlschema/bindinfo/binding.rng b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/xmlschema/bindinfo/binding.rng deleted file mode 100644 index f689228d585..00000000000 --- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/xmlschema/bindinfo/binding.rng +++ /dev/null @@ -1,913 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright (c) 1997, 2012, 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. ---> - -<!DOCTYPE grammar [ - - -<!ENTITY XJCURI "http://java.sun.com/xml/ns/jaxb/xjc"> -]> -<grammar - xmlns="http://relaxng.org/ns/structure/1.0" - xmlns:cc="http://www.xml.gr.jp/xmlns/relaxngcc" - xmlns:xs="http://www.w3.org/2001/XMLSchema" - xmlns:xjc="&XJCURI;" - xmlns:p="post-processor-to-build-schema-for-validation" - - ns="http://java.sun.com/xml/ns/jaxb" - - cc:runtime-type="com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.NGCCRuntimeEx" - cc:package="com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.parser" - datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> -<!-- cc:$runtime-type="com.sun.xml.internal.xsom.impl.parser.NGCCRuntimeEx">--> - - <cc:java-import> - import com.sun.codemodel.internal.*; - import com.sun.tools.internal.xjc.generator.bean.field.*; - import com.sun.tools.internal.xjc.model.*; - import com.sun.xml.internal.bind.api.impl.NameConverter; - import com.sun.xml.internal.bind.v2.WellKnownNamespace; - import com.sun.xml.internal.bind.marshaller.SAX2DOMEx; - import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.*; - import com.sun.tools.internal.xjc.reader.Const; - import org.xml.sax.*; - import org.w3c.dom.Document; - import org.xml.sax.helpers.DefaultHandler; - import java.util.*; - import javax.xml.namespace.QName; - import javax.xml.parsers.ParserConfigurationException; - </cc:java-import> - - <start cc:class="Root"> - <choice> - <!-- root of the external binding file. --> - <ref name="declaration"/> - <!-- root of the internal binding --> - <ref name="annotation"/> - </choice> - </start> - - <!-- - in context of XML Schema annotation - --> - <define name="annotation" cc:access="public" cc:class="AnnotationState" - cc:return-type="BindInfo" cc:return-value="bi"> - - <cc:java-import> - import java.io.StringWriter; - import com.sun.xml.internal.bind.marshaller.DataWriter; - </cc:java-import> - <cc:java-body> - // customization declarations - public BindInfo bi; - - private StringWriter w; - - private SAX2DOMEx sax2dom; - </cc:java-body> - - <element name="xs:annotation"> - bi = new BindInfo($runtime.copyLocator()); - $runtime.currentBindInfo = bi; - - <p:ignore><ref name="anyAttributes"/></p:ignore> - <zeroOrMore> - <choice> - <element name="xs:appinfo"> - <p:ignore><ref name="anyAttributes"/></p:ignore> - <zeroOrMore> - <choice> - <group> - result = <ref name="declaration" /> - bi.addDecl(result); - </group> - <element> - <anyName><except> - <nsName ns="&XJCURI;"/> - <nsName /><!-- JAXB namespace URI --> - <nsName ns="http://www.w3.org/2001/XMLSchema" /> - </except></anyName> - - if($runtime.isExtensionURI($uri)) { - // parse this sub-tree as an extension - try { - sax2dom = new SAX2DOMEx(); - } catch( ParserConfigurationException e ) { - throw new Error(e); // impossible - } - $runtime.redirectSubtree(sax2dom,$uri,$localName,$qname); - } else { - // ignore this sub-tree - sax2dom = null; - $runtime.redirectSubtree(new DefaultHandler(),$uri,$localName,$qname); - } - <empty/> - <p:ignore><ref name="anyContents"/></p:ignore> - if(sax2dom!=null) { - bi.addDecl(new BIXPluginCustomization(((Document)sax2dom.getDOM()).getDocumentElement(),$runtime.copyLocator())); - } - </element> - <text/> - </choice> - </zeroOrMore> - </element> - <!-- ignore documentations --> - <element name="xs:documentation"> - <p:ignore><ref name="anyAttributes"/></p:ignore> - <zeroOrMore> - <choice> - <group> - msg = <text /> - bi.appendDocumentation($runtime.truncateDocComment(msg),true); - </group> - <group> - <element> - <anyName /> - w = new StringWriter(); - DataWriter xw = new DataWriter(w,"UTF-8"); - xw.setXmlDecl(false); - $runtime.redirectSubtree(xw,$uri,$localName,$qname); - <empty/> - <p:ignore><ref name="anyContents"/></p:ignore> - </element> - <![CDATA[ - bi.appendDocumentation("<pre>"+ - $runtime.escapeMarkup($runtime.truncateDocComment(w.toString()))+ - "</pre>", - false ); - w=null; - ]]> - </group> - </choice> - </zeroOrMore> - </element> - </choice> - </zeroOrMore> - </element> - </define> - - - - <!-- - - Individual customization declarations - - --> - - <define name="declaration" - cc:return-type="BIDeclaration" cc:return-value="result"> - - <cc:java-body> - private BIDeclaration result; - </cc:java-body> - <!-- result field will have the parsed object --> - <choice> - result = <ref name="globalBindings" /> - result = <ref name="schemaBindings" /> - result = <ref name="class"/> - result = <ref name="conversion"/> - result = <ref name="property"/> - result = <ref name="typesafeEnum"/> - result = <ref name="enumMember"/> - <!-- result = <ref name="idSymbolSpace"/--> - <!-- result = <ref name="dom"/--> - </choice> - </define> - - - <define name="globalBindings" - cc:return-type="BIGlobalBinding" cc:return-value="makeResult()"> - - <cc:java-body> - private Locator loc; - private Map globalConvs = new HashMap(); - private NameConverter nameConverter = NameConverter.standard; - private String enableJavaNamingConvention = "true"; - private String fixedAttrToConstantProperty = "false"; - private String needIsSetMethod = "false"; - private String simpleTypeSubstitution = "false"; - private boolean flattenClasses = false; - private Set enumBaseTypes = new HashSet(); - private int defaultEnumSizeCap = 256; - private boolean generateEnumMemberName = false; - private boolean choiceContentPropertyWithModelGroupBinding = false; - private boolean xSmartWildcardDefaultBinding = false; - private boolean xSimpleMode; - private boolean generateValueClass = true; - private boolean generateElementClass = false; - private boolean generateMixedExtensions = false; - - public BIGlobalBinding makeResult() { - if( enumBaseTypes.size()==0 ) - enumBaseTypes.add(new QName(WellKnownNamespace.XML_SCHEMA,"NCName")); // defaults to NCName - - return new BIGlobalBinding( - globalConvs,nameConverter, - choiceContentPropertyWithModelGroupBinding, - generateValueClass, - generateElementClass, - $runtime.parseBoolean(enableJavaNamingConvention), - $runtime.parseBoolean(fixedAttrToConstantProperty), - $runtime.parseBoolean(needIsSetMethod), - $runtime.parseBoolean(simpleTypeSubstitution), - generateEnumMemberName, - flattenClasses, - enumBaseTypes, - defaultEnumSizeCap, - ct, - serializable, - xSuperClass, - xSuperInterface, - xSimpleMode, - xSmartWildcardDefaultBinding, - loc); - } - </cc:java-body> - <element name="globalBindings"> - loc = $runtime.copyLocator(); - - <optional> - <attribute name="underscoreBinding"> - <choice> - <value>asWordSeparator</value><!-- default --> - <group> - <value>asCharInWord</value> - nameConverter = NameConverter.jaxrpcCompatible; - </group> - </choice> - </attribute> - </optional> - - <optional> - <attribute name="enableJavaNamingConventions"> - enableJavaNamingConvention = <data type="boolean"/> - </attribute> - </optional> - - <optional> - <attribute name="fixedAttributeAsConstantProperty"> - fixedAttrToConstantProperty = <data type="boolean"/> - </attribute> - </optional> - - <optional> - <attribute name="generateIsSetMethod"> - needIsSetMethod = <data type="boolean"/> - </attribute> - </optional> - - <optional> - <attribute name="mapSimpleTypeDef"> - simpleTypeSubstitution = <data type="boolean"/> - </attribute> - </optional> - - <optional> - <attribute name="localScoping"> - <choice> - <group> - <value>nested</value> - flattenClasses = false; - </group> - <group> - <value>toplevel</value> - flattenClasses = true; - </group> - </choice> - </attribute> - </optional> - - <optional> - <attribute name="collectionType"> - ct = <ref name="collectionType" /> - </attribute> - </optional> - - <optional> - <attribute name="typesafeEnumMemberName"> - <choice> - <value>generateError</value> <!-- default --> - <group> - <value>generateName</value> - generateEnumMemberName = true; - </group> - </choice> - </attribute> - </optional> - - <optional> - <attribute name="typesafeEnumBase"> - <list> - <oneOrMore> - value = <data type="QName"/> - QName qn = $runtime.parseQName(value); - enumBaseTypes.add( qn ); - </oneOrMore> - </list> - </attribute> - </optional> - - <optional> - <attribute name="typesafeEnumMaxMembers"> - <list> - <oneOrMore> - value = <data type="int"/> - defaultEnumSizeCap = Integer.parseInt(value); - </oneOrMore> - </list> - </attribute> - </optional> - - - <optional> - <attribute name="choiceContentProperty"> - value = <data type="boolean"/> - choiceContentPropertyWithModelGroupBinding = $runtime.parseBoolean(value); - </attribute> - </optional> - - <optional> - <attribute name="generateValueClass"> - value = <data type="boolean"/> - generateValueClass = $runtime.parseBoolean(value); - </attribute> - </optional> - - <optional> - <attribute name="generateElementClass"> - value = <data type="boolean"/> - generateElementClass = $runtime.parseBoolean(value); - </attribute> - </optional> - - <optional> - <attribute name="generateMixedExtensions"> - value = <data type="boolean"/> - generateMixedExtensions = $runtime.parseBoolean(value); - </attribute> - </optional> - - <!-- unimplemented attributes --> - <optional> - <attribute name="enableValidation"> - value = <data type="boolean"/> - if( $runtime.parseBoolean(value)==true ) - $runtime.reportUnsupportedFeature("enableValidation"); - </attribute> - </optional> - <optional> - <attribute name="enableFailFastCheck"> - value = <data type="boolean"/> - if( $runtime.parseBoolean(value)==true ) - $runtime.reportUnsupportedFeature("enableFailFastCheck"); - </attribute> - </optional> - - <!-- body --> - <zeroOrMore> - <choice> - <element name="javaType"> - <attribute name="xmlType"> - xmlType = <data type="QName"/> - </attribute> - conv = <ref name="conversionBody" /> - - globalConvs.put( $runtime.parseQName(xmlType), conv ); - </element> - <element name="serializable"> - <optional> - <attribute name="uid"> - serialuid = <data type="long"/> - </attribute> - </optional> - if(serialuid!=null) - serializable = new BISerializable(Long.parseLong(serialuid)); - else - serializable = new BISerializable(null); - </element> - - <!-- global vendor extensions --> - serializable = <ref name="serializable"/> - xSuperClass = <ref name="superClass"/> - xSuperInterface = <ref name="superInterface"/> - <ref name="typeSubstitution" /> - <element name="xjc:smartWildcardDefaultBinding"> - <!-- - changes the default binding of wildcards so that unknown elements will be - bound to DOM. This feature is not publicly available, and we may change it - later. - --> - xSmartWildcardDefaultBinding = true; - <empty /> - </element> - - <element name="xjc:simple"> - xSimpleMode = true; - <empty /> - </element> - - <!-- - light-weight runtime. we no longer support them, - but we don't issue an error when we see them. - --> - <element name="xjc:noMarshaller"> - <empty /> - </element> - <element name="xjc:noUnmarshaller"> - <empty /> - </element> - <element name="xjc:noValidator"> - <empty /> - </element> - <element name="xjc:noValidatingUnmarshaller"> - <empty /> - </element> - </choice> - </zeroOrMore> - </element> - </define> - - - <define name="schemaBindings" - cc:return-type="BISchemaBinding" cc:return-value="makeResult()"> - - <cc:java-body> - private Locator loc; - public BISchemaBinding makeResult() { - return new BISchemaBinding(packageName,javadoc,tt,et,at,mt,nt,loc); - } - </cc:java-body> - - <element name="schemaBindings"> - loc = $runtime.copyLocator(); - - <optional> - <element name="package"> - <optional> - packageName = <attribute name="name"/> - </optional> - <optional> - javadoc = <ref name="javadoc"/> - </optional> - </element> - </optional> - - <optional> - <element name="nameXmlTransform"> - <!-- use newer version of RELAXNGCC and wrap them by <interleave> --> - <zeroOrMore> - <choice> - <element name="typeName"> - tt = <ref name="nameXmlTransformRule"/> - </element> - <element name="elementName"> - et = <ref name="nameXmlTransformRule"/> - </element> - <element name="attributeName"> - at = <ref name="nameXmlTransformRule"/> - </element> - <element name="modelGroupName"> - mt = <ref name="nameXmlTransformRule"/> - </element> - <element name="anonymousTypeName"> - nt = <ref name="nameXmlTransformRule"/> - </element> - </choice> - </zeroOrMore> - </element> - </optional> - </element> - </define> - - <define name="nameXmlTransformRule" - cc:return-type="BISchemaBinding.NamingRule" - cc:return-value="new BISchemaBinding.NamingRule(prefix,suffix)"> - - <cc:java-body> - private String prefix=""; - private String suffix=""; - </cc:java-body> - - - <optional> - <attribute name="prefix"> - prefix = <data type="NCName"/> - </attribute> - </optional> - <optional> - <attribute name="suffix"> - suffix = <data type="NCName"/> - </attribute> - </optional> - </define> - - - - <define name="javadoc" cc:return-type="String" cc:return-value="javadoc"> - <element name="javadoc"> - javadoc = <text /> - javadoc = $runtime.truncateDocComment(javadoc); - </element> - </define> - - <define name="collectionType" cc:class="CollectionTypeState" - cc:return-type="FieldRenderer" cc:return-value="r"> - <cc:java-body> - private FieldRenderer r = null; - </cc:java-body> - type = <data type="token"/> - - if( type.equals("indexed") ) - r = FieldRenderer.ARRAY; - else - try { - r = new UntypedListFieldRenderer( $runtime.codeModel.ref(type) ); - } catch( ClassNotFoundException e ) { - throw new NoClassDefFoundError(e.getMessage()); - } - </define> - - - - <define name="class" cc:class="BIClassState" - cc:return-type="BIClass" cc:return-value="makeResult()"> - - <cc:java-body> - private Locator loc; - public BIClass makeResult() { - return new BIClass(loc,name,implClass,javadoc); - } - </cc:java-body> - - <element name="class"> - loc = $runtime.copyLocator(); - <optional> - javadoc = <ref name="javadoc"/> - </optional> - <optional> - <attribute name="name"> - name = <data type="identifier" datatypeLibrary="http://java.sun.com/xml/ns/relaxng/java-datatypes"/> - </attribute> - </optional> - <optional> - implClass = <attribute name="implClass"/> - </optional> - </element> - </define> - - <define name="property" - cc:return-type="BIProperty" cc:return-value="makeResult()"> - - <cc:java-body> - private Locator loc; - private Boolean isConst = null; - private Boolean isSet = null; - private Boolean genElemProp = null; - - public BIProperty makeResult() throws SAXException { - JType baseTypeRef = null; - if(baseType!=null) - baseTypeRef = $runtime.getType(baseType); - - return new BIProperty(loc,name,javadoc,baseTypeRef,conv,ct,isConst,isSet,genElemProp); - } - </cc:java-body> - - <element name="property"> - loc = $runtime.copyLocator(); - <optional> - name = <attribute name="name"/> - </optional> - <optional> - baseType = <attribute name="baseType"/> - </optional> - <optional> - <attribute name="collectionType"> - ct = <ref name="collectionType" /> - </attribute> - </optional> - <optional> - <attribute name="fixedAttributeAsConstantProperty"> - isConstStr = <data type="boolean"/> - isConst = $runtime.parseBoolean(isConstStr)?Boolean.TRUE:Boolean.FALSE; - </attribute> - </optional> - <optional> - <attribute name="generateIsSetMethod"> - isSetStr = <data type="boolean"/> - isSet = $runtime.parseBoolean(isSetStr)?Boolean.TRUE:Boolean.FALSE; - </attribute> - </optional> - <optional> - <attribute name="generateElementProperty"> - genElemPropStr = <data type="boolean"/> - genElemProp = $runtime.parseBoolean(genElemPropStr)?Boolean.TRUE:Boolean.FALSE; - </attribute> - </optional> - <optional> - <attribute name="generateFailFastSetterMethod"> - failFast = <data type="boolean"/> - </attribute> - if( $runtime.parseBoolean(failFast) ) { - $runtime.reportUnimplementedFeature("generateFailFastSetterMethod"); - } - </optional> - - - <interleave> - <optional> - javadoc = <ref name="javadoc"/> - </optional> - <optional> - <element name="baseType"> - conv = <ref name="conversion"/> - </element> - </optional> - </interleave> - </element> - </define> - - <define name="conversion" - cc:return-type="BIConversion" cc:return-value="r"> - <element name="javaType"> - r = <ref name="conversionBody"/> - </element> - </define> - - - <define name="conversionBody" - cc:return-type="BIConversion" cc:return-value="makeResult()"> - - <cc:java-import> - import com.sun.tools.internal.xjc.generator.util.WhitespaceNormalizer; - </cc:java-import> - <cc:java-body><![CDATA[ - public BIConversion makeResult() throws SAXException { - return new BIConversion.User( $runtime.copyLocator(), parse, print, $runtime.getType(type) ); - } - - // initialize with default values. - private String type = "java.lang.String"; // in case a schema has an error - private String parse = null; - private String print = null; - private boolean context = false; - ]]></cc:java-body> - - - <optional> - parse = <attribute name="parseMethod" /> - </optional> - <optional> - print = <attribute name="printMethod" /> - </optional> - <attribute name="name" cc:alias="type"/> - <optional> - <attribute name="hasNsContext"> - _context = <data type="boolean"/> - context = $runtime.parseBoolean(_context); - </attribute> - </optional> - </define> - - - <!-- type safe enum customization --> - <define name="typesafeEnum" - cc:return-type="BIEnum" cc:return-value="makeResult()"> - - <cc:java-import> - import java.util.HashMap; - </cc:java-import> - <cc:java-body> - private HashMap members = new HashMap(); - private boolean dontBind = false; - private Locator loc,loc2; - - private BIEnum makeResult() { - return new BIEnum(loc,dontBind,name,javadoc,members); - } - </cc:java-body> - - <element name="typesafeEnumClass"> - loc = $runtime.copyLocator(); - <choice> - <attribute name="map"> - <value>false</value> - dontBind = true; - </attribute> - <group> - <optional> - name = <attribute name="name"/> - </optional> - <optional> - javadoc = <ref name="javadoc" /> - </optional> - <zeroOrMore> - jname = null; - javadoc = null; - <element name="typesafeEnumMember"> - loc2 = $runtime.copyLocator(); - <optional> - jname = <attribute name="name"/> - </optional> - value = <attribute name="value"/> - <optional> - javadoc = <ref name="javadoc" /> - </optional> - members.put( value, new BIEnumMember(loc2,jname,javadoc) ); - </element> - </zeroOrMore> - </group> - </choice> - </element> - </define> - - - <!-- stand-alone type safe enum member customization --> - <!-- - Note that only the name attribute is allowed here, and the same element - under the typesafeEnumClass is handled differently. - --> - <define name="enumMember" - cc:return-type="BIEnumMember" cc:return-value="makeResult()"> - <cc:java-body> - private Locator loc; - private BIEnumMember makeResult() { - return new BIEnumMember(loc,name,javadoc); - } - </cc:java-body> - - <element name="typesafeEnumMember"> - loc = $runtime.copyLocator(); - name = <attribute name="name"/> - <optional> - javadoc = <ref name="javadoc" /> - </optional> - </element> - </define> - - - <!-- XJC-exntension: root class support --> - <define name="superClass" cc:return-type="JDefinedClass" cc:return-value="makeResult()"> - <cc:java-body> - private JDefinedClass makeResult() { - try { - JDefinedClass c = $runtime.codeModel._class(name); - c.hide(); - return c; - } catch( JClassAlreadyExistsException e ) { - return e.getExistingClass(); - } - } - </cc:java-body> - - <element name="xjc:superClass"> - name = <attribute name="name" /> - </element> - </define> - - <!-- XJC-exntension: root interface support --> - <define name="superInterface" cc:return-type="JDefinedClass" cc:return-value="makeResult()"> - <cc:java-body> - private JDefinedClass makeResult() { - try { - JDefinedClass c = $runtime.codeModel._class(name,ClassType.INTERFACE); - c.hide(); - return c; - } catch( JClassAlreadyExistsException e ) { - return e.getExistingClass(); - } - } - </cc:java-body> - - <element name="xjc:superInterface"> - name = <attribute name="name" /> - </element> - </define> - - <!-- XJC-exntension: serialization support --> - <define name="serializable" cc:return-type="BISerializable" cc:return-value="makeResult()"> - <cc:java-body> - private long uid = 1; - private BISerializable makeResult() { - return new BISerializable(uid); - } - </cc:java-body> - - <element name="xjc:serializable"> -// loc = $runtime.copyLocator(); - <optional> - <attribute name="uid"> - v = <data type="long"/> - uid = Long.parseLong(v); - </attribute> - </optional> - </element> - </define> - - - <!-- XJC extension: type substitution --> - <define name="typeSubstitution" cc:return-type="boolean" cc:return-value="true"> - <element name="xjc:typeSubstitution"> - <attribute name="type"><value>complex</value></attribute> - </element> - </define> - - - <!-- XJC extension: ID symbol space support --> - <!--define name="idSymbolSpace" cc:return-type="BIXIdSymbolSpace" cc:return-value="makeResult()"> - <cc:java-body> - private Locator loc; - private BIXIdSymbolSpace makeResult() { - return new BIXIdSymbolSpace(loc,name); - } - </cc:java-body> - - <element name="xjc:idSymbolSpace"> - loc = $runtime.copyLocator(); - name = <attribute name="name"/> - </element> - </define--> - - - <!-- XJC extension: DOM support --> - <!--define name="dom" cc:return-type="BIXDom" cc:return-value="makeResult()"> - <cc:java-import> - import com.sun.tools.internal.xjc.grammar.ext.*; - </cc:java-import> - <cc:java-body> - private String factoryName = "w3c"; - private Locator loc; - private BIXDom makeResult() { - try { - return new BIXDom(DOMItemFactory.getInstance(factoryName),loc); - } catch( DOMItemFactory.UndefinedNameException e ) { - throw new InternalError(); // impossible since we use validation to reject incorrect values - } - } - </cc:java-body> - - <element name="xjc:dom"> - loc = $runtime.copyLocator(); - <optional> - <attribute name="type"> - <choice> - factoryName = <value>dom4j</value> - factoryName = <value>w3c</value> - </choice> - </attribute> - </optional> - </element> - </define--> - - - - - - - <p:ignore> - <!-- these patterns are ignored when using RelaxNGCC --> - <define name="anyContents"> - <zeroOrMore> - <choice> - <text/> - <ref name="anyAttributes"/> - <element> - <anyName/> - <ref name="anyContents"/> - </element> - </choice> - </zeroOrMore> - </define> - - <define name="anyAttributes"> - <zeroOrMore> - <attribute> - <anyName/> - <text/> - </attribute> - </zeroOrMore> - </define> - </p:ignore> -</grammar> diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/schemagen/xmlschema/xmlschema-for-jaxb.rng b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/schemagen/xmlschema/xmlschema-for-jaxb.rng deleted file mode 100644 index 88eb2f56610..00000000000 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/schemagen/xmlschema/xmlschema-for-jaxb.rng +++ /dev/null @@ -1,1579 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright (c) 1997, 2012, 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. ---> - -<grammar xmlns="http://relaxng.org/ns/structure/1.0" - datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" - ns="http://www.w3.org/2001/XMLSchema" - xmlns:xs="http://www.w3.org/2001/XMLSchema" - xmlns:doc="http://www.jenitennison.com/doc" - xmlns:txw="http://java.sun.com/txw"> - -<doc:p> - RELAX NG schema for XML Schema by <doc:link - href="mailto:mail@jenitennison.com">Jeni Tennison</doc:link>. Based on - <doc:link href="http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/">XML - Schema Part I: Structures Recommendation</doc:link> and <doc:link - href="http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/">XML Schema Part - II: Datatypes</doc:link>. -</doc:p> -<doc:changes date="2001-11-24"> - <doc:p> - Amended to comply with 10 August 2001 Tutorial. - </doc:p> - <doc:change>Removed key attributes.</doc:change> - <doc:change>Replaced not element with except elements.</doc:change> - <doc:change> - Replaced multiple consecutive optional attributes to use the - zeroOrMore/choice pattern. - </doc:change> - <doc:change> - Removed interleave elements inside list elements (which are no longer - permitted). - </doc:change> -</doc:changes> - -<define name="openAttrs" txw:mode="inherit"> - <doc:p> - This allows any number of attributes that are not in the XML Schema - namespace or are in no namespace. This is somewhat more complicated than - the XML Schema anyAttribute equivalent. - </doc:p> - <!-- KK don't care --> - <empty/> - <!--zeroOrMore> - <attribute> - <anyName> - <except> - <nsName /> - <nsName ns="" /> - <name>xml:lang</name> - </except> - </anyName> - <text /> - </attribute> - </zeroOrMore--> -</define> - -<define name="annotated" txw:mode="inherit"> - <doc:p> - This allows any number of attributes that are not in the XML Schema - namespace or are in no namespace, an optional id attribute of type ID, - and an optional annotation element. This is used as the basis for many - element content models. - </doc:p> - <ref name="openAttrs" /> - <optional> - <attribute name="id"> - <data type="ID" /> - </attribute> - </optional> - <optional> - <ref name="annotation" /> - </optional> -</define> - -<define name="schemaTop" txw:mode="inline"> - <doc:p> - This gives the content model of the top level of the schema. - </doc:p> - <choice> - <ref name="redefinable" /> - <ref name="topLevelElement" /> - <ref name="topLevelAttribute" /> - <!--ref name="notation" /--> - </choice> -</define> - -<define name="redefinable" txw:mode="inline"> - <doc:p> - This gives the components that can be redefined within the redefine - element. They also occur at the top level of the schema. - </doc:p> - <choice> - <ref name="simpleTypeHost" /> - <ref name="complexTypeHost" /> - <!--ref name="namedGroup" /> - <ref name="namedAttributeGroup" /--> - </choice> -</define> - -<define name="formChoice"> - <doc:p> - This gives the values for the various form attributes: - elementFormDefault and attributeFormDefault on the schema element, and - the form attributes on the element and attribute elements. - </doc:p> - <choice> - <value>qualified</value> - <value>unqualified</value> - </choice> -</define> - -<!-- KK: merge the two --> -<define name="reducedDerivationControl"> - <doc:p> - This gives the values that can be taken in the lists used to control - derivation by extension or restriction (this is 'reduced' derivation - because some derivation can involve substitution). This RELAX NG schema, - like the XML Schema Recommendation here, allows the keywords 'extension' and - 'restriction' to be repeated any number of times. - </doc:p> - <list> - <oneOrMore> - <choice> - <value>extension</value> - <value>restriction</value> - </choice> - </oneOrMore> - </list> -</define> - -<define name="derivationSet"> - <doc:p> - This specifies the possible values for attributes that control derivation. - </doc:p> - <choice> - <value>#all</value> - <ref name="reducedDerivationControl" /> - </choice> -</define> - -<start> - <doc:p> - This is the beginning point for the schema, and defines the schema - element. - </doc:p> - <element name="schema" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-schema"> - <ref name="openAttrs" /> - <zeroOrMore> - <choice> - <attribute name="version"> - <data type="token" /> - </attribute> - <attribute name="finalDefault"> - <ref name="derivationSet" /> - </attribute> - <attribute name="blockDefault"> - <ref name="blockSet" /> - </attribute> - <attribute name="attributeFormDefault"> - <ref name="formChoice" /> - </attribute> - <attribute name="elementFormDefault"> - <ref name="formChoice" /> - </attribute> - <attribute name="id"> - <data type="ID" /> - </attribute> - <attribute name="xml:lang"> - <data type="language" /> - </attribute> - <attribute name="targetNamespace"> - <data type="anyURI" /> - </attribute> - </choice> - </zeroOrMore> - <zeroOrMore> - <choice> - <!--ref name="include" /--> - <ref name="import" /> - <!--ref name="redefine" /--> - <ref name="annotation" /> - </choice> - </zeroOrMore> - <zeroOrMore> - <choice> - <ref name="schemaTop" /> - <ref name="annotation" /> - </choice> - </zeroOrMore> - </element> -</start> - -<define name="allNNI"> - <doc:p> - This gives the value type for the maxOccurs attribute, which may be a - non-negative number or the keyword 'unbounded'. - </doc:p> - <choice> - <data type="nonNegativeInteger" /> - <value type="token">unbounded</value> - </choice> -</define> - -<define name="occurs" txw:mode="inherit"> - <doc:p> - This specifies the occurs attributes, minOccurs and maxOccurs, as they - are normally used. - </doc:p> - <zeroOrMore> - <choice> - <attribute name="minOccurs"> - <data type="nonNegativeInteger" /> - </attribute> - <attribute name="maxOccurs"> - <ref name="allNNI" /> - </attribute> - </choice> - </zeroOrMore> -</define> - -<define name="typeDefParticle" txw:mode="inline"> - <doc:p> - This gives the possible content of complex types. - </doc:p> - <choice> - <!--ref name="groupRef" /--> - <ref name="all" /> - <ref name="choice" /> - <ref name="sequence" /> - </choice> -</define> - -<define name="nestedParticle" txw:mode="inline"> - <doc:p> - This gives the particles that can make up a model group. - </doc:p> - <choice> - <ref name="localElement" /> - <!--ref name="groupRef" /--> - <ref name="choice" /> - <ref name="sequence" /> - <ref name="any" /> - </choice> -</define> - -<define name="fixedOrDefault" txw:mode="inline"> - <doc:p> - This specifies the relationship between fixed and default attributes on - element and attribute elements - if one is present, then the other cannot - be. This is a constraint that cannot be specified using XML Schema. - </doc:p> - <choice> - <empty /> - <attribute name="fixed" /> - <attribute name="default" /> - </choice> -</define> - -<define name="attributeType" txw:mode="inherit"> - <doc:p> - This specifies the relationship between the type attribute and the - simpleType element child of attribute elements - if one is present, then - the other cannot be, although it is possible for neither to be allowed. - </doc:p> - <choice> - <empty /> - <attribute name="type"> - <data type="QName" /> - </attribute> - <ref name="simpleTypeHost" /> - </choice> -</define> - -<define name="localAttribute"> - <doc:p> - This describes attribute elements when used in a local context. They - have an optional use attribute, possibly a fixed or default attribute, - and then can either have a ref attribute (referring to a top-level - attribute) or a name attribute with an optional form attribute and - specifying an attribute type. - </doc:p> - <element name="attribute" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-attribute"> - <ref name="annotated" /> - <optional> - <attribute name="use"> - <choice> - <value type="token">optional</value> - <value type="token">prohibited</value> - <value type="token">required</value> - </choice> - </attribute> - </optional> - <ref name="fixedOrDefault" /> - <choice> - <attribute name="ref"> - <data type="QName" /> - </attribute> - <group> - <attribute name="name"> - <data type="NCName" /> - </attribute> - <optional> - <attribute name="form"> - <ref name="formChoice" /> - </attribute> - </optional> - <ref name="attributeType" /> - </group> - </choice> - </element> -</define> - -<define name="topLevelAttribute"> - <doc:p> - This describes attribute elements when used at the top level of the - schema. They must have a name, may have a fixed or default attribute, - and specify their type through a type attribute or child simpleType - element. The name attribute of each attribute element that appears at - the top level of the schema is unique. - </doc:p> - <element name="attribute" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-attribute"> - <ref name="annotated" /> - <attribute name="name"> - <data type="NCName" /> - </attribute> - <ref name="fixedOrDefault" /> - <ref name="attributeType" /> - </element> -</define> - -<define name="attrDecls" txw:mode="inherit"> - <doc:p> - This gives the model group for specifying the attributes in a complex - type, an extension or restriction. - </doc:p> - <zeroOrMore> - <choice> - <ref name="localAttribute" /> - <!--ref name="attributeGroupRef" /--> - </choice> - </zeroOrMore> - <optional> - <ref name="anyAttribute" /> - </optional> -</define> - -<define name="anyAttribute"> - <doc:p> - This specifies the anyAttribute wildcard. - </doc:p> - <element name="anyAttribute" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-anyAttribute"> - <ref name="wildcard" /> - </element> -</define> - -<define name="complexTypeModel" txw:mode="inherit"> - <doc:p> - This specifies the content of a complexType element. As children, it can - have a simpleContent, a complexContent or a model group. Only if it has - one of the latter two, may it have a mixed attribute. This latter - constraint is something that cannot be specified in XML Schema. - </doc:p> - <choice> - <ref name="simpleContent" /> - <group> - <optional> - <attribute name="mixed"> - <data type="boolean" /> - </attribute> - </optional> - <choice> - <ref name="complexContent" /> - <group> - <optional> - <ref name="typeDefParticle" /> - </optional> - <ref name="attrDecls" /> - </group> - </choice> - </group> - </choice> -</define> - -<define name="complexTypeHost" txw:mode="inherit"> - <ref name="typeHost" /> - <ref name="complexType" /> -</define> - -<define name="typeHost" txw:mode="inherit"><empty/><empty/></define> - -<define name="complexType" txw:mode="inherit"> - <element name="complexType" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-complexType"> - <doc:p> - This specifies the basic content of a complexType element. - </doc:p> - <ref name="annotated" /> - <ref name="complexTypeModel" /> - <optional> - <attribute name="name"> - <data type="NCName" /> - </attribute> - </optional> - <zeroOrMore> - <choice> - <attribute name="abstract"> - <data type="boolean" /> - </attribute> - <attribute name="block"> - <ref name="derivationSet" /> - </attribute> - <attribute name="final"> - <ref name="derivationSet" /> - </attribute> - </choice> - </zeroOrMore> - </element> -</define> - -<define name="complexRestriction"> - <doc:p> - This describes a restriction element within a complexContent element - (i.e. one that restricts a complex type). It has a base attribute, may - contain a model group and may contain attribute declarations of various - sorts. - </doc:p> - <element name="restriction" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-complexContent::restriction"> - <ref name="annotated" /> - <attribute name="base"> - <data type="QName" /> - </attribute> - <optional> - <ref name="typeDefParticle" /> - </optional> - <ref name="attrDecls" /> - </element> -</define> - -<define name="extensionType"> - <doc:p> - This specifies the basic model for an extension element: adding a - required base attribute to the model used for most components. - </doc:p> - <ref name="annotated" /> - <attribute name="base"> - <data type="QName" /> - </attribute> -</define> - -<define name="complexExtension"> - <doc:p> - This describes an extension element within a complexContent element - (i.e. one that restricts a complex type). It may contain a model group - and may contain attribute declarations of various sorts. - </doc:p> - <element name="extension" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-complexContent::extension"> - <ref name="extensionType" /> - <optional> - <ref name="typeDefParticle" /> - </optional> - <ref name="attrDecls" /> - </element> -</define> - -<define name="complexContent"> - <doc:p> - This describes a complexContent element. It may have a mixed attribute, - and either a restriction or extension element as content. - </doc:p> - <element name="complexContent" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-complexContent"> - <ref name="annotated" /> - <optional> - <attribute name="mixed"> - <data type="boolean" /> - </attribute> - </optional> - <choice> - <ref name="complexRestriction" /> - <ref name="complexExtension" /> - </choice> - </element> -</define> - -<define name="simpleRestriction"> - <doc:p> - This describes a restriction element that appears within a simpleContent - or simpleType element (i.e. one that restricts a simple type). Its - content follows the simple restriction model that is detailed below, and - may include attribute declarations. - </doc:p> - <element name="restriction" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-simpleContent::restriction"> - <ref name="annotated" /> - <ref name="simpleRestrictionModel" /> - <ref name="attrDecls" /> - </element> -</define> - -<define name="simpleExtension"> - <doc:p> - This describes an extension element that appears within a simpleContent - element (i.e. one that extends a simple type). Like other extensions, it - has a base type, but it can only be used to add attributes. - </doc:p> - <element name="extension" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-simpleContent::extension"> - <ref name="extensionType" /> - <ref name="attrDecls" /> - </element> -</define> - -<define name="simpleContent"> - <doc:p> - This describes a simpleContent element, whose content can either hold a - restriction or extension element. - </doc:p> - <element name="simpleContent" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-simpleContent"> - <ref name="annotated" /> - <choice> - <ref name="simpleRestriction" /> - <ref name="simpleExtension" /> - </choice> - </element> -</define> - -<define name="blockSet"> - <doc:p> - This gives the possible values for block attributes on element elements, - which includes substitution amongst the list of possible values. This - RELAX NG schema, like the XML Schema Recommendation, allows each of the - keywords 'extension', 'restriction' and 'substitution' to occur more than - once within the list. - </doc:p> - <choice> - <value type="token">#all</value> - <list> - <oneOrMore> - <choice> - <value>extension</value> - <value>restriction</value> - <value>substitution</value> - </choice> - </oneOrMore> - </list> - </choice> -</define> - -<define name="element" txw:mode="inherit"> - <doc:p> - This describes the basic content model of an element element. It is - annotated, may have a fixed or default attribute, and may have nillable - and/or block attributes. Its type may be specified through a type - attribute, a local simple type or a local complex type - the choice - between these methods is something that cannot be indicated with XML - Schema. This content is optionally followed by some identify constraints. - </doc:p> - <ref name="annotated" /> - <ref name="fixedOrDefault" /> - <zeroOrMore> - <choice> - <attribute name="nillable"> - <data type="boolean" /> - </attribute> - <attribute name="block"> - <ref name="blockSet" /> - </attribute> - </choice> - </zeroOrMore> - <choice> - <empty /> - <attribute name="type"> - <data type="QName" /> - </attribute> - <ref name="simpleTypeHost" /> - <ref name="complexTypeHost" /> - </choice> - <!--zeroOrMore> - <ref name="identityConstraint" /> - </zeroOrMore--> -</define> - -<define name="topLevelElement"> - <doc:p> - This describes an element element that appears at the top level of the - schema. On top of the basic content for an element element, it has to - have a name, which is a unique identifier in the element symbol space. It - may have substitutionGroup, abstract and/or final attributes. - </doc:p> - <element name="element" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-element"> - <ref name="element" /> - <attribute name="name"> - <data type="NCName" /> - </attribute> - <zeroOrMore> - <choice> - <attribute name="substitutionGroup"> - <data type="QName" /> - </attribute> - <attribute name="abstract"> - <data type="boolean" /> - </attribute> - <attribute name="final"> - <ref name="derivationSet" /> - </attribute> - </choice> - </zeroOrMore> - </element> -</define> - -<define name="localElement"> - <doc:p> - This describes an element element that appears locally, within a - complexType or group element. It may have minOccurs and/or maxOccurs - attributes. If it has a ref attribute, then that's all it can - have. Otherwise, it must have a name and specifies its type in the same - way as the basic element content model described above. It may in this - case also have a form element. These constraints on local elements - cannot be described within XML Schema. - </doc:p> - <element name="element" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-element"> - <ref name="occurs" /> - <choice> - <attribute name="ref"> - <data type="QName" /> - </attribute> - <group> - <ref name="element" /> - <attribute name="name"> - <data type="NCName" /> - </attribute> - <optional> - <attribute name="form"> - <ref name="formChoice" /> - </attribute> - </optional> - </group> - </choice> - </element> -</define> - -<!--define name="namedGroup"> - <doc:p> - This describes an group element that appears at the top level of the - schema. It must have a name attribute, and must have one of an all, - choice or sequence element child. - </doc:p> - <element name="group" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-group"> - <ref name="annotated" /> - <attribute name="name"> - <data type="NCName" /> - </attribute> - <choice> - <element name="all"> - <ref name="simpleExplicitGroup" /> <!- - RS - relaxed all content model - -> - </element> - <element name="choice"> - <ref name="simpleExplicitGroup" /> - </element> - <element name="sequence"> - <ref name="simpleExplicitGroup" /> - </element> - </choice> - </element> -</define--> - -<!--define name="groupRef"> - <doc:p> - This describes group element that occurs locally, referring to a - top-level named group. It may have occurrence attributes, and must have - a ref attribute. - </doc:p> - <element name="group" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-group"> - <ref name="annotated" /> - <ref name="occurs" /> - <attribute name="ref"> - <data type="QName" /> - </attribute> - </element> -</define--> - -<define name="explicitGroup" txw:mode="inherit"> - <doc:p> - This gives the content of a model group (not a group element) in the - normal run of things. It has occurrence attributes and any number of - particles within it. - </doc:p> - <ref name="annotated" /> - <ref name="occurs" /> - <zeroOrMore> - <ref name="nestedParticle" /> - </zeroOrMore> -</define> - -<define name="simpleExplicitGroup"> - <doc:p> - This gives the content of a model group (not a group element) within a - named group - it differs from the above in that it doesn't have any - occurrence attributes. - </doc:p> - <ref name="annotated" /> - <zeroOrMore> - <ref name="nestedParticle" /> - </zeroOrMore> -</define> - -<define name="all"> - <doc:p> - This describes an all element that appears outside a named group (i.e. as - the content of a complexType element). It has the standard model for an - all element, but adds minOccurs and maxOccurs attributes which can only - take certain values. - </doc:p> - <element name="all" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-all"> - <ref name="explicitGroup" /> - </element> -</define> - -<define name="choice"> - <doc:p> - This describes a choice element that appears outside a named group. - </doc:p> - <element name="choice" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-choice"> - <ref name="explicitGroup" /> - </element> -</define> - -<define name="sequence"> - <doc:p> - This describes a sequence element that appears outside a named group. - </doc:p> - <element name="sequence" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-sequence"> - <ref name="explicitGroup" /> - </element> -</define> - -<define name="wildcard" txw:mode="inherit"> - <doc:p> - This describes a wildcard element (i.e. any or anyAttribute). The - namespace attribute can take a list URIs interspersed with the keywords - '##targetNamespace' and/or '##local'. This RELAX NG schema, like the XML - Schema Recommendation, allows the keywords to be specified more than once - each within the list, if they're given. This model also specifies the - processContents attribute. - </doc:p> - <ref name="annotated" /> - <zeroOrMore> - <choice> - <attribute name="namespace"> - <choice> - <value type="token">##any</value> - <value type="token">##other</value> - <list> - <zeroOrMore> - <choice> - <data type="anyURI" /> - <value>##targetNamespace</value> - <value>##local</value> - </choice> - </zeroOrMore> - </list> - </choice> - </attribute> - <attribute name="processContents"> - <choice> - <value type="token">lax</value> - <value type="token">skip</value> - <value type="token">strict</value> - </choice> - </attribute> - </choice> - </zeroOrMore> -</define> - -<define name="any"> - <doc:p> - This describes an any element as a wildcard. - </doc:p> - <element name="any" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-any"> - <ref name="wildcard" /> - <ref name="occurs" /> - </element> -</define> - -<!--define name="namedAttributeGroup"> - <doc:p> - This describes an attributeGroup element as it appears at the top level - of the schema. It must have a name attribute, and then contains - attribute declarations. - </doc:p> - <element name="attributeGroup" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-attributeGroup"> - <ref name="annotated" /> - <attribute name="name"> - <data type="NCName" /> - </attribute> - <ref name="attrDecls" /> - </element> -</define--> - -<!--define name="attributeGroupRef"> - <doc:p> - This describes an attributeGroup element as it appears within a complex - type. It must have a ref attribute. - </doc:p> - <element name="attributeGroup" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-attributeGroup"> - <ref name="annotated" /> - <attribute name="ref"> - <data type="QName" /> - </attribute> - </element> -</define--> - -<!--define name="include"> - <doc:p> - This describes an include element, which must have a schemaLocation - attribute. - </doc:p> - <element name="include" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-include"> - <ref name="annotated" /> - <attribute name="schemaLocation"> - <data type="anyURI" /> - </attribute> - </element> -</define--> - -<!--define name="redefine"> - <doc:p> - This describes a redefine element, which must have a schemaLocation - attribute and can then contain any mix of annotations and redefinable - components. - </doc:p> - <element name="redefine" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-redefine"> - <ref name="openAttrs" /> - <optional> - <attribute name="id"> - <data type="ID" /> - </attribute> - </optional> - <attribute name="schemaLocation"> - <data type="anyURI" /> - </attribute> - <zeroOrMore> - <choice> - <ref name="annotation" /> - <ref name="redefinable" /> - </choice> - </zeroOrMore> - </element> -</define--> - -<define name="import"> - <doc:p> - This describes an import element that's used when its parent schema - element specifies a targetNamespace. In these cases, the namespace - attribute on the import element is optional. - </doc:p> - <element name="import" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-import"> - <ref name="annotated" /> - <optional> - <attribute name="schemaLocation"> - <data type="anyURI" /> - </attribute> - </optional> - <optional> - <attribute name="namespace"> - <data type="anyURI" /> - </attribute> - </optional> - </element> -</define> - -<!--define name="selector"> - <doc:p> - This describes a selector element. The xpath attribute is a simplified - XPath - the regular expression given here is the one from the XML Schema - for XML Schema. - </doc:p> - <element name="selector" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-selector"> - <ref name="annotated" /> - <attribute name="xpath"> - <data type="token"> - <param name="pattern">(\.//)?(((child::)?((\i\c*:)?(\i\c*|\*)))|\.)(/(((child::)?((\i\c*:)?(\i\c*|\*)))|\.))*(\|(\.//)?(((child::)?((\i\c*:)?(\i\c*|\*)))|\.)(/(((child::)?((\i\c*:)?(\i\c*|\*)))|\.))*)*</param> - </data> - </attribute> - </element> -</define> - -<define name="field"> - <doc:p> - This describes a field element. The xpath attribute is a simplified - XPath - the regular expression given here is the one from the XML Schema - for XML Schema. - </doc:p> - <element name="field" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-field"> - <ref name="annotated" /> - <attribute name="xpath"> - <data type="token"> - <param name="pattern">(\.//)?((((child::)?((\i\c*:)?(\i\c*|\*)))|\.)/)*((((child::)?((\i\c*:)?(\i\c*|\*)))|\.)|((attribute::|@)((\i\c*:)?(\i\c*|\*))))(\|(\.//)?((((child::)?((\i\c*:)?(\i\c*|\*)))|\.)/)*((((child::)?((\i\c*:)?(\i\c*|\*)))|\.)|((attribute::|@)((\i\c*:)?(\i\c*|\*)))))*</param> - </data> - </attribute> - </element> -</define> - -<define name="keybase" txw:mode="inherit"> - <doc:p> - This gives the basic content for identity constraints - a name attribute - that uniquely identifies the identity constraint, a selector element and - one or more field elements. - </doc:p> - <ref name="annotated" /> - <attribute name="name"> - <data type="NCName" /> - </attribute> - <ref name="selector" /> - <oneOrMore> - <ref name="field" /> - </oneOrMore> -</define> - -<define name="identityConstraint" txw:mode="inline"> - <doc:p> - This gives a model group for the three identity constraint elements, used - within the content of element elements. - </doc:p> - <choice> - <ref name="unique" /> - <ref name="key" /> - <ref name="keyref" /> - </choice> -</define> - -<define name="unique"> - <doc:p> - This describes a unique element. - </doc:p> - <element name="unique" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-unique"> - <ref name="keybase" /> - </element> -</define> - -<define name="key"> - <doc:p> - This describes a key element. - </doc:p> - <element name="key" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-key"> - <ref name="keybase" /> - </element> -</define> - -<define name="keyref"> - <doc:p> - This describes a keyref element. - </doc:p> - <element name="keyref" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-keyref"> - <ref name="keybase" /> - <attribute name="refer"> - <data type="QName" /> - </attribute> - </element> -</define--> - -<!--define name="notation"> - <doc:p> - This describes a notation element. The names of notation elements are - unique in the notation symbol space. The public attribute is required, - and the system attribute is optional. - </doc:p> - <element name="notation" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-notation"> - <ref name="annotated" /> - <attribute name="name"> - <data type="NCName" /> - </attribute> - <attribute name="public"> - <data type="token" /> - </attribute> - <optional> - <attribute name="system"> - <data type="anyURI" /> - </attribute> - </optional> - </element> -</define--> - -<define name="appinfoContent"> - <doc:p> - This is designed to describe the content of the appinfo elements in the - schema. At the moment this allows any mixed content without validation. - Note that this is fairly complex compared to the XML Schema equivalent, - which would be a single any element. - </doc:p> - <ref name="anyContent" /> -</define> - -<define name="anyContent"> - <empty/> <!-- KK don't care --> - <!--mixed> - <zeroOrMore> - <element> - <anyName /> - <zeroOrMore> - <attribute> - <anyName /> - </attribute> - </zeroOrMore> - <ref name="anyContent" /> - <empty /> - </element> - </zeroOrMore> - </mixed--> -</define> - -<define name="appinfo"> - <doc:p> - This describes an appinfo element. It has an optional source attribute - and can currently contain anything at all. - </doc:p> - <element name="appinfo" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-appinfo"> - <optional> - <attribute name="source"> - <data type="anyURI" /> - </attribute> - </optional> - <ref name="appinfoContent" /> - </element> -</define> - -<define name="documentationContent"> - <doc:p> - This is designed to describe the content of the documentation elements in - the schema. At the moment this allows any mixed content without - validation. Note that this is fairly complex compared to the XML Schema - equivalent, which would be a single any element. - </doc:p> - <ref name="anyContent" /> -</define> - -<define name="documentation"> - <doc:p> - This describes a documentation element. It has optional source - and xml:lang attributes and can currently contain anything at all. - </doc:p> - <element name="documentation" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-documentation"> - <zeroOrMore> - <choice> - <attribute name="source"> - <data type="anyURI" /> - </attribute> - <attribute name="xml:lang"> - <data type="language" /> - </attribute> - </choice> - </zeroOrMore> - <ref name="documentationContent" /> - </element> -</define> - -<define name="annotation"> - <doc:p> - This describes an annotation element. It can have any attributes, may - have an id attribute, and contains any number of documentation or appinfo - elements. - </doc:p> - <element name="annotation" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-annotation"> - <ref name="openAttrs" /> - <optional> - <attribute name="id"> - <data type="ID" /> - </attribute> - </optional> - <zeroOrMore> - <choice> - <ref name="documentation" /> - <ref name="appinfo" /> - </choice> - </zeroOrMore> - </element> -</define> - -<define name="simpleDerivation" txw:mode="inline"> - <doc:p> - This gives the various types of derivation of simple types. - </doc:p> - <choice> - <ref name="simpleRestriction" /> - <ref name="list" /> - <ref name="union" /> - </choice> -</define> - -<define name="simpleDerivationSet"> - <doc:p> - This specifies the values of the final attribute for simple types. This - RELAX NG schema for XML Schema, like the XML Schema Recommendation, allows - the keywords 'list', 'union' and 'restriction' to appear more than once - within the list. - </doc:p> - <choice> - <value type="token">#all</value> - <list> - <zeroOrMore> - <choice> - <value>list</value> - <value>union</value> - <value>restriction</value> - </choice> - </zeroOrMore> - </list> - </choice> -</define> - -<define name="simpleTypeHost" txw:mode="inherit"> - <ref name="typeHost" /> - <ref name="simpleType" /> -</define> - -<define name="simpleType" txw:mode="inherit"> - <doc:p> - This gives the basic content of a simple type. - </doc:p> - <element name="simpleType" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-simpleType"> - <ref name="annotated" /> - <ref name="simpleDerivation" /> - <optional> - <attribute name="name"> - <data type="NCName" /> - </attribute> - </optional> - <optional> - <attribute name="final"> - <ref name="simpleDerivationSet" /> - </attribute> - </optional> - </element> -</define> - -<!--define name="rangeFacets" txw:mode="inherit"> - <doc:p> - This describes the relationship between the various range facets. Only - one of minExclusive and minInclusive can be present, and only one of - maxExclusive and maxInclusive can be present. This is a constraint that - can't easily be expressed using XML Schema. This RELAX NG schema - for XML Schema is a little more restrictive than the XML Schema - Recommendation in that it also forces there to be a maximum of one of - each of these types of facets. - </doc:p> - <interleave> - <optional> - <choice> - <ref name="minExclusive" /> - <ref name="minInclusive" /> - </choice> - </optional> - <optional> - <choice> - <ref name="maxExclusive" /> - <ref name="maxInclusive" /> - </choice> - </optional> - </interleave> -</define> - -<define name="digitFacets" txw:mode="inherit"> - <doc:p> - This specifies optional totalDigits and fractionDigits elements. This - RELAX NG schema for XML Schema is a little more restrictive than the XML - Schema Recommendation in that it also forces there to be a maximum of one - of each of these types of facets. - </doc:p> - <optional> - <ref name="totalDigits" /> - </optional> - <optional> - <ref name="fractionDigits" /> - </optional> -</define> - -<define name="lengthFacets" txw:mode="inherit"> - <doc:p> - This specifies optional length, minLength and maxLength elements. This - RELAX NG schema for XML Schema is a little more restrictive than the XML - Schema Recommendation in that it also forces there to be a maximum of one - of each of these types of facets, and says that if a length element is - given, then neither minLength nor maxLength should be present. - </doc:p> - <choice> - <ref name="length" /> - <interleave> - <optional> - <ref name="minLength" /> - </optional> - <optional> - <ref name="maxLength" /> - </optional> - </interleave> - </choice> -</define> - -<define name="commonFacets" txw:mode="inherit"> - <doc:p> - This specifies zero or more enumeration or pattern elements and an - optional whiteSpace element. This RELAX NG schema for XML Schema is a - little more restrictive than the XML Schema Recommendation in that it - also forces there to be a maximum of one whiteSpace element within the - facets. Note that the whiteSpace facet is constrained to have a value of - 'collapse'. - </doc:p> - <zeroOrMore> - <ref name="enumeration" /> - </zeroOrMore> - <optional> - <ref name="whiteSpaceCollapse" /> - </optional> - <zeroOrMore> - <ref name="pattern" /> - </zeroOrMore> -</define--> - -<define name="simpleRestrictionModel"> - <doc:p> - This specifies the types of facets that are valid in restrictions on the - built-in data types. This can only perform rudimentary checking, but - should be enough in most circumstances. Note that for xs:anySimpleType - and xs:string, the whiteSpace facet can take any value, for - xs:normalizedString it can be 'replace' or 'collapse', and for all other - built-in types it has to be 'collapse'. - </doc:p> - <choice> - <attribute name="base"> - <data type="QName" /> - </attribute> - <ref name="simpleTypeHost" /> - </choice> - <interleave> - <!--ref name="rangeFacets" /> - <ref name="digitFacets" /> - <ref name="lengthFacets" /> - <optional> - <ref name="whiteSpace" /> - </optional--> - <zeroOrMore> - <ref name="enumeration" /> - </zeroOrMore> - <!--zeroOrMore> - <ref name="pattern" /> - </zeroOrMore--> - </interleave> -</define> - -<define name="list"> - <doc:p> - This describes a list element. It can either specify a local simple type - or have a itemType attribute. This constraint cannot be expressed in XML - Schema. - </doc:p> - <element name="list" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-list"> - <ref name="annotated" /> - <choice> - <ref name="simpleTypeHost" /> - <attribute name="itemType"> - <data type="QName" /> - </attribute> - </choice> - </element> -</define> - -<define name="union"> - <doc:p> - This describes a union element. If the memberTypes attribute is missing - or empty, then it must contain one or more simpleType elements; if - it's present, then it can contain simpleType elements or list simple - types in the memberTypes attribute. This constraint cannot be expressed - in XML Schema. - </doc:p> - <element name="union" - doc:href="http://www.w3.org/TR/xmlschema-1/#element-union"> - <ref name="annotated" /> - <choice> - <group> - <attribute name="memberTypes"> - <list> - <oneOrMore> - <data type="QName" /> - </oneOrMore> - </list> - </attribute> - <zeroOrMore> - <ref name="simpleTypeHost" /> - </zeroOrMore> - </group> - <group> - <optional> - <attribute name="memberTypes"> - <empty /> - </attribute> - </optional> - <oneOrMore> - <ref name="simpleTypeHost" /> - </oneOrMore> - </group> - </choice> - </element> -</define> - -<define name="facet" txw:mode="inherit"> - <doc:p> - This is the basic content of a facet. It has an optional fixed attribute. - </doc:p> - <ref name="annotated" /> - <optional> - <attribute name="fixed"> - <data type="boolean" /> - </attribute> - </optional> -</define> - -<define name="noFixedFacet" txw:mode="inherit"> - <doc:p> - This is the content of a facet that cannot be fixed (enumeration or - pattern). It has a value attribute that can take any kind of value. - </doc:p> - <ref name="annotated" /> - <attribute name="value" /> -</define> - -<!--define name="rangeFacet"> - <doc:p> - This is the content of a range facet. The value must be one of the data - types shown (as these are the only types of data that accept ranges). I - haven't gone so far as to indicate the data type of the value - attribute of a range facet according to the base type as this would be - very complicated (although it would be possible in RELAX NG). - </doc:p> - <ref name="facet" /> - <attribute name="value"> - <choice> - <data type="decimal" /> - <data type="float" /> - <data type="double" /> - <data type="duration" /> - <data type="dateTime" /> - <data type="time" /> - <data type="date" /> - <data type="gYearMonth" /> - <data type="gYear" /> - <data type="gMonthDay" /> - <data type="gMonth" /> - <data type="gDay" /> - </choice> - </attribute> -</define> - -<define name="minExclusive"> - <doc:p> - This describes a minExclusive element. - </doc:p> - <element name="minExclusive" - doc:href="http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#element-minExclusive"> - <ref name="rangeFacet" /> - </element> -</define> - -<define name="minInclusive"> - <doc:p> - This describes a minInclusive element. - </doc:p> - <element name="minInclusive" - doc:href="http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#element-minInclusive"> - <ref name="rangeFacet" /> - </element> -</define> - -<define name="maxExclusive"> - <doc:p> - This describes a maxExclusive element. - </doc:p> - <element name="maxExclusive" - doc:href="http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#element-maxExclusive"> - <ref name="rangeFacet" /> - </element> -</define> - -<define name="maxInclusive"> - <doc:p> - This describes a maxInclusive element. - </doc:p> - <element name="maxInclusive" - doc:href="http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#element-maxInclusive"> - <ref name="rangeFacet" /> - </element> -</define> - -<define name="numFacet"> - <doc:p> - This is the content of a numerical facet. - </doc:p> - <ref name="facet" /> - <attribute name="value"> - <data type="nonNegativeInteger" /> - </attribute> -</define> - -<define name="totalDigits"> - <doc:p> - This describes a totalDigits element. The value attribute must take a - positive integer. - </doc:p> - <element name="totalDigits" - doc:href="http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#element-totalDigits"> - <ref name="facet" /> - <attribute name="value"> - <data type="positiveInteger" /> - </attribute> - </element> -</define> - -<define name="fractionDigits"> - <doc:p> - This describes a fractionDigits element. - </doc:p> - <element name="fractionDigits" - doc:href="http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#element-fractionDigits"> - <ref name="numFacet" /> - </element> -</define> - -<define name="length"> - <doc:p> - This describes a length element. - </doc:p> - <element name="length" - doc:href="http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#element-length"> - <ref name="numFacet" /> - </element> -</define> - -<define name="minLength"> - <doc:p> - This describes a minLength element. - </doc:p> - <element name="minLength" - doc:href="http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#element-minLength"> - <ref name="numFacet" /> - </element> -</define> - -<define name="maxLength"> - <doc:p> - This describes a maxLength element. - </doc:p> - <element name="maxLength" - doc:href="http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#element-maxLength"> - <ref name="numFacet" /> - </element> -</define--> - -<define name="enumeration"> - <doc:p> - This describes an enumeration element. - </doc:p> - <element name="enumeration" - doc:href="http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#element-enumeration"> - <ref name="noFixedFacet" /> - </element> -</define> - -<!--define name="whiteSpace"> - <doc:p> - This describes a whiteSpace element that can take any of the permitted - values. - </doc:p> - <element name="whiteSpace" - doc:href="http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#element-whiteSpace"> - <ref name="facet" /> - <attribute name="value"> - <choice> - <value type="token">preserve</value> - <value type="token">replace</value> - <value type="token">collapse</value> - </choice> - </attribute> - </element> -</define> - -<define name="whiteSpaceReplaceOrCollapse"> - <doc:p> - This describes a whiteSpace element that can only take the values - 'replace' or 'collapse'. - </doc:p> - <element name="whiteSpace" - doc:href="http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#element-whiteSpace"> - <ref name="facet" /> - <attribute name="value"> - <choice> - <value type="token">replace</value> - <value type="token">collapse</value> - </choice> - </attribute> - </element> -</define> - -<define name="whiteSpaceCollapse"> - <doc:p> - This describes a whiteSpace element that can only take the value - 'collapse'. - </doc:p> - <element name="whiteSpace" - doc:href="http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#element-whiteSpace"> - <ref name="facet" /> - <attribute name="value"> - <value type="token">collapse</value> - </attribute> - </element> -</define> - -<define name="pattern"> - <doc:p> - This describes a pattern element. - </doc:p> - <element name="pattern" - doc:href="http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#element-pattern"> - <ref name="noFixedFacet" /> - </element> -</define--> - -</grammar> diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/rngom/parse/compact/CompactSyntax.jj b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/rngom/parse/compact/CompactSyntax.jj deleted file mode 100644 index c0b8d256cbd..00000000000 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/rngom/parse/compact/CompactSyntax.jj +++ /dev/null @@ -1,1963 +0,0 @@ -options { - STATIC = false; - UNICODE_INPUT = true; - JAVA_UNICODE_ESCAPE = true; -} - -PARSER_BEGIN(CompactSyntax) - -package com.sun.xml.internal.rngom.parse.compact; - -import java.io.Reader; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.List; - -import com.sun.xml.internal.rngom.ast.builder.Annotations; -import com.sun.xml.internal.rngom.ast.builder.BuildException; -import com.sun.xml.internal.rngom.ast.builder.CommentList; -import com.sun.xml.internal.rngom.ast.builder.DataPatternBuilder; -import com.sun.xml.internal.rngom.ast.builder.Div; -import com.sun.xml.internal.rngom.ast.builder.ElementAnnotationBuilder; -import com.sun.xml.internal.rngom.ast.builder.Grammar; -import com.sun.xml.internal.rngom.ast.builder.GrammarSection; -import com.sun.xml.internal.rngom.ast.builder.Include; -import com.sun.xml.internal.rngom.ast.builder.IncludedGrammar; -import com.sun.xml.internal.rngom.ast.builder.NameClassBuilder; -import com.sun.xml.internal.rngom.ast.builder.SchemaBuilder; -import com.sun.xml.internal.rngom.ast.builder.Scope; -import com.sun.xml.internal.rngom.ast.om.Location; -import com.sun.xml.internal.rngom.ast.om.ParsedElementAnnotation; -import com.sun.xml.internal.rngom.ast.om.ParsedNameClass; -import com.sun.xml.internal.rngom.ast.om.ParsedPattern; -import com.sun.xml.internal.rngom.parse.Context; -import com.sun.xml.internal.rngom.parse.IllegalSchemaException; -import com.sun.xml.internal.rngom.parse.Parseable; -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; -import org.xml.sax.helpers.LocatorImpl; - -import com.sun.xml.internal.rngom.util.Localizer; -import com.sun.xml.internal.rngom.xml.util.WellKnownNamespaces; - - -public class CompactSyntax implements Context { - private static final int IN_ELEMENT = 0; - private static final int IN_ATTRIBUTE = 1; - private static final int IN_ANY_NAME = 2; - private static final int IN_NS_NAME = 4; - - private String defaultNamespace; - private String compatibilityPrefix = null; - private SchemaBuilder sb; - private NameClassBuilder ncb; - private String sourceUri; - /** - * This is what we are parsing right now. - */ - private CompactParseable parseable; - private ErrorHandler eh; - private final Hashtable namespaceTable = new Hashtable(); - private final Hashtable datatypesTable = new Hashtable(); - private boolean hadError = false; - private static final Localizer localizer = new Localizer(new Localizer(Parseable.class),CompactSyntax.class); - private final Hashtable attributeNameTable = new Hashtable(); - private boolean annotationsIncludeElements = false; - - /** - * String that represents the inherited namespace. - * - * <p> - * HACK: we always allocate a new String instance so that - * we can distinguish inherited value from the explicitly - * given value. - */ - private /*final*/ String inheritedNs; // essentially final but JavaCC don't let us declare it as so. - - final class LocatedString { - private final String str; - private final Token tok; - - LocatedString(String str, Token tok) { - this.str = str; - this.tok = tok; - } - - String getString() { - return str; - } - - Location getLocation() { - return makeLocation(tok); - } - - Token getToken() { - return tok; - } - - } - - public CompactSyntax(CompactParseable parseable, Reader r, String sourceUri, SchemaBuilder sb, ErrorHandler eh, String inheritedNs) { - this(r); - this.sourceUri = sourceUri; - this.parseable = parseable; - this.sb = sb; - this.ncb = sb.getNameClassBuilder(); - this.eh = eh; - // this causes the root pattern to have non-null annotations - // which is useful because it gives a context to trang - this.topLevelComments = sb.makeCommentList(); - this.inheritedNs = defaultNamespace = new String(inheritedNs); - } - - ParsedPattern parse(Scope scope) throws IllegalSchemaException { - try { - ParsedPattern p = Input(scope); - if (!hadError) - return p; - } - catch (ParseException e) { - error("syntax_error", e.getMessage(), e.currentToken.next); - } - catch (EscapeSyntaxException e) { - reportEscapeSyntaxException(e); - } - throw new IllegalSchemaException(); - } - - ParsedPattern parseInclude(IncludedGrammar g) throws IllegalSchemaException { - try { - ParsedPattern p = IncludedGrammar(g); - if (!hadError) - return p; - } - catch (ParseException e) { - error("syntax_error", e.getMessage(), e.currentToken.next); - } - catch (EscapeSyntaxException e) { - reportEscapeSyntaxException(e); - } - throw new IllegalSchemaException(); - } - - private void checkNsName(int context, LocatedString ns) { - if ((context & IN_NS_NAME) != 0) - error("ns_name_except_contains_ns_name", ns.getToken()); - } - - private void checkAnyName(int context, Token t) { - if ((context & IN_NS_NAME) != 0) - error("ns_name_except_contains_any_name", t); - if ((context & IN_ANY_NAME) != 0) - error("any_name_except_contains_any_name", t); - } - - private void error(String key, Token tok) { - doError(localizer.message(key), tok); - } - - private void error(String key, String arg, Token tok) { - doError(localizer.message(key, arg), tok); - } - - private void error(String key, String arg1, String arg2, Token tok) { - doError(localizer.message(key, arg1, arg2), tok); - } - - private void doError(String message, Token tok) { - hadError = true; - if (eh != null) { - LocatorImpl loc = new LocatorImpl(); - loc.setLineNumber(tok.beginLine); - loc.setColumnNumber(tok.beginColumn); - loc.setSystemId(sourceUri); - try { - eh.error(new SAXParseException(message, loc)); - } - catch (SAXException se) { - throw new BuildException(se); - } - } - } - - private void reportEscapeSyntaxException(EscapeSyntaxException e) { - if (eh != null) { - LocatorImpl loc = new LocatorImpl(); - loc.setLineNumber(e.getLineNumber()); - loc.setColumnNumber(e.getColumnNumber()); - loc.setSystemId(sourceUri); - try { - eh.error(new SAXParseException(localizer.message(e.getKey()), loc)); - } - catch (SAXException se) { - throw new BuildException(se); - } - } - } - - private static String unquote(String s) { - if (s.length() >= 6 && s.charAt(0) == s.charAt(1)) { - s = s.replace('\u0000', '\n'); - return s.substring(3, s.length() - 3); - } - else - return s.substring(1, s.length() - 1); - } - - Location makeLocation(Token t) { - return sb.makeLocation(sourceUri, t.beginLine, t.beginColumn); - } - - private static ParsedPattern[] addPattern(ParsedPattern[] patterns, int i, ParsedPattern p) { - if (i >= patterns.length) { - ParsedPattern[] oldPatterns = patterns; - patterns = new ParsedPattern[oldPatterns.length*2]; - System.arraycopy(oldPatterns, 0, patterns, 0, oldPatterns.length); - } - patterns[i] = p; - return patterns; - } - - String getCompatibilityPrefix() { - if (compatibilityPrefix == null) { - compatibilityPrefix = "a"; - while (namespaceTable.get(compatibilityPrefix) != null) - compatibilityPrefix = compatibilityPrefix + "a"; - } - return compatibilityPrefix; - } - - public String resolveNamespacePrefix(String prefix) { - String result = (String)namespaceTable.get(prefix); - if (result.length() == 0) - return null; - return result; - } - - public Enumeration prefixes() { - return namespaceTable.keys(); - } - - public String getBaseUri() { - return sourceUri; - } - - public boolean isUnparsedEntity(String entityName) { - return false; - } - - public boolean isNotation(String notationName) { - return false; - } - - public Context copy() { - return this; - } - - private Context getContext() { - return this; - } - - private CommentList getComments() { - return getComments(getTopLevelComments()); - } - - private CommentList topLevelComments; - - private CommentList getTopLevelComments() { - CommentList tem = topLevelComments; - topLevelComments = null; - return tem; - } - - private void noteTopLevelComments() { - topLevelComments = getComments(topLevelComments); - } - - private void topLevelComments(GrammarSection section) { - section.topLevelComment(getComments(null)); - } - - private Token lastCommentSourceToken = null; - - private CommentList getComments(CommentList comments) { - Token nextToken = getToken(1); - if (lastCommentSourceToken != nextToken) { - if (lastCommentSourceToken == null) - lastCommentSourceToken = token; - do { - lastCommentSourceToken = lastCommentSourceToken.next; - Token t = lastCommentSourceToken.specialToken; - if (t != null) { - while (t.specialToken != null) - t = t.specialToken; - if (comments == null) - comments = sb.makeCommentList(); - for (; t != null; t = t.next) { - String s = mungeComment(t.image); - Location loc = makeLocation(t); - if (t.next != null - && t.next.kind == CompactSyntaxConstants.SINGLE_LINE_COMMENT_CONTINUE) { - StringBuffer buf = new StringBuffer(s); - do { - t = t.next; - buf.append('\n'); - buf.append(mungeComment(t.image)); - } while (t.next != null - && t.next.kind == CompactSyntaxConstants.SINGLE_LINE_COMMENT_CONTINUE); - s = buf.toString(); - } - comments.addComment(s, loc); - } - } - } while (lastCommentSourceToken != nextToken); - } - return comments; - } - - private ParsedPattern afterComments(ParsedPattern p) { - CommentList comments = getComments(null); - if (comments == null) - return p; - return sb.commentAfter(p, comments); - } - - private ParsedNameClass afterComments(ParsedNameClass nc) { - CommentList comments = getComments(null); - if (comments == null) - return nc; - return ncb.commentAfter(nc, comments); - } - - private static String mungeComment(String image) { - int i = image.indexOf('#') + 1; - while (i < image.length() && image.charAt(i) == '#') - i++; - if (i < image.length() && image.charAt(i) == ' ') - i++; - return image.substring(i); - } - - private Annotations getCommentsAsAnnotations() { - CommentList comments = getComments(); - if (comments == null) - return null; - return sb.makeAnnotations(comments, getContext()); - } - - private Annotations addCommentsToChildAnnotations(Annotations a) { - CommentList comments = getComments(); - if (comments == null) - return a; - if (a == null) - a = sb.makeAnnotations(null, getContext()); - a.addComment(comments); - return a; - } - - private Annotations addCommentsToLeadingAnnotations(Annotations a) { - CommentList comments = getComments(); - if (comments == null) - return a; - if (a == null) - return sb.makeAnnotations(comments, getContext()); - a.addLeadingComment(comments); - return a; - } - - private Annotations getTopLevelCommentsAsAnnotations() { - CommentList comments = getTopLevelComments(); - if (comments == null) - return null; - return sb.makeAnnotations(comments, getContext()); - } - - private void clearAttributeList() { - attributeNameTable.clear(); - } - - private void addAttribute(Annotations a, String ns, String localName, String prefix, String value, Token tok) { - String key = ns + "#" + localName; - if (attributeNameTable.get(key) != null) - error("duplicate_attribute", ns, localName, tok); - else { - attributeNameTable.put(key, key); - a.addAttribute(ns, localName, prefix, value, makeLocation(tok)); - } - } - - private void checkExcept(Token[] except) { - if (except[0] != null) - error("except_missing_parentheses", except[0]); - } - - private String lookupPrefix(String prefix, Token t) { - String ns = (String)namespaceTable.get(prefix); - if (ns == null) { - error("undeclared_prefix", prefix, t); - return "#error"; - } - return ns; - } - private String lookupDatatype(String prefix, Token t) { - String ns = (String)datatypesTable.get(prefix); - if (ns == null) { - error("undeclared_prefix", prefix, t); - return ""; // XXX - } - return ns; - } - private String resolve(String str) { - try { - return new URL(new URL(sourceUri), str).toString(); - } - catch (MalformedURLException e) { } - return str; - } -} - -PARSER_END(CompactSyntax) - -ParsedPattern Input(Scope scope) : -{ - ParsedPattern p; -} -{ - Preamble() - (LOOKAHEAD(TopLevelLookahead()) p = TopLevelGrammar(scope) - | p = Expr(true, scope, null, null) { p = afterComments(p); } <EOF>) - { return p; } -} - -void TopLevelLookahead() : -{} -{ - <PREFIXED_NAME> "[" - | Identifier() ("[" | "=" | "&=" | "|=") - | LookaheadGrammarKeyword() - | LookaheadBody() LookaheadAfterAnnotations() - | LookaheadDocumentation() (LookaheadBody())? LookaheadAfterAnnotations() -} - -void LookaheadAfterAnnotations() : -{} -{ - Identifier() ("=" | "&=" | "|=") - | LookaheadGrammarKeyword() -} - -void LookaheadGrammarKeyword() : -{} -{ - "start" | "div" | "include" -} - -void LookaheadDocumentation() : -{} -{ - ((<DOCUMENTATION> | <DOCUMENTATION_AFTER_SINGLE_LINE_COMMENT>) (<DOCUMENTATION_CONTINUE>)*)+ -} - -void LookaheadBody() : -{} -{ - "[" - (<PREFIXED_NAME> | UnprefixedName() | "=" | <LITERAL> | "~" | LookaheadBody() )* - "]" -} - -ParsedPattern IncludedGrammar(IncludedGrammar g) : -{ - Annotations a; - ParsedPattern p; -} -{ - Preamble() - (LOOKAHEAD(TopLevelLookahead()) a = GrammarBody(g, g, getTopLevelCommentsAsAnnotations()) - | a = Annotations() "grammar" "{" a = GrammarBody(g, g, a) { topLevelComments(g); } "}") - { p = afterComments(g.endIncludedGrammar(sb.makeLocation(sourceUri, 1, 1), a)); } - <EOF> - { return p; } -} - -ParsedPattern TopLevelGrammar(Scope scope) : -{ - Annotations a = getTopLevelCommentsAsAnnotations(); - Grammar g; - ParsedPattern p; -} -{ - { g = sb.makeGrammar(scope); } - a = GrammarBody(g, g, a) - { p = afterComments(g.endGrammar(sb.makeLocation(sourceUri, 1, 1), a)); } - <EOF> - { return p; } -} - -void Preamble() : -{} -{ - (NamespaceDecl() | DatatypesDecl())* - { - namespaceTable.put("xml", WellKnownNamespaces.XML); - if (datatypesTable.get("xsd") == null) - datatypesTable.put("xsd", WellKnownNamespaces.XML_SCHEMA_DATATYPES); - } -} - -void NamespaceDecl() : -{ - LocatedString prefix = null; - boolean isDefault = false; - String namespaceName; -} -{ - { noteTopLevelComments(); } - (("namespace" prefix = UnprefixedName()) - | ("default" { isDefault = true; } - "namespace" (prefix = UnprefixedName())?)) - "=" - namespaceName = NamespaceName() - { - if (isDefault) - defaultNamespace = namespaceName; - if (prefix != null) { - if (prefix.getString().equals("xmlns")) - error("xmlns_prefix", prefix.getToken()); - else if (prefix.getString().equals("xml")) { - if (!namespaceName.equals(WellKnownNamespaces.XML)) - error("xml_prefix_bad_uri", prefix.getToken()); - } - else if (namespaceName.equals(WellKnownNamespaces.XML)) - error("xml_uri_bad_prefix", prefix.getToken()); - else { - if (namespaceName.equals(WellKnownNamespaces.RELAX_NG_COMPATIBILITY_ANNOTATIONS)) - compatibilityPrefix = prefix.getString(); - namespaceTable.put(prefix.getString(), namespaceName); - } - } - } -} - -String NamespaceName() : -{ - String r; -} -{ - (r = Literal() | "inherit" { r = this.inheritedNs; }) - { return r; } -} - -void DatatypesDecl() : -{ - LocatedString prefix; - String uri; -} -{ - { noteTopLevelComments(); } - "datatypes" prefix = UnprefixedName() "=" uri = Literal() - { - datatypesTable.put(prefix.getString(), uri); - } -} - -ParsedPattern AnnotatedPrimaryExpr(boolean topLevel, Scope scope, Token[] except) : -{ - Annotations a; - ParsedPattern p; - ParsedElementAnnotation e; - Token t; -} -{ - a = Annotations() - p = PrimaryExpr(topLevel, scope, a, except) - ( t = <FANNOTATE> e = AnnotationElement(false) { - if (topLevel) - error("top_level_follow_annotation", t); - else - p = sb.annotateAfter(p, e); - })* - { return p; } -} - - -ParsedPattern PrimaryExpr(boolean topLevel, Scope scope, Annotations a, Token[] except) : -{ - ParsedPattern p; -} -{ - (p = ElementExpr(scope, a) - | p = AttributeExpr(scope, a) - | p = GrammarExpr(scope, a) - | p = ExternalRefExpr(scope, a) - | p = ListExpr(scope, a) - | p = MixedExpr(scope, a) - | p = ParenExpr(topLevel, scope, a) - | p = IdentifierExpr(scope, a) - | p = ParentExpr(scope, a) - | p = DataExpr(topLevel, scope, a, except) - | p = ValueExpr(topLevel, a) - | p = TextExpr(a) - | p = EmptyExpr(a) - | p = NotAllowedExpr(a)) - { return p; } -} - -ParsedPattern EmptyExpr(Annotations a) : -{ - Token t; -} -{ - t = "empty" - { return sb.makeEmpty(makeLocation(t), a); } -} - -ParsedPattern TextExpr(Annotations a) : -{ - Token t; -} -{ - t = "text" - { return sb.makeText(makeLocation(t), a); } -} - -ParsedPattern NotAllowedExpr(Annotations a) : -{ - Token t; -} -{ - t = "notAllowed" - { return sb.makeNotAllowed(makeLocation(t), a); } -} - -ParsedPattern Expr(boolean topLevel, Scope scope, Token t, Annotations a) : -{ - List patterns = new ArrayList(); - ParsedPattern p; - boolean[] hadOccur = new boolean[1]; - Token[] except = new Token[1]; -} -{ - p = UnaryExpr(topLevel, scope, hadOccur, except) - { patterns.add(p); } - ( - { checkExcept(except); } - (t = "|" p = UnaryExpr(topLevel, scope, null, except) - { patterns.add(p); checkExcept(except); } )+ - { p = sb.makeChoice(patterns, makeLocation(t), a); } - | (t = "&" p = UnaryExpr(topLevel, scope, null, except) - { patterns.add(p); checkExcept(except); } )+ - { p = sb.makeInterleave(patterns, makeLocation(t), a); } - | (t = "," p = UnaryExpr(topLevel, scope, null, except) - { patterns.add(p); checkExcept(except); } )+ - { p = sb.makeGroup(patterns, makeLocation(t), a); } - )? - { - if (patterns.size() == 1 && a != null) { - if (hadOccur[0]) - p = sb.annotate(p, a); - else - p = sb.makeGroup(patterns, makeLocation(t), a); - } - return p; - } -} - -ParsedPattern UnaryExpr(boolean topLevel, Scope scope, boolean[] hadOccur, Token[] except) : -{ - ParsedPattern p; - Token t; - ParsedElementAnnotation e; -} -{ - p = AnnotatedPrimaryExpr(topLevel, scope, except) - ( - { - if (hadOccur != null) hadOccur[0] = true; - p = afterComments(p); - } - (t = "+" { checkExcept(except); p = sb.makeOneOrMore(p, makeLocation(t), null); } - | t = "?" { checkExcept(except); p = sb.makeOptional(p, makeLocation(t), null); } - | t = "*" { checkExcept(except); p = sb.makeZeroOrMore(p, makeLocation(t), null); }) - ( t = <FANNOTATE> e = AnnotationElement(false) { - if (topLevel) - error("top_level_follow_annotation", t); - else - p = sb.annotateAfter(p, e); - } )* - )? - { return p; } -} - -ParsedPattern ElementExpr(Scope scope, Annotations a) : -{ - Token t; - ParsedNameClass nc; - ParsedPattern p; -} -{ - t = "element" - nc = NameClass(IN_ELEMENT, null) - "{" - p = Expr(false, scope, null, null) - { p = afterComments(p); } - "}" - { return sb.makeElement(nc, p, makeLocation(t), a); } -} - -ParsedPattern AttributeExpr(Scope scope, Annotations a) : -{ - Token t; - ParsedNameClass nc; - ParsedPattern p; -} -{ - t = "attribute" - nc = NameClass(IN_ATTRIBUTE, null) - "{" - p = Expr(false, scope, null, null) - { p = afterComments(p); } - "}" - { return sb.makeAttribute(nc, p, makeLocation(t), a); } -} - -ParsedNameClass NameClass(int context, Annotations[] pa) : -{ - Annotations a; - ParsedNameClass nc; -} -{ - a = Annotations() - (nc = PrimaryNameClass(context, a) nc = AnnotateAfter(nc) nc = NameClassAlternatives(context, nc, pa) - | nc = AnyNameExceptClass(context, a, pa) - | nc = NsNameExceptClass(context, a, pa)) - { return nc; } -} - -ParsedNameClass AnnotateAfter(ParsedNameClass nc) : -{ - ParsedElementAnnotation e; -} -{ - ( <FANNOTATE> e = AnnotationElement(false) { nc = ncb.annotateAfter(nc, e); })* - { return nc; } -} - -ParsedNameClass NameClassAlternatives(int context, ParsedNameClass nc, Annotations[] pa) : -{ - Token t; - ParsedNameClass[] nameClasses; - int nNameClasses; -} -{ - ( - { - nameClasses = new ParsedNameClass[2]; - nameClasses[0] = nc; - nNameClasses = 1; - } - (t = "|" nc = BasicNameClass(context) nc = AnnotateAfter(nc) - { - if (nNameClasses >= nameClasses.length) { - ParsedNameClass[] oldNameClasses = nameClasses; - nameClasses = new ParsedNameClass[oldNameClasses.length*2]; - System.arraycopy(oldNameClasses, 0, nameClasses, 0, oldNameClasses.length); - } - nameClasses[nNameClasses++] = nc; - })+ - { - Annotations a; - if (pa == null) - a = null; - else { - a = pa[0]; - pa[0] = null; - } - nc = ncb.makeChoice(Arrays.asList(nameClasses).subList(0,nNameClasses), makeLocation(t), a); - } - )? - { return nc; } -} - -ParsedNameClass BasicNameClass(int context) : -{ - Annotations a; - ParsedNameClass nc; -} -{ - a = Annotations() - (nc = PrimaryNameClass(context, a) - | nc = OpenNameClass(context, a)) - { return nc; } -} - -ParsedNameClass PrimaryNameClass(int context, Annotations a) : -{ - ParsedNameClass nc; -} -{ - (nc = UnprefixedNameClass(context, a) - | nc = PrefixedNameClass(a) - | nc = ParenNameClass(context, a)) - { return nc; } -} - -ParsedNameClass OpenNameClass(int context, Annotations a) : -{ - Token t; - LocatedString ns; -} -{ - ns = NsName() { checkNsName(context, ns); return ncb.makeNsName(ns.getString(), ns.getLocation(), a); } - | t = "*" { checkAnyName(context, t); return ncb.makeAnyName(makeLocation(t), a); } -} - - -ParsedNameClass UnprefixedNameClass(int context, Annotations a) : -{ - LocatedString name; -} -{ - name = UnprefixedName() - { - String ns; - if ((context & (IN_ATTRIBUTE|IN_ELEMENT)) == IN_ATTRIBUTE) - ns = ""; - else - ns = defaultNamespace; - return ncb.makeName(ns, name.getString(), null, name.getLocation(), a); - } -} - -ParsedNameClass PrefixedNameClass(Annotations a) : -{ - Token t; -} -{ - t = <PREFIXED_NAME> - { - String qn = t.image; - int colon = qn.indexOf(':'); - String prefix = qn.substring(0, colon); - return ncb.makeName(lookupPrefix(prefix, t), qn.substring(colon + 1), prefix, makeLocation(t), a); - } -} - -ParsedNameClass NsNameExceptClass(int context, Annotations a, Annotations[] pa) : -{ - LocatedString ns; - ParsedNameClass nc; -} -{ - ns = NsName() - { checkNsName(context, ns); } - (nc = ExceptNameClass(context | IN_NS_NAME) - { nc = ncb.makeNsName(ns.getString(), nc, ns.getLocation(), a); } - nc = AnnotateAfter(nc) - | { nc = ncb.makeNsName(ns.getString(), ns.getLocation(), a); } - nc = AnnotateAfter(nc) - nc = NameClassAlternatives(context, nc, pa)) - { return nc; } -} - -LocatedString NsName() : -{ - Token t; -} -{ - t = <PREFIX_STAR> - { - String qn = t.image; - String prefix = qn.substring(0, qn.length() - 2); - return new LocatedString(lookupPrefix(prefix, t), t); - } -} - -ParsedNameClass AnyNameExceptClass(int context, Annotations a, Annotations[] pa) : -{ - Token t; - ParsedNameClass nc; -} -{ - t = "*" - { checkAnyName(context, t); } - (nc = ExceptNameClass(context | IN_ANY_NAME) - { nc = ncb.makeAnyName(nc, makeLocation(t), a); } - nc = AnnotateAfter(nc) - | { nc = ncb.makeAnyName(makeLocation(t), a); } - nc = AnnotateAfter(nc) - nc = NameClassAlternatives(context, nc, pa)) - { return nc; } -} - -ParsedNameClass ParenNameClass(int context, Annotations a) : -{ - Token t; - ParsedNameClass nc; - Annotations[] pa = new Annotations[]{ a }; -} -{ - t = "(" nc = NameClass(context, pa) { nc = afterComments(nc); } ")" - { - if (pa[0] != null) - nc = ncb.makeChoice(Collections.singletonList(nc), makeLocation(t), pa[0]); - return nc; - } -} - -ParsedNameClass ExceptNameClass(int context) : -{ - ParsedNameClass nc; -} -{ - "-" nc = BasicNameClass(context) - { return nc; } -} - -ParsedPattern ListExpr(Scope scope, Annotations a) : -{ - Token t; - ParsedPattern p; -} -{ - t = "list" - "{" - p = Expr(false, scope, null, null) - { p = afterComments(p); } - "}" - { return sb.makeList(p, makeLocation(t), a); } -} - -ParsedPattern MixedExpr(Scope scope, Annotations a) : -{ - Token t; - ParsedPattern p; -} -{ - t = "mixed" - "{" - p = Expr(false, scope, null, null) - { p = afterComments(p); } - "}" - { return sb.makeMixed(p, makeLocation(t), a); } -} - -ParsedPattern GrammarExpr(Scope scope, Annotations a) : -{ - Token t; - Grammar g; -} -{ - t = "grammar" { g = sb.makeGrammar(scope); } - "{" a = GrammarBody(g, g, a) { topLevelComments(g); } "}" - { return g.endGrammar(makeLocation(t), a); } -} - -ParsedPattern ParenExpr(boolean topLevel, Scope scope, Annotations a) : -{ - Token t; - ParsedPattern p; -} -{ - t = "(" p = Expr(topLevel, scope, t, a) { p = afterComments(p); } ")" - { return p; } -} - -Annotations GrammarBody(GrammarSection section, Scope scope, Annotations a) : -{ - ParsedElementAnnotation e; -} -{ - (LOOKAHEAD(2) e = AnnotationElementNotKeyword() - { if (a == null) a = sb.makeAnnotations(null, getContext()); a.addElement(e); })* - (GrammarComponent(section, scope))* - { return a; } -} - -void GrammarComponent(GrammarSection section, Scope scope) : -{ - ParsedElementAnnotation e; - Annotations a; -} -{ - (a = Annotations() - (Definition(section, scope, a) - | Include(section, scope, a) - | Div(section, scope, a))) - (LOOKAHEAD(2) e = AnnotationElementNotKeyword() { section.topLevelAnnotation(e); })* -} - -void Definition(GrammarSection section, Scope scope, Annotations a) : -{} -{ - (Define(section, scope, a) | Start(section, scope, a)) -} - -void Start(GrammarSection section, Scope scope, Annotations a) : -{ - Token t; - GrammarSection.Combine combine; - ParsedPattern p; -} -{ - t = "start" combine = AssignOp() p = Expr(false, scope, null, null) - { section.define(GrammarSection.START, combine, p, makeLocation(t), a); } -} - -void Define(GrammarSection section, Scope scope, Annotations a) : -{ - LocatedString name; - GrammarSection.Combine combine; - ParsedPattern p; -} -{ - name = Identifier() combine = AssignOp() p = Expr(false, scope, null, null) - { section.define(name.getString(), combine, p, name.getLocation(), a); } -} - -GrammarSection.Combine AssignOp() : -{} -{ - "=" { return null; } - | "|=" { return GrammarSection.COMBINE_CHOICE; } - | "&=" { return GrammarSection.COMBINE_INTERLEAVE; } -} - -void Include(GrammarSection section, Scope scope, Annotations a) : -{ - Token t; - String href; - String ns; - Include include = section.makeInclude(); -} -{ - t = "include" href = Literal() - ns = Inherit() - ("{" a = IncludeBody(include, scope, a) { topLevelComments(include); } "}")? - { - try { - include.endInclude(parseable, resolve(href), ns, makeLocation(t), a); - } - catch (IllegalSchemaException e) { } - } -} - -Annotations IncludeBody(GrammarSection section, Scope scope, Annotations a) : -{ - ParsedElementAnnotation e; -} -{ - (LOOKAHEAD(2) e = AnnotationElementNotKeyword() - { if (a == null) a = sb.makeAnnotations(null, getContext()); a.addElement(e); })* - (IncludeComponent(section, scope))* - { return a; } -} - - -void IncludeComponent(GrammarSection section, Scope scope) : -{ - ParsedElementAnnotation e; - Annotations a; -} -{ - (a = Annotations() (Definition(section, scope, a) - | IncludeDiv(section, scope, a))) - (LOOKAHEAD(2) e = AnnotationElementNotKeyword() { section.topLevelAnnotation(e); })* -} - -void Div(GrammarSection section, Scope scope, Annotations a) : -{ - Token t; - Div div = section.makeDiv(); -} -{ - t = "div" "{" a = GrammarBody(div, scope, a) { topLevelComments(div); } "}" - { div.endDiv(makeLocation(t), a); } -} - -void IncludeDiv(GrammarSection section, Scope scope, Annotations a) : -{ - Token t; - Div div = section.makeDiv(); -} -{ - t = "div" "{" a = IncludeBody(div, scope, a) { topLevelComments(div); } "}" - { div.endDiv(makeLocation(t), a); } -} - -ParsedPattern ExternalRefExpr(Scope scope, Annotations a) : -{ - Token t; - String href; - String ns; -} -{ - t = "external" href = Literal() - ns = Inherit() - { - try { - return sb.makeExternalRef(parseable, resolve(href), ns, scope, makeLocation(t), a); - } - catch (IllegalSchemaException e) { - return sb.makeErrorPattern(); - } - } -} - -String Inherit() : -{ - String ns = null; -} -{ - ("inherit" "=" ns = Prefix())? - { - if (ns == null) - ns = defaultNamespace; - return ns; - } -} - -ParsedPattern ParentExpr(Scope scope, Annotations a) : -{ - LocatedString name; -} -{ - "parent" { a = addCommentsToChildAnnotations(a); } name = Identifier() - { - if(scope==null) { - error("parent_ref_outside_grammar",name.getToken()); - return sb.makeErrorPattern(); - } else { - return scope.makeParentRef(name.getString(), name.getLocation(), a); - } - } -} - -ParsedPattern IdentifierExpr(Scope scope, Annotations a) : -{ - LocatedString name; -} -{ - name = Identifier() - { - if(scope==null) { - error("ref_outside_grammar",name.getToken()); - return sb.makeErrorPattern(); - } else { - return scope.makeRef(name.getString(), name.getLocation(), a); - } - } -} - -ParsedPattern ValueExpr(boolean topLevel, Annotations a) : -{ - LocatedString s; -} -{ - s = LocatedLiteral() - { - if (topLevel && annotationsIncludeElements) { - error("top_level_follow_annotation", s.getToken()); - a = null; - } - return sb.makeValue("", "token", s.getString(), getContext(), defaultNamespace, s.getLocation(), a); - } -} - -ParsedPattern DataExpr(boolean topLevel, Scope scope, Annotations a, Token[] except) : -{ - Token datatypeToken; - Location loc; - String datatype; - String datatypeUri = null; - String s = null; - ParsedPattern e = null; - DataPatternBuilder dpb; -} -{ - datatypeToken = DatatypeName() - { - datatype = datatypeToken.image; - loc = makeLocation(datatypeToken); - int colon = datatype.indexOf(':'); - if (colon < 0) - datatypeUri = ""; - else { - String prefix = datatype.substring(0, colon); - datatypeUri = lookupDatatype(prefix, datatypeToken); - datatype = datatype.substring(colon + 1); - } - } - ((s = Literal() - { - if (topLevel && annotationsIncludeElements) { - error("top_level_follow_annotation", datatypeToken); - a = null; - } - return sb.makeValue(datatypeUri, datatype, s, getContext(), defaultNamespace, loc, a); - } - ) - | ( { dpb = sb.makeDataPatternBuilder(datatypeUri, datatype, loc); } - ( (Params(dpb) (e = Except(scope, except))?) - | (e = Except(scope, except))?) - { return e == null ? dpb.makePattern(loc, a) : dpb.makePattern(e, loc, a); })) -} - -Token DatatypeName() : -{ - Token t; -} -{ - (t = "string" | t = "token" | t = <PREFIXED_NAME>) - { return t; } -} - -LocatedString Identifier() : -{ - LocatedString s; - Token t; -} -{ - (t = <IDENTIFIER> { s = new LocatedString(t.image, t); } - | t = <ESCAPED_IDENTIFIER> { s = new LocatedString(t.image.substring(1), t); }) - { return s; } -} - -String Prefix() : -{ - Token t; - String prefix; -} -{ - (t = <IDENTIFIER> { prefix = t.image; } - | t = <ESCAPED_IDENTIFIER> { prefix = t.image.substring(1); } - | t = Keyword() { prefix = t.image; }) - { return lookupPrefix(prefix, t); } -} - -LocatedString UnprefixedName() : -{ - LocatedString s; - Token t; -} -{ - (s = Identifier() - | t = Keyword() { s = new LocatedString(t.image, t); }) - { return s; } -} - -void Params(DataPatternBuilder dpb) : -{} -{ - "{" (Param(dpb))* "}" -} - -void Param(DataPatternBuilder dpb) : -{ - LocatedString name; - Annotations a; - String value; -} -{ - a = Annotations() name = UnprefixedName() "=" { a = addCommentsToLeadingAnnotations(a); } value = Literal() - { dpb.addParam(name.getString(), value, getContext(), defaultNamespace, name.getLocation(), a); } -} - -ParsedPattern Except(Scope scope, Token[] except) : -{ - Annotations a; - ParsedPattern p; - Token t; - Token[] innerExcept = new Token[1]; -} -{ - t = "-" a = Annotations() p = PrimaryExpr(false, scope, a, innerExcept) - { - checkExcept(innerExcept); - except[0] = t; - return p; - } -} - -ParsedElementAnnotation Documentation() : -{ - CommentList comments = getComments(); - ElementAnnotationBuilder eab; - Token t; -} -{ - (t = <DOCUMENTATION> | t = <DOCUMENTATION_AFTER_SINGLE_LINE_COMMENT>) - { - eab = sb.makeElementAnnotationBuilder(WellKnownNamespaces.RELAX_NG_COMPATIBILITY_ANNOTATIONS, - "documentation", - getCompatibilityPrefix(), - makeLocation(t), - comments, - getContext()); - eab.addText(mungeComment(t.image), makeLocation(t), null); - } - (t = <DOCUMENTATION_CONTINUE> { eab.addText("\n" + mungeComment(t.image), makeLocation(t), null); })* - { return eab.makeElementAnnotation(); } -} - -Annotations Annotations() : -{ - CommentList comments = getComments(); - Annotations a = null; - ParsedElementAnnotation e; -} -{ - ( { a = sb.makeAnnotations(comments, getContext()); } - (e = Documentation() { a.addElement(e); })+ - { - comments = getComments(); - if (comments != null) - a.addLeadingComment(comments); - } - )? - ("[" { if (a == null) a = sb.makeAnnotations(comments, getContext()); clearAttributeList(); annotationsIncludeElements = false; } - (LOOKAHEAD(2) PrefixedAnnotationAttribute(a, false) )* - ( e = AnnotationElement(false) { a.addElement(e); annotationsIncludeElements = true; } )* - { a.addComment(getComments()); } - "]")? - { - if (a == null && comments != null) - a = sb.makeAnnotations(comments, getContext()); - return a; - } -} - -void AnnotationAttribute(Annotations a) : -{} -{ - PrefixedAnnotationAttribute(a, true) | UnprefixedAnnotationAttribute(a) -} - -void PrefixedAnnotationAttribute(Annotations a, boolean nested) : -{ - Token t; - String value; -} -{ - t = <PREFIXED_NAME> "=" value = Literal() - { - String qn = t.image; - int colon = qn.indexOf(':'); - String prefix = qn.substring(0, colon); - String ns = lookupPrefix(prefix, t); - if (ns == this.inheritedNs) - error("inherited_annotation_namespace", t); - else if (ns.length() == 0 && !nested) - error("unqualified_annotation_attribute", t); - else if (ns.equals(WellKnownNamespaces.RELAX_NG) && !nested) - error("relax_ng_namespace", t); - /*else if (ns.length() == 0 - && qn.length() - colon - 1 == 5 - && qn.regionMatches(colon + 1, "xmlns", 0, 5)) - error("xmlns_annotation_attribute", t);*/ - else if (ns.equals(WellKnownNamespaces.XMLNS)) - error("xmlns_annotation_attribute_uri", t); - else { - if (ns.length() == 0) - prefix = null; - addAttribute(a, ns, qn.substring(colon + 1), prefix, value, t); - } - } -} - -void UnprefixedAnnotationAttribute(Annotations a) : -{ - LocatedString name; - String value; -} -{ - name = UnprefixedName() "=" value = Literal() - { - if (name.getString().equals("xmlns")) - error("xmlns_annotation_attribute", name.getToken()); - else - addAttribute(a, "", name.getString(), null, value, name.getToken()); - } -} - -ParsedElementAnnotation AnnotationElement(boolean nested) : -{ - ParsedElementAnnotation a; -} -{ - (a = PrefixedAnnotationElement(nested) - | a = UnprefixedAnnotationElement()) - { return a; } -} - -ParsedElementAnnotation AnnotationElementNotKeyword() : -{ - ParsedElementAnnotation a; -} -{ - (a = PrefixedAnnotationElement(false) - | a = IdentifierAnnotationElement()) - { return a; } -} - -ParsedElementAnnotation PrefixedAnnotationElement(boolean nested) : -{ - CommentList comments = getComments(); - Token t; - ElementAnnotationBuilder eab; -} -{ - t = <PREFIXED_NAME> - { - String qn = t.image; - int colon = qn.indexOf(':'); - String prefix = qn.substring(0, colon); - String ns = lookupPrefix(prefix, t); - if (ns == this.inheritedNs) { - error("inherited_annotation_namespace", t); - ns = ""; - } - else if (!nested && ns.equals(WellKnownNamespaces.RELAX_NG)) { - error("relax_ng_namespace", t); - ns = ""; - } - else { - if (ns.length() == 0) - prefix = null; - } - eab = sb.makeElementAnnotationBuilder(ns, qn.substring(colon + 1), prefix, - makeLocation(t), comments, getContext()); - } - AnnotationElementContent(eab) - { return eab.makeElementAnnotation(); } -} - -ParsedElementAnnotation UnprefixedAnnotationElement() : -{ - CommentList comments = getComments(); - LocatedString name; - ElementAnnotationBuilder eab; -} -{ - name = UnprefixedName() - { - eab = sb.makeElementAnnotationBuilder("", name.getString(), null, - name.getLocation(), comments, getContext()); - } - AnnotationElementContent(eab) - { return eab.makeElementAnnotation(); } -} - -ParsedElementAnnotation IdentifierAnnotationElement() : -{ - CommentList comments = getComments(); - LocatedString name; - ElementAnnotationBuilder eab; -} -{ - name = Identifier() - { - eab = sb.makeElementAnnotationBuilder("", name.getString(), null, - name.getLocation(), comments, getContext()); - } - AnnotationElementContent(eab) - { return eab.makeElementAnnotation(); } -} - -void AnnotationElementContent(ElementAnnotationBuilder eab) : -{ - ParsedElementAnnotation e; -} -{ - "[" { clearAttributeList(); } - (LOOKAHEAD(2) AnnotationAttribute(eab))* - ((AnnotationElementLiteral(eab) - ("~" AnnotationElementLiteral(eab))*) - | e = AnnotationElement(true) { eab.addElement(e); })* - { eab.addComment(getComments()); } - "]" -} - -void AnnotationElementLiteral(ElementAnnotationBuilder eab) : -{ - Token t; - CommentList comments = getComments(); -} -{ - t = <LITERAL> { eab.addText(unquote(t.image), makeLocation(t), comments); } -} - -String Literal() : -{ - Token t; - String s; - StringBuffer buf; -} -{ - t = <LITERAL> - { - s = unquote(t.image); - } - ( - { buf = new StringBuffer(s); } - ("~" t = <LITERAL> { buf.append(unquote(t.image)); })+ - { s = buf.toString(); } - )? - { return s; } -} - -LocatedString LocatedLiteral() : -{ - Token t; - Token t2; - String s; - StringBuffer buf; -} -{ - t = <LITERAL> - { - s = unquote(t.image); - } - ( - { buf = new StringBuffer(s); } - ("~" t2 = <LITERAL> { buf.append(unquote(t2.image)); })+ - { s = buf.toString(); } - )? - { return new LocatedString(s, t); } -} - -Token Keyword() : -{ - Token t; -} -{ - (t = "element" - | t = "attribute" - | t = "namespace" - | t = "list" - | t = "mixed" - | t = "grammar" - | t = "empty" - | t = "text" - | t = "parent" - | t = "external" - | t = "notAllowed" - | t = "start" - | t = "include" - | t = "default" - | t = "inherit" - | t = "string" - | t = "token" - | t = "datatypes" - | t = "div") - { return t; } -} - -<*> -SKIP: { - < #NEWLINE : [ "\u0000", "\n" ] > - | < #NOT_NEWLINE : ~[ "\u0000", "\n" ] > - | < WS: ([ "\u0000", " ", "\n", "\t" ])+ > : DEFAULT -} - -TOKEN : -{ - < DOCUMENTATION: "##" (<NOT_NEWLINE>)* > : AFTER_DOCUMENTATION -} - -<AFTER_DOCUMENTATION> -TOKEN : -{ - < DOCUMENTATION_CONTINUE: <NEWLINE> ([" ", "\t"])* <DOCUMENTATION> > -} - -SPECIAL_TOKEN: -{ - < SINGLE_LINE_COMMENT: "#" (<NOT_NEWLINE>)* > : AFTER_SINGLE_LINE_COMMENT -} - -<AFTER_SINGLE_LINE_COMMENT> -TOKEN : -{ - < DOCUMENTATION_AFTER_SINGLE_LINE_COMMENT: <NEWLINE> ([" ", "\t"])* <DOCUMENTATION> > : AFTER_DOCUMENTATION -} - -<AFTER_SINGLE_LINE_COMMENT> -SPECIAL_TOKEN : -{ - < SINGLE_LINE_COMMENT_CONTINUE: <NEWLINE> ([" ", "\t"])* <SINGLE_LINE_COMMENT> > -} - -TOKEN : -{ - < #BASE_CHAR : [ - "\u0041" - "\u005a", - "\u0061" - "\u007a", - "\u00c0" - "\u00d6", - "\u00d8" - "\u00f6", - "\u00f8" - "\u00ff", - "\u0100" - "\u0131", - "\u0134" - "\u013e", - "\u0141" - "\u0148", - "\u014a" - "\u017e", - "\u0180" - "\u01c3", - "\u01cd" - "\u01f0", - "\u01f4" - "\u01f5", - "\u01fa" - "\u0217", - "\u0250" - "\u02a8", - "\u02bb" - "\u02c1", - "\u0386", - "\u0388" - "\u038a", - "\u038c", - "\u038e" - "\u03a1", - "\u03a3" - "\u03ce", - "\u03d0" - "\u03d6", - "\u03da", - "\u03dc", - "\u03de", - "\u03e0", - "\u03e2" - "\u03f3", - "\u0401" - "\u040c", - "\u040e" - "\u044f", - "\u0451" - "\u045c", - "\u045e" - "\u0481", - "\u0490" - "\u04c4", - "\u04c7" - "\u04c8", - "\u04cb" - "\u04cc", - "\u04d0" - "\u04eb", - "\u04ee" - "\u04f5", - "\u04f8" - "\u04f9", - "\u0531" - "\u0556", - "\u0559", - "\u0561" - "\u0586", - "\u05d0" - "\u05ea", - "\u05f0" - "\u05f2", - "\u0621" - "\u063a", - "\u0641" - "\u064a", - "\u0671" - "\u06b7", - "\u06ba" - "\u06be", - "\u06c0" - "\u06ce", - "\u06d0" - "\u06d3", - "\u06d5", - "\u06e5" - "\u06e6", - "\u0905" - "\u0939", - "\u093d", - "\u0958" - "\u0961", - "\u0985" - "\u098c", - "\u098f" - "\u0990", - "\u0993" - "\u09a8", - "\u09aa" - "\u09b0", - "\u09b2", - "\u09b6" - "\u09b9", - "\u09dc" - "\u09dd", - "\u09df" - "\u09e1", - "\u09f0" - "\u09f1", - "\u0a05" - "\u0a0a", - "\u0a0f" - "\u0a10", - "\u0a13" - "\u0a28", - "\u0a2a" - "\u0a30", - "\u0a32" - "\u0a33", - "\u0a35" - "\u0a36", - "\u0a38" - "\u0a39", - "\u0a59" - "\u0a5c", - "\u0a5e", - "\u0a72" - "\u0a74", - "\u0a85" - "\u0a8b", - "\u0a8d", - "\u0a8f" - "\u0a91", - "\u0a93" - "\u0aa8", - "\u0aaa" - "\u0ab0", - "\u0ab2" - "\u0ab3", - "\u0ab5" - "\u0ab9", - "\u0abd", - "\u0ae0", - "\u0b05" - "\u0b0c", - "\u0b0f" - "\u0b10", - "\u0b13" - "\u0b28", - "\u0b2a" - "\u0b30", - "\u0b32" - "\u0b33", - "\u0b36" - "\u0b39", - "\u0b3d", - "\u0b5c" - "\u0b5d", - "\u0b5f" - "\u0b61", - "\u0b85" - "\u0b8a", - "\u0b8e" - "\u0b90", - "\u0b92" - "\u0b95", - "\u0b99" - "\u0b9a", - "\u0b9c", - "\u0b9e" - "\u0b9f", - "\u0ba3" - "\u0ba4", - "\u0ba8" - "\u0baa", - "\u0bae" - "\u0bb5", - "\u0bb7" - "\u0bb9", - "\u0c05" - "\u0c0c", - "\u0c0e" - "\u0c10", - "\u0c12" - "\u0c28", - "\u0c2a" - "\u0c33", - "\u0c35" - "\u0c39", - "\u0c60" - "\u0c61", - "\u0c85" - "\u0c8c", - "\u0c8e" - "\u0c90", - "\u0c92" - "\u0ca8", - "\u0caa" - "\u0cb3", - "\u0cb5" - "\u0cb9", - "\u0cde", - "\u0ce0" - "\u0ce1", - "\u0d05" - "\u0d0c", - "\u0d0e" - "\u0d10", - "\u0d12" - "\u0d28", - "\u0d2a" - "\u0d39", - "\u0d60" - "\u0d61", - "\u0e01" - "\u0e2e", - "\u0e30", - "\u0e32" - "\u0e33", - "\u0e40" - "\u0e45", - "\u0e81" - "\u0e82", - "\u0e84", - "\u0e87" - "\u0e88", - "\u0e8a", - "\u0e8d", - "\u0e94" - "\u0e97", - "\u0e99" - "\u0e9f", - "\u0ea1" - "\u0ea3", - "\u0ea5", - "\u0ea7", - "\u0eaa" - "\u0eab", - "\u0ead" - "\u0eae", - "\u0eb0", - "\u0eb2" - "\u0eb3", - "\u0ebd", - "\u0ec0" - "\u0ec4", - "\u0f40" - "\u0f47", - "\u0f49" - "\u0f69", - "\u10a0" - "\u10c5", - "\u10d0" - "\u10f6", - "\u1100", - "\u1102" - "\u1103", - "\u1105" - "\u1107", - "\u1109", - "\u110b" - "\u110c", - "\u110e" - "\u1112", - "\u113c", - "\u113e", - "\u1140", - "\u114c", - "\u114e", - "\u1150", - "\u1154" - "\u1155", - "\u1159", - "\u115f" - "\u1161", - "\u1163", - "\u1165", - "\u1167", - "\u1169", - "\u116d" - "\u116e", - "\u1172" - "\u1173", - "\u1175", - "\u119e", - "\u11a8", - "\u11ab", - "\u11ae" - "\u11af", - "\u11b7" - "\u11b8", - "\u11ba", - "\u11bc" - "\u11c2", - "\u11eb", - "\u11f0", - "\u11f9", - "\u1e00" - "\u1e9b", - "\u1ea0" - "\u1ef9", - "\u1f00" - "\u1f15", - "\u1f18" - "\u1f1d", - "\u1f20" - "\u1f45", - "\u1f48" - "\u1f4d", - "\u1f50" - "\u1f57", - "\u1f59", - "\u1f5b", - "\u1f5d", - "\u1f5f" - "\u1f7d", - "\u1f80" - "\u1fb4", - "\u1fb6" - "\u1fbc", - "\u1fbe", - "\u1fc2" - "\u1fc4", - "\u1fc6" - "\u1fcc", - "\u1fd0" - "\u1fd3", - "\u1fd6" - "\u1fdb", - "\u1fe0" - "\u1fec", - "\u1ff2" - "\u1ff4", - "\u1ff6" - "\u1ffc", - "\u2126", - "\u212a" - "\u212b", - "\u212e", - "\u2180" - "\u2182", - "\u3041" - "\u3094", - "\u30a1" - "\u30fa", - "\u3105" - "\u312c", - "\uac00" - "\ud7a3" - ] > - | < #IDEOGRAPHIC : [ - "\u4e00" - "\u9fa5", - "\u3007", - "\u3021" - "\u3029" - ] > - | < #LETTER : (<BASE_CHAR> | <IDEOGRAPHIC>) > - | < #COMBINING_CHAR : [ - "\u0300" - "\u0345", - "\u0360" - "\u0361", - "\u0483" - "\u0486", - "\u0591" - "\u05a1", - "\u05a3" - "\u05b9", - "\u05bb" - "\u05bd", - "\u05bf", - "\u05c1" - "\u05c2", - "\u05c4", - "\u064b" - "\u0652", - "\u0670", - "\u06d6" - "\u06dc", - "\u06dd" - "\u06df", - "\u06e0" - "\u06e4", - "\u06e7" - "\u06e8", - "\u06ea" - "\u06ed", - "\u0901" - "\u0903", - "\u093c", - "\u093e" - "\u094c", - "\u094d", - "\u0951" - "\u0954", - "\u0962" - "\u0963", - "\u0981" - "\u0983", - "\u09bc", - "\u09be", - "\u09bf", - "\u09c0" - "\u09c4", - "\u09c7" - "\u09c8", - "\u09cb" - "\u09cd", - "\u09d7", - "\u09e2" - "\u09e3", - "\u0a02", - "\u0a3c", - "\u0a3e", - "\u0a3f", - "\u0a40" - "\u0a42", - "\u0a47" - "\u0a48", - "\u0a4b" - "\u0a4d", - "\u0a70" - "\u0a71", - "\u0a81" - "\u0a83", - "\u0abc", - "\u0abe" - "\u0ac5", - "\u0ac7" - "\u0ac9", - "\u0acb" - "\u0acd", - "\u0b01" - "\u0b03", - "\u0b3c", - "\u0b3e" - "\u0b43", - "\u0b47" - "\u0b48", - "\u0b4b" - "\u0b4d", - "\u0b56" - "\u0b57", - "\u0b82" - "\u0b83", - "\u0bbe" - "\u0bc2", - "\u0bc6" - "\u0bc8", - "\u0bca" - "\u0bcd", - "\u0bd7", - "\u0c01" - "\u0c03", - "\u0c3e" - "\u0c44", - "\u0c46" - "\u0c48", - "\u0c4a" - "\u0c4d", - "\u0c55" - "\u0c56", - "\u0c82" - "\u0c83", - "\u0cbe" - "\u0cc4", - "\u0cc6" - "\u0cc8", - "\u0cca" - "\u0ccd", - "\u0cd5" - "\u0cd6", - "\u0d02" - "\u0d03", - "\u0d3e" - "\u0d43", - "\u0d46" - "\u0d48", - "\u0d4a" - "\u0d4d", - "\u0d57", - "\u0e31", - "\u0e34" - "\u0e3a", - "\u0e47" - "\u0e4e", - "\u0eb1", - "\u0eb4" - "\u0eb9", - "\u0ebb" - "\u0ebc", - "\u0ec8" - "\u0ecd", - "\u0f18" - "\u0f19", - "\u0f35", - "\u0f37", - "\u0f39", - "\u0f3e", - "\u0f3f", - "\u0f71" - "\u0f84", - "\u0f86" - "\u0f8b", - "\u0f90" - "\u0f95", - "\u0f97", - "\u0f99" - "\u0fad", - "\u0fb1" - "\u0fb7", - "\u0fb9", - "\u20d0" - "\u20dc", - "\u20e1", - "\u302a" - "\u302f", - "\u3099", - "\u309a" - ] > - | < #DIGIT : [ - "\u0030" - "\u0039", - "\u0660" - "\u0669", - "\u06f0" - "\u06f9", - "\u0966" - "\u096f", - "\u09e6" - "\u09ef", - "\u0a66" - "\u0a6f", - "\u0ae6" - "\u0aef", - "\u0b66" - "\u0b6f", - "\u0be7" - "\u0bef", - "\u0c66" - "\u0c6f", - "\u0ce6" - "\u0cef", - "\u0d66" - "\u0d6f", - "\u0e50" - "\u0e59", - "\u0ed0" - "\u0ed9", - "\u0f20" - "\u0f29" - ] > - | < #EXTENDER : [ - "\u00b7", - "\u02d0", - "\u02d1", - "\u0387", - "\u0640", - "\u0e46", - "\u0ec6", - "\u3005", - "\u3031" - "\u3035", - "\u309d" - "\u309e", - "\u30fc" - "\u30fe" - ] > - | < #NMSTART : (<LETTER> | "_") > - | < #NMCHAR : (<LETTER> | <COMBINING_CHAR> | <EXTENDER> | <DIGIT> | "." | "-" | "_") > - | < #NCNAME: <NMSTART> (<NMCHAR>)* > -} - -TOKEN : -{ - < IDENTIFIER: <NCNAME> > - | < ESCAPED_IDENTIFIER: "\\" <NCNAME> > - | < PREFIX_STAR: <NCNAME> ":*" > - | < PREFIXED_NAME: <NCNAME> ":" <NCNAME> > - | < LITERAL : ("\"" (~["\u0000", "\""])* "\"") - | ("'" (~["\u0000", "'"])* "'") - | ("\"\"\"" (~["\""] - | ("\"" ~["\""]) - | ("\"\"" ~["\""]))* "\"\"\"") - | ("'''" (~["'"] - | ("'" ~["'"]) - | ("''" ~["'"]))* "'''") > - | < FANNOTATE : ">>" > -} - -/* This avoids lexical errors from JavaCC. */ -<*> -TOKEN : -{ - < ILLEGAL_CHAR : [ "\u0000" - "\u0008", "\u000b" - "\uffff" ] > -} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/pacakge-info.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/package-info.java similarity index 95% rename from jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/pacakge-info.java rename to jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/package-info.java index c64df853e20..e3fff6d0645 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/pacakge-info.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it From 5fa1e08e4231cf3293c94d4a5418e7f4e7388086 Mon Sep 17 00:00:00 2001 From: Omair Majid <omajid@openjdk.org> Date: Mon, 26 May 2014 17:22:04 -0400 Subject: [PATCH 145/157] 8043975: Update README for jdk9 Reviewed-by: tbell --- README | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README b/README index 40c9fbc6a77..e1fdec5d4ab 100644 --- a/README +++ b/README @@ -1,15 +1,15 @@ README: This file should be located at the top of the OpenJDK Mercurial root repository. A full OpenJDK repository set (forest) should also include - the following 6 nested repositories: - "jdk", "hotspot", "langtools", "corba", "jaxws" and "jaxp". + the following 7 nested repositories: + "jdk", "hotspot", "langtools", "nashorn", "corba", "jaxws" and "jaxp". The root repository can be obtained with something like: - hg clone http://hg.openjdk.java.net/jdk8/jdk8 openjdk8 + hg clone http://hg.openjdk.java.net/jdk9/jdk9 openjdk9 You can run the get_source.sh script located in the root repository to get the other needed repositories: - cd openjdk8 && sh ./get_source.sh + cd openjdk9 && sh ./get_source.sh People unfamiliar with Mercurial should read the first few chapters of the Mercurial book: http://hgbook.red-bean.com/read/ @@ -19,9 +19,9 @@ README: Simple Build Instructions: 0. Get the necessary system software/packages installed on your system, see - http://hg.openjdk.java.net/jdk8/jdk8/raw-file/tip/README-builds.html + http://hg.openjdk.java.net/jdk9/jdk9/raw-file/tip/README-builds.html - 1. If you don't have a jdk7u7 or newer jdk, download and install it from + 1. If you don't have a jdk8 or newer jdk, download and install it from http://java.sun.com/javase/downloads/index.jsp Add the /bin directory of this installation to your PATH environment variable. @@ -37,4 +37,4 @@ where make is GNU make 3.81 or newer, /usr/bin/make on Linux usually is 3.81 or newer. Note that on Solaris, GNU make is called "gmake". Complete details are available in the file: - http://hg.openjdk.java.net/jdk8/jdk8/raw-file/tip/README-builds.html + http://hg.openjdk.java.net/jdk9/jdk9/raw-file/tip/README-builds.html From 9442603fcd6193694b9615dc6533af0e4ec61747 Mon Sep 17 00:00:00 2001 From: James Cheng <james.cheng@oracle.com> Date: Mon, 26 May 2014 18:34:26 -0700 Subject: [PATCH 146/157] 8035974: Refactor DigestBase.engineUpdate() method for better code generation by JIT compiler Move the lopp from DigestBase.engineUpdate() to new private method implCompressMultiBlock() which can be intrinsified. Reviewed-by: psandoz, ascarpino, forax --- .../sun/security/provider/DigestBase.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/classes/sun/security/provider/DigestBase.java b/jdk/src/share/classes/sun/security/provider/DigestBase.java index 58812f30ec3..98af71afdf0 100644 --- a/jdk/src/share/classes/sun/security/provider/DigestBase.java +++ b/jdk/src/share/classes/sun/security/provider/DigestBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -122,10 +122,10 @@ abstract class DigestBase extends MessageDigestSpi implements Cloneable { } } // compress complete blocks - while (len >= blockSize) { - implCompress(b, ofs); - len -= blockSize; - ofs += blockSize; + if (len >= blockSize) { + int limit = ofs + len; + ofs = implCompressMultiBlock(b, ofs, limit - blockSize); + len = limit - ofs; } // copy remainder to buffer if (len > 0) { @@ -134,6 +134,14 @@ abstract class DigestBase extends MessageDigestSpi implements Cloneable { } } + // compress complete blocks + private int implCompressMultiBlock(byte[] b, int ofs, int limit) { + for (; ofs <= limit; ofs += blockSize) { + implCompress(b, ofs); + } + return ofs; + } + // reset this object. See JCA doc. protected final void engineReset() { if (bytesProcessed == 0) { From 989151115e14e12c0e71c589f572ffd0a0be4c30 Mon Sep 17 00:00:00 2001 From: Masayoshi Okutsu <okutsu@openjdk.org> Date: Tue, 27 May 2014 16:20:09 +0900 Subject: [PATCH 147/157] 8033627: UTC+02:00 time zones are not detected correctly on Windows Reviewed-by: peytoia --- jdk/src/windows/lib/tzmappings | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/jdk/src/windows/lib/tzmappings b/jdk/src/windows/lib/tzmappings index 706eff6eb69..953ea10be7a 100644 --- a/jdk/src/windows/lib/tzmappings +++ b/jdk/src/windows/lib/tzmappings @@ -137,8 +137,8 @@ Central:36,37::America/Chicago: Central Standard Time:36,37::America/Chicago: Eastern:38,39::America/New_York: Eastern Standard Time:38,39::America/New_York: -E. Europe:4,5:BY:Europe/Minsk: -E. Europe Standard Time:4,5:BY:Europe/Minsk: +E. Europe:4,5::EET: +E. Europe Standard Time:4,5::EET: Egypt:4,68::Africa/Cairo: Egypt Standard Time:4,68::Africa/Cairo: South Africa:4,69::Africa/Harare: @@ -192,5 +192,6 @@ Magadan Standard Time:924,924::Asia/Magadan: Kaliningrad Standard Time:925,925:RU:Europe/Kaliningrad: Turkey Standard Time:926,926::Asia/Istanbul: Bahia Standard Time:927,927::America/Bahia: -Western Brazilian Standard Time:928,928:BR:America/Rio_Branco: -Armenian Standard Time:929,929:AM:Asia/Yerevan: +Libya Standard Time:928,928:LY:Africa/Tripoli: +Western Brazilian Standard Time:929,929:BR:America/Rio_Branco: +Armenian Standard Time:930,930:AM:Asia/Yerevan: From 2a4f86523419d915212529cc83b197df326a5103 Mon Sep 17 00:00:00 2001 From: Jonathan Lu <luchsh@openjdk.org> Date: Tue, 27 May 2014 17:56:35 +0800 Subject: [PATCH 148/157] 8043495: Add native FileChannelImpl.transferTo0() implementation for AIX Reviewed-by: alanb --- .../native/sun/nio/ch/FileChannelImpl.c | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c b/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c index d47cc3da10b..895289067d6 100644 --- a/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c +++ b/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c @@ -39,6 +39,8 @@ #if defined(__linux__) || defined(__solaris__) #include <sys/sendfile.h> +#elif defined(_AIX) +#include <sys/socket.h> #elif defined(_ALLBSD_SOURCE) #include <sys/types.h> #include <sys/socket.h> @@ -207,9 +209,7 @@ Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this, numBytes = count; -#ifdef __APPLE__ result = sendfile(srcFD, dstFD, position, &numBytes, NULL, 0); -#endif if (numBytes > 0) return numBytes; @@ -228,7 +228,48 @@ Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this, } return result; + +#elif defined(_AIX) + jlong max = (jlong)java_lang_Integer_MAX_VALUE; + struct sf_parms sf_iobuf; + jlong result; + + if (position > max) + return IOS_UNSUPPORTED_CASE; + + if (count > max) + count = max; + + memset(&sf_iobuf, 0, sizeof(sf_iobuf)); + sf_iobuf.file_descriptor = srcFD; + sf_iobuf.file_offset = (off_t)position; + sf_iobuf.file_bytes = count; + + result = send_file(&dstFD, &sf_iobuf, SF_SYNC_CACHE); + + /* AIX send_file() will return 0 when this operation complete successfully, + * return 1 when partial bytes transfered and return -1 when an error has + * Occured. + */ + if (result == -1) { + if (errno == EWOULDBLOCK) + return IOS_UNAVAILABLE; + if ((errno == EINVAL) && ((ssize_t)count >= 0)) + return IOS_UNSUPPORTED_CASE; + if (errno == EINTR) + return IOS_INTERRUPTED; + if (errno == ENOTSOCK) + return IOS_UNSUPPORTED; + JNU_ThrowIOExceptionWithLastError(env, "Transfer failed"); + return IOS_THROWN; + } + + if (sf_iobuf.bytes_sent > 0) + return (jlong)sf_iobuf.bytes_sent; + + return IOS_UNSUPPORTED_CASE; #else return IOS_UNSUPPORTED_CASE; #endif } + From d779eeab899f0757597d90394fead7934b0ff31e Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan <sundar@openjdk.org> Date: Tue, 27 May 2014 17:40:19 +0530 Subject: [PATCH 149/157] 8044000: Access to undefined property yields "null" instead of "undefined" Reviewed-by: lagergren, jlaskey --- .../internal/runtime/linker/Bootstrap.java | 14 +++++++-- .../runtime/linker/JSObjectLinker.java | 19 ++++++++++-- .../runtime/linker/NashornGuards.java | 15 ++++++++++ .../api/scripting/ScriptObjectMirrorTest.java | 29 +++++++++++++++++++ 4 files changed, 72 insertions(+), 5 deletions(-) diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java index c8f39fcfaca..48821036d25 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java @@ -61,9 +61,17 @@ public final class Bootstrap { private static final DynamicLinker dynamicLinker; static { final DynamicLinkerFactory factory = new DynamicLinkerFactory(); - factory.setPrioritizedLinkers(new NashornLinker(), new NashornPrimitiveLinker(), new NashornStaticClassLinker(), - new BoundDynamicMethodLinker(), new JavaSuperAdapterLinker(), new JSObjectLinker(), new ReflectionCheckLinker()); - factory.setFallbackLinkers(new NashornBeansLinker(), new NashornBottomLinker()); + final NashornBeansLinker nashornBeansLinker = new NashornBeansLinker(); + final JSObjectLinker jsObjectLinker = new JSObjectLinker(nashornBeansLinker); + factory.setPrioritizedLinkers( + new NashornLinker(), + new NashornPrimitiveLinker(), + new NashornStaticClassLinker(), + new BoundDynamicMethodLinker(), + new JavaSuperAdapterLinker(), + jsObjectLinker, + new ReflectionCheckLinker()); + factory.setFallbackLinkers(nashornBeansLinker, new NashornBottomLinker()); factory.setSyncOnRelink(true); final int relinkThreshold = Options.getIntProperty("nashorn.unstable.relink.threshold", -1); if (relinkThreshold > -1) { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java index f3c8284be86..52fb46bc5c7 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java @@ -30,6 +30,7 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.util.HashMap; import java.util.Map; +import javax.script.Bindings; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.GuardedTypeConversion; @@ -48,14 +49,23 @@ import jdk.nashorn.internal.runtime.JSType; * as ScriptObjects from other Nashorn contexts. */ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory { + private final NashornBeansLinker nashornBeansLinker; + + JSObjectLinker(final NashornBeansLinker nashornBeansLinker) { + this.nashornBeansLinker = nashornBeansLinker; + } + @Override public boolean canLinkType(final Class<?> type) { return canLinkTypeStatic(type); } static boolean canLinkTypeStatic(final Class<?> type) { - // can link JSObject - return JSObject.class.isAssignableFrom(type); + // can link JSObject also handles Map, Bindings to make + // sure those are not JSObjects. + return Map.class.isAssignableFrom(type) || + Bindings.class.isAssignableFrom(type) || + JSObject.class.isAssignableFrom(type); } @Override @@ -72,6 +82,11 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker, GuardingTy final GuardedInvocation inv; if (self instanceof JSObject) { inv = lookup(desc); + } else if (self instanceof Map || self instanceof Bindings) { + // guard to make sure the Map or Bindings does not turn into JSObject later! + final GuardedInvocation beanInv = nashornBeansLinker.getGuardedInvocation(request, linkerServices); + inv = new GuardedInvocation(beanInv.getInvocation(), + NashornGuards.combineGuards(beanInv.getGuard(), NashornGuards.getNotJSObjectGuard())); } else { throw new AssertionError(); // Should never reach here. } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java index ca3e10c48d4..77c5e93cb77 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java @@ -31,6 +31,7 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.ref.WeakReference; import jdk.internal.dynalink.CallSiteDescriptor; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.codegen.ObjectClassGenerator; import jdk.nashorn.internal.objects.Global; import jdk.nashorn.internal.runtime.Property; @@ -43,6 +44,7 @@ import jdk.nashorn.internal.runtime.ScriptObject; */ public final class NashornGuards { private static final MethodHandle IS_SCRIPTOBJECT = findOwnMH("isScriptObject", boolean.class, Object.class); + private static final MethodHandle IS_NOT_JSOBJECT = findOwnMH("isNotJSObject", boolean.class, Object.class); private static final MethodHandle IS_SCRIPTFUNCTION = findOwnMH("isScriptFunction", boolean.class, Object.class); private static final MethodHandle IS_MAP = findOwnMH("isMap", boolean.class, Object.class, PropertyMap.class); private static final MethodHandle SAME_OBJECT = findOwnMH("sameObject", boolean.class, Object.class, WeakReference.class); @@ -60,6 +62,14 @@ public final class NashornGuards { return IS_SCRIPTOBJECT; } + /** + * Get the guard that checks if an item is not a {@code JSObject} + * @return method handle for guard + */ + public static MethodHandle getNotJSObjectGuard() { + return IS_NOT_JSOBJECT; + } + /** * Get the guard that checks if an item is a {@code ScriptFunction} * @return method handle for guard @@ -156,6 +166,11 @@ public final class NashornGuards { return self instanceof ScriptObject; } + @SuppressWarnings("unused") + private static boolean isNotJSObject(final Object self) { + return !(self instanceof JSObject); + } + @SuppressWarnings("unused") private static boolean isScriptFunction(final Object self) { return self instanceof ScriptFunction; diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java index 241f22c39ea..30eaefcadb5 100644 --- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java +++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java @@ -29,6 +29,8 @@ import java.nio.ByteBuffer; import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.script.Bindings; +import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; @@ -276,4 +278,31 @@ public class ScriptObjectMirrorTest { "({ toString: function() { return 'foo' } })"); assertEquals("foo", obj.to(String.class)); } + + // @bug 8044000: Access to undefined property yields "null" instead of "undefined" + @Test + public void mapScriptObjectMirrorCallsiteTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine engine = m.getEngineByName("nashorn"); + final String TEST_SCRIPT = "typeof obj.foo"; + + final Bindings global = engine.getContext().getBindings(ScriptContext.ENGINE_SCOPE); + engine.eval("var obj = java.util.Collections.emptyMap()"); + // this will drive callsite "obj.foo" of TEST_SCRIPT + // to use "obj instanceof Map" as it's guard + engine.eval(TEST_SCRIPT, global); + // redefine 'obj' to be a script object + engine.eval("obj = {}"); + + final Bindings newGlobal = engine.createBindings(); + // transfer 'obj' from default global to new global + // new global will get a ScriptObjectMirror wrapping 'obj' + newGlobal.put("obj", global.get("obj")); + + // Every ScriptObjectMirror is a Map! If callsite "obj.foo" + // does not see the new 'obj' is a ScriptObjectMirror, it'll + // continue to use Map's get("obj.foo") instead of ScriptObjectMirror's + // getMember("obj.foo") - thereby getting null instead of undefined + assertEquals("undefined", engine.eval(TEST_SCRIPT, newGlobal)); + } } From 649331e00faa70d9f3a1b95a4f8aa3caa8976363 Mon Sep 17 00:00:00 2001 From: Paul Govereau <pgovereau@openjdk.org> Date: Tue, 27 May 2014 18:57:44 +0100 Subject: [PATCH 150/157] 8041704: wrong error message when mixing lambda expression and inner class Reviewed-by: vromero --- .../com/sun/tools/javac/comp/Attr.java | 20 ++++++++++++++++--- ...ambdaExpressionWithNonAccessibleIdTest.out | 3 +-- .../lambda/T8041704/ErrorMessageTest.java | 12 +++++++++++ .../lambda/T8041704/ErrorMessageTest.out | 2 ++ 4 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.java create mode 100644 langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 335704eaef4..89656d48a01 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -4678,16 +4678,30 @@ public class Attr extends JCTree.Visitor { private void initTypeIfNeeded(JCTree that) { if (that.type == null) { if (that.hasTag(METHODDEF)) { - that.type = dummyMethodType(); + that.type = dummyMethodType((JCMethodDecl)that); } else { that.type = syms.unknownType; } } } + /* Construct a dummy method type. If we have a method declaration, + * and the declared return type is void, then use that return type + * instead of UNKNOWN to avoid spurious error messages in lambda + * bodies (see:JDK-8041704). + */ + private Type dummyMethodType(JCMethodDecl md) { + Type restype = syms.unknownType; + if (md != null && md.restype.hasTag(TYPEIDENT)) { + JCPrimitiveTypeTree prim = (JCPrimitiveTypeTree)md.restype; + if (prim.typetag == VOID) + restype = syms.voidType; + } + return new MethodType(List.<Type>nil(), restype, + List.<Type>nil(), syms.methodClass); + } private Type dummyMethodType() { - return new MethodType(List.<Type>nil(), syms.unknownType, - List.<Type>nil(), syms.methodClass); + return dummyMethodType(null); } @Override diff --git a/langtools/test/tools/javac/T8030816/CrashLambdaExpressionWithNonAccessibleIdTest.out b/langtools/test/tools/javac/T8030816/CrashLambdaExpressionWithNonAccessibleIdTest.out index d253b9c660b..3b2266c0b21 100644 --- a/langtools/test/tools/javac/T8030816/CrashLambdaExpressionWithNonAccessibleIdTest.out +++ b/langtools/test/tools/javac/T8030816/CrashLambdaExpressionWithNonAccessibleIdTest.out @@ -1,3 +1,2 @@ -CrashLambdaExpressionWithNonAccessibleIdTest.java:15:35: compiler.err.missing.ret.stmt CrashLambdaExpressionWithNonAccessibleIdTest.java:14:17: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, CrashLambdaExpressionWithNonAccessibleIdTest, null) -2 errors +1 error diff --git a/langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.java b/langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.java new file mode 100644 index 00000000000..5bd38c79d59 --- /dev/null +++ b/langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.java @@ -0,0 +1,12 @@ +/** + * @test /nodynamiccopyright/ + * @bug 8041704 + * @summary wrong error message when mixing lambda expression and inner class + * @compile/fail/ref=ErrorMessageTest.out -XDrawDiagnostics ErrorMessageTest.java + */ + +public class ErrorMessageTest { + void f(Runnable r) { + f(() -> { f(new MISSING() { public void run() {} }); }); + } +} diff --git a/langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.out b/langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.out new file mode 100644 index 00000000000..bdd25993c86 --- /dev/null +++ b/langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.out @@ -0,0 +1,2 @@ +ErrorMessageTest.java:10:25: compiler.err.cant.resolve.location: kindname.class, MISSING, , , (compiler.misc.location: kindname.class, ErrorMessageTest, null) +1 error From 0b1c40b161ca58bd44adc74ea0195b6caa50a251 Mon Sep 17 00:00:00 2001 From: Paul Govereau <pgovereau@openjdk.org> Date: Tue, 27 May 2014 22:26:53 +0100 Subject: [PATCH 151/157] 8042741: Java 8 compiler throws NullPointerException depending location in source file Reviewed-by: vromero, jlahoda --- .../com/sun/tools/javac/comp/Flow.java | 11 +++- .../test/tools/javac/flow/T8042741/A.java | 37 +++++++++++ .../javac/flow/T8042741/PositionTest.java | 62 +++++++++++++++++++ 3 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 langtools/test/tools/javac/flow/T8042741/A.java create mode 100644 langtools/test/tools/javac/flow/T8042741/PositionTest.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java index ba2bdc89e20..a9e13874512 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java @@ -231,7 +231,8 @@ public class Flow { } } - public List<Type> analyzeLambdaThrownTypes(Env<AttrContext> env, JCLambda that, TreeMaker make) { + public List<Type> analyzeLambdaThrownTypes(final Env<AttrContext> env, + JCLambda that, TreeMaker make) { //we need to disable diagnostics temporarily; the problem is that if //a lambda expression contains e.g. an unreachable statement, an error //message will be reported and will cause compilation to skip the flow analyis @@ -239,7 +240,13 @@ public class Flow { //related errors, which will allow for more errors to be detected Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log); try { - new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit).analyzeTree(env); + new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit) { + @Override + protected boolean trackable(VarSymbol sym) { + return !env.info.scope.includes(sym) && + sym.owner.kind == MTH; + } + }.analyzeTree(env); LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer(); flowAnalyzer.analyzeTree(env, that, make); return flowAnalyzer.inferredThrownTypes; diff --git a/langtools/test/tools/javac/flow/T8042741/A.java b/langtools/test/tools/javac/flow/T8042741/A.java new file mode 100644 index 00000000000..36deb2d172f --- /dev/null +++ b/langtools/test/tools/javac/flow/T8042741/A.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +// str must be at absolute position greater than that of lambda +// expression in PositionTest.java +// padding..........................................................padding +// padding..........................................................padding +// padding..........................................................padding +// padding..........................................................padding +// padding..........................................................padding + +public class A { + public final String str; + { + str = ""; + } +} diff --git a/langtools/test/tools/javac/flow/T8042741/PositionTest.java b/langtools/test/tools/javac/flow/T8042741/PositionTest.java new file mode 100644 index 00000000000..cc0da15e4f5 --- /dev/null +++ b/langtools/test/tools/javac/flow/T8042741/PositionTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @bug 8042741 + * @summary Java 8 compiler throws NullPointerException depending location in source file + * @compile A.java PositionTest.java + */ + +public class PositionTest extends A { + <E extends Exception> void test(SAM<E> r) throws E { + test(() -> { System.err.println(str); }); + } + interface SAM<E extends Exception> { + public void run() throws E; + } + void f() { + try { + test(() -> { + test(() -> { + try { + test(() -> { System.err.println(str); }); + System.err.println(str); + } catch (Exception e) {} + System.err.println(str); + }); + System.err.println(str); + }); + } catch (Exception e) { } + } + void g() throws Exception { + test(() -> { + try { + try { + test(() -> { System.err.println(str); }); + } catch (Exception e) {} + System.err.println(str); + } catch (Exception e) {} + System.err.println(str); + }); + } +} From 773e460c33a752a63147079f7ae11c9ec3454a3c Mon Sep 17 00:00:00 2001 From: Paul Govereau <pgovereau@openjdk.org> Date: Tue, 27 May 2014 14:23:55 -0400 Subject: [PATCH 152/157] 7177211: SharedNameTable.create and .dispose are not used Reviewed-by: jjg --- .../src/share/classes/com/sun/tools/javac/util/Names.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Names.java b/langtools/src/share/classes/com/sun/tools/javac/util/Names.java index 57058c99340..af96c77b066 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Names.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Names.java @@ -317,9 +317,9 @@ public class Names { protected Name.Table createTable(Options options) { boolean useUnsharedTable = options.isSet("useUnsharedTable"); if (useUnsharedTable) - return new UnsharedNameTable(this); + return UnsharedNameTable.create(this); else - return new SharedNameTable(this); + return SharedNameTable.create(this); } public void dispose() { From bccd5e4671da0800a1bc4c46d18bf7955af30cb8 Mon Sep 17 00:00:00 2001 From: Mandy Chung <mchung@openjdk.org> Date: Tue, 27 May 2014 12:15:08 -0700 Subject: [PATCH 153/157] 8044034: Remove unused com/sun/tools/hat files Reviewed-by: sla --- .../classes/com/sun/tools/hat/MANIFEST.mf | 2 - .../classes/com/sun/tools/hat/README.txt | 20 ----- .../share/classes/com/sun/tools/hat/build.xml | 82 ------------------- 3 files changed, 104 deletions(-) delete mode 100644 jdk/src/share/classes/com/sun/tools/hat/MANIFEST.mf delete mode 100644 jdk/src/share/classes/com/sun/tools/hat/README.txt delete mode 100644 jdk/src/share/classes/com/sun/tools/hat/build.xml diff --git a/jdk/src/share/classes/com/sun/tools/hat/MANIFEST.mf b/jdk/src/share/classes/com/sun/tools/hat/MANIFEST.mf deleted file mode 100644 index 35334c8e34c..00000000000 --- a/jdk/src/share/classes/com/sun/tools/hat/MANIFEST.mf +++ /dev/null @@ -1,2 +0,0 @@ -Manifest-Version: 1.0 -Main-Class: com.sun.tools.hat.Main diff --git a/jdk/src/share/classes/com/sun/tools/hat/README.txt b/jdk/src/share/classes/com/sun/tools/hat/README.txt deleted file mode 100644 index 9bc0b9a3351..00000000000 --- a/jdk/src/share/classes/com/sun/tools/hat/README.txt +++ /dev/null @@ -1,20 +0,0 @@ --------------- -This HAT source originally came from the http://hat.dev.java.net site. - -The utility has been named 'jhat' in the JDK, it is basically the same tool. - -Q: Where do I make changes? In the JDK or hat.dev.java.net? - -A: It depends on whether the change is intended for the JDK jhat version only, - or expected to be given back to the java.net project. - In general, we should putback changes to the java.net project and - bringover those changes to the JDK. - -Q: I want to build just jhat.jar instead of building entire JDK. What should I do? - -A: Use ant makefile (build.xml) in the current directory. This builds just the -jhat sources and creates jhat.jar under ./build directory. - -To run the built jhat.jar, you can use the command: - - java -jar build/jhat.jar heap_dump diff --git a/jdk/src/share/classes/com/sun/tools/hat/build.xml b/jdk/src/share/classes/com/sun/tools/hat/build.xml deleted file mode 100644 index 2d7bdc800fd..00000000000 --- a/jdk/src/share/classes/com/sun/tools/hat/build.xml +++ /dev/null @@ -1,82 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- - Copyright (c) 2005, 2008, 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. ---> - -<!-- - - The Original Code is HAT. The Initial Developer of the - Original Code is Bill Foote, with contributions from others - at JavaSoft/Sun. - ---> - -<!-- This is an Ant project file to build Heap Analysis Tool (HAT). - For more information on Ant, please see http://ant.apache.org/ - - To build jhat.jar, run ant in current directory. jhat.jar is - built in ./build directory. ---> - -<project name="Java Heap Analysis Tool" default="all" basedir="."> - - <!-- Property Definitions --> - - <property name="app.name" value="jhat"/> - <property name="src.dir" value="."/> - <property name="build.dir" value="build"/> - <property name="classes.dir" value="${build.dir}/classes"/> - <property name="dist.jar" value="${app.name}.jar"/> - - <target name="prepare"> - <mkdir dir="${build.dir}"/> - <mkdir dir="${classes.dir}"/> - </target> - - <target name="clean"> - <delete dir="${build.dir}"/> - </target> - - <target name="compile" depends="prepare" description="Compiles the sources"> - <javac srcdir="${src.dir}" destdir="${classes.dir}" - debug="on" deprecation="on"> - </javac> - - </target> - - <target name="deploy" depends="compile" description="Creates a deployment bundle"> - <delete file="${build.dir}/${dist.jar}" /> - <mkdir dir="${classes.dir}/com/sun/tools/hat/resources" /> - <copy todir="${classes.dir}/com/sun/tools/hat/resources"> - <fileset dir="${src.dir}/resources" includes="*" /> - </copy> - - <jar jarfile="${build.dir}/${dist.jar}" - manifest="${src.dir}/MANIFEST.mf" basedir="${classes.dir}"/> - </target> - - <target name="all" depends="deploy" description="Builds sources and deployment jar"/> - -</project> From 20e26966e1c4e18d7df65ef2d07e87687eb6acfc Mon Sep 17 00:00:00 2001 From: Roger Riggs <rriggs@openjdk.org> Date: Tue, 27 May 2014 16:05:04 -0400 Subject: [PATCH 154/157] 8003488: (process) Provide Process.getPid() Add Process.getPid Reviewed-by: alanb, martin, igerasim --- jdk/src/share/classes/java/lang/Process.java | 14 +++++ .../classes/java/lang/UNIXProcess.java | 5 ++ .../classes/java/lang/ProcessImpl.java | 22 +++++--- .../windows/native/java/lang/ProcessImpl_md.c | 11 ++++ jdk/test/java/lang/ProcessBuilder/Basic.java | 54 ++++++++++++++++++- 5 files changed, 98 insertions(+), 8 deletions(-) diff --git a/jdk/src/share/classes/java/lang/Process.java b/jdk/src/share/classes/java/lang/Process.java index 4e945382465..9d9bc3316ba 100644 --- a/jdk/src/share/classes/java/lang/Process.java +++ b/jdk/src/share/classes/java/lang/Process.java @@ -262,4 +262,18 @@ public abstract class Process { return true; } } + + /** + * Returns the native process id of the subprocess. + * The native process id is an identification number that the operating + * system assigns to the process. + * + * @return the native process id of the subprocess + * @throws UnsupportedOperationException if the Process implementation + * does not support this operation + * @since 1.9 + */ + public long getPid() { + throw new UnsupportedOperationException(); + } } diff --git a/jdk/src/solaris/classes/java/lang/UNIXProcess.java b/jdk/src/solaris/classes/java/lang/UNIXProcess.java index 35d37e6b5d3..56ba83f036f 100644 --- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java +++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java @@ -482,6 +482,11 @@ final class UNIXProcess extends Process { return this; } + @Override + public long getPid() { + return pid; + } + @Override public synchronized boolean isAlive() { return !hasExited; diff --git a/jdk/src/windows/classes/java/lang/ProcessImpl.java b/jdk/src/windows/classes/java/lang/ProcessImpl.java index b288dbd28dc..02e0c7bf346 100644 --- a/jdk/src/windows/classes/java/lang/ProcessImpl.java +++ b/jdk/src/windows/classes/java/lang/ProcessImpl.java @@ -25,15 +25,15 @@ package java.lang; -import java.io.IOException; -import java.io.File; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FileDescriptor; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.lang.ProcessBuilder.Redirect; import java.security.AccessController; import java.security.PrivilegedAction; @@ -482,6 +482,14 @@ final class ProcessImpl extends Process { private static native void terminateProcess(long handle); + @Override + public long getPid() { + int pid = getProcessId0(handle); + return pid; + } + + private static native int getProcessId0(long handle); + @Override public boolean isAlive() { return isProcessAlive(handle); diff --git a/jdk/src/windows/native/java/lang/ProcessImpl_md.c b/jdk/src/windows/native/java/lang/ProcessImpl_md.c index a432f1198dc..59f907cd99b 100644 --- a/jdk/src/windows/native/java/lang/ProcessImpl_md.c +++ b/jdk/src/windows/native/java/lang/ProcessImpl_md.c @@ -248,6 +248,17 @@ static void restoreIOEHandleState( } } +/* + * Class: java_lang_ProcessImpl + * Method: getProcessId0 + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_java_lang_ProcessImpl_getProcessId0 + (JNIEnv *env, jclass clazz, jlong handle) { + DWORD pid = GetProcessId((HANDLE) jlong_to_ptr(handle)); + return (jint)pid; +} + /* Please, read about the MS inheritance problem http://support.microsoft.com/kb/315939 and critical section/synchronized block solution. */ diff --git a/jdk/test/java/lang/ProcessBuilder/Basic.java b/jdk/test/java/lang/ProcessBuilder/Basic.java index ce0bad7772f..039feb16404 100644 --- a/jdk/test/java/lang/ProcessBuilder/Basic.java +++ b/jdk/test/java/lang/ProcessBuilder/Basic.java @@ -26,7 +26,7 @@ * @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689 * 5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313 * 6464154 6523983 6206031 4960438 6631352 6631966 6850957 6850958 - * 4947220 7018606 7034570 4244896 5049299 + * 4947220 7018606 7034570 4244896 5049299 8003488 * @summary Basic tests for Process and Environment Variable code * @run main/othervm/timeout=300 Basic * @run main/othervm/timeout=300 -Djdk.lang.Process.launchMechanism=fork Basic @@ -1136,6 +1136,53 @@ public class Basic { } } + static void checkProcessPid() { + long actualPid = 0; + long expectedPid = -1; + if (Windows.is()) { + String[] argsTasklist = {"tasklist.exe", "/NH", "/FI", "\"IMAGENAME eq tasklist.exe\""}; + ProcessBuilder pb = new ProcessBuilder(argsTasklist); + try { + Process proc = pb.start(); + expectedPid = proc.getPid(); + + String output = commandOutput(proc); + String[] splits = output.split("\\s+"); + actualPid = Integer.valueOf(splits[2]); + } catch (Throwable t) { + unexpected(t); + } + } else if (Unix.is() || MacOSX.is()) { + String[] shArgs = {"sh", "-c", "echo $$"}; + ProcessBuilder pb = new ProcessBuilder(shArgs); + try { + Process proc = pb.start(); + expectedPid = proc.getPid(); + + String output = commandOutput(proc); + String[] splits = output.split("\\s+"); + actualPid = Integer.valueOf(splits[0]); + } catch (Throwable t) { + unexpected(t); + } + } else { + fail("No test for checkProcessPid on platform: " + System.getProperty("os.name")); + return; + } + + equal(actualPid, expectedPid); + + // Test the default implementation of Process.getPid + try { + DelegatingProcess p = new DelegatingProcess(null); + p.getPid(); + fail("non-overridden Process.getPid method should throw UOE"); + } catch (UnsupportedOperationException uoe) { + // correct + } + + } + private static void realMain(String[] args) throws Throwable { if (Windows.is()) System.out.println("This appears to be a Windows system."); @@ -1147,6 +1194,11 @@ public class Basic { try { testIORedirection(); } catch (Throwable t) { unexpected(t); } + //---------------------------------------------------------------- + // Basic tests for getPid() + //---------------------------------------------------------------- + checkProcessPid(); + //---------------------------------------------------------------- // Basic tests for setting, replacing and deleting envvars //---------------------------------------------------------------- From 849ed753e2052eade5193e30faa8a13a9ec507c9 Mon Sep 17 00:00:00 2001 From: Dan Smith <dlsmith@openjdk.org> Date: Tue, 27 May 2014 16:32:56 -0600 Subject: [PATCH 155/157] 8042338: Refactor Types.upperBound to treat wildcards and variables separately Reviewed-by: vromero --- .../com/sun/tools/javac/api/JavacTrees.java | 2 +- .../com/sun/tools/javac/code/Types.java | 137 +++++++----------- .../com/sun/tools/javac/comp/Attr.java | 4 +- .../com/sun/tools/javac/comp/Check.java | 4 +- .../com/sun/tools/javac/comp/Lower.java | 4 +- .../com/sun/tools/javac/comp/Resolve.java | 4 +- 6 files changed, 59 insertions(+), 96 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java index eb4b43f3622..56296d458c6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java @@ -394,7 +394,7 @@ public class JavacTrees extends DocTrees { paramTypes = lb.toList(); } - ClassSymbol sym = (ClassSymbol) types.upperBound(tsym.type).tsym; + ClassSymbol sym = (ClassSymbol) types.cvarUpperBound(tsym.type).tsym; Symbol msym = (memberName == sym.name) ? findConstructor(sym, paramTypes) diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index 15b79180844..9066a03ae2a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -118,37 +118,34 @@ public class Types { } // </editor-fold> - // <editor-fold defaultstate="collapsed" desc="upperBound"> + // <editor-fold defaultstate="collapsed" desc="bounds"> /** - * The "rvalue conversion".<br> - * The upper bound of most types is the type - * itself. Wildcards, on the other hand have upper - * and lower bounds. - * @param t a type - * @return the upper bound of the given type + * Get a wildcard's upper bound, returning non-wildcards unchanged. + * @param t a type argument, either a wildcard or a type */ - public Type upperBound(Type t) { - return upperBound.visit(t); + public Type wildUpperBound(Type t) { + if (t.hasTag(WILDCARD)) { + WildcardType w = (WildcardType) t; + if (w.isSuperBound()) + return w.bound == null ? syms.objectType : w.bound.bound; + else + return wildUpperBound(w.type); + } + else return t; } - // where - private final MapVisitor<Void> upperBound = new MapVisitor<Void>() { - @Override - public Type visitWildcardType(WildcardType t, Void ignored) { - if (t.isSuperBound()) - return t.bound == null ? syms.objectType : t.bound.bound; - else - return visit(t.type); - } + /** + * Get a capture variable's upper bound, returning other types unchanged. + * @param t a type + */ + public Type cvarUpperBound(Type t) { + if (t.hasTag(TYPEVAR)) { + TypeVar v = (TypeVar) t; + return v.isCaptured() ? cvarUpperBound(v.bound) : v; + } + else return t; + } - @Override - public Type visitCapturedType(CapturedType t, Void ignored) { - return visit(t.bound); - } - }; - // </editor-fold> - - // <editor-fold defaultstate="collapsed" desc="wildLowerBound"> /** * Get a wildcard's lower bound, returning non-wildcards unchanged. * @param t a type argument, either a wildcard or a type @@ -160,9 +157,7 @@ public class Types { } else return t; } - // </editor-fold> - // <editor-fold defaultstate="collapsed" desc="cvarLowerBound"> /** * Get a capture variable's lower bound, returning other types unchanged. * @param t a type @@ -894,7 +889,7 @@ public class Types { s.getAnnotationMirrors()); changed = true; } else if (s != orig) { - s = new WildcardType(upperBound(s), + s = new WildcardType(wildUpperBound(s), BoundKind.EXTENDS, syms.boundClass, s.getAnnotationMirrors()); @@ -1104,7 +1099,7 @@ public class Types { //check that u == t, where u has been set by Type.withTypeVar return s.isSuperBound() && !s.isExtendsBound() && - visit(t, upperBound(s)); + visit(t, wildUpperBound(s)); } } default: @@ -1131,7 +1126,7 @@ public class Types { return visit(s, t); if (s.isSuperBound() && !s.isExtendsBound()) - return visit(t, upperBound(s)) && visit(t, wildLowerBound(s)); + return visit(t, wildUpperBound(s)) && visit(t, wildLowerBound(s)); if (t.isCompound() && s.isCompound()) { if (!visit(supertype(t), supertype(s))) @@ -1298,7 +1293,7 @@ public class Types { switch(wt.kind) { case UNBOUND: //similar to ? extends Object case EXTENDS: { - Type bound = upperBound(s); + Type bound = wildUpperBound(s); undetvar.addBound(InferenceBound.UPPER, bound, this); break; } @@ -1359,28 +1354,6 @@ public class Types { // where private TypeRelation containsType = new TypeRelation() { - private Type U(Type t) { - while (t.hasTag(WILDCARD)) { - WildcardType w = (WildcardType)t; - if (w.isSuperBound()) - return w.bound == null ? syms.objectType : w.bound.bound; - else - t = w.type; - } - return t; - } - - private Type L(Type t) { - while (t.hasTag(WILDCARD)) { - WildcardType w = (WildcardType)t; - if (w.isExtendsBound()) - return syms.botType; - else - t = w.type; - } - return t; - } - public Boolean visitType(Type t, Type s) { if (s.isPartial()) return containedBy(s, t); @@ -1392,13 +1365,13 @@ public class Types { // System.err.println(); // System.err.format(" does %s contain %s?%n", t, s); // System.err.format(" %s U(%s) <: U(%s) %s = %s%n", -// upperBound(s), s, t, U(t), +// wildUpperBound(s), s, t, wildUpperBound(t), // t.isSuperBound() -// || isSubtypeNoCapture(upperBound(s), U(t))); +// || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t))); // System.err.format(" %s L(%s) <: L(%s) %s = %s%n", -// L(t), t, s, wildLowerBound(s), +// wildLowerBound(t), t, s, wildLowerBound(s), // t.isExtendsBound() -// || isSubtypeNoCapture(L(t), wildLowerBound(s))); +// || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s))); // System.err.println(); // } @@ -1410,8 +1383,9 @@ public class Types { // debugContainsType(t, s); return isSameWildcard(t, s) || isCaptureOf(s, t) - || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), wildLowerBound(s))) && - (t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t)))); + || ((t.isExtendsBound() || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s))) && + // TODO: JDK-8039214, cvarUpperBound call here is incorrect + (t.isSuperBound() || isSubtypeNoCapture(cvarUpperBound(wildUpperBound(s)), wildUpperBound(t)))); } } @@ -1529,7 +1503,7 @@ public class Types { @Override public Boolean visitWildcardType(WildcardType t, Type s) { - return isCastable(upperBound(t), s, warnStack.head); + return isCastable(wildUpperBound(t), s, warnStack.head); } @Override @@ -1770,12 +1744,12 @@ public class Types { if (t.isExtendsBound()) { if (s.isExtendsBound()) - return !isCastableRecursive(t.type, upperBound(s)); + return !isCastableRecursive(t.type, wildUpperBound(s)); else if (s.isSuperBound()) return notSoftSubtypeRecursive(wildLowerBound(s), t.type); } else if (t.isSuperBound()) { if (s.isExtendsBound()) - return notSoftSubtypeRecursive(t.type, upperBound(s)); + return notSoftSubtypeRecursive(t.type, wildUpperBound(s)); } return false; } @@ -1811,7 +1785,7 @@ public class Types { noWarnings); } if (!s.hasTag(WILDCARD)) - s = upperBound(s); + s = cvarUpperBound(s); return !isSubtype(t, relaxBound(s)); } @@ -1868,7 +1842,7 @@ public class Types { // <editor-fold defaultstate="collapsed" desc="Array Utils"> public boolean isArray(Type t) { while (t.hasTag(WILDCARD)) - t = upperBound(t); + t = wildUpperBound(t); return t.hasTag(ARRAY); } @@ -1878,7 +1852,7 @@ public class Types { public Type elemtype(Type t) { switch (t.getTag()) { case WILDCARD: - return elemtype(upperBound(t)); + return elemtype(wildUpperBound(t)); case ARRAY: return ((ArrayType)t).elemtype; case FORALL: @@ -2080,7 +2054,7 @@ public class Types { @Override public Type visitWildcardType(WildcardType t, Symbol sym) { - return memberType(upperBound(t), sym); + return memberType(wildUpperBound(t), sym); } @Override @@ -2208,7 +2182,7 @@ public class Types { @Override public Type visitWildcardType(WildcardType t, Boolean recurse) { final List<Attribute.TypeCompound> annos = t.getAnnotationMirrors(); - Type erased = erasure(upperBound(t), recurse); + Type erased = erasure(wildUpperBound(t), recurse); if (!annos.isEmpty()) { erased = erased.annotatedType(annos); } @@ -2417,8 +2391,7 @@ public class Types { if (t.hasErasedSupertypes()) { t.interfaces_field = erasureRecursive(interfaces); } else if (formals.nonEmpty()) { - t.interfaces_field = - upperBounds(subst(interfaces, formals, actuals)); + t.interfaces_field = subst(interfaces, formals, actuals); } else { t.interfaces_field = interfaces; @@ -2987,7 +2960,7 @@ public class Types { t.getAnnotationMirrors()); } else { Type st = subst(supertype(t)); - List<Type> is = upperBounds(subst(interfaces(t))); + List<Type> is = subst(interfaces(t)); if (st == supertype(t) && is == interfaces(t)) return t; else @@ -3004,7 +2977,7 @@ public class Types { return t; } else { if (t.isExtendsBound() && bound.isExtendsBound()) - bound = upperBound(bound); + bound = wildUpperBound(bound); return new WildcardType(bound, t.kind, syms.boundClass, t.bound, t.getAnnotationMirrors()); } @@ -3458,8 +3431,8 @@ public class Types { TypePair pair = new TypePair(c1, c2); Type m; if (mergeCache.add(pair)) { - m = new WildcardType(lub(upperBound(act1.head), - upperBound(act2.head)), + m = new WildcardType(lub(wildUpperBound(act1.head), + wildUpperBound(act2.head)), BoundKind.EXTENDS, syms.boundClass, Type.noAnnotations); @@ -4041,16 +4014,6 @@ public class Types { // </editor-fold> // <editor-fold defaultstate="collapsed" desc="Internal utility methods"> - private List<Type> upperBounds(List<Type> ss) { - if (ss.isEmpty()) return ss; - Type head = upperBound(ss.head); - List<Type> tail = upperBounds(ss.tail); - if (head != ss.head || tail != ss.tail) - return tail.prepend(head); - else - return ss; - } - private boolean sideCast(Type from, Type to, Warner warn) { // We are casting from type $from$ to type $to$, which are // non-final unrelated types. This method @@ -4207,7 +4170,7 @@ public class Types { @Override public Void visitWildcardType(WildcardType source, Type target) throws AdaptFailure { if (source.isExtendsBound()) - adaptRecursive(upperBound(source), upperBound(target)); + adaptRecursive(wildUpperBound(source), wildUpperBound(target)); else if (source.isSuperBound()) adaptRecursive(wildLowerBound(source), wildLowerBound(target)); return null; @@ -4224,7 +4187,7 @@ public class Types { val = isSubtype(wildLowerBound(val), wildLowerBound(target)) ? target : val; } else if (val.isExtendsBound() && target.isExtendsBound()) { - val = isSubtype(upperBound(val), upperBound(target)) + val = isSubtype(wildUpperBound(val), wildUpperBound(target)) ? val : target; } else if (!isSameType(val, target)) { throw new AdaptFailure(); @@ -4335,7 +4298,7 @@ public class Types { } public Type visitType(Type t, Void s) { - return high ? upperBound(t) : t; + return t; } @Override diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 89656d48a01..defa825bfe5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -1176,7 +1176,7 @@ public class Attr extends JCTree.Visitor { //the Formal Parameter of a for-each loop is not in the scope when //attributing the for-each expression; we mimick this by attributing //the for-each expression first (against original scope). - Type exprType = types.upperBound(attribExpr(tree.expr, loopEnv)); + Type exprType = types.cvarUpperBound(attribExpr(tree.expr, loopEnv)); attribStat(tree.var, loopEnv); chk.checkNonVoid(tree.pos(), exprType); Type elemtype = types.elemtype(exprType); // perhaps expr is an array? @@ -1193,7 +1193,7 @@ public class Attr extends JCTree.Visitor { List<Type> iterableParams = base.allparams(); elemtype = iterableParams.isEmpty() ? syms.objectType - : types.upperBound(iterableParams.head); + : types.wildUpperBound(iterableParams.head); } } chk.checkType(tree.expr.pos(), elemtype, tree.var.sym.type); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 1283d87d27b..7cfb78ec5dd 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -621,10 +621,10 @@ public class Check { if (a.isUnbound()) { return true; } else if (!a.hasTag(WILDCARD)) { - a = types.upperBound(a); + a = types.cvarUpperBound(a); return types.isSubtype(a, bound); } else if (a.isExtendsBound()) { - return types.isCastable(bound, types.upperBound(a), types.noWarnings); + return types.isCastable(bound, types.wildUpperBound(a), types.noWarnings); } else if (a.isSuperBound()) { return !types.notSoftSubtype(types.wildLowerBound(a), bound); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java index 33762e0d9d4..5bffdebdca7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java @@ -3522,7 +3522,7 @@ public class Lower extends TreeTranslator { private void visitIterableForeachLoop(JCEnhancedForLoop tree) { make_at(tree.expr.pos()); Type iteratorTarget = syms.objectType; - Type iterableType = types.asSuper(types.upperBound(tree.expr.type), + Type iterableType = types.asSuper(types.cvarUpperBound(tree.expr.type), syms.iterableType.tsym); if (iterableType.getTypeArguments().nonEmpty()) iteratorTarget = types.erasure(iterableType.getTypeArguments().head); @@ -3556,7 +3556,7 @@ public class Lower extends TreeTranslator { List.<Type>nil()); JCExpression vardefinit = make.App(make.Select(make.Ident(itvar), next)); if (tree.var.type.isPrimitive()) - vardefinit = make.TypeCast(types.upperBound(iteratorTarget), vardefinit); + vardefinit = make.TypeCast(types.cvarUpperBound(iteratorTarget), vardefinit); else vardefinit = make.TypeCast(tree.var.type, vardefinit); JCVariableDecl indexDef = (JCVariableDecl)make.VarDef(tree.var.mods, diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index a058f4a742b..fffe05c55a0 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -347,7 +347,7 @@ public class Resolve { boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) { return (t.hasTag(ARRAY)) - ? isAccessible(env, types.upperBound(types.elemtype(t))) + ? isAccessible(env, types.cvarUpperBound(types.elemtype(t))) : isAccessible(env, t.tsym, checkInner); } @@ -1014,7 +1014,7 @@ public class Resolve { */ private Type U(Type found) { return found == pt ? - found : types.upperBound(found); + found : types.cvarUpperBound(found); } @Override From 2b4c40d39b77b36b9b5aa2e530880cac4053db43 Mon Sep 17 00:00:00 2001 From: Dan Smith <dlsmith@openjdk.org> Date: Tue, 27 May 2014 16:39:05 -0600 Subject: [PATCH 156/157] 8044050: Move misplaced inference tests to test/tools/javac/generics/inference Reviewed-by: vromero --- .../EagerReturnTypeResolution/EagerReturnTypeResolutionTesta.java | 0 .../EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.java | 0 .../EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.out | 0 .../EagerReturnTypeResolution/PrimitiveTypeBoxingTest.java | 0 .../EagerReturnTypeResolution/PrimitiveTypeBoxingTest.out | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename langtools/test/tools/javac/{ => generics}/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTesta.java (100%) rename langtools/test/tools/javac/{ => generics}/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.java (100%) rename langtools/test/tools/javac/{ => generics}/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.out (100%) rename langtools/test/tools/javac/{ => generics}/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.java (100%) rename langtools/test/tools/javac/{ => generics}/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.out (100%) diff --git a/langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTesta.java b/langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTesta.java similarity index 100% rename from langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTesta.java rename to langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTesta.java diff --git a/langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.java b/langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.java similarity index 100% rename from langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.java rename to langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.java diff --git a/langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.out b/langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.out similarity index 100% rename from langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.out rename to langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.out diff --git a/langtools/test/tools/javac/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.java b/langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.java similarity index 100% rename from langtools/test/tools/javac/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.java rename to langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.java diff --git a/langtools/test/tools/javac/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.out b/langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.out similarity index 100% rename from langtools/test/tools/javac/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.out rename to langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.out From 1b0c4c65947e32181655148c1dc5025771d9e387 Mon Sep 17 00:00:00 2001 From: "J. Duke" <duke@openjdk.org> Date: Wed, 5 Jul 2017 19:41:14 +0200 Subject: [PATCH 157/157] Added tag jdk9-b14 for changeset 97932f6ad950 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 36ba8ab267f..e7144757c53 100644 --- a/.hgtags +++ b/.hgtags @@ -256,3 +256,4 @@ efe7dbc6088691757404e0c8745f894e3ca9c022 jdk9-b09 0809c9a4d36e6291f1c4384604c4bbf29e975722 jdk9-b11 0d1f816217dce5e72187f167cc1816080cbeb453 jdk9-b12 1a30593dcb9802faec3b6edb24d86ca088594e4e jdk9-b13 +97932f6ad950ae5a73a9da5c96e6e58503ff646b jdk9-b14