# HG changeset patch # User sla # Date 1358514951 -3600 # Node ID 557bda927cc233fea59668661b91dbdd936c26f5 # Parent e94ed1591b42bd4ed75f30edf05a44c00a415f5a# Parent f422634e582853165d1c25f9566a8f3e8a0a6335 Merge diff -r e94ed1591b42 -r 557bda927cc2 .hgtags --- a/.hgtags Wed Jan 16 16:30:04 2013 +0100 +++ b/.hgtags Fri Jan 18 14:15:51 2013 +0100 @@ -303,3 +303,7 @@ b6c9c0109a608eedbb6b868d260952990e3c91fe hs25-b13 cb8a4e04bc8c104de8a2f67463c7e31232bf8d68 jdk8-b69 990bbd393c239d95310ccc38094e57923bbf1d4a hs25-b14 +e94068d4ff52849c8aa0786a53a59b63d1312a39 jdk8-b70 +0847210f85480bf3848dc90bc2ab23c0a4791b55 jdk8-b71 +d5cb5830f570d1304ea4b196dde672a291b55f29 jdk8-b72 +1e129851479e4f5df439109fca2c7be1f1613522 hs25-b15 diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/ci/ciArrayKlass.java --- a/agent/src/share/classes/sun/jvm/hotspot/ci/ciArrayKlass.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/ci/ciArrayKlass.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/ci/ciField.java --- a/agent/src/share/classes/sun/jvm/hotspot/ci/ciField.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/ci/ciField.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/ci/ciInstance.java --- a/agent/src/share/classes/sun/jvm/hotspot/ci/ciInstance.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/ci/ciInstance.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/ci/ciKlass.java --- a/agent/src/share/classes/sun/jvm/hotspot/ci/ciKlass.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/ci/ciKlass.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/ci/ciMetadata.java --- a/agent/src/share/classes/sun/jvm/hotspot/ci/ciMetadata.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/ci/ciMetadata.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/ci/ciObjArrayKlass.java --- a/agent/src/share/classes/sun/jvm/hotspot/ci/ciObjArrayKlass.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/ci/ciObjArrayKlass.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/ci/ciObject.java --- a/agent/src/share/classes/sun/jvm/hotspot/ci/ciObject.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/ci/ciObject.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/ci/ciObjectFactory.java --- a/agent/src/share/classes/sun/jvm/hotspot/ci/ciObjectFactory.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/ci/ciObjectFactory.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/ci/ciReceiverTypeData.java --- a/agent/src/share/classes/sun/jvm/hotspot/ci/ciReceiverTypeData.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/ci/ciReceiverTypeData.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/ci/ciSymbol.java --- a/agent/src/share/classes/sun/jvm/hotspot/ci/ciSymbol.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/ci/ciSymbol.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/ci/ciType.java --- a/agent/src/share/classes/sun/jvm/hotspot/ci/ciType.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/ci/ciType.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/ci/ciTypeArrayKlass.java --- a/agent/src/share/classes/sun/jvm/hotspot/ci/ciTypeArrayKlass.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/ci/ciTypeArrayKlass.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/ci/ciVirtualCallData.java --- a/agent/src/share/classes/sun/jvm/hotspot/ci/ciVirtualCallData.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/ci/ciVirtualCallData.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/classfile/ClassLoaderData.java --- a/agent/src/share/classes/sun/jvm/hotspot/classfile/ClassLoaderData.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/classfile/ClassLoaderData.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/memory/LoaderConstraintTable.java --- a/agent/src/share/classes/sun/jvm/hotspot/memory/LoaderConstraintTable.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/memory/LoaderConstraintTable.java Fri Jan 18 14:15:51 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/oops/BitData.java --- a/agent/src/share/classes/sun/jvm/hotspot/oops/BitData.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/BitData.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/oops/ProfileData.java --- a/agent/src/share/classes/sun/jvm/hotspot/oops/ProfileData.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ProfileData.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/oops/RetData.java --- a/agent/src/share/classes/sun/jvm/hotspot/oops/RetData.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/RetData.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/Block.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/Block.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/Block.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/Block_Array.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/Block_Array.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/Block_Array.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/Block_List.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/Block_List.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/Block_List.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/CallDynamicJavaNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/CallDynamicJavaNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/CallDynamicJavaNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/CallJavaNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/CallJavaNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/CallJavaNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/CallNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/CallNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/CallNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/CallRuntimeNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/CallRuntimeNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/CallRuntimeNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/CallStaticJavaNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/CallStaticJavaNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/CallStaticJavaNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/Compile.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/Compile.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/Compile.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/HaltNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/HaltNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/HaltNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/InlineTree.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/InlineTree.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/InlineTree.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/JVMState.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/JVMState.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/JVMState.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/LoopNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/LoopNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/LoopNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/MachCallJavaNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/MachCallJavaNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/MachCallJavaNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/MachCallNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/MachCallNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/MachCallNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/MachCallRuntimeNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/MachCallRuntimeNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/MachCallRuntimeNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/MachCallStaticJavaNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/MachCallStaticJavaNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/MachCallStaticJavaNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/MachIfNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/MachIfNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/MachIfNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/MachNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/MachNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/MachNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/MachReturnNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/MachReturnNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/MachReturnNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/MachSafePointNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/MachSafePointNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/MachSafePointNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/MultiNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/MultiNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/MultiNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/Node.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/Node.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/Node.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/Node_Array.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/Node_Array.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/Node_Array.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/Node_List.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/Node_List.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/Node_List.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/Phase.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/Phase.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/Phase.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/PhaseCFG.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/PhaseCFG.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/PhaseCFG.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/PhaseRegAlloc.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/PhaseRegAlloc.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/PhaseRegAlloc.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/PhiNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/PhiNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/PhiNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/ProjNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/ProjNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/ProjNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/RegionNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/RegionNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/RegionNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/RootNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/RootNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/RootNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/SafePointNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/SafePointNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/SafePointNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/opto/TypeNode.java --- a/agent/src/share/classes/sun/jvm/hotspot/opto/TypeNode.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/TypeNode.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/prims/JvmtiExport.java --- a/agent/src/share/classes/sun/jvm/hotspot/prims/JvmtiExport.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/prims/JvmtiExport.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/utilities/GenericGrowableArray.java --- a/agent/src/share/classes/sun/jvm/hotspot/utilities/GenericGrowableArray.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/GenericGrowableArray.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/classes/sun/jvm/hotspot/utilities/GrowableArray.java --- a/agent/src/share/classes/sun/jvm/hotspot/utilities/GrowableArray.java Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/GrowableArray.java Fri Jan 18 14:15:51 2013 +0100 @@ -16,9 +16,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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. * */ diff -r e94ed1591b42 -r 557bda927cc2 agent/src/share/native/sadis.c --- a/agent/src/share/native/sadis.c Wed Jan 16 16:30:04 2013 +0100 +++ b/agent/src/share/native/sadis.c Fri Jan 18 14:15:51 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright 2012, Oracle and/or its affiliates. All Rights Reserved. + * Copyright (c) 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 diff -r e94ed1591b42 -r 557bda927cc2 make/hotspot_version --- a/make/hotspot_version Wed Jan 16 16:30:04 2013 +0100 +++ b/make/hotspot_version Fri Jan 18 14:15:51 2013 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 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 @@ -31,11 +31,11 @@ # # Don't put quotes (fail windows build). -HOTSPOT_VM_COPYRIGHT=Copyright 2012 +HOTSPOT_VM_COPYRIGHT=Copyright 2013 HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=15 +HS_BUILD_NUMBER=16 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/sparc/vm/assembler_sparc.hpp --- a/src/cpu/sparc/vm/assembler_sparc.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/sparc/vm/assembler_sparc.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -675,8 +675,8 @@ AbstractAssembler::flush(); } - inline void emit_long(int); // shadows AbstractAssembler::emit_long - inline void emit_data(int x) { emit_long(x); } + inline void emit_int32(int); // shadows AbstractAssembler::emit_int32 + inline void emit_data(int x) { emit_int32(x); } inline void emit_data(int, RelocationHolder const&); inline void emit_data(int, relocInfo::relocType rtype); // helper for above fcns @@ -691,12 +691,12 @@ inline void add(Register s1, Register s2, Register d ); inline void add(Register s1, int simm13a, Register d ); - void addcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void addcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void addc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | rs2(s2) ); } - void addc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void addccc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void addccc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void addcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void addcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void addc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | rs2(s2) ); } + void addc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void addccc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void addccc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 136 @@ -749,76 +749,76 @@ // at address s1 is swapped with the data in d. If the values are not equal, // the the contents of memory at s1 is loaded into d, without the swap. - void casa( Register s1, Register s2, Register d, int ia = -1 ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(casa_op3 ) | rs1(s1) | (ia == -1 ? immed(true) : imm_asi(ia)) | rs2(s2)); } - void casxa( Register s1, Register s2, Register d, int ia = -1 ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(casxa_op3) | rs1(s1) | (ia == -1 ? immed(true) : imm_asi(ia)) | rs2(s2)); } + void casa( Register s1, Register s2, Register d, int ia = -1 ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(casa_op3 ) | rs1(s1) | (ia == -1 ? immed(true) : imm_asi(ia)) | rs2(s2)); } + void casxa( Register s1, Register s2, Register d, int ia = -1 ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(casxa_op3) | rs1(s1) | (ia == -1 ? immed(true) : imm_asi(ia)) | rs2(s2)); } // pp 152 - void udiv( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(udiv_op3 ) | rs1(s1) | rs2(s2)); } - void udiv( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(udiv_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void sdiv( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sdiv_op3 ) | rs1(s1) | rs2(s2)); } - void sdiv( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sdiv_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void udivcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(udiv_op3 | cc_bit_op3) | rs1(s1) | rs2(s2)); } - void udivcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(udiv_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void sdivcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sdiv_op3 | cc_bit_op3) | rs1(s1) | rs2(s2)); } - void sdivcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sdiv_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void udiv( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(udiv_op3 ) | rs1(s1) | rs2(s2)); } + void udiv( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(udiv_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void sdiv( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sdiv_op3 ) | rs1(s1) | rs2(s2)); } + void sdiv( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sdiv_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void udivcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(udiv_op3 | cc_bit_op3) | rs1(s1) | rs2(s2)); } + void udivcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(udiv_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void sdivcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sdiv_op3 | cc_bit_op3) | rs1(s1) | rs2(s2)); } + void sdivcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sdiv_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 155 - void done() { v9_only(); cti(); emit_long( op(arith_op) | fcn(0) | op3(done_op3) ); } - void retry() { v9_only(); cti(); emit_long( op(arith_op) | fcn(1) | op3(retry_op3) ); } + void done() { v9_only(); cti(); emit_int32( op(arith_op) | fcn(0) | op3(done_op3) ); } + void retry() { v9_only(); cti(); emit_int32( op(arith_op) | fcn(1) | op3(retry_op3) ); } // pp 156 - void fadd( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x40 + w) | fs2(s2, w)); } - void fsub( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x44 + w) | fs2(s2, w)); } + void fadd( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x40 + w) | fs2(s2, w)); } + void fsub( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x44 + w) | fs2(s2, w)); } // pp 157 - void fcmp( FloatRegisterImpl::Width w, CC cc, FloatRegister s1, FloatRegister s2) { v8_no_cc(cc); emit_long( op(arith_op) | cmpcc(cc) | op3(fpop2_op3) | fs1(s1, w) | opf(0x50 + w) | fs2(s2, w)); } - void fcmpe( FloatRegisterImpl::Width w, CC cc, FloatRegister s1, FloatRegister s2) { v8_no_cc(cc); emit_long( op(arith_op) | cmpcc(cc) | op3(fpop2_op3) | fs1(s1, w) | opf(0x54 + w) | fs2(s2, w)); } + void fcmp( FloatRegisterImpl::Width w, CC cc, FloatRegister s1, FloatRegister s2) { v8_no_cc(cc); emit_int32( op(arith_op) | cmpcc(cc) | op3(fpop2_op3) | fs1(s1, w) | opf(0x50 + w) | fs2(s2, w)); } + void fcmpe( FloatRegisterImpl::Width w, CC cc, FloatRegister s1, FloatRegister s2) { v8_no_cc(cc); emit_int32( op(arith_op) | cmpcc(cc) | op3(fpop2_op3) | fs1(s1, w) | opf(0x54 + w) | fs2(s2, w)); } // pp 159 - void ftox( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v9_only(); emit_long( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(fpop1_op3) | opf(0x80 + w) | fs2(s, w)); } - void ftoi( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_long( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(fpop1_op3) | opf(0xd0 + w) | fs2(s, w)); } + void ftox( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v9_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(fpop1_op3) | opf(0x80 + w) | fs2(s, w)); } + void ftoi( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(fpop1_op3) | opf(0xd0 + w) | fs2(s, w)); } // pp 160 - void ftof( FloatRegisterImpl::Width sw, FloatRegisterImpl::Width dw, FloatRegister s, FloatRegister d ) { emit_long( op(arith_op) | fd(d, dw) | op3(fpop1_op3) | opf(0xc0 + sw + dw*4) | fs2(s, sw)); } + void ftof( FloatRegisterImpl::Width sw, FloatRegisterImpl::Width dw, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, dw) | op3(fpop1_op3) | opf(0xc0 + sw + dw*4) | fs2(s, sw)); } // pp 161 - void fxtof( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v9_only(); emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x80 + w*4) | fs2(s, FloatRegisterImpl::D)); } - void fitof( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0xc0 + w*4) | fs2(s, FloatRegisterImpl::S)); } + void fxtof( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v9_only(); emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x80 + w*4) | fs2(s, FloatRegisterImpl::D)); } + void fitof( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0xc0 + w*4) | fs2(s, FloatRegisterImpl::S)); } // pp 162 - void fmov( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x00 + w) | fs2(s, w)); } + void fmov( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x00 + w) | fs2(s, w)); } - void fneg( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x04 + w) | fs2(s, w)); } + void fneg( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x04 + w) | fs2(s, w)); } // page 144 sparc v8 architecture (double prec works on v8 if the source and destination registers are the same). fnegs is the only instruction available // on v8 to do negation of single, double and quad precision floats. - void fneg( FloatRegisterImpl::Width w, FloatRegister sd ) { if (VM_Version::v9_instructions_work()) emit_long( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x04 + w) | fs2(sd, w)); else emit_long( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x05) | fs2(sd, w)); } + void fneg( FloatRegisterImpl::Width w, FloatRegister sd ) { if (VM_Version::v9_instructions_work()) emit_int32( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x04 + w) | fs2(sd, w)); else emit_int32( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x05) | fs2(sd, w)); } - void fabs( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x08 + w) | fs2(s, w)); } + void fabs( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x08 + w) | fs2(s, w)); } // page 144 sparc v8 architecture (double prec works on v8 if the source and destination registers are the same). fabss is the only instruction available // on v8 to do abs operation on single/double/quad precision floats. - void fabs( FloatRegisterImpl::Width w, FloatRegister sd ) { if (VM_Version::v9_instructions_work()) emit_long( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x08 + w) | fs2(sd, w)); else emit_long( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x09) | fs2(sd, w)); } + void fabs( FloatRegisterImpl::Width w, FloatRegister sd ) { if (VM_Version::v9_instructions_work()) emit_int32( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x08 + w) | fs2(sd, w)); else emit_int32( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x09) | fs2(sd, w)); } // pp 163 - void fmul( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x48 + w) | fs2(s2, w)); } - void fmul( FloatRegisterImpl::Width sw, FloatRegisterImpl::Width dw, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_long( op(arith_op) | fd(d, dw) | op3(fpop1_op3) | fs1(s1, sw) | opf(0x60 + sw + dw*4) | fs2(s2, sw)); } - void fdiv( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x4c + w) | fs2(s2, w)); } + void fmul( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x48 + w) | fs2(s2, w)); } + void fmul( FloatRegisterImpl::Width sw, FloatRegisterImpl::Width dw, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, dw) | op3(fpop1_op3) | fs1(s1, sw) | opf(0x60 + sw + dw*4) | fs2(s2, sw)); } + void fdiv( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x4c + w) | fs2(s2, w)); } // pp 164 - void fsqrt( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x28 + w) | fs2(s, w)); } + void fsqrt( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x28 + w) | fs2(s, w)); } // pp 165 @@ -827,22 +827,22 @@ // pp 167 - void flushw() { v9_only(); emit_long( op(arith_op) | op3(flushw_op3) ); } + void flushw() { v9_only(); emit_int32( op(arith_op) | op3(flushw_op3) ); } // pp 168 - void illtrap( int const22a) { if (const22a != 0) v9_only(); emit_long( op(branch_op) | u_field(const22a, 21, 0) ); } + void illtrap( int const22a) { if (const22a != 0) v9_only(); emit_int32( op(branch_op) | u_field(const22a, 21, 0) ); } // v8 unimp == illtrap(0) // pp 169 - void impdep1( int id1, int const19a ) { v9_only(); emit_long( op(arith_op) | fcn(id1) | op3(impdep1_op3) | u_field(const19a, 18, 0)); } - void impdep2( int id1, int const19a ) { v9_only(); emit_long( op(arith_op) | fcn(id1) | op3(impdep2_op3) | u_field(const19a, 18, 0)); } + void impdep1( int id1, int const19a ) { v9_only(); emit_int32( op(arith_op) | fcn(id1) | op3(impdep1_op3) | u_field(const19a, 18, 0)); } + void impdep2( int id1, int const19a ) { v9_only(); emit_int32( op(arith_op) | fcn(id1) | op3(impdep2_op3) | u_field(const19a, 18, 0)); } // pp 149 (v8) - void cpop1( int opc, int cr1, int cr2, int crd ) { v8_only(); emit_long( op(arith_op) | fcn(crd) | op3(impdep1_op3) | u_field(cr1, 18, 14) | opf(opc) | u_field(cr2, 4, 0)); } - void cpop2( int opc, int cr1, int cr2, int crd ) { v8_only(); emit_long( op(arith_op) | fcn(crd) | op3(impdep2_op3) | u_field(cr1, 18, 14) | opf(opc) | u_field(cr2, 4, 0)); } + void cpop1( int opc, int cr1, int cr2, int crd ) { v8_only(); emit_int32( op(arith_op) | fcn(crd) | op3(impdep1_op3) | u_field(cr1, 18, 14) | opf(opc) | u_field(cr2, 4, 0)); } + void cpop2( int opc, int cr1, int cr2, int crd ) { v8_only(); emit_int32( op(arith_op) | fcn(crd) | op3(impdep2_op3) | u_field(cr1, 18, 14) | opf(opc) | u_field(cr2, 4, 0)); } // pp 170 @@ -872,8 +872,8 @@ // 173 - void ldfa( FloatRegisterImpl::Width w, Register s1, Register s2, int ia, FloatRegister d ) { v9_only(); emit_long( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3 | alt_bit_op3, w) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void ldfa( FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d ) { v9_only(); emit_long( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3 | alt_bit_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void ldfa( FloatRegisterImpl::Width w, Register s1, Register s2, int ia, FloatRegister d ) { v9_only(); emit_int32( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3 | alt_bit_op3, w) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void ldfa( FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d ) { v9_only(); emit_int32( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3 | alt_bit_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 175, lduw is ld on v8 @@ -896,22 +896,22 @@ // pp 177 - void ldsba( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void ldsba( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsb_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void ldsha( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsh_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void ldsha( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsh_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void ldswa( Register s1, Register s2, int ia, Register d ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(ldsw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void ldswa( Register s1, int simm13a, Register d ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(ldsw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void lduba( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldub_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void lduba( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldub_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void lduha( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(lduh_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void lduha( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(lduh_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void lduwa( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(lduw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void lduwa( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(lduw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void ldxa( Register s1, Register s2, int ia, Register d ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(ldx_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void ldxa( Register s1, int simm13a, Register d ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(ldx_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void ldda( Register s1, Register s2, int ia, Register d ) { v9_dep(); emit_long( op(ldst_op) | rd(d) | op3(ldd_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void ldda( Register s1, int simm13a, Register d ) { v9_dep(); emit_long( op(ldst_op) | rd(d) | op3(ldd_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void ldsba( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldsb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void ldsba( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldsb_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void ldsha( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldsh_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void ldsha( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldsh_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void ldswa( Register s1, Register s2, int ia, Register d ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(ldsw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void ldswa( Register s1, int simm13a, Register d ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(ldsw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void lduba( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldub_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void lduba( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldub_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void lduha( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(lduh_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void lduha( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(lduh_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void lduwa( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(lduw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void lduwa( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(lduw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void ldxa( Register s1, Register s2, int ia, Register d ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(ldx_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void ldxa( Register s1, int simm13a, Register d ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(ldx_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void ldda( Register s1, Register s2, int ia, Register d ) { v9_dep(); emit_int32( op(ldst_op) | rd(d) | op3(ldd_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void ldda( Register s1, int simm13a, Register d ) { v9_dep(); emit_int32( op(ldst_op) | rd(d) | op3(ldd_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 179 @@ -920,111 +920,111 @@ // pp 180 - void ldstuba( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldstub_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void ldstuba( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldstub_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void ldstuba( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldstub_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void ldstuba( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldstub_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 181 - void and3( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(and_op3 ) | rs1(s1) | rs2(s2) ); } - void and3( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(and_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void andcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(and_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void andcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(and_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void andn( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(andn_op3 ) | rs1(s1) | rs2(s2) ); } - void andn( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(andn_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void andncc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(andn_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void andncc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(andn_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void or3( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(or_op3 ) | rs1(s1) | rs2(s2) ); } - void or3( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(or_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void orcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(or_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void orcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(or_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void orn( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(orn_op3) | rs1(s1) | rs2(s2) ); } - void orn( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(orn_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void orncc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(orn_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void orncc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(orn_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void xor3( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xor_op3 ) | rs1(s1) | rs2(s2) ); } - void xor3( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xor_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void xorcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xor_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void xorcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xor_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void xnor( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xnor_op3 ) | rs1(s1) | rs2(s2) ); } - void xnor( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xnor_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void xnorcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xnor_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void xnorcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xnor_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void and3( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(and_op3 ) | rs1(s1) | rs2(s2) ); } + void and3( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(and_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void andcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(and_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void andcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(and_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void andn( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(andn_op3 ) | rs1(s1) | rs2(s2) ); } + void andn( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(andn_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void andncc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(andn_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void andncc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(andn_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void or3( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(or_op3 ) | rs1(s1) | rs2(s2) ); } + void or3( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(or_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void orcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(or_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void orcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(or_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void orn( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(orn_op3) | rs1(s1) | rs2(s2) ); } + void orn( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(orn_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void orncc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(orn_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void orncc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(orn_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void xor3( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xor_op3 ) | rs1(s1) | rs2(s2) ); } + void xor3( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xor_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void xorcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xor_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void xorcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xor_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void xnor( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xnor_op3 ) | rs1(s1) | rs2(s2) ); } + void xnor( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xnor_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void xnorcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xnor_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void xnorcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xnor_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 183 - void membar( Membar_mask_bits const7a ) { v9_only(); emit_long( op(arith_op) | op3(membar_op3) | rs1(O7) | immed(true) | u_field( int(const7a), 6, 0)); } + void membar( Membar_mask_bits const7a ) { v9_only(); emit_int32( op(arith_op) | op3(membar_op3) | rs1(O7) | immed(true) | u_field( int(const7a), 6, 0)); } // pp 185 - void fmov( FloatRegisterImpl::Width w, Condition c, bool floatCC, CC cca, FloatRegister s2, FloatRegister d ) { v9_only(); emit_long( op(arith_op) | fd(d, w) | op3(fpop2_op3) | cond_mov(c) | opf_cc(cca, floatCC) | opf_low6(w) | fs2(s2, w)); } + void fmov( FloatRegisterImpl::Width w, Condition c, bool floatCC, CC cca, FloatRegister s2, FloatRegister d ) { v9_only(); emit_int32( op(arith_op) | fd(d, w) | op3(fpop2_op3) | cond_mov(c) | opf_cc(cca, floatCC) | opf_low6(w) | fs2(s2, w)); } // pp 189 - void fmov( FloatRegisterImpl::Width w, RCondition c, Register s1, FloatRegister s2, FloatRegister d ) { v9_only(); emit_long( op(arith_op) | fd(d, w) | op3(fpop2_op3) | rs1(s1) | rcond(c) | opf_low5(4 + w) | fs2(s2, w)); } + void fmov( FloatRegisterImpl::Width w, RCondition c, Register s1, FloatRegister s2, FloatRegister d ) { v9_only(); emit_int32( op(arith_op) | fd(d, w) | op3(fpop2_op3) | rs1(s1) | rcond(c) | opf_low5(4 + w) | fs2(s2, w)); } // pp 191 - void movcc( Condition c, bool floatCC, CC cca, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(movcc_op3) | mov_cc(cca, floatCC) | cond_mov(c) | rs2(s2) ); } - void movcc( Condition c, bool floatCC, CC cca, int simm11a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(movcc_op3) | mov_cc(cca, floatCC) | cond_mov(c) | immed(true) | simm(simm11a, 11) ); } + void movcc( Condition c, bool floatCC, CC cca, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(movcc_op3) | mov_cc(cca, floatCC) | cond_mov(c) | rs2(s2) ); } + void movcc( Condition c, bool floatCC, CC cca, int simm11a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(movcc_op3) | mov_cc(cca, floatCC) | cond_mov(c) | immed(true) | simm(simm11a, 11) ); } // pp 195 - void movr( RCondition c, Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(movr_op3) | rs1(s1) | rcond(c) | rs2(s2) ); } - void movr( RCondition c, Register s1, int simm10a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(movr_op3) | rs1(s1) | rcond(c) | immed(true) | simm(simm10a, 10) ); } + void movr( RCondition c, Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(movr_op3) | rs1(s1) | rcond(c) | rs2(s2) ); } + void movr( RCondition c, Register s1, int simm10a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(movr_op3) | rs1(s1) | rcond(c) | immed(true) | simm(simm10a, 10) ); } // pp 196 - void mulx( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(mulx_op3 ) | rs1(s1) | rs2(s2) ); } - void mulx( Register s1, int simm13a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(mulx_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void sdivx( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sdivx_op3) | rs1(s1) | rs2(s2) ); } - void sdivx( Register s1, int simm13a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sdivx_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void udivx( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(udivx_op3) | rs1(s1) | rs2(s2) ); } - void udivx( Register s1, int simm13a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(udivx_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void mulx( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(mulx_op3 ) | rs1(s1) | rs2(s2) ); } + void mulx( Register s1, int simm13a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(mulx_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void sdivx( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sdivx_op3) | rs1(s1) | rs2(s2) ); } + void sdivx( Register s1, int simm13a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sdivx_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void udivx( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(udivx_op3) | rs1(s1) | rs2(s2) ); } + void udivx( Register s1, int simm13a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(udivx_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 197 - void umul( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(umul_op3 ) | rs1(s1) | rs2(s2) ); } - void umul( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(umul_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void smul( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(smul_op3 ) | rs1(s1) | rs2(s2) ); } - void smul( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(smul_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void umulcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(umul_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void umulcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(umul_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void smulcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(smul_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void smulcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(smul_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void umul( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(umul_op3 ) | rs1(s1) | rs2(s2) ); } + void umul( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(umul_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void smul( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(smul_op3 ) | rs1(s1) | rs2(s2) ); } + void smul( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(smul_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void umulcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(umul_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void umulcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(umul_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void smulcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(smul_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void smulcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(smul_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 199 - void mulscc( Register s1, Register s2, Register d ) { v9_dep(); emit_long( op(arith_op) | rd(d) | op3(mulscc_op3) | rs1(s1) | rs2(s2) ); } - void mulscc( Register s1, int simm13a, Register d ) { v9_dep(); emit_long( op(arith_op) | rd(d) | op3(mulscc_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void mulscc( Register s1, Register s2, Register d ) { v9_dep(); emit_int32( op(arith_op) | rd(d) | op3(mulscc_op3) | rs1(s1) | rs2(s2) ); } + void mulscc( Register s1, int simm13a, Register d ) { v9_dep(); emit_int32( op(arith_op) | rd(d) | op3(mulscc_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 201 - void nop() { emit_long( op(branch_op) | op2(sethi_op2) ); } + void nop() { emit_int32( op(branch_op) | op2(sethi_op2) ); } // pp 202 - void popc( Register s, Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(popc_op3) | rs2(s)); } - void popc( int simm13a, Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(popc_op3) | immed(true) | simm(simm13a, 13)); } + void popc( Register s, Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(popc_op3) | rs2(s)); } + void popc( int simm13a, Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(popc_op3) | immed(true) | simm(simm13a, 13)); } // pp 203 - void prefetch( Register s1, Register s2, PrefetchFcn f) { v9_only(); emit_long( op(ldst_op) | fcn(f) | op3(prefetch_op3) | rs1(s1) | rs2(s2) ); } + void prefetch( Register s1, Register s2, PrefetchFcn f) { v9_only(); emit_int32( op(ldst_op) | fcn(f) | op3(prefetch_op3) | rs1(s1) | rs2(s2) ); } void prefetch( Register s1, int simm13a, PrefetchFcn f) { v9_only(); emit_data( op(ldst_op) | fcn(f) | op3(prefetch_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } - void prefetcha( Register s1, Register s2, int ia, PrefetchFcn f ) { v9_only(); emit_long( op(ldst_op) | fcn(f) | op3(prefetch_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void prefetcha( Register s1, int simm13a, PrefetchFcn f ) { v9_only(); emit_long( op(ldst_op) | fcn(f) | op3(prefetch_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void prefetcha( Register s1, Register s2, int ia, PrefetchFcn f ) { v9_only(); emit_int32( op(ldst_op) | fcn(f) | op3(prefetch_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void prefetcha( Register s1, int simm13a, PrefetchFcn f ) { v9_only(); emit_int32( op(ldst_op) | fcn(f) | op3(prefetch_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 208 // not implementing read privileged register - inline void rdy( Register d) { v9_dep(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(0, 18, 14)); } - inline void rdccr( Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(2, 18, 14)); } - inline void rdasi( Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(3, 18, 14)); } - inline void rdtick( Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(4, 18, 14)); } // Spoon! - inline void rdpc( Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(5, 18, 14)); } - inline void rdfprs( Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(6, 18, 14)); } + inline void rdy( Register d) { v9_dep(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(0, 18, 14)); } + inline void rdccr( Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(2, 18, 14)); } + inline void rdasi( Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(3, 18, 14)); } + inline void rdtick( Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(4, 18, 14)); } // Spoon! + inline void rdpc( Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(5, 18, 14)); } + inline void rdfprs( Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(6, 18, 14)); } // pp 213 @@ -1033,47 +1033,47 @@ // pp 214 - void save( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(save_op3) | rs1(s1) | rs2(s2) ); } + void save( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(save_op3) | rs1(s1) | rs2(s2) ); } void save( Register s1, int simm13a, Register d ) { // make sure frame is at least large enough for the register save area assert(-simm13a >= 16 * wordSize, "frame too small"); - emit_long( op(arith_op) | rd(d) | op3(save_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); + emit_int32( op(arith_op) | rd(d) | op3(save_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void restore( Register s1 = G0, Register s2 = G0, Register d = G0 ) { emit_long( op(arith_op) | rd(d) | op3(restore_op3) | rs1(s1) | rs2(s2) ); } - void restore( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(restore_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void restore( Register s1 = G0, Register s2 = G0, Register d = G0 ) { emit_int32( op(arith_op) | rd(d) | op3(restore_op3) | rs1(s1) | rs2(s2) ); } + void restore( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(restore_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 216 - void saved() { v9_only(); emit_long( op(arith_op) | fcn(0) | op3(saved_op3)); } - void restored() { v9_only(); emit_long( op(arith_op) | fcn(1) | op3(saved_op3)); } + void saved() { v9_only(); emit_int32( op(arith_op) | fcn(0) | op3(saved_op3)); } + void restored() { v9_only(); emit_int32( op(arith_op) | fcn(1) | op3(saved_op3)); } // pp 217 inline void sethi( int imm22a, Register d, RelocationHolder const& rspec = RelocationHolder() ); // pp 218 - void sll( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(0) | rs2(s2) ); } - void sll( Register s1, int imm5a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); } - void srl( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(0) | rs2(s2) ); } - void srl( Register s1, int imm5a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); } - void sra( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(0) | rs2(s2) ); } - void sra( Register s1, int imm5a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); } + void sll( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(0) | rs2(s2) ); } + void sll( Register s1, int imm5a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); } + void srl( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(0) | rs2(s2) ); } + void srl( Register s1, int imm5a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); } + void sra( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(0) | rs2(s2) ); } + void sra( Register s1, int imm5a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); } - void sllx( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(1) | rs2(s2) ); } - void sllx( Register s1, int imm6a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); } - void srlx( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(1) | rs2(s2) ); } - void srlx( Register s1, int imm6a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); } - void srax( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(1) | rs2(s2) ); } - void srax( Register s1, int imm6a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); } + void sllx( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(1) | rs2(s2) ); } + void sllx( Register s1, int imm6a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); } + void srlx( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(1) | rs2(s2) ); } + void srlx( Register s1, int imm6a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); } + void srax( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(1) | rs2(s2) ); } + void srax( Register s1, int imm6a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); } // pp 220 - void sir( int simm13a ) { emit_long( op(arith_op) | fcn(15) | op3(sir_op3) | immed(true) | simm(simm13a, 13)); } + void sir( int simm13a ) { emit_int32( op(arith_op) | fcn(15) | op3(sir_op3) | immed(true) | simm(simm13a, 13)); } // pp 221 - void stbar() { emit_long( op(arith_op) | op3(membar_op3) | u_field(15, 18, 14)); } + void stbar() { emit_int32( op(arith_op) | op3(membar_op3) | u_field(15, 18, 14)); } // pp 222 @@ -1087,8 +1087,8 @@ // pp 224 - void stfa( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2, int ia ) { v9_only(); emit_long( op(ldst_op) | fd(d, w) | alt_op3(stf_op3 | alt_bit_op3, w) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void stfa( FloatRegisterImpl::Width w, FloatRegister d, Register s1, int simm13a ) { v9_only(); emit_long( op(ldst_op) | fd(d, w) | alt_op3(stf_op3 | alt_bit_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void stfa( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2, int ia ) { v9_only(); emit_int32( op(ldst_op) | fd(d, w) | alt_op3(stf_op3 | alt_bit_op3, w) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void stfa( FloatRegisterImpl::Width w, FloatRegister d, Register s1, int simm13a ) { v9_only(); emit_int32( op(ldst_op) | fd(d, w) | alt_op3(stf_op3 | alt_bit_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // p 226 @@ -1105,16 +1105,16 @@ // pp 177 - void stba( Register d, Register s1, Register s2, int ia ) { emit_long( op(ldst_op) | rd(d) | op3(stb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void stba( Register d, Register s1, int simm13a ) { emit_long( op(ldst_op) | rd(d) | op3(stb_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void stha( Register d, Register s1, Register s2, int ia ) { emit_long( op(ldst_op) | rd(d) | op3(sth_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void stha( Register d, Register s1, int simm13a ) { emit_long( op(ldst_op) | rd(d) | op3(sth_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void stwa( Register d, Register s1, Register s2, int ia ) { emit_long( op(ldst_op) | rd(d) | op3(stw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void stwa( Register d, Register s1, int simm13a ) { emit_long( op(ldst_op) | rd(d) | op3(stw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void stxa( Register d, Register s1, Register s2, int ia ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(stx_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void stxa( Register d, Register s1, int simm13a ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(stx_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void stda( Register d, Register s1, Register s2, int ia ) { emit_long( op(ldst_op) | rd(d) | op3(std_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void stda( Register d, Register s1, int simm13a ) { emit_long( op(ldst_op) | rd(d) | op3(std_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void stba( Register d, Register s1, Register s2, int ia ) { emit_int32( op(ldst_op) | rd(d) | op3(stb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void stba( Register d, Register s1, int simm13a ) { emit_int32( op(ldst_op) | rd(d) | op3(stb_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void stha( Register d, Register s1, Register s2, int ia ) { emit_int32( op(ldst_op) | rd(d) | op3(sth_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void stha( Register d, Register s1, int simm13a ) { emit_int32( op(ldst_op) | rd(d) | op3(sth_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void stwa( Register d, Register s1, Register s2, int ia ) { emit_int32( op(ldst_op) | rd(d) | op3(stw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void stwa( Register d, Register s1, int simm13a ) { emit_int32( op(ldst_op) | rd(d) | op3(stw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void stxa( Register d, Register s1, Register s2, int ia ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(stx_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void stxa( Register d, Register s1, int simm13a ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(stx_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void stda( Register d, Register s1, Register s2, int ia ) { emit_int32( op(ldst_op) | rd(d) | op3(std_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void stda( Register d, Register s1, int simm13a ) { emit_int32( op(ldst_op) | rd(d) | op3(std_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 97 (v8) @@ -1129,15 +1129,15 @@ // pp 230 - void sub( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 ) | rs1(s1) | rs2(s2) ); } - void sub( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void sub( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sub_op3 ) | rs1(s1) | rs2(s2) ); } + void sub( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sub_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void subcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 | cc_bit_op3 ) | rs1(s1) | rs2(s2) ); } - void subcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 | cc_bit_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void subc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(subc_op3 ) | rs1(s1) | rs2(s2) ); } - void subc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(subc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void subccc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(subc_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void subccc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(subc_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void subcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sub_op3 | cc_bit_op3 ) | rs1(s1) | rs2(s2) ); } + void subcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sub_op3 | cc_bit_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void subc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(subc_op3 ) | rs1(s1) | rs2(s2) ); } + void subc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(subc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void subccc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(subc_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void subccc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(subc_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 231 @@ -1146,55 +1146,55 @@ // pp 232 - void swapa( Register s1, Register s2, int ia, Register d ) { v9_dep(); emit_long( op(ldst_op) | rd(d) | op3(swap_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void swapa( Register s1, int simm13a, Register d ) { v9_dep(); emit_long( op(ldst_op) | rd(d) | op3(swap_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void swapa( Register s1, Register s2, int ia, Register d ) { v9_dep(); emit_int32( op(ldst_op) | rd(d) | op3(swap_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void swapa( Register s1, int simm13a, Register d ) { v9_dep(); emit_int32( op(ldst_op) | rd(d) | op3(swap_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 234, note op in book is wrong, see pp 268 - void taddcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(taddcc_op3 ) | rs1(s1) | rs2(s2) ); } - void taddcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(taddcc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void taddcctv( Register s1, Register s2, Register d ) { v9_dep(); emit_long( op(arith_op) | rd(d) | op3(taddcctv_op3) | rs1(s1) | rs2(s2) ); } - void taddcctv( Register s1, int simm13a, Register d ) { v9_dep(); emit_long( op(arith_op) | rd(d) | op3(taddcctv_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void taddcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(taddcc_op3 ) | rs1(s1) | rs2(s2) ); } + void taddcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(taddcc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void taddcctv( Register s1, Register s2, Register d ) { v9_dep(); emit_int32( op(arith_op) | rd(d) | op3(taddcctv_op3) | rs1(s1) | rs2(s2) ); } + void taddcctv( Register s1, int simm13a, Register d ) { v9_dep(); emit_int32( op(arith_op) | rd(d) | op3(taddcctv_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 235 - void tsubcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(tsubcc_op3 ) | rs1(s1) | rs2(s2) ); } - void tsubcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(tsubcc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void tsubcctv( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(tsubcctv_op3) | rs1(s1) | rs2(s2) ); } - void tsubcctv( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(tsubcctv_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void tsubcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(tsubcc_op3 ) | rs1(s1) | rs2(s2) ); } + void tsubcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(tsubcc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void tsubcctv( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(tsubcctv_op3) | rs1(s1) | rs2(s2) ); } + void tsubcctv( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(tsubcctv_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 237 - void trap( Condition c, CC cc, Register s1, Register s2 ) { v8_no_cc(cc); emit_long( op(arith_op) | cond(c) | op3(trap_op3) | rs1(s1) | trapcc(cc) | rs2(s2)); } - void trap( Condition c, CC cc, Register s1, int trapa ) { v8_no_cc(cc); emit_long( op(arith_op) | cond(c) | op3(trap_op3) | rs1(s1) | trapcc(cc) | immed(true) | u_field(trapa, 6, 0)); } + void trap( Condition c, CC cc, Register s1, Register s2 ) { v8_no_cc(cc); emit_int32( op(arith_op) | cond(c) | op3(trap_op3) | rs1(s1) | trapcc(cc) | rs2(s2)); } + void trap( Condition c, CC cc, Register s1, int trapa ) { v8_no_cc(cc); emit_int32( op(arith_op) | cond(c) | op3(trap_op3) | rs1(s1) | trapcc(cc) | immed(true) | u_field(trapa, 6, 0)); } // simple uncond. trap void trap( int trapa ) { trap( always, icc, G0, trapa ); } // pp 239 omit write priv register for now - inline void wry( Register d) { v9_dep(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(0, 29, 25)); } - inline void wrccr(Register s) { v9_only(); emit_long( op(arith_op) | rs1(s) | op3(wrreg_op3) | u_field(2, 29, 25)); } - inline void wrccr(Register s, int simm13a) { v9_only(); emit_long( op(arith_op) | + inline void wry( Register d) { v9_dep(); emit_int32( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(0, 29, 25)); } + inline void wrccr(Register s) { v9_only(); emit_int32( op(arith_op) | rs1(s) | op3(wrreg_op3) | u_field(2, 29, 25)); } + inline void wrccr(Register s, int simm13a) { v9_only(); emit_int32( op(arith_op) | rs1(s) | op3(wrreg_op3) | u_field(2, 29, 25) | immed(true) | simm(simm13a, 13)); } - inline void wrasi(Register d) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(3, 29, 25)); } + inline void wrasi(Register d) { v9_only(); emit_int32( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(3, 29, 25)); } // wrasi(d, imm) stores (d xor imm) to asi - inline void wrasi(Register d, int simm13a) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | + inline void wrasi(Register d, int simm13a) { v9_only(); emit_int32( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(3, 29, 25) | immed(true) | simm(simm13a, 13)); } - inline void wrfprs( Register d) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(6, 29, 25)); } + inline void wrfprs( Register d) { v9_only(); emit_int32( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(6, 29, 25)); } // VIS3 instructions - void movstosw( FloatRegister s, Register d ) { vis3_only(); emit_long( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mstosw_opf) | fs2(s, FloatRegisterImpl::S)); } - void movstouw( FloatRegister s, Register d ) { vis3_only(); emit_long( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mstouw_opf) | fs2(s, FloatRegisterImpl::S)); } - void movdtox( FloatRegister s, Register d ) { vis3_only(); emit_long( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mdtox_opf) | fs2(s, FloatRegisterImpl::D)); } + void movstosw( FloatRegister s, Register d ) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mstosw_opf) | fs2(s, FloatRegisterImpl::S)); } + void movstouw( FloatRegister s, Register d ) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mstouw_opf) | fs2(s, FloatRegisterImpl::S)); } + void movdtox( FloatRegister s, Register d ) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mdtox_opf) | fs2(s, FloatRegisterImpl::D)); } - void movwtos( Register s, FloatRegister d ) { vis3_only(); emit_long( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(mftoi_op3) | opf(mwtos_opf) | rs2(s)); } - void movxtod( Register s, FloatRegister d ) { vis3_only(); emit_long( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(mftoi_op3) | opf(mxtod_opf) | rs2(s)); } + void movwtos( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(mftoi_op3) | opf(mwtos_opf) | rs2(s)); } + void movxtod( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(mftoi_op3) | opf(mxtod_opf) | rs2(s)); } // Creation Assembler(CodeBuffer* code) : AbstractAssembler(code) { diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/sparc/vm/assembler_sparc.inline.hpp --- a/src/cpu/sparc/vm/assembler_sparc.inline.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/sparc/vm/assembler_sparc.inline.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -35,24 +35,24 @@ # endif } -inline void Assembler::emit_long(int x) { +inline void Assembler::emit_int32(int x) { check_delay(); - AbstractAssembler::emit_long(x); + AbstractAssembler::emit_int32(x); } inline void Assembler::emit_data(int x, relocInfo::relocType rtype) { relocate(rtype); - emit_long(x); + emit_int32(x); } inline void Assembler::emit_data(int x, RelocationHolder const& rspec) { relocate(rspec); - emit_long(x); + emit_int32(x); } -inline void Assembler::add(Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | rs2(s2) ); } -inline void Assembler::add(Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } +inline void Assembler::add(Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::add(Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt ) { v9_only(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(bpr_op2) | wdisp16(intptr_t(d), intptr_t(pc())) | predict(p) | rs1(s1), rt); has_delay_slot(); } inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, Label& L) { bpr( c, a, p, s1, target(L)); } @@ -79,93 +79,93 @@ inline void Assembler::call( address d, relocInfo::relocType rt ) { cti(); emit_data( op(call_op) | wdisp(intptr_t(d), intptr_t(pc()), 30), rt); has_delay_slot(); assert(rt != relocInfo::virtual_call_type, "must use virtual_call_Relocation::spec"); } inline void Assembler::call( Label& L, relocInfo::relocType rt ) { call( target(L), rt); } -inline void Assembler::flush( Register s1, Register s2) { emit_long( op(arith_op) | op3(flush_op3) | rs1(s1) | rs2(s2)); } +inline void Assembler::flush( Register s1, Register s2) { emit_int32( op(arith_op) | op3(flush_op3) | rs1(s1) | rs2(s2)); } inline void Assembler::flush( Register s1, int simm13a) { emit_data( op(arith_op) | op3(flush_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::jmpl( Register s1, Register s2, Register d ) { cti(); emit_long( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); } +inline void Assembler::jmpl( Register s1, Register s2, Register d ) { cti(); emit_int32( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); } inline void Assembler::jmpl( Register s1, int simm13a, Register d, RelocationHolder const& rspec ) { cti(); emit_data( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); has_delay_slot(); } -inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d) { emit_long( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d) { emit_int32( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d, RelocationHolder const& rspec) { emit_data( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); } -inline void Assembler::ldfsr( Register s1, Register s2) { v9_dep(); emit_long( op(ldst_op) | op3(ldfsr_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldfsr( Register s1, Register s2) { v9_dep(); emit_int32( op(ldst_op) | op3(ldfsr_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldfsr( Register s1, int simm13a) { v9_dep(); emit_data( op(ldst_op) | op3(ldfsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldxfsr( Register s1, Register s2) { v9_only(); emit_long( op(ldst_op) | rd(G1) | op3(ldfsr_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldxfsr( Register s1, Register s2) { v9_only(); emit_int32( op(ldst_op) | rd(G1) | op3(ldfsr_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldxfsr( Register s1, int simm13a) { v9_only(); emit_data( op(ldst_op) | rd(G1) | op3(ldfsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldc( Register s1, Register s2, int crd) { v8_only(); emit_long( op(ldst_op) | fcn(crd) | op3(ldc_op3 ) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldc( Register s1, Register s2, int crd) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(ldc_op3 ) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldc( Register s1, int simm13a, int crd) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(ldc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::lddc( Register s1, Register s2, int crd) { v8_only(); emit_long( op(ldst_op) | fcn(crd) | op3(lddc_op3 ) | rs1(s1) | rs2(s2) ); } +inline void Assembler::lddc( Register s1, Register s2, int crd) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(lddc_op3 ) | rs1(s1) | rs2(s2) ); } inline void Assembler::lddc( Register s1, int simm13a, int crd) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(lddc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldcsr( Register s1, Register s2, int crd) { v8_only(); emit_long( op(ldst_op) | fcn(crd) | op3(ldcsr_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldcsr( Register s1, Register s2, int crd) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(ldcsr_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldcsr( Register s1, int simm13a, int crd) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(ldcsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldsb( Register s1, Register s2, Register d) { emit_long( op(ldst_op) | rd(d) | op3(ldsb_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldsb( Register s1, Register s2, Register d) { emit_int32( op(ldst_op) | rd(d) | op3(ldsb_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldsb( Register s1, int simm13a, Register d) { emit_data( op(ldst_op) | rd(d) | op3(ldsb_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldsh( Register s1, Register s2, Register d) { emit_long( op(ldst_op) | rd(d) | op3(ldsh_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldsh( Register s1, Register s2, Register d) { emit_int32( op(ldst_op) | rd(d) | op3(ldsh_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldsh( Register s1, int simm13a, Register d) { emit_data( op(ldst_op) | rd(d) | op3(ldsh_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldsw( Register s1, Register s2, Register d) { emit_long( op(ldst_op) | rd(d) | op3(ldsw_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldsw( Register s1, Register s2, Register d) { emit_int32( op(ldst_op) | rd(d) | op3(ldsw_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldsw( Register s1, int simm13a, Register d) { emit_data( op(ldst_op) | rd(d) | op3(ldsw_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldub( Register s1, Register s2, Register d) { emit_long( op(ldst_op) | rd(d) | op3(ldub_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldub( Register s1, Register s2, Register d) { emit_int32( op(ldst_op) | rd(d) | op3(ldub_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldub( Register s1, int simm13a, Register d) { emit_data( op(ldst_op) | rd(d) | op3(ldub_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::lduh( Register s1, Register s2, Register d) { emit_long( op(ldst_op) | rd(d) | op3(lduh_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::lduh( Register s1, Register s2, Register d) { emit_int32( op(ldst_op) | rd(d) | op3(lduh_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::lduh( Register s1, int simm13a, Register d) { emit_data( op(ldst_op) | rd(d) | op3(lduh_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::lduw( Register s1, Register s2, Register d) { emit_long( op(ldst_op) | rd(d) | op3(lduw_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::lduw( Register s1, Register s2, Register d) { emit_int32( op(ldst_op) | rd(d) | op3(lduw_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::lduw( Register s1, int simm13a, Register d) { emit_data( op(ldst_op) | rd(d) | op3(lduw_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldx( Register s1, Register s2, Register d) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(ldx_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldx( Register s1, Register s2, Register d) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(ldx_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldx( Register s1, int simm13a, Register d) { v9_only(); emit_data( op(ldst_op) | rd(d) | op3(ldx_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldd( Register s1, Register s2, Register d) { v9_dep(); assert(d->is_even(), "not even"); emit_long( op(ldst_op) | rd(d) | op3(ldd_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldd( Register s1, Register s2, Register d) { v9_dep(); assert(d->is_even(), "not even"); emit_int32( op(ldst_op) | rd(d) | op3(ldd_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldd( Register s1, int simm13a, Register d) { v9_dep(); assert(d->is_even(), "not even"); emit_data( op(ldst_op) | rd(d) | op3(ldd_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldstub( Register s1, Register s2, Register d) { emit_long( op(ldst_op) | rd(d) | op3(ldstub_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldstub( Register s1, Register s2, Register d) { emit_int32( op(ldst_op) | rd(d) | op3(ldstub_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldstub( Register s1, int simm13a, Register d) { emit_data( op(ldst_op) | rd(d) | op3(ldstub_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::rett( Register s1, Register s2 ) { cti(); emit_long( op(arith_op) | op3(rett_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); } +inline void Assembler::rett( Register s1, Register s2 ) { cti(); emit_int32( op(arith_op) | op3(rett_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); } inline void Assembler::rett( Register s1, int simm13a, relocInfo::relocType rt) { cti(); emit_data( op(arith_op) | op3(rett_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rt); has_delay_slot(); } inline void Assembler::sethi( int imm22a, Register d, RelocationHolder const& rspec ) { emit_data( op(branch_op) | rd(d) | op2(sethi_op2) | hi22(imm22a), rspec); } // pp 222 -inline void Assembler::stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2) { emit_long( op(ldst_op) | fd(d, w) | alt_op3(stf_op3, w) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2) { emit_int32( op(ldst_op) | fd(d, w) | alt_op3(stf_op3, w) | rs1(s1) | rs2(s2) ); } inline void Assembler::stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, int simm13a) { emit_data( op(ldst_op) | fd(d, w) | alt_op3(stf_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::stfsr( Register s1, Register s2) { v9_dep(); emit_long( op(ldst_op) | op3(stfsr_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stfsr( Register s1, Register s2) { v9_dep(); emit_int32( op(ldst_op) | op3(stfsr_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::stfsr( Register s1, int simm13a) { v9_dep(); emit_data( op(ldst_op) | op3(stfsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::stxfsr( Register s1, Register s2) { v9_only(); emit_long( op(ldst_op) | rd(G1) | op3(stfsr_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stxfsr( Register s1, Register s2) { v9_only(); emit_int32( op(ldst_op) | rd(G1) | op3(stfsr_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::stxfsr( Register s1, int simm13a) { v9_only(); emit_data( op(ldst_op) | rd(G1) | op3(stfsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } // p 226 -inline void Assembler::stb( Register d, Register s1, Register s2) { emit_long( op(ldst_op) | rd(d) | op3(stb_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stb( Register d, Register s1, Register s2) { emit_int32( op(ldst_op) | rd(d) | op3(stb_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::stb( Register d, Register s1, int simm13a) { emit_data( op(ldst_op) | rd(d) | op3(stb_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::sth( Register d, Register s1, Register s2) { emit_long( op(ldst_op) | rd(d) | op3(sth_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::sth( Register d, Register s1, Register s2) { emit_int32( op(ldst_op) | rd(d) | op3(sth_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::sth( Register d, Register s1, int simm13a) { emit_data( op(ldst_op) | rd(d) | op3(sth_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::stw( Register d, Register s1, Register s2) { emit_long( op(ldst_op) | rd(d) | op3(stw_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stw( Register d, Register s1, Register s2) { emit_int32( op(ldst_op) | rd(d) | op3(stw_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::stw( Register d, Register s1, int simm13a) { emit_data( op(ldst_op) | rd(d) | op3(stw_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::stx( Register d, Register s1, Register s2) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(stx_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stx( Register d, Register s1, Register s2) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(stx_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::stx( Register d, Register s1, int simm13a) { v9_only(); emit_data( op(ldst_op) | rd(d) | op3(stx_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::std( Register d, Register s1, Register s2) { v9_dep(); assert(d->is_even(), "not even"); emit_long( op(ldst_op) | rd(d) | op3(std_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::std( Register d, Register s1, Register s2) { v9_dep(); assert(d->is_even(), "not even"); emit_int32( op(ldst_op) | rd(d) | op3(std_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::std( Register d, Register s1, int simm13a) { v9_dep(); assert(d->is_even(), "not even"); emit_data( op(ldst_op) | rd(d) | op3(std_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } // v8 p 99 -inline void Assembler::stc( int crd, Register s1, Register s2) { v8_only(); emit_long( op(ldst_op) | fcn(crd) | op3(stc_op3 ) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stc( int crd, Register s1, Register s2) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(stc_op3 ) | rs1(s1) | rs2(s2) ); } inline void Assembler::stc( int crd, Register s1, int simm13a) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(stc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::stdc( int crd, Register s1, Register s2) { v8_only(); emit_long( op(ldst_op) | fcn(crd) | op3(stdc_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stdc( int crd, Register s1, Register s2) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(stdc_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::stdc( int crd, Register s1, int simm13a) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(stdc_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::stcsr( int crd, Register s1, Register s2) { v8_only(); emit_long( op(ldst_op) | fcn(crd) | op3(stcsr_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stcsr( int crd, Register s1, Register s2) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(stcsr_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::stcsr( int crd, Register s1, int simm13a) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(stcsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::stdcq( int crd, Register s1, Register s2) { v8_only(); emit_long( op(ldst_op) | fcn(crd) | op3(stdcq_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stdcq( int crd, Register s1, Register s2) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(stdcq_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::stdcq( int crd, Register s1, int simm13a) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(stdcq_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } // pp 231 -inline void Assembler::swap( Register s1, Register s2, Register d) { v9_dep(); emit_long( op(ldst_op) | rd(d) | op3(swap_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::swap( Register s1, Register s2, Register d) { v9_dep(); emit_int32( op(ldst_op) | rd(d) | op3(swap_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::swap( Register s1, int simm13a, Register d) { v9_dep(); emit_data( op(ldst_op) | rd(d) | op3(swap_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } #endif // CPU_SPARC_VM_ASSEMBLER_SPARC_INLINE_HPP diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/sparc/vm/cppInterpreter_sparc.cpp --- a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -137,7 +137,7 @@ } __ ret(); // return from interpreter activation __ delayed()->restore(I5_savedSP, G0, SP); // remove interpreter frame - NOT_PRODUCT(__ emit_long(0);) // marker for disassembly + NOT_PRODUCT(__ emit_int32(0);) // marker for disassembly return entry; } @@ -232,7 +232,7 @@ } __ retl(); // return from interpreter activation __ delayed()->nop(); // schedule this better - NOT_PRODUCT(__ emit_long(0);) // marker for disassembly + NOT_PRODUCT(__ emit_int32(0);) // marker for disassembly return entry; } @@ -1473,7 +1473,7 @@ __ brx(Assembler::equal, false, Assembler::pt, skip); \ __ delayed()->nop(); \ __ breakpoint_trap(); \ - __ emit_long(marker); \ + __ emit_int32(marker); \ __ bind(skip); \ } #else diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/sparc/vm/macroAssembler_sparc.cpp --- a/src/cpu/sparc/vm/macroAssembler_sparc.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/sparc/vm/macroAssembler_sparc.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -1224,7 +1224,7 @@ // Relocation with special format (see relocInfo_sparc.hpp). relocate(rspec, 1); // Assembler::sethi(0x3fffff, d); - emit_long( op(branch_op) | rd(d) | op2(sethi_op2) | hi22(0x3fffff) ); + emit_int32( op(branch_op) | rd(d) | op2(sethi_op2) | hi22(0x3fffff) ); // Don't add relocation for 'add'. Do patching during 'sethi' processing. add(d, 0x3ff, d); @@ -1240,7 +1240,7 @@ // Relocation with special format (see relocInfo_sparc.hpp). relocate(rspec, 1); // Assembler::sethi(encoded_k, d); - emit_long( op(branch_op) | rd(d) | op2(sethi_op2) | hi22(encoded_k) ); + emit_int32( op(branch_op) | rd(d) | op2(sethi_op2) | hi22(encoded_k) ); // Don't add relocation for 'add'. Do patching during 'sethi' processing. add(d, low10(encoded_k), d); diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/sparc/vm/templateInterpreter_sparc.cpp --- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -259,7 +259,7 @@ } __ ret(); // return from interpreter activation __ delayed()->restore(I5_savedSP, G0, SP); // remove interpreter frame - NOT_PRODUCT(__ emit_long(0);) // marker for disassembly + NOT_PRODUCT(__ emit_int32(0);) // marker for disassembly return entry; } diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/x86/vm/assembler_x86.cpp --- a/src/cpu/x86/vm/assembler_x86.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/x86/vm/assembler_x86.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -182,7 +182,7 @@ // make this go away someday void Assembler::emit_data(jint data, relocInfo::relocType rtype, int format) { if (rtype == relocInfo::none) - emit_long(data); + emit_int32(data); else emit_data(data, Relocation::spec_simple(rtype), format); } @@ -202,7 +202,7 @@ else code_section()->relocate(inst_mark(), rspec, format); } - emit_long(data); + emit_int32(data); } static int encode(Register r) { @@ -243,7 +243,7 @@ } else { emit_int8(op1); emit_int8(op2 | encode(dst)); - emit_long(imm32); + emit_int32(imm32); } } @@ -254,7 +254,7 @@ assert((op1 & 0x02) == 0, "sign-extension bit should not be set"); emit_int8(op1); emit_int8(op2 | encode(dst)); - emit_long(imm32); + emit_int32(imm32); } // immediate-to-memory forms @@ -268,7 +268,7 @@ } else { emit_int8(op1); emit_operand(rm, adr, 4); - emit_long(imm32); + emit_int32(imm32); } } @@ -976,7 +976,7 @@ emit_int8(0x1F); emit_int8((unsigned char)0x80); // emit_rm(cbuf, 0x2, EAX_enc, EAX_enc); - emit_long(0); // 32-bits offset (4 bytes) + emit_int32(0); // 32-bits offset (4 bytes) } void Assembler::addr_nop_8() { @@ -987,7 +987,7 @@ emit_int8((unsigned char)0x84); // emit_rm(cbuf, 0x2, EAX_enc, 0x4); emit_int8(0x00); // emit_rm(cbuf, 0x0, EAX_enc, EAX_enc); - emit_long(0); // 32-bits offset (4 bytes) + emit_int32(0); // 32-bits offset (4 bytes) } void Assembler::addsd(XMMRegister dst, XMMRegister src) { @@ -1076,7 +1076,7 @@ prefix(dst); emit_int8((unsigned char)0x81); emit_operand(rsp, dst, 4); - emit_long(imm32); + emit_int32(imm32); } void Assembler::andl(Register dst, int32_t imm32) { @@ -1204,7 +1204,7 @@ prefix(dst); emit_int8((unsigned char)0x81); emit_operand(rdi, dst, 4); - emit_long(imm32); + emit_int32(imm32); } void Assembler::cmpl(Register dst, int32_t imm32) { @@ -1408,7 +1408,7 @@ } else { emit_int8(0x69); emit_int8((unsigned char)(0xC0 | encode)); - emit_long(value); + emit_int32(value); } } @@ -1440,7 +1440,7 @@ "must be 32bit offset (call4)"); emit_int8(0x0F); emit_int8((unsigned char)(0x80 | cc)); - emit_long(offs - long_size); + emit_int32(offs - long_size); } } else { // Note: could eliminate cond. jumps to this jump if condition @@ -1450,7 +1450,7 @@ L.add_patch_at(code(), locator()); emit_int8(0x0F); emit_int8((unsigned char)(0x80 | cc)); - emit_long(0); + emit_int32(0); } } @@ -1498,7 +1498,7 @@ emit_int8((offs - short_size) & 0xFF); } else { emit_int8((unsigned char)0xE9); - emit_long(offs - long_size); + emit_int32(offs - long_size); } } else { // By default, forward jumps are always 32-bit displacements, since @@ -1508,7 +1508,7 @@ InstructionMark im(this); L.add_patch_at(code(), locator()); emit_int8((unsigned char)0xE9); - emit_long(0); + emit_int32(0); } } @@ -1732,7 +1732,7 @@ void Assembler::movl(Register dst, int32_t imm32) { int encode = prefix_and_encode(dst->encoding()); emit_int8((unsigned char)(0xB8 | encode)); - emit_long(imm32); + emit_int32(imm32); } void Assembler::movl(Register dst, Register src) { @@ -1753,7 +1753,7 @@ prefix(dst); emit_int8((unsigned char)0xC7); emit_operand(rax, dst, 4); - emit_long(imm32); + emit_int32(imm32); } void Assembler::movl(Address dst, Register src) { @@ -2468,6 +2468,26 @@ emit_int8((unsigned char)(0xC0 | encode)); } +void Assembler::vptest(XMMRegister dst, Address src) { + assert(VM_Version::supports_avx(), ""); + InstructionMark im(this); + bool vector256 = true; + assert(dst != xnoreg, "sanity"); + int dst_enc = dst->encoding(); + // swap src<->dst for encoding + vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector256); + emit_int8(0x17); + emit_operand(dst, src); +} + +void Assembler::vptest(XMMRegister dst, XMMRegister src) { + assert(VM_Version::supports_avx(), ""); + bool vector256 = true; + int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, vector256, VEX_OPCODE_0F_38); + emit_int8(0x17); + emit_int8((unsigned char)(0xC0 | encode)); +} + void Assembler::punpcklbw(XMMRegister dst, Address src) { NOT_LP64(assert(VM_Version::supports_sse2(), "")); assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes"); @@ -2499,7 +2519,7 @@ // in 64bits we push 64bits onto the stack but only // take a 32bit immediate emit_int8(0x68); - emit_long(imm32); + emit_int32(imm32); } void Assembler::push(Register src) { @@ -2544,12 +2564,18 @@ emit_int8((unsigned char)0xA5); } +// sets rcx bytes with rax, value at [edi] +void Assembler::rep_stosb() { + emit_int8((unsigned char)0xF3); // REP + LP64_ONLY(prefix(REX_W)); + emit_int8((unsigned char)0xAA); // STOSB +} + // sets rcx pointer sized words with rax, value at [edi] // generic -void Assembler::rep_set() { // rep_set - emit_int8((unsigned char)0xF3); - // STOSQ - LP64_ONLY(prefix(REX_W)); +void Assembler::rep_stos() { + emit_int8((unsigned char)0xF3); // REP + LP64_ONLY(prefix(REX_W)); // LP64:STOSQ, LP32:STOSD emit_int8((unsigned char)0xAB); } @@ -2785,7 +2811,7 @@ emit_int8((unsigned char)0xF7); emit_int8((unsigned char)(0xC0 | encode)); } - emit_long(imm32); + emit_int32(imm32); } void Assembler::testl(Register dst, Register src) { @@ -3650,6 +3676,15 @@ emit_int8(0x01); } +// duplicate 4-bytes integer data from src into 8 locations in dest +void Assembler::vpbroadcastd(XMMRegister dst, XMMRegister src) { + assert(VM_Version::supports_avx2(), ""); + bool vector256 = true; + int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, vector256, VEX_OPCODE_0F_38); + emit_int8(0x58); + emit_int8((unsigned char)(0xC0 | encode)); +} + void Assembler::vzeroupper() { assert(VM_Version::supports_avx(), ""); (void)vex_prefix_and_encode(xmm0, xmm0, xmm0, VEX_SIMD_NONE); @@ -4720,7 +4755,7 @@ prefixq(dst); emit_int8((unsigned char)0x81); emit_operand(rsp, dst, 4); - emit_long(imm32); + emit_int32(imm32); } void Assembler::andq(Register dst, int32_t imm32) { @@ -4793,7 +4828,7 @@ prefixq(dst); emit_int8((unsigned char)0x81); emit_operand(rdi, dst, 4); - emit_long(imm32); + emit_int32(imm32); } void Assembler::cmpq(Register dst, int32_t imm32) { @@ -4932,7 +4967,7 @@ } else { emit_int8(0x69); emit_int8((unsigned char)(0xC0 | encode)); - emit_long(value); + emit_int32(value); } } @@ -5085,7 +5120,7 @@ InstructionMark im(this); int encode = prefixq_and_encode(dst->encoding()); emit_int8((unsigned char)(0xC7 | encode)); - emit_long(imm32); + emit_int32(imm32); } void Assembler::movslq(Address dst, int32_t imm32) { @@ -5094,7 +5129,7 @@ prefixq(dst); emit_int8((unsigned char)0xC7); emit_operand(rax, dst, 4); - emit_long(imm32); + emit_int32(imm32); } void Assembler::movslq(Register dst, Address src) { @@ -5172,7 +5207,7 @@ prefixq(dst); emit_int8((unsigned char)0x81); emit_operand(rcx, dst, 4); - emit_long(imm32); + emit_int32(imm32); } void Assembler::orq(Register dst, int32_t imm32) { @@ -5407,7 +5442,7 @@ emit_int8((unsigned char)0xF7); emit_int8((unsigned char)(0xC0 | encode)); } - emit_long(imm32); + emit_int32(imm32); } void Assembler::testq(Register dst, Register src) { diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/x86/vm/assembler_x86.hpp --- a/src/cpu/x86/vm/assembler_x86.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/x86/vm/assembler_x86.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -832,7 +832,8 @@ // These do register sized moves/scans void rep_mov(); - void rep_set(); + void rep_stos(); + void rep_stosb(); void repne_scan(); #ifdef _LP64 void repne_scanl(); @@ -1443,9 +1444,12 @@ // Shift Right by bytes Logical DoubleQuadword Immediate void psrldq(XMMRegister dst, int shift); - // Logical Compare Double Quadword + // Logical Compare 128bit void ptest(XMMRegister dst, XMMRegister src); void ptest(XMMRegister dst, Address src); + // Logical Compare 256bit + void vptest(XMMRegister dst, XMMRegister src); + void vptest(XMMRegister dst, Address src); // Interleave Low Bytes void punpcklbw(XMMRegister dst, XMMRegister src); @@ -1753,6 +1757,9 @@ void vextractf128h(Address dst, XMMRegister src); void vextracti128h(Address dst, XMMRegister src); + // duplicate 4-bytes integer data from src into 8 locations in dest + void vpbroadcastd(XMMRegister dst, XMMRegister src); + // AVX instruction which is used to clear upper 128 bits of YMM registers and // to avoid transaction penalty between AVX and SSE states. There is no // penalty if legacy SSE instructions are encoded using VEX prefix because diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/x86/vm/globals_x86.hpp --- a/src/cpu/x86/vm/globals_x86.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/x86/vm/globals_x86.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -120,6 +120,9 @@ product(bool, UseUnalignedLoadStores, false, \ "Use SSE2 MOVDQU instruction for Arraycopy") \ \ + product(bool, UseFastStosb, false, \ + "Use fast-string operation for zeroing: rep stosb") \ + \ /* assembler */ \ product(bool, Use486InstrsOnly, false, \ "Use 80486 Compliant instruction subset") \ diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/x86/vm/macroAssembler_x86.cpp --- a/src/cpu/x86/vm/macroAssembler_x86.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/x86/vm/macroAssembler_x86.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -2540,7 +2540,7 @@ // 0000 1111 1000 tttn #32-bit disp emit_int8(0x0F); emit_int8((unsigned char)(0x80 | cc)); - emit_long(offs - long_size); + emit_int32(offs - long_size); } } else { #ifdef ASSERT @@ -5224,6 +5224,22 @@ } +void MacroAssembler::clear_mem(Register base, Register cnt, Register tmp) { + // cnt - number of qwords (8-byte words). + // base - start address, qword aligned. + assert(base==rdi, "base register must be edi for rep stos"); + assert(tmp==rax, "tmp register must be eax for rep stos"); + assert(cnt==rcx, "cnt register must be ecx for rep stos"); + + xorptr(tmp, tmp); + if (UseFastStosb) { + shlptr(cnt,3); // convert to number of bytes + rep_stosb(); + } else { + NOT_LP64(shlptr(cnt,1);) // convert to number of dwords for 32-bit VM + rep_stos(); + } +} // IndexOf for constant substrings with size >= 8 chars // which don't need to be loaded through stack. @@ -5659,42 +5675,114 @@ testl(cnt2, cnt2); jcc(Assembler::zero, LENGTH_DIFF_LABEL); - // Load first characters + // Compare first characters load_unsigned_short(result, Address(str1, 0)); load_unsigned_short(cnt1, Address(str2, 0)); - - // Compare first characters subl(result, cnt1); jcc(Assembler::notZero, POP_LABEL); - decrementl(cnt2); - jcc(Assembler::zero, LENGTH_DIFF_LABEL); - - { - // Check after comparing first character to see if strings are equivalent - Label LSkip2; - // Check if the strings start at same location - cmpptr(str1, str2); - jccb(Assembler::notEqual, LSkip2); - - // Check if the length difference is zero (from stack) - cmpl(Address(rsp, 0), 0x0); - jcc(Assembler::equal, LENGTH_DIFF_LABEL); - - // Strings might not be equivalent - bind(LSkip2); - } + cmpl(cnt2, 1); + jcc(Assembler::equal, LENGTH_DIFF_LABEL); + + // Check if the strings start at the same location. + cmpptr(str1, str2); + jcc(Assembler::equal, LENGTH_DIFF_LABEL); Address::ScaleFactor scale = Address::times_2; int stride = 8; - // Advance to next element - addptr(str1, 16/stride); - addptr(str2, 16/stride); - - if (UseSSE42Intrinsics) { + if (UseAVX >= 2) { + Label COMPARE_WIDE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_WIDE_TAIL, COMPARE_SMALL_STR; + Label COMPARE_WIDE_VECTORS_LOOP, COMPARE_16_CHARS, COMPARE_INDEX_CHAR; + Label COMPARE_TAIL_LONG; + int pcmpmask = 0x19; + + // Setup to compare 16-chars (32-bytes) vectors, + // start from first character again because it has aligned address. + int stride2 = 16; + int adr_stride = stride << scale; + int adr_stride2 = stride2 << scale; + + assert(result == rax && cnt2 == rdx && cnt1 == rcx, "pcmpestri"); + // rax and rdx are used by pcmpestri as elements counters + movl(result, cnt2); + andl(cnt2, ~(stride2-1)); // cnt2 holds the vector count + jcc(Assembler::zero, COMPARE_TAIL_LONG); + + // fast path : compare first 2 8-char vectors. + bind(COMPARE_16_CHARS); + movdqu(vec1, Address(str1, 0)); + pcmpestri(vec1, Address(str2, 0), pcmpmask); + jccb(Assembler::below, COMPARE_INDEX_CHAR); + + movdqu(vec1, Address(str1, adr_stride)); + pcmpestri(vec1, Address(str2, adr_stride), pcmpmask); + jccb(Assembler::aboveEqual, COMPARE_WIDE_VECTORS); + addl(cnt1, stride); + + // Compare the characters at index in cnt1 + bind(COMPARE_INDEX_CHAR); //cnt1 has the offset of the mismatching character + load_unsigned_short(result, Address(str1, cnt1, scale)); + load_unsigned_short(cnt2, Address(str2, cnt1, scale)); + subl(result, cnt2); + jmp(POP_LABEL); + + // Setup the registers to start vector comparison loop + bind(COMPARE_WIDE_VECTORS); + lea(str1, Address(str1, result, scale)); + lea(str2, Address(str2, result, scale)); + subl(result, stride2); + subl(cnt2, stride2); + jccb(Assembler::zero, COMPARE_WIDE_TAIL); + negptr(result); + + // In a loop, compare 16-chars (32-bytes) at once using (vpxor+vptest) + bind(COMPARE_WIDE_VECTORS_LOOP); + vmovdqu(vec1, Address(str1, result, scale)); + vpxor(vec1, Address(str2, result, scale)); + vptest(vec1, vec1); + jccb(Assembler::notZero, VECTOR_NOT_EQUAL); + addptr(result, stride2); + subl(cnt2, stride2); + jccb(Assembler::notZero, COMPARE_WIDE_VECTORS_LOOP); + + // compare wide vectors tail + bind(COMPARE_WIDE_TAIL); + testptr(result, result); + jccb(Assembler::zero, LENGTH_DIFF_LABEL); + + movl(result, stride2); + movl(cnt2, result); + negptr(result); + jmpb(COMPARE_WIDE_VECTORS_LOOP); + + // Identifies the mismatching (higher or lower)16-bytes in the 32-byte vectors. + bind(VECTOR_NOT_EQUAL); + lea(str1, Address(str1, result, scale)); + lea(str2, Address(str2, result, scale)); + jmp(COMPARE_16_CHARS); + + // Compare tail chars, length between 1 to 15 chars + bind(COMPARE_TAIL_LONG); + movl(cnt2, result); + cmpl(cnt2, stride); + jccb(Assembler::less, COMPARE_SMALL_STR); + + movdqu(vec1, Address(str1, 0)); + pcmpestri(vec1, Address(str2, 0), pcmpmask); + jcc(Assembler::below, COMPARE_INDEX_CHAR); + subptr(cnt2, stride); + jccb(Assembler::zero, LENGTH_DIFF_LABEL); + lea(str1, Address(str1, result, scale)); + lea(str2, Address(str2, result, scale)); + negptr(cnt2); + jmpb(WHILE_HEAD_LABEL); + + bind(COMPARE_SMALL_STR); + } else if (UseSSE42Intrinsics) { Label COMPARE_WIDE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL; int pcmpmask = 0x19; - // Setup to compare 16-byte vectors + // Setup to compare 8-char (16-byte) vectors, + // start from first character again because it has aligned address. movl(result, cnt2); andl(cnt2, ~(stride - 1)); // cnt2 holds the vector count jccb(Assembler::zero, COMPARE_TAIL); @@ -5726,7 +5814,7 @@ jccb(Assembler::notZero, COMPARE_WIDE_VECTORS); // compare wide vectors tail - testl(result, result); + testptr(result, result); jccb(Assembler::zero, LENGTH_DIFF_LABEL); movl(cnt2, stride); @@ -5738,21 +5826,20 @@ // Mismatched characters in the vectors bind(VECTOR_NOT_EQUAL); - addptr(result, cnt1); - movptr(cnt2, result); - load_unsigned_short(result, Address(str1, cnt2, scale)); - load_unsigned_short(cnt1, Address(str2, cnt2, scale)); - subl(result, cnt1); + addptr(cnt1, result); + load_unsigned_short(result, Address(str1, cnt1, scale)); + load_unsigned_short(cnt2, Address(str2, cnt1, scale)); + subl(result, cnt2); jmpb(POP_LABEL); bind(COMPARE_TAIL); // limit is zero movl(cnt2, result); // Fallthru to tail compare } - // Shift str2 and str1 to the end of the arrays, negate min - lea(str1, Address(str1, cnt2, scale, 0)); - lea(str2, Address(str2, cnt2, scale, 0)); + lea(str1, Address(str1, cnt2, scale)); + lea(str2, Address(str2, cnt2, scale)); + decrementl(cnt2); // first character was compared already negptr(cnt2); // Compare the rest of the elements @@ -5817,7 +5904,44 @@ shll(limit, 1); // byte count != 0 movl(result, limit); // copy - if (UseSSE42Intrinsics) { + if (UseAVX >= 2) { + // With AVX2, use 32-byte vector compare + Label COMPARE_WIDE_VECTORS, COMPARE_TAIL; + + // Compare 32-byte vectors + andl(result, 0x0000001e); // tail count (in bytes) + andl(limit, 0xffffffe0); // vector count (in bytes) + jccb(Assembler::zero, COMPARE_TAIL); + + lea(ary1, Address(ary1, limit, Address::times_1)); + lea(ary2, Address(ary2, limit, Address::times_1)); + negptr(limit); + + bind(COMPARE_WIDE_VECTORS); + vmovdqu(vec1, Address(ary1, limit, Address::times_1)); + vmovdqu(vec2, Address(ary2, limit, Address::times_1)); + vpxor(vec1, vec2); + + vptest(vec1, vec1); + jccb(Assembler::notZero, FALSE_LABEL); + addptr(limit, 32); + jcc(Assembler::notZero, COMPARE_WIDE_VECTORS); + + testl(result, result); + jccb(Assembler::zero, TRUE_LABEL); + + vmovdqu(vec1, Address(ary1, result, Address::times_1, -32)); + vmovdqu(vec2, Address(ary2, result, Address::times_1, -32)); + vpxor(vec1, vec2); + + vptest(vec1, vec1); + jccb(Assembler::notZero, FALSE_LABEL); + jmpb(TRUE_LABEL); + + bind(COMPARE_TAIL); // limit is zero + movl(limit, result); + // Fallthru to tail compare + } else if (UseSSE42Intrinsics) { // With SSE4.2, use double quad vector compare Label COMPARE_WIDE_VECTORS, COMPARE_TAIL; @@ -5995,29 +6119,53 @@ { assert( UseSSE >= 2, "supported cpu only" ); Label L_fill_32_bytes_loop, L_check_fill_8_bytes, L_fill_8_bytes_loop, L_fill_8_bytes; - // Fill 32-byte chunks movdl(xtmp, value); - pshufd(xtmp, xtmp, 0); - - subl(count, 8 << shift); - jcc(Assembler::less, L_check_fill_8_bytes); - align(16); - - BIND(L_fill_32_bytes_loop); - - if (UseUnalignedLoadStores) { - movdqu(Address(to, 0), xtmp); - movdqu(Address(to, 16), xtmp); + if (UseAVX >= 2 && UseUnalignedLoadStores) { + // Fill 64-byte chunks + Label L_fill_64_bytes_loop, L_check_fill_32_bytes; + vpbroadcastd(xtmp, xtmp); + + subl(count, 16 << shift); + jcc(Assembler::less, L_check_fill_32_bytes); + align(16); + + BIND(L_fill_64_bytes_loop); + vmovdqu(Address(to, 0), xtmp); + vmovdqu(Address(to, 32), xtmp); + addptr(to, 64); + subl(count, 16 << shift); + jcc(Assembler::greaterEqual, L_fill_64_bytes_loop); + + BIND(L_check_fill_32_bytes); + addl(count, 8 << shift); + jccb(Assembler::less, L_check_fill_8_bytes); + vmovdqu(Address(to, 0), xtmp); + addptr(to, 32); + subl(count, 8 << shift); } else { - movq(Address(to, 0), xtmp); - movq(Address(to, 8), xtmp); - movq(Address(to, 16), xtmp); - movq(Address(to, 24), xtmp); + // Fill 32-byte chunks + pshufd(xtmp, xtmp, 0); + + subl(count, 8 << shift); + jcc(Assembler::less, L_check_fill_8_bytes); + align(16); + + BIND(L_fill_32_bytes_loop); + + if (UseUnalignedLoadStores) { + movdqu(Address(to, 0), xtmp); + movdqu(Address(to, 16), xtmp); + } else { + movq(Address(to, 0), xtmp); + movq(Address(to, 8), xtmp); + movq(Address(to, 16), xtmp); + movq(Address(to, 24), xtmp); + } + + addptr(to, 32); + subl(count, 8 << shift); + jcc(Assembler::greaterEqual, L_fill_32_bytes_loop); } - - addptr(to, 32); - subl(count, 8 << shift); - jcc(Assembler::greaterEqual, L_fill_32_bytes_loop); BIND(L_check_fill_8_bytes); addl(count, 8 << shift); jccb(Assembler::zero, L_exit); diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/x86/vm/macroAssembler_x86.hpp --- a/src/cpu/x86/vm/macroAssembler_x86.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/x86/vm/macroAssembler_x86.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -1011,6 +1011,10 @@ Assembler::vxorpd(dst, nds, src, vector256); } + // Simple version for AVX2 256bit vectors + void vpxor(XMMRegister dst, XMMRegister src) { Assembler::vpxor(dst, dst, src, true); } + void vpxor(XMMRegister dst, Address src) { Assembler::vpxor(dst, dst, src, true); } + // Move packed integer values from low 128 bit to hign 128 bit in 256 bit vector. void vinserti128h(XMMRegister dst, XMMRegister nds, XMMRegister src) { if (UseAVX > 1) // vinserti128h is available only in AVX2 @@ -1096,6 +1100,9 @@ // C2 compiled method's prolog code. void verified_entry(int framesize, bool stack_bang, bool fp_mode_24b); + // clear memory of size 'cnt' qwords, starting at 'base'. + void clear_mem(Register base, Register cnt, Register rtmp); + // IndexOf strings. // Small strings are loaded through stack if they cross page boundary. void string_indexof(Register str1, Register str2, diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/x86/vm/stubGenerator_x86_32.cpp --- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -796,16 +796,22 @@ __ align(OptoLoopAlignment); __ BIND(L_copy_64_bytes_loop); - if(UseUnalignedLoadStores) { - __ movdqu(xmm0, Address(from, 0)); - __ movdqu(Address(from, to_from, Address::times_1, 0), xmm0); - __ movdqu(xmm1, Address(from, 16)); - __ movdqu(Address(from, to_from, Address::times_1, 16), xmm1); - __ movdqu(xmm2, Address(from, 32)); - __ movdqu(Address(from, to_from, Address::times_1, 32), xmm2); - __ movdqu(xmm3, Address(from, 48)); - __ movdqu(Address(from, to_from, Address::times_1, 48), xmm3); - + if (UseUnalignedLoadStores) { + if (UseAVX >= 2) { + __ vmovdqu(xmm0, Address(from, 0)); + __ vmovdqu(Address(from, to_from, Address::times_1, 0), xmm0); + __ vmovdqu(xmm1, Address(from, 32)); + __ vmovdqu(Address(from, to_from, Address::times_1, 32), xmm1); + } else { + __ movdqu(xmm0, Address(from, 0)); + __ movdqu(Address(from, to_from, Address::times_1, 0), xmm0); + __ movdqu(xmm1, Address(from, 16)); + __ movdqu(Address(from, to_from, Address::times_1, 16), xmm1); + __ movdqu(xmm2, Address(from, 32)); + __ movdqu(Address(from, to_from, Address::times_1, 32), xmm2); + __ movdqu(xmm3, Address(from, 48)); + __ movdqu(Address(from, to_from, Address::times_1, 48), xmm3); + } } else { __ movq(xmm0, Address(from, 0)); __ movq(Address(from, to_from, Address::times_1, 0), xmm0); diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/x86/vm/stubGenerator_x86_64.cpp --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -1286,23 +1286,54 @@ // end_to - destination array end address // qword_count - 64-bits element count, negative // to - scratch - // L_copy_32_bytes - entry label + // L_copy_bytes - entry label // L_copy_8_bytes - exit label // - void copy_32_bytes_forward(Register end_from, Register end_to, + void copy_bytes_forward(Register end_from, Register end_to, Register qword_count, Register to, - Label& L_copy_32_bytes, Label& L_copy_8_bytes) { + Label& L_copy_bytes, Label& L_copy_8_bytes) { DEBUG_ONLY(__ stop("enter at entry label, not here")); Label L_loop; __ align(OptoLoopAlignment); - __ BIND(L_loop); - if(UseUnalignedLoadStores) { - __ movdqu(xmm0, Address(end_from, qword_count, Address::times_8, -24)); - __ movdqu(Address(end_to, qword_count, Address::times_8, -24), xmm0); - __ movdqu(xmm1, Address(end_from, qword_count, Address::times_8, - 8)); - __ movdqu(Address(end_to, qword_count, Address::times_8, - 8), xmm1); - + if (UseUnalignedLoadStores) { + Label L_end; + // Copy 64-bytes per iteration + __ BIND(L_loop); + if (UseAVX >= 2) { + __ vmovdqu(xmm0, Address(end_from, qword_count, Address::times_8, -56)); + __ vmovdqu(Address(end_to, qword_count, Address::times_8, -56), xmm0); + __ vmovdqu(xmm1, Address(end_from, qword_count, Address::times_8, -24)); + __ vmovdqu(Address(end_to, qword_count, Address::times_8, -24), xmm1); + } else { + __ movdqu(xmm0, Address(end_from, qword_count, Address::times_8, -56)); + __ movdqu(Address(end_to, qword_count, Address::times_8, -56), xmm0); + __ movdqu(xmm1, Address(end_from, qword_count, Address::times_8, -40)); + __ movdqu(Address(end_to, qword_count, Address::times_8, -40), xmm1); + __ movdqu(xmm2, Address(end_from, qword_count, Address::times_8, -24)); + __ movdqu(Address(end_to, qword_count, Address::times_8, -24), xmm2); + __ movdqu(xmm3, Address(end_from, qword_count, Address::times_8, - 8)); + __ movdqu(Address(end_to, qword_count, Address::times_8, - 8), xmm3); + } + __ BIND(L_copy_bytes); + __ addptr(qword_count, 8); + __ jcc(Assembler::lessEqual, L_loop); + __ subptr(qword_count, 4); // sub(8) and add(4) + __ jccb(Assembler::greater, L_end); + // Copy trailing 32 bytes + if (UseAVX >= 2) { + __ vmovdqu(xmm0, Address(end_from, qword_count, Address::times_8, -24)); + __ vmovdqu(Address(end_to, qword_count, Address::times_8, -24), xmm0); + } else { + __ movdqu(xmm0, Address(end_from, qword_count, Address::times_8, -24)); + __ movdqu(Address(end_to, qword_count, Address::times_8, -24), xmm0); + __ movdqu(xmm1, Address(end_from, qword_count, Address::times_8, - 8)); + __ movdqu(Address(end_to, qword_count, Address::times_8, - 8), xmm1); + } + __ addptr(qword_count, 4); + __ BIND(L_end); } else { + // Copy 32-bytes per iteration + __ BIND(L_loop); __ movq(to, Address(end_from, qword_count, Address::times_8, -24)); __ movq(Address(end_to, qword_count, Address::times_8, -24), to); __ movq(to, Address(end_from, qword_count, Address::times_8, -16)); @@ -1311,15 +1342,15 @@ __ movq(Address(end_to, qword_count, Address::times_8, - 8), to); __ movq(to, Address(end_from, qword_count, Address::times_8, - 0)); __ movq(Address(end_to, qword_count, Address::times_8, - 0), to); + + __ BIND(L_copy_bytes); + __ addptr(qword_count, 4); + __ jcc(Assembler::lessEqual, L_loop); } - __ BIND(L_copy_32_bytes); - __ addptr(qword_count, 4); - __ jcc(Assembler::lessEqual, L_loop); __ subptr(qword_count, 4); __ jcc(Assembler::less, L_copy_8_bytes); // Copy trailing qwords } - // Copy big chunks backward // // Inputs: @@ -1327,23 +1358,55 @@ // dest - destination array address // qword_count - 64-bits element count // to - scratch - // L_copy_32_bytes - entry label + // L_copy_bytes - entry label // L_copy_8_bytes - exit label // - void copy_32_bytes_backward(Register from, Register dest, + void copy_bytes_backward(Register from, Register dest, Register qword_count, Register to, - Label& L_copy_32_bytes, Label& L_copy_8_bytes) { + Label& L_copy_bytes, Label& L_copy_8_bytes) { DEBUG_ONLY(__ stop("enter at entry label, not here")); Label L_loop; __ align(OptoLoopAlignment); - __ BIND(L_loop); - if(UseUnalignedLoadStores) { - __ movdqu(xmm0, Address(from, qword_count, Address::times_8, 16)); - __ movdqu(Address(dest, qword_count, Address::times_8, 16), xmm0); - __ movdqu(xmm1, Address(from, qword_count, Address::times_8, 0)); - __ movdqu(Address(dest, qword_count, Address::times_8, 0), xmm1); - + if (UseUnalignedLoadStores) { + Label L_end; + // Copy 64-bytes per iteration + __ BIND(L_loop); + if (UseAVX >= 2) { + __ vmovdqu(xmm0, Address(from, qword_count, Address::times_8, 32)); + __ vmovdqu(Address(dest, qword_count, Address::times_8, 32), xmm0); + __ vmovdqu(xmm1, Address(from, qword_count, Address::times_8, 0)); + __ vmovdqu(Address(dest, qword_count, Address::times_8, 0), xmm1); + } else { + __ movdqu(xmm0, Address(from, qword_count, Address::times_8, 48)); + __ movdqu(Address(dest, qword_count, Address::times_8, 48), xmm0); + __ movdqu(xmm1, Address(from, qword_count, Address::times_8, 32)); + __ movdqu(Address(dest, qword_count, Address::times_8, 32), xmm1); + __ movdqu(xmm2, Address(from, qword_count, Address::times_8, 16)); + __ movdqu(Address(dest, qword_count, Address::times_8, 16), xmm2); + __ movdqu(xmm3, Address(from, qword_count, Address::times_8, 0)); + __ movdqu(Address(dest, qword_count, Address::times_8, 0), xmm3); + } + __ BIND(L_copy_bytes); + __ subptr(qword_count, 8); + __ jcc(Assembler::greaterEqual, L_loop); + + __ addptr(qword_count, 4); // add(8) and sub(4) + __ jccb(Assembler::less, L_end); + // Copy trailing 32 bytes + if (UseAVX >= 2) { + __ vmovdqu(xmm0, Address(from, qword_count, Address::times_8, 0)); + __ vmovdqu(Address(dest, qword_count, Address::times_8, 0), xmm0); + } else { + __ movdqu(xmm0, Address(from, qword_count, Address::times_8, 16)); + __ movdqu(Address(dest, qword_count, Address::times_8, 16), xmm0); + __ movdqu(xmm1, Address(from, qword_count, Address::times_8, 0)); + __ movdqu(Address(dest, qword_count, Address::times_8, 0), xmm1); + } + __ subptr(qword_count, 4); + __ BIND(L_end); } else { + // Copy 32-bytes per iteration + __ BIND(L_loop); __ movq(to, Address(from, qword_count, Address::times_8, 24)); __ movq(Address(dest, qword_count, Address::times_8, 24), to); __ movq(to, Address(from, qword_count, Address::times_8, 16)); @@ -1352,10 +1415,11 @@ __ movq(Address(dest, qword_count, Address::times_8, 8), to); __ movq(to, Address(from, qword_count, Address::times_8, 0)); __ movq(Address(dest, qword_count, Address::times_8, 0), to); + + __ BIND(L_copy_bytes); + __ subptr(qword_count, 4); + __ jcc(Assembler::greaterEqual, L_loop); } - __ BIND(L_copy_32_bytes); - __ subptr(qword_count, 4); - __ jcc(Assembler::greaterEqual, L_loop); __ addptr(qword_count, 4); __ jcc(Assembler::greater, L_copy_8_bytes); // Copy trailing qwords } @@ -1385,7 +1449,7 @@ StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); - Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes; + Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes; Label L_copy_byte, L_exit; const Register from = rdi; // source array address const Register to = rsi; // destination array address @@ -1417,7 +1481,7 @@ __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); __ lea(end_to, Address(to, qword_count, Address::times_8, -8)); __ negptr(qword_count); // make the count negative - __ jmp(L_copy_32_bytes); + __ jmp(L_copy_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); @@ -1460,8 +1524,8 @@ __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); - // Copy in 32-bytes chunks - copy_32_bytes_forward(end_from, end_to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes); + // Copy in multi-bytes chunks + copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes); __ jmp(L_copy_4_bytes); return start; @@ -1488,7 +1552,7 @@ StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); - Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes; + Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes; const Register from = rdi; // source array address const Register to = rsi; // destination array address const Register count = rdx; // elements count @@ -1531,10 +1595,10 @@ // Check for and copy trailing dword __ BIND(L_copy_4_bytes); __ testl(byte_count, 4); - __ jcc(Assembler::zero, L_copy_32_bytes); + __ jcc(Assembler::zero, L_copy_bytes); __ movl(rax, Address(from, qword_count, Address::times_8)); __ movl(Address(to, qword_count, Address::times_8), rax); - __ jmp(L_copy_32_bytes); + __ jmp(L_copy_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); @@ -1549,8 +1613,8 @@ __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); - // Copy in 32-bytes chunks - copy_32_bytes_backward(from, to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes); + // Copy in multi-bytes chunks + copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes); restore_arg_regs(); inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr); // Update counter after rscratch1 is free @@ -1585,7 +1649,7 @@ StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); - Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes,L_copy_2_bytes,L_exit; + Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes,L_copy_2_bytes,L_exit; const Register from = rdi; // source array address const Register to = rsi; // destination array address const Register count = rdx; // elements count @@ -1616,7 +1680,7 @@ __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); __ lea(end_to, Address(to, qword_count, Address::times_8, -8)); __ negptr(qword_count); - __ jmp(L_copy_32_bytes); + __ jmp(L_copy_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); @@ -1652,8 +1716,8 @@ __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); - // Copy in 32-bytes chunks - copy_32_bytes_forward(end_from, end_to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes); + // Copy in multi-bytes chunks + copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes); __ jmp(L_copy_4_bytes); return start; @@ -1700,7 +1764,7 @@ StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); - Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes; + Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes; const Register from = rdi; // source array address const Register to = rsi; // destination array address const Register count = rdx; // elements count @@ -1735,10 +1799,10 @@ // Check for and copy trailing dword __ BIND(L_copy_4_bytes); __ testl(word_count, 2); - __ jcc(Assembler::zero, L_copy_32_bytes); + __ jcc(Assembler::zero, L_copy_bytes); __ movl(rax, Address(from, qword_count, Address::times_8)); __ movl(Address(to, qword_count, Address::times_8), rax); - __ jmp(L_copy_32_bytes); + __ jmp(L_copy_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); @@ -1753,8 +1817,8 @@ __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); - // Copy in 32-bytes chunks - copy_32_bytes_backward(from, to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes); + // Copy in multi-bytes chunks + copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes); restore_arg_regs(); inc_counter_np(SharedRuntime::_jshort_array_copy_ctr); // Update counter after rscratch1 is free @@ -1790,7 +1854,7 @@ StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); - Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes, L_exit; + Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes, L_exit; const Register from = rdi; // source array address const Register to = rsi; // destination array address const Register count = rdx; // elements count @@ -1826,7 +1890,7 @@ __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); __ lea(end_to, Address(to, qword_count, Address::times_8, -8)); __ negptr(qword_count); - __ jmp(L_copy_32_bytes); + __ jmp(L_copy_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); @@ -1853,8 +1917,8 @@ __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); - // Copy 32-bytes chunks - copy_32_bytes_forward(end_from, end_to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes); + // Copy in multi-bytes chunks + copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes); __ jmp(L_copy_4_bytes); return start; @@ -1882,7 +1946,7 @@ StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); - Label L_copy_32_bytes, L_copy_8_bytes, L_copy_2_bytes, L_exit; + Label L_copy_bytes, L_copy_8_bytes, L_copy_2_bytes, L_exit; const Register from = rdi; // source array address const Register to = rsi; // destination array address const Register count = rdx; // elements count @@ -1916,10 +1980,10 @@ // Check for and copy trailing dword __ testl(dword_count, 1); - __ jcc(Assembler::zero, L_copy_32_bytes); + __ jcc(Assembler::zero, L_copy_bytes); __ movl(rax, Address(from, dword_count, Address::times_4, -4)); __ movl(Address(to, dword_count, Address::times_4, -4), rax); - __ jmp(L_copy_32_bytes); + __ jmp(L_copy_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); @@ -1937,8 +2001,8 @@ __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); - // Copy in 32-bytes chunks - copy_32_bytes_backward(from, to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes); + // Copy in multi-bytes chunks + copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes); __ bind(L_exit); if (is_oop) { @@ -1976,7 +2040,7 @@ StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); - Label L_copy_32_bytes, L_copy_8_bytes, L_exit; + Label L_copy_bytes, L_copy_8_bytes, L_exit; const Register from = rdi; // source array address const Register to = rsi; // destination array address const Register qword_count = rdx; // elements count @@ -2008,7 +2072,7 @@ __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); __ lea(end_to, Address(to, qword_count, Address::times_8, -8)); __ negptr(qword_count); - __ jmp(L_copy_32_bytes); + __ jmp(L_copy_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); @@ -2027,8 +2091,8 @@ __ ret(0); } - // Copy 64-byte chunks - copy_32_bytes_forward(end_from, end_to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes); + // Copy in multi-bytes chunks + copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes); if (is_oop) { __ BIND(L_exit); @@ -2065,7 +2129,7 @@ StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); - Label L_copy_32_bytes, L_copy_8_bytes, L_exit; + Label L_copy_bytes, L_copy_8_bytes, L_exit; const Register from = rdi; // source array address const Register to = rsi; // destination array address const Register qword_count = rdx; // elements count @@ -2091,7 +2155,7 @@ gen_write_ref_array_pre_barrier(to, saved_count, dest_uninitialized); } - __ jmp(L_copy_32_bytes); + __ jmp(L_copy_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); @@ -2110,8 +2174,8 @@ __ ret(0); } - // Copy in 32-bytes chunks - copy_32_bytes_backward(from, to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes); + // Copy in multi-bytes chunks + copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes); if (is_oop) { __ BIND(L_exit); diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/x86/vm/vm_version_x86.cpp --- a/src/cpu/x86/vm/vm_version_x86.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/x86/vm/vm_version_x86.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -429,7 +429,7 @@ } char buf[256]; - jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", cores_per_cpu(), threads_per_core(), cpu_family(), _model, _stepping, (supports_cmov() ? ", cmov" : ""), @@ -446,6 +446,7 @@ (supports_avx() ? ", avx" : ""), (supports_avx2() ? ", avx2" : ""), (supports_aes() ? ", aes" : ""), + (supports_erms() ? ", erms" : ""), (supports_mmx_ext() ? ", mmxext" : ""), (supports_3dnow_prefetch() ? ", 3dnowpref" : ""), (supports_lzcnt() ? ", lzcnt": ""), @@ -671,6 +672,16 @@ FLAG_SET_DEFAULT(UsePopCountInstruction, false); } + // Use fast-string operations if available. + if (supports_erms()) { + if (FLAG_IS_DEFAULT(UseFastStosb)) { + UseFastStosb = true; + } + } else if (UseFastStosb) { + warning("fast-string operations are not available on this CPU"); + FLAG_SET_DEFAULT(UseFastStosb, false); + } + #ifdef COMPILER2 if (FLAG_IS_DEFAULT(AlignVector)) { // Modern processors allow misaligned memory operations for vectors. diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/x86/vm/vm_version_x86.hpp --- a/src/cpu/x86/vm/vm_version_x86.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/x86/vm/vm_version_x86.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -204,7 +204,8 @@ avx2 : 1, : 2, bmi2 : 1, - : 23; + erms : 1, + : 22; } bits; }; @@ -247,7 +248,8 @@ CPU_TSCINV = (1 << 16), CPU_AVX = (1 << 17), CPU_AVX2 = (1 << 18), - CPU_AES = (1 << 19) + CPU_AES = (1 << 19), + CPU_ERMS = (1 << 20) // enhanced 'rep movsb/stosb' instructions } cpuFeatureFlags; enum { @@ -425,6 +427,8 @@ result |= CPU_TSCINV; if (_cpuid_info.std_cpuid1_ecx.bits.aes != 0) result |= CPU_AES; + if (_cpuid_info.sef_cpuid7_ebx.bits.erms != 0) + result |= CPU_ERMS; // AMD features. if (is_amd()) { @@ -489,7 +493,7 @@ return (_cpuid_info.std_max_function >= 0xB) && // eax[4:0] | ebx[0:15] == 0 indicates invalid topology level. // Some cpus have max cpuid >= 0xB but do not support processor topology. - ((_cpuid_info.tpl_cpuidB0_eax & 0x1f | _cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus) != 0); + (((_cpuid_info.tpl_cpuidB0_eax & 0x1f) | _cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus) != 0); } static uint cores_per_cpu() { @@ -550,6 +554,7 @@ static bool supports_avx2() { return (_cpuFeatures & CPU_AVX2) != 0; } static bool supports_tsc() { return (_cpuFeatures & CPU_TSC) != 0; } static bool supports_aes() { return (_cpuFeatures & CPU_AES) != 0; } + static bool supports_erms() { return (_cpuFeatures & CPU_ERMS) != 0; } // Intel features static bool is_intel_family_core() { return is_intel() && diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/x86/vm/x86_32.ad --- a/src/cpu/x86/vm/x86_32.ad Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/x86/vm/x86_32.ad Fri Jan 18 14:15:51 2013 +0100 @@ -11572,15 +11572,28 @@ // ======================================================================= // fast clearing of an array instruct rep_stos(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlagsReg cr) %{ + predicate(!UseFastStosb); match(Set dummy (ClearArray cnt base)); effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); - format %{ "SHL ECX,1\t# Convert doublewords to words\n\t" - "XOR EAX,EAX\n\t" + format %{ "XOR EAX,EAX\t# ClearArray:\n\t" + "SHL ECX,1\t# Convert doublewords to words\n\t" "REP STOS\t# store EAX into [EDI++] while ECX--" %} - opcode(0,0x4); - ins_encode( Opcode(0xD1), RegOpc(ECX), - OpcRegReg(0x33,EAX,EAX), - Opcode(0xF3), Opcode(0xAB) ); + ins_encode %{ + __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); + %} + ins_pipe( pipe_slow ); +%} + +instruct rep_fast_stosb(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlagsReg cr) %{ + predicate(UseFastStosb); + match(Set dummy (ClearArray cnt base)); + effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); + format %{ "XOR EAX,EAX\t# ClearArray:\n\t" + "SHL ECX,3\t# Convert doublewords to bytes\n\t" + "REP STOSB\t# store EAX into [EDI++] while ECX--" %} + ins_encode %{ + __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); + %} ins_pipe( pipe_slow ); %} diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/x86/vm/x86_64.ad --- a/src/cpu/x86/vm/x86_64.ad Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/x86/vm/x86_64.ad Fri Jan 18 14:15:51 2013 +0100 @@ -10374,16 +10374,33 @@ instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, rFlagsReg cr) %{ + predicate(!UseFastStosb); match(Set dummy (ClearArray cnt base)); effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); - format %{ "xorl rax, rax\t# ClearArray:\n\t" - "rep stosq\t# Store rax to *rdi++ while rcx--" %} - ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax - Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos + format %{ "xorq rax, rax\t# ClearArray:\n\t" + "rep stosq\t# Store rax to *rdi++ while rcx--" %} + ins_encode %{ + __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); + %} ins_pipe(pipe_slow); %} +instruct rep_fast_stosb(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, + rFlagsReg cr) +%{ + predicate(UseFastStosb); + match(Set dummy (ClearArray cnt base)); + effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); + format %{ "xorq rax, rax\t# ClearArray:\n\t" + "shlq rcx,3\t# Convert doublewords to bytes\n\t" + "rep stosb\t# Store rax to *rdi++ while rcx--" %} + ins_encode %{ + __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); + %} + ins_pipe( pipe_slow ); +%} + instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, rax_RegI result, regD tmp1, rFlagsReg cr) %{ diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/zero/vm/frame_zero.cpp --- a/src/cpu/zero/vm/frame_zero.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/zero/vm/frame_zero.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -98,10 +98,20 @@ #endif // CC_INTERP void frame::patch_pc(Thread* thread, address pc) { - // We borrow this call to set the thread pointer in the interpreter - // state; the hook to set up deoptimized frames isn't supplied it. - assert(pc == NULL, "should be"); - get_interpreterState()->set_thread((JavaThread *) thread); + + if (pc != NULL) { + _cb = CodeCache::find_blob(pc); + SharkFrame* sharkframe = zeroframe()->as_shark_frame(); + sharkframe->set_pc(pc); + _pc = pc; + _deopt_state = is_deoptimized; + + } else { + // We borrow this call to set the thread pointer in the interpreter + // state; the hook to set up deoptimized frames isn't supplied it. + assert(pc == NULL, "should be"); + get_interpreterState()->set_thread((JavaThread *) thread); + } } bool frame::safe_for_sender(JavaThread *thread) { diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/zero/vm/frame_zero.inline.hpp --- a/src/cpu/zero/vm/frame_zero.inline.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/zero/vm/frame_zero.inline.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -45,27 +45,36 @@ case ZeroFrame::ENTRY_FRAME: _pc = StubRoutines::call_stub_return_pc(); _cb = NULL; + _deopt_state = not_deoptimized; break; case ZeroFrame::INTERPRETER_FRAME: _pc = NULL; _cb = NULL; + _deopt_state = not_deoptimized; break; - case ZeroFrame::SHARK_FRAME: + case ZeroFrame::SHARK_FRAME: { _pc = zero_sharkframe()->pc(); _cb = CodeCache::find_blob_unsafe(pc()); + address original_pc = nmethod::get_deopt_original_pc(this); + if (original_pc != NULL) { + _pc = original_pc; + _deopt_state = is_deoptimized; + } else { + _deopt_state = not_deoptimized; + } break; - + } case ZeroFrame::FAKE_STUB_FRAME: _pc = NULL; _cb = NULL; + _deopt_state = not_deoptimized; break; default: ShouldNotReachHere(); } - _deopt_state = not_deoptimized; } // Accessors diff -r e94ed1591b42 -r 557bda927cc2 src/cpu/zero/vm/sharkFrame_zero.hpp --- a/src/cpu/zero/vm/sharkFrame_zero.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/cpu/zero/vm/sharkFrame_zero.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -68,6 +68,10 @@ return (address) value_of_word(pc_off); } + void set_pc(address pc) const { + *((address*) addr_of_word(pc_off)) = pc; + } + intptr_t* unextended_sp() const { return (intptr_t *) value_of_word(unextended_sp_off); } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/asm/assembler.hpp --- a/src/share/vm/asm/assembler.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/asm/assembler.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -216,8 +216,6 @@ bool isByte(int x) const { return 0 <= x && x < 0x100; } bool isShiftCount(int x) const { return 0 <= x && x < 32; } - void emit_long(jint x) { emit_int32(x); } // deprecated - // Instruction boundaries (required when emitting relocatable values). class InstructionMark: public StackObj { private: diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/c1/c1_GraphBuilder.cpp --- a/src/share/vm/c1/c1_GraphBuilder.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -3223,7 +3223,12 @@ } if (try_inline_full(callee, holder_known, bc, receiver)) return true; - print_inlining(callee, _inline_bailout_msg, /*success*/ false); + + // Entire compilation could fail during try_inline_full call. + // In that case printing inlining decision info is useless. + if (!bailed_out()) + print_inlining(callee, _inline_bailout_msg, /*success*/ false); + return false; } @@ -3753,7 +3758,8 @@ push_scope(callee, cont); // the BlockListBuilder for the callee could have bailed out - CHECK_BAILOUT_(false); + if (bailed_out()) + return false; // Temporarily set up bytecode stream so we can append instructions // (only using the bci of this stream) @@ -3819,7 +3825,8 @@ iterate_all_blocks(callee_start_block == NULL); // If we bailed out during parsing, return immediately (this is bad news) - if (bailed_out()) return false; + if (bailed_out()) + return false; // iterate_all_blocks theoretically traverses in random order; in // practice, we have only traversed the continuation if we are @@ -3828,9 +3835,6 @@ !continuation()->is_set(BlockBegin::was_visited_flag), "continuation should not have been parsed yet if we created it"); - // If we bailed out during parsing, return immediately (this is bad news) - CHECK_BAILOUT_(false); - // At this point we are almost ready to return and resume parsing of // the caller back in the GraphBuilder. The only thing we want to do // first is an optimization: during parsing of the callee we @@ -4171,7 +4175,10 @@ else log->inline_success("receiver is statically known"); } else { - log->inline_fail(msg); + if (msg != NULL) + log->inline_fail(msg); + else + log->inline_fail("reason unknown"); } } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/c1/c1_LIR.hpp --- a/src/share/vm/c1/c1_LIR.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/c1/c1_LIR.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -2259,7 +2259,7 @@ typedef enum { inputMode, firstMode = inputMode, tempMode, outputMode, numModes, invalidMode = -1 } OprMode; enum { - maxNumberOfOperands = 16, + maxNumberOfOperands = 20, maxNumberOfInfos = 4 }; diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/c1/c1_globals.hpp --- a/src/share/vm/c1/c1_globals.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/c1/c1_globals.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -147,7 +147,7 @@ "Inline methods containing exception handlers " \ "(NOTE: does not work with current backend)") \ \ - develop(bool, InlineSynchronizedMethods, true, \ + product(bool, InlineSynchronizedMethods, true, \ "Inline synchronized methods") \ \ develop(bool, InlineNIOCheckIndex, true, \ diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/ci/ciType.cpp --- a/src/share/vm/ci/ciType.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/ci/ciType.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -60,6 +60,19 @@ } // ------------------------------------------------------------------ +// ciType::name +// +// Return the name of this type +const char* ciType::name() { + if (is_primitive_type()) { + return type2name(basic_type()); + } else { + assert(is_klass(), "must be"); + return as_klass()->name()->as_utf8(); + } +} + +// ------------------------------------------------------------------ // ciType::print_impl // // Implementation of the print method. @@ -73,7 +86,8 @@ // // Print the name of this type void ciType::print_name_on(outputStream* st) { - st->print(type2name(basic_type())); + ResourceMark rm; + st->print(name()); } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/ci/ciType.hpp --- a/src/share/vm/ci/ciType.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/ci/ciType.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -77,6 +77,7 @@ bool is_type() const { return true; } bool is_classless() const { return is_primitive_type(); } + const char* name(); virtual void print_name_on(outputStream* st); void print_name() { print_name_on(tty); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/classfile/classFileParser.cpp --- a/src/share/vm/classfile/classFileParser.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/classfile/classFileParser.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -2503,26 +2503,38 @@ *has_default_methods = true; } methods->at_put(index, method()); - if (*methods_annotations == NULL) { - *methods_annotations = - MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + + if (method_annotations != NULL) { + if (*methods_annotations == NULL) { + *methods_annotations = + MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + } + (*methods_annotations)->at_put(index, method_annotations); } - (*methods_annotations)->at_put(index, method_annotations); - if (*methods_parameter_annotations == NULL) { - *methods_parameter_annotations = - MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + + if (method_parameter_annotations != NULL) { + if (*methods_parameter_annotations == NULL) { + *methods_parameter_annotations = + MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + } + (*methods_parameter_annotations)->at_put(index, method_parameter_annotations); } - (*methods_parameter_annotations)->at_put(index, method_parameter_annotations); - if (*methods_default_annotations == NULL) { - *methods_default_annotations = - MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + + if (method_default_annotations != NULL) { + if (*methods_default_annotations == NULL) { + *methods_default_annotations = + MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + } + (*methods_default_annotations)->at_put(index, method_default_annotations); } - (*methods_default_annotations)->at_put(index, method_default_annotations); - if (*methods_type_annotations == NULL) { - *methods_type_annotations = - MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + + if (method_type_annotations != NULL) { + if (*methods_type_annotations == NULL) { + *methods_type_annotations = + MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + } + (*methods_type_annotations)->at_put(index, method_type_annotations); } - (*methods_type_annotations)->at_put(index, method_type_annotations); } if (_need_verify && length > 1) { @@ -3338,8 +3350,7 @@ bool has_final_method = false; AccessFlags promoted_flags; promoted_flags.set_flags(0); - // These need to be oop pointers because they are allocated lazily - // inside parse_methods inside a nested HandleMark + Array* methods_annotations = NULL; Array* methods_parameter_annotations = NULL; Array* methods_default_annotations = NULL; diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/classfile/classLoaderData.cpp --- a/src/share/vm/classfile/classLoaderData.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/classfile/classLoaderData.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -318,6 +318,7 @@ } Metaspace* ClassLoaderData::metaspace_non_null() { + assert(!DumpSharedSpaces, "wrong metaspace!"); // If the metaspace has not been allocated, create a new one. Might want // to create smaller arena for Reflection class loaders also. // The reason for the delayed allocation is because some class loaders are @@ -330,10 +331,19 @@ } if (this == the_null_class_loader_data()) { assert (class_loader() == NULL, "Must be"); - size_t word_size = Metaspace::first_chunk_word_size(); - set_metaspace(new Metaspace(_metaspace_lock, word_size)); + set_metaspace(new Metaspace(_metaspace_lock, Metaspace::BootMetaspaceType)); + } else if (is_anonymous()) { + if (TraceClassLoaderData && Verbose && class_loader() != NULL) { + tty->print_cr("is_anonymous: %s", class_loader()->klass()->internal_name()); + } + set_metaspace(new Metaspace(_metaspace_lock, Metaspace::AnonymousMetaspaceType)); + } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) { + if (TraceClassLoaderData && Verbose && class_loader() != NULL) { + tty->print_cr("is_reflection: %s", class_loader()->klass()->internal_name()); + } + set_metaspace(new Metaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType)); } else { - set_metaspace(new Metaspace(_metaspace_lock)); // default size for now. + set_metaspace(new Metaspace(_metaspace_lock, Metaspace::StandardMetaspaceType)); } } return _metaspace; @@ -672,8 +682,8 @@ "only supported for null loader data for now"); assert (!_shared_metaspaces_initialized, "only initialize once"); MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag); - _ro_metaspace = new Metaspace(_metaspace_lock, SharedReadOnlySize/wordSize); - _rw_metaspace = new Metaspace(_metaspace_lock, SharedReadWriteSize/wordSize); + _ro_metaspace = new Metaspace(_metaspace_lock, Metaspace::ROMetaspaceType); + _rw_metaspace = new Metaspace(_metaspace_lock, Metaspace::ReadWriteMetaspaceType); _shared_metaspaces_initialized = true; } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/classfile/classLoaderData.hpp --- a/src/share/vm/classfile/classLoaderData.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/classfile/classLoaderData.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -8,7 +8,7 @@ * * 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 + * 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). * diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/classfile/defaultMethods.cpp --- a/src/share/vm/classfile/defaultMethods.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/classfile/defaultMethods.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -1285,13 +1285,15 @@ enum { ANNOTATIONS, PARAMETERS, DEFAULTS, NUM_ARRAYS }; - Array* original_annots[NUM_ARRAYS]; + Array* original_annots[NUM_ARRAYS] = { NULL }; Array* original_methods = klass->methods(); Annotations* annots = klass->annotations(); - original_annots[ANNOTATIONS] = annots->methods_annotations(); - original_annots[PARAMETERS] = annots->methods_parameter_annotations(); - original_annots[DEFAULTS] = annots->methods_default_annotations(); + if (annots != NULL) { + original_annots[ANNOTATIONS] = annots->methods_annotations(); + original_annots[PARAMETERS] = annots->methods_parameter_annotations(); + original_annots[DEFAULTS] = annots->methods_default_annotations(); + } Array* original_ordering = klass->method_ordering(); Array* merged_ordering = Universe::the_empty_int_array(); @@ -1370,9 +1372,15 @@ // Replace klass methods with new merged lists klass->set_methods(merged_methods); - annots->set_methods_annotations(merged_annots[ANNOTATIONS]); - annots->set_methods_parameter_annotations(merged_annots[PARAMETERS]); - annots->set_methods_default_annotations(merged_annots[DEFAULTS]); + if (annots != NULL) { + annots->set_methods_annotations(merged_annots[ANNOTATIONS]); + annots->set_methods_parameter_annotations(merged_annots[PARAMETERS]); + annots->set_methods_default_annotations(merged_annots[DEFAULTS]); + } else { + assert(merged_annots[ANNOTATIONS] == NULL, "Must be"); + assert(merged_annots[PARAMETERS] == NULL, "Must be"); + assert(merged_annots[DEFAULTS] == NULL, "Must be"); + } ClassLoaderData* cld = klass->class_loader_data(); MetadataFactory::free_array(cld, original_methods); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/classfile/javaClasses.cpp --- a/src/share/vm/classfile/javaClasses.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/classfile/javaClasses.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -687,19 +687,6 @@ } -Method* java_lang_Class::resolved_constructor(oop java_class) { - Metadata* constructor = java_class->metadata_field(_resolved_constructor_offset); - assert(constructor == NULL || constructor->is_method(), "should be method"); - return ((Method*)constructor); -} - - -void java_lang_Class::set_resolved_constructor(oop java_class, Method* constructor) { - assert(constructor->is_method(), "should be method"); - java_class->metadata_field_put(_resolved_constructor_offset, constructor); -} - - bool java_lang_Class::is_primitive(oop java_class) { // should assert: //assert(java_lang_Class::is_instance(java_class), "must be a Class object"); @@ -2949,7 +2936,6 @@ int java_lang_Class::_klass_offset; int java_lang_Class::_array_klass_offset; -int java_lang_Class::_resolved_constructor_offset; int java_lang_Class::_oop_size_offset; int java_lang_Class::_static_oop_field_count_offset; GrowableArray* java_lang_Class::_fixup_mirror_list = NULL; @@ -3303,7 +3289,6 @@ // Fake fields // CHECK_OFFSET("java/lang/Class", java_lang_Class, klass); // %%% this needs to be checked // CHECK_OFFSET("java/lang/Class", java_lang_Class, array_klass); // %%% this needs to be checked - // CHECK_OFFSET("java/lang/Class", java_lang_Class, resolved_constructor); // %%% this needs to be checked // java.lang.Throwable diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/classfile/javaClasses.hpp --- a/src/share/vm/classfile/javaClasses.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/classfile/javaClasses.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -206,7 +206,6 @@ #define CLASS_INJECTED_FIELDS(macro) \ macro(java_lang_Class, klass, intptr_signature, false) \ - macro(java_lang_Class, resolved_constructor, intptr_signature, false) \ macro(java_lang_Class, array_klass, intptr_signature, false) \ macro(java_lang_Class, oop_size, int_signature, false) \ macro(java_lang_Class, static_oop_field_count, int_signature, false) @@ -218,7 +217,6 @@ // The fake offsets are added by the class loader when java.lang.Class is loaded static int _klass_offset; - static int _resolved_constructor_offset; static int _array_klass_offset; static int _oop_size_offset; @@ -254,15 +252,11 @@ static bool is_primitive(oop java_class); static BasicType primitive_type(oop java_class); static oop primitive_mirror(BasicType t); - // JVM_NewInstance support - static Method* resolved_constructor(oop java_class); - static void set_resolved_constructor(oop java_class, Method* constructor); // JVM_NewArray support static Klass* array_klass(oop java_class); static void set_array_klass(oop java_class, Klass* klass); // compiler support for class operations static int klass_offset_in_bytes() { return _klass_offset; } - static int resolved_constructor_offset_in_bytes() { return _resolved_constructor_offset; } static int array_klass_offset_in_bytes() { return _array_klass_offset; } // Support for classRedefinedCount field static int classRedefinedCount(oop the_class_mirror); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/classfile/vmSymbols.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -386,7 +386,6 @@ template(basicType_name, "basicType") \ template(append_name, "append") \ template(klass_name, "klass") \ - template(resolved_constructor_name, "resolved_constructor") \ template(array_klass_name, "array_klass") \ template(oop_size_name, "oop_size") \ template(static_oop_field_count_name, "static_oop_field_count") \ diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/code/codeCache.cpp --- a/src/share/vm/code/codeCache.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/code/codeCache.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -30,6 +30,7 @@ #include "code/icBuffer.hpp" #include "code/nmethod.hpp" #include "code/pcDesc.hpp" +#include "compiler/compileBroker.hpp" #include "gc_implementation/shared/markSweep.hpp" #include "memory/allocation.inline.hpp" #include "memory/gcLocker.hpp" @@ -39,6 +40,7 @@ #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" +#include "runtime/arguments.hpp" #include "runtime/icache.hpp" #include "runtime/java.hpp" #include "runtime/mutexLocker.hpp" @@ -168,6 +170,8 @@ return (nmethod*)cb; } +static size_t maxCodeCacheUsed = 0; + CodeBlob* CodeCache::allocate(int size) { // Do not seize the CodeCache lock here--if the caller has not // already done so, we are going to lose bigtime, since the code @@ -192,6 +196,8 @@ (address)_heap->end() - (address)_heap->begin()); } } + maxCodeCacheUsed = MAX2(maxCodeCacheUsed, ((address)_heap->high_boundary() - + (address)_heap->low_boundary()) - unallocated_capacity()); verify_if_often(); print_trace("allocation", cb, size); return cb; @@ -928,7 +934,14 @@ FREE_C_HEAP_ARRAY(int, buckets, mtCode); } +#endif // !PRODUCT + void CodeCache::print() { + print_summary(tty); + +#ifndef PRODUCT + if (!Verbose) return; + CodeBlob_sizes live; CodeBlob_sizes dead; @@ -953,7 +966,7 @@ } - if (Verbose) { + if (WizardMode) { // print the oop_map usage int code_size = 0; int number_of_blobs = 0; @@ -977,20 +990,30 @@ tty->print_cr(" map size = %d", map_size); } +#endif // !PRODUCT } -#endif // PRODUCT +void CodeCache::print_summary(outputStream* st, bool detailed) { + size_t total = (_heap->high_boundary() - _heap->low_boundary()); + st->print_cr("CodeCache: size=" SIZE_FORMAT "Kb used=" SIZE_FORMAT + "Kb max_used=" SIZE_FORMAT "Kb free=" SIZE_FORMAT + "Kb max_free_chunk=" SIZE_FORMAT "Kb", + total/K, (total - unallocated_capacity())/K, + maxCodeCacheUsed/K, unallocated_capacity()/K, largest_free_block()/K); -void CodeCache::print_bounds(outputStream* st) { - st->print_cr("Code Cache [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")", - _heap->low_boundary(), - _heap->high(), - _heap->high_boundary()); - st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT - " adapters=" UINT32_FORMAT " free_code_cache=" SIZE_FORMAT "Kb" - " largest_free_block=" SIZE_FORMAT, - nof_blobs(), nof_nmethods(), nof_adapters(), - unallocated_capacity()/K, largest_free_block()); + if (detailed) { + st->print_cr(" bounds [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT "]", + _heap->low_boundary(), + _heap->high(), + _heap->high_boundary()); + st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT + " adapters=" UINT32_FORMAT, + nof_blobs(), nof_nmethods(), nof_adapters()); + st->print_cr(" compilation: %s", CompileBroker::should_compile_new_jobs() ? + "enabled" : Arguments::mode() == Arguments::_int ? + "disabled (interpreter mode)" : + "disabled (not enough contiguous free space left)"); + } } void CodeCache::log_state(outputStream* st) { diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/code/codeCache.hpp --- a/src/share/vm/code/codeCache.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/code/codeCache.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -145,11 +145,11 @@ static void prune_scavenge_root_nmethods(); // Printing/debugging - static void print() PRODUCT_RETURN; // prints summary + static void print(); // prints summary static void print_internals(); static void verify(); // verifies the code cache static void print_trace(const char* event, CodeBlob* cb, int size = 0) PRODUCT_RETURN; - static void print_bounds(outputStream* st); // Prints a summary of the bounds of the code cache + static void print_summary(outputStream* st, bool detailed = true); // Prints a summary of the code cache usage static void log_state(outputStream* st); // The full limits of the codeCache diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/compiler/abstractCompiler.hpp --- a/src/share/vm/compiler/abstractCompiler.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/compiler/abstractCompiler.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -50,6 +50,7 @@ // Missing feature tests virtual bool supports_native() { return true; } virtual bool supports_osr () { return true; } + virtual bool can_compile_method(methodHandle method) { return true; } #if defined(TIERED) || ( !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK)) virtual bool is_c1 () { return false; } virtual bool is_c2 () { return false; } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/compiler/compileBroker.cpp --- a/src/share/vm/compiler/compileBroker.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/compiler/compileBroker.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -1218,7 +1218,7 @@ // lock, make sure that the compilation // isn't prohibited in a straightforward way. - if (compiler(comp_level) == NULL || compilation_is_prohibited(method, osr_bci, comp_level)) { + if (compiler(comp_level) == NULL || !compiler(comp_level)->can_compile_method(method) || compilation_is_prohibited(method, osr_bci, comp_level)) { return NULL; } @@ -1714,6 +1714,20 @@ } } +// wrapper for CodeCache::print_summary() +static void codecache_print(bool detailed) +{ + ResourceMark rm; + stringStream s; + // Dump code cache into a buffer before locking the tty, + { + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + CodeCache::print_summary(&s, detailed); + } + ttyLocker ttyl; + tty->print_cr(s.as_string()); +} + // ------------------------------------------------------------------ // CompileBroker::invoke_compiler_on_method // @@ -1841,6 +1855,9 @@ tty->print_cr("size: %d time: %d inlined: %d bytes", code_size, (int)time.milliseconds(), task->num_inlined_bytecodes()); } + if (PrintCodeCacheOnCompilation) + codecache_print(/* detailed= */ false); + // Disable compilation, if required. switch (compilable) { case ciEnv::MethodCompilable_never: @@ -1885,6 +1902,7 @@ UseInterpreter = true; if (UseCompiler || AlwaysCompileLoopMethods ) { if (xtty != NULL) { + ResourceMark rm; stringStream s; // Dump code cache state into a buffer before locking the tty, // because log_state() will use locks causing lock conflicts. @@ -1898,9 +1916,9 @@ } warning("CodeCache is full. Compiler has been disabled."); warning("Try increasing the code cache size using -XX:ReservedCodeCacheSize="); - CodeCache::print_bounds(tty); #ifndef PRODUCT if (CompileTheWorld || ExitOnFullCodeCache) { + codecache_print(/* detailed= */ true); before_exit(JavaThread::current()); exit_globals(); // will delete tty vm_direct_exit(CompileTheWorld ? 0 : 1); @@ -1913,6 +1931,7 @@ AlwaysCompileLoopMethods = false; } } + codecache_print(/* detailed= */ true); } // ------------------------------------------------------------------ diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -56,7 +56,7 @@ if (_generations == NULL) vm_exit_during_initialization("Unable to allocate gen spec"); - if (ParNewGeneration::in_use()) { + if (UseParNewGC) { if (UseAdaptiveSizePolicy) { _generations[0] = new GenerationSpec(Generation::ASParNew, _initial_gen0_size, _max_gen0_size); @@ -96,7 +96,7 @@ void ConcurrentMarkSweepPolicy::initialize_gc_policy_counters() { // initialize the policy counters - 2 collectors, 3 generations - if (ParNewGeneration::in_use()) { + if (UseParNewGC) { _gc_policy_counters = new GCPolicyCounters("ParNew:CMS", 2, 3); } else { @@ -119,7 +119,7 @@ assert(size_policy() != NULL, "A size policy is required"); // initialize the policy counters - 2 collectors, 3 generations - if (ParNewGeneration::in_use()) { + if (UseParNewGC) { _gc_policy_counters = new CMSGCAdaptivePolicyCounters("ParNew:CMS", 2, 3, size_policy()); } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -214,7 +214,6 @@ assert(q->forwardee() == NULL, "should be forwarded to NULL"); } - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(q, adjusted_size)); compact_top += adjusted_size; // we need to update the offset table so that the beginnings of objects can be diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -827,10 +827,10 @@ GenCollectedHeap* gch = GenCollectedHeap::heap(); if (PrintGCDetails) { if (Verbose) { - gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"("SIZE_FORMAT")]", + gclog_or_tty->print("[%d %s-%s: "SIZE_FORMAT"("SIZE_FORMAT")]", level(), short_name(), s, used(), capacity()); } else { - gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"K("SIZE_FORMAT"K)]", + gclog_or_tty->print("[%d %s-%s: "SIZE_FORMAT"K("SIZE_FORMAT"K)]", level(), short_name(), s, used() / K, capacity() / K); } } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/g1/collectionSetChooser.cpp --- a/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -85,7 +85,7 @@ _curr_index(0), _length(0), _first_par_unreserved_idx(0), _region_live_threshold_bytes(0), _remaining_reclaimable_bytes(0) { _region_live_threshold_bytes = - HeapRegion::GrainBytes * (size_t) G1OldCSetRegionLiveThresholdPercent / 100; + HeapRegion::GrainBytes * (size_t) G1MixedGCLiveThresholdPercent / 100; } #ifndef PRODUCT diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/g1/concurrentMark.cpp --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -192,6 +192,7 @@ setEmpty(); _capacity = (jint) capacity; _saved_index = -1; + _should_expand = false; NOT_PRODUCT(_max_depth = 0); return true; } @@ -747,8 +748,8 @@ assert(_heap_end != NULL, "heap bounds should look ok"); assert(_heap_start < _heap_end, "heap bounds should look ok"); - // reset all the marking data structures and any necessary flags - clear_marking_state(); + // Reset all the marking data structures and any necessary flags + reset_marking_state(); if (verbose_low()) { gclog_or_tty->print_cr("[global] resetting"); @@ -766,6 +767,23 @@ set_concurrent_marking_in_progress(); } + +void ConcurrentMark::reset_marking_state(bool clear_overflow) { + _markStack.set_should_expand(); + _markStack.setEmpty(); // Also clears the _markStack overflow flag + if (clear_overflow) { + clear_has_overflown(); + } else { + assert(has_overflown(), "pre-condition"); + } + _finger = _heap_start; + + for (uint i = 0; i < _max_worker_id; ++i) { + CMTaskQueue* queue = _task_queues->queue(i); + queue->set_empty(); + } +} + void ConcurrentMark::set_phase(uint active_tasks, bool concurrent) { assert(active_tasks <= _max_worker_id, "we should not have more"); @@ -796,7 +814,7 @@ void ConcurrentMark::set_non_marking_state() { // We set the global marking state to some default values when we're // not doing marking. - clear_marking_state(); + reset_marking_state(); _active_tasks = 0; clear_concurrent_marking_in_progress(); } @@ -963,7 +981,7 @@ // not clear the overflow flag since we rely on it being true when // we exit this method to abort the pause and restart concurent // marking. - clear_marking_state(concurrent() /* clear_overflow */); + reset_marking_state(concurrent() /* clear_overflow */); force_overflow()->update(); if (G1Log::fine()) { @@ -1257,8 +1275,9 @@ if (has_overflown()) { // Oops. We overflowed. Restart concurrent marking. _restart_for_overflow = true; - // Clear the flag. We do not need it any more. - clear_has_overflown(); + // Clear the marking state because we will be restarting + // marking due to overflowing the global mark stack. + reset_marking_state(); if (G1TraceMarkStackOverflow) { gclog_or_tty->print_cr("\nRemark led to restart for overflow."); } @@ -1282,6 +1301,8 @@ /* option */ VerifyOption_G1UseNextMarking); } assert(!restart_for_overflow(), "sanity"); + // Completely reset the marking state since marking completed + set_non_marking_state(); } // Expand the marking stack, if we have to and if we can. @@ -1289,11 +1310,6 @@ _markStack.expand(); } - // Reset the marking state if marking completed - if (!restart_for_overflow()) { - set_non_marking_state(); - } - #if VERIFY_OBJS_PROCESSED _scan_obj_cl.objs_processed = 0; ThreadLocalObjQueue::objs_enqueued = 0; @@ -2963,22 +2979,6 @@ } #endif // PRODUCT -void ConcurrentMark::clear_marking_state(bool clear_overflow) { - _markStack.set_should_expand(); - _markStack.setEmpty(); // Also clears the _markStack overflow flag - if (clear_overflow) { - clear_has_overflown(); - } else { - assert(has_overflown(), "pre-condition"); - } - _finger = _heap_start; - - for (uint i = 0; i < _max_worker_id; ++i) { - CMTaskQueue* queue = _task_queues->queue(i); - queue->set_empty(); - } -} - // Aggregate the counting data that was constructed concurrently // with marking. class AggregateCountDataHRClosure: public HeapRegionClosure { @@ -3185,7 +3185,7 @@ // Clear the liveness counting data clear_all_count_data(); // Empty mark stack - clear_marking_state(); + reset_marking_state(); for (uint i = 0; i < _max_worker_id; ++i) { _tasks[i]->clear_region_fields(); } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/g1/concurrentMark.hpp --- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -478,15 +478,18 @@ // It resets the global marking data structures, as well as the // task local ones; should be called during initial mark. void reset(); - // It resets all the marking data structures. - void clear_marking_state(bool clear_overflow = true); + + // Resets all the marking data structures. Called when we have to restart + // marking or when marking completes (via set_non_marking_state below). + void reset_marking_state(bool clear_overflow = true); + + // We do this after we're done with marking so that the marking data + // structures are initialised to a sensible and predictable state. + void set_non_marking_state(); // It should be called to indicate which phase we're in (concurrent // mark or remark) and how many threads are currently active. void set_phase(uint active_tasks, bool concurrent); - // We do this after we're done with marking so that the marking data - // structures are initialised to a sensible and predictable state. - void set_non_marking_state(); // prints all gathered CM-related statistics void print_stats(); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp --- a/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -159,13 +159,11 @@ VM_CGC_Operation op(&final_cl, verbose_str, true /* needs_pll */); VMThread::execute(&op); } - if (cm()->restart_for_overflow() && - G1TraceMarkStackOverflow) { - gclog_or_tty->print_cr("Restarting conc marking because of MS overflow " - "in remark (restart #%d).", iter); - } - if (cm()->restart_for_overflow()) { + if (G1TraceMarkStackOverflow) { + gclog_or_tty->print_cr("Restarting conc marking because of MS overflow " + "in remark (restart #%d).", iter); + } if (G1Log::fine()) { gclog_or_tty->date_stamp(PrintGCDateStamps); gclog_or_tty->stamp(PrintGCTimeStamps); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -3668,7 +3668,7 @@ gclog_or_tty->stamp(PrintGCTimeStamps); GCCauseString gc_cause_str = GCCauseString("GC pause", gc_cause()) - .append(g1_policy()->gcs_are_young() ? " (young)" : " (mixed)") + .append(g1_policy()->gcs_are_young() ? "(young)" : "(mixed)") .append(g1_policy()->during_initial_mark_pause() ? " (initial-mark)" : ""); gclog_or_tty->print("[%s", (const char*)gc_cause_str); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -309,9 +309,9 @@ } G1YoungGenSizer::G1YoungGenSizer() : _sizer_kind(SizerDefaults), _adaptive_size(true) { - assert(G1DefaultMinNewGenPercent <= G1DefaultMaxNewGenPercent, "Min larger than max"); - assert(G1DefaultMinNewGenPercent > 0 && G1DefaultMinNewGenPercent < 100, "Min out of bounds"); - assert(G1DefaultMaxNewGenPercent > 0 && G1DefaultMaxNewGenPercent < 100, "Max out of bounds"); + assert(G1NewSizePercent <= G1MaxNewSizePercent, "Min larger than max"); + assert(G1NewSizePercent > 0 && G1NewSizePercent < 100, "Min out of bounds"); + assert(G1MaxNewSizePercent > 0 && G1MaxNewSizePercent < 100, "Max out of bounds"); if (FLAG_IS_CMDLINE(NewRatio)) { if (FLAG_IS_CMDLINE(NewSize) || FLAG_IS_CMDLINE(MaxNewSize)) { @@ -344,12 +344,12 @@ } uint G1YoungGenSizer::calculate_default_min_length(uint new_number_of_heap_regions) { - uint default_value = (new_number_of_heap_regions * G1DefaultMinNewGenPercent) / 100; + uint default_value = (new_number_of_heap_regions * G1NewSizePercent) / 100; return MAX2(1U, default_value); } uint G1YoungGenSizer::calculate_default_max_length(uint new_number_of_heap_regions) { - uint default_value = (new_number_of_heap_regions * G1DefaultMaxNewGenPercent) / 100; + uint default_value = (new_number_of_heap_regions * G1MaxNewSizePercent) / 100; return MAX2(1U, default_value); } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -94,18 +94,18 @@ // will occur. // // If nothing related to the the young gen size is set on the command -// line we should allow the young gen to be between -// G1DefaultMinNewGenPercent and G1DefaultMaxNewGenPercent of the -// heap size. This means that every time the heap size changes the -// limits for the young gen size will be updated. +// line we should allow the young gen to be between G1NewSizePercent +// and G1MaxNewSizePercent of the heap size. This means that every time +// the heap size changes, the limits for the young gen size will be +// recalculated. // // If only -XX:NewSize is set we should use the specified value as the -// minimum size for young gen. Still using G1DefaultMaxNewGenPercent -// of the heap as maximum. +// minimum size for young gen. Still using G1MaxNewSizePercent of the +// heap as maximum. // // If only -XX:MaxNewSize is set we should use the specified value as the -// maximum size for young gen. Still using G1DefaultMinNewGenPercent -// of the heap as minimum. +// maximum size for young gen. Still using G1NewSizePercent of the heap +// as minimum. // // If -XX:NewSize and -XX:MaxNewSize are both specified we use these values. // No updates when the heap size changes. There is a special case when diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/g1/g1MarkSweep.cpp --- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -282,10 +282,8 @@ if (r->startsHumongous()) { // We must adjust the pointers on the single H object. oop obj = oop(r->bottom()); - debug_only(GenMarkSweep::track_interior_pointers(obj)); // point all the oops to the new location obj->adjust_pointers(); - debug_only(GenMarkSweep::check_interior_pointers()); } } else { // This really ought to be "as_CompactibleSpace"... diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/g1/g1_globals.hpp --- a/src/share/vm/gc_implementation/g1/g1_globals.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -287,23 +287,24 @@ "The number of times we'll force an overflow during " \ "concurrent marking") \ \ - experimental(uintx, G1DefaultMinNewGenPercent, 20, \ - "Percentage (0-100) of the heap size to use as minimum " \ - "young gen size.") \ + experimental(uintx, G1NewSizePercent, 5, \ + "Percentage (0-100) of the heap size to use as default " \ + "minimum young gen size.") \ \ - experimental(uintx, G1DefaultMaxNewGenPercent, 80, \ - "Percentage (0-100) of the heap size to use as maximum " \ - "young gen size.") \ + experimental(uintx, G1MaxNewSizePercent, 60, \ + "Percentage (0-100) of the heap size to use as default " \ + " maximum young gen size.") \ \ - experimental(uintx, G1OldCSetRegionLiveThresholdPercent, 90, \ - "Threshold for regions to be added to the collection set. " \ - "Regions with more live bytes than this will not be collected.") \ + experimental(uintx, G1MixedGCLiveThresholdPercent, 65, \ + "Threshold for regions to be considered for inclusion in the " \ + "collection set of mixed GCs. " \ + "Regions with live bytes exceeding this will not be collected.") \ \ - product(uintx, G1HeapWastePercent, 5, \ + product(uintx, G1HeapWastePercent, 10, \ "Amount of space, expressed as a percentage of the heap size, " \ "that G1 is willing not to collect to avoid expensive GCs.") \ \ - product(uintx, G1MixedGCCountTarget, 4, \ + product(uintx, G1MixedGCCountTarget, 8, \ "The target number of mixed GCs after a marking cycle.") \ \ experimental(uintx, G1OldCSetRegionThresholdPercent, 10, \ diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/parNew/parNewGeneration.cpp --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -878,12 +878,6 @@ bool ParNewGeneration::_avoid_promotion_undo = false; -void ParNewGeneration::adjust_desired_tenuring_threshold() { - // Set the desired survivor size to half the real survivor space - _tenuring_threshold = - age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize); -} - // A Generation that does parallel young-gen collection. void ParNewGeneration::collect(bool full, @@ -1013,6 +1007,8 @@ size_policy->reset_gc_overhead_limit_count(); assert(to()->is_empty(), "to space should be empty now"); + + adjust_desired_tenuring_threshold(); } else { assert(_promo_failure_scan_stack.is_empty(), "post condition"); _promo_failure_scan_stack.clear(true); // Clear cached segments. @@ -1035,7 +1031,6 @@ from()->set_concurrent_iteration_safe_limit(from()->top()); to()->set_concurrent_iteration_safe_limit(to()->top()); - adjust_desired_tenuring_threshold(); if (ResizePLAB) { plab_stats()->adjust_desired_plab_sz(n_workers); } @@ -1623,7 +1618,3 @@ const char* ParNewGeneration::name() const { return "par new generation"; } - -bool ParNewGeneration::in_use() { - return UseParNewGC && ParallelGCThreads > 0; -} diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/parNew/parNewGeneration.hpp --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -347,10 +347,6 @@ bool survivor_overflow() { return _survivor_overflow; } void set_survivor_overflow(bool v) { _survivor_overflow = v; } - // Adjust the tenuring threshold. See the implementation for - // the details of the policy. - virtual void adjust_desired_tenuring_threshold(); - public: ParNewGeneration(ReservedSpace rs, size_t initial_byte_size, int level); @@ -361,8 +357,6 @@ delete _task_queues; } - static bool in_use(); - virtual void ref_processor_init(); virtual Generation::Name kind() { return Generation::ParNew; } virtual const char* name() const; diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -164,7 +164,6 @@ start_array->allocate_block(compact_top); } - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(oop(q), size)); compact_top += size; assert(compact_top <= dest->space()->end(), "Exceeding space in destination"); @@ -225,7 +224,6 @@ start_array->allocate_block(compact_top); } - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(oop(q), sz)); compact_top += sz; assert(compact_top <= dest->space()->end(), "Exceeding space in destination"); @@ -304,11 +302,8 @@ HeapWord* end = _first_dead; while (q < end) { - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q))); // point all the oops to the new location size_t size = oop(q)->adjust_pointers(); - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers()); - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size)); q += size; } @@ -328,11 +323,8 @@ Prefetch::write(q, interval); if (oop(q)->is_gc_marked()) { // q is alive - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q))); // point all the oops to the new location size_t size = oop(q)->adjust_pointers(); - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers()); - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size)); debug_only(prev_q = q); q += size; } else { @@ -366,7 +358,6 @@ while (q < end) { size_t size = oop(q)->size(); assert(!oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)"); - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, q)); debug_only(prev_q = q); q += size; } @@ -401,7 +392,6 @@ Prefetch::write(compaction_top, copy_interval); // copy object and reinit its mark - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, compaction_top)); assert(q != compaction_top, "everything in this pass should be moving"); Copy::aligned_conjoint_words(q, compaction_top, size); oop(compaction_top)->init_mark(); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -99,25 +99,6 @@ bool PSParallelCompact::_dwl_initialized = false; #endif // #ifdef ASSERT -#ifdef VALIDATE_MARK_SWEEP -GrowableArray* PSParallelCompact::_root_refs_stack = NULL; -GrowableArray * PSParallelCompact::_live_oops = NULL; -GrowableArray * PSParallelCompact::_live_oops_moved_to = NULL; -GrowableArray* PSParallelCompact::_live_oops_size = NULL; -size_t PSParallelCompact::_live_oops_index = 0; -GrowableArray* PSParallelCompact::_other_refs_stack = NULL; -GrowableArray* PSParallelCompact::_adjusted_pointers = NULL; -bool PSParallelCompact::_pointer_tracking = false; -bool PSParallelCompact::_root_tracking = true; - -GrowableArray* PSParallelCompact::_cur_gc_live_oops = NULL; -GrowableArray* PSParallelCompact::_cur_gc_live_oops_moved_to = NULL; -GrowableArray * PSParallelCompact::_cur_gc_live_oops_size = NULL; -GrowableArray* PSParallelCompact::_last_gc_live_oops = NULL; -GrowableArray* PSParallelCompact::_last_gc_live_oops_moved_to = NULL; -GrowableArray * PSParallelCompact::_last_gc_live_oops_size = NULL; -#endif - void SplitInfo::record(size_t src_region_idx, size_t partial_obj_size, HeapWord* destination) { @@ -2715,151 +2696,6 @@ } #endif // #ifdef ASSERT - -#ifdef VALIDATE_MARK_SWEEP - -void PSParallelCompact::track_adjusted_pointer(void* p, bool isroot) { - if (!ValidateMarkSweep) - return; - - if (!isroot) { - if (_pointer_tracking) { - guarantee(_adjusted_pointers->contains(p), "should have seen this pointer"); - _adjusted_pointers->remove(p); - } - } else { - ptrdiff_t index = _root_refs_stack->find(p); - if (index != -1) { - int l = _root_refs_stack->length(); - if (l > 0 && l - 1 != index) { - void* last = _root_refs_stack->pop(); - assert(last != p, "should be different"); - _root_refs_stack->at_put(index, last); - } else { - _root_refs_stack->remove(p); - } - } - } -} - - -void PSParallelCompact::check_adjust_pointer(void* p) { - _adjusted_pointers->push(p); -} - - -class AdjusterTracker: public OopClosure { - public: - AdjusterTracker() {}; - void do_oop(oop* o) { PSParallelCompact::check_adjust_pointer(o); } - void do_oop(narrowOop* o) { PSParallelCompact::check_adjust_pointer(o); } -}; - - -void PSParallelCompact::track_interior_pointers(oop obj) { - if (ValidateMarkSweep) { - _adjusted_pointers->clear(); - _pointer_tracking = true; - - AdjusterTracker checker; - obj->oop_iterate_no_header(&checker); - } -} - - -void PSParallelCompact::check_interior_pointers() { - if (ValidateMarkSweep) { - _pointer_tracking = false; - guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers"); - } -} - - -void PSParallelCompact::reset_live_oop_tracking() { - if (ValidateMarkSweep) { - guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops"); - _live_oops_index = 0; - } -} - - -void PSParallelCompact::register_live_oop(oop p, size_t size) { - if (ValidateMarkSweep) { - _live_oops->push(p); - _live_oops_size->push(size); - _live_oops_index++; - } -} - -void PSParallelCompact::validate_live_oop(oop p, size_t size) { - if (ValidateMarkSweep) { - oop obj = _live_oops->at((int)_live_oops_index); - guarantee(obj == p, "should be the same object"); - guarantee(_live_oops_size->at((int)_live_oops_index) == size, "should be the same size"); - _live_oops_index++; - } -} - -void PSParallelCompact::live_oop_moved_to(HeapWord* q, size_t size, - HeapWord* compaction_top) { - assert(oop(q)->forwardee() == NULL || oop(q)->forwardee() == oop(compaction_top), - "should be moved to forwarded location"); - if (ValidateMarkSweep) { - PSParallelCompact::validate_live_oop(oop(q), size); - _live_oops_moved_to->push(oop(compaction_top)); - } - if (RecordMarkSweepCompaction) { - _cur_gc_live_oops->push(q); - _cur_gc_live_oops_moved_to->push(compaction_top); - _cur_gc_live_oops_size->push(size); - } -} - - -void PSParallelCompact::compaction_complete() { - if (RecordMarkSweepCompaction) { - GrowableArray* _tmp_live_oops = _cur_gc_live_oops; - GrowableArray* _tmp_live_oops_moved_to = _cur_gc_live_oops_moved_to; - GrowableArray * _tmp_live_oops_size = _cur_gc_live_oops_size; - - _cur_gc_live_oops = _last_gc_live_oops; - _cur_gc_live_oops_moved_to = _last_gc_live_oops_moved_to; - _cur_gc_live_oops_size = _last_gc_live_oops_size; - _last_gc_live_oops = _tmp_live_oops; - _last_gc_live_oops_moved_to = _tmp_live_oops_moved_to; - _last_gc_live_oops_size = _tmp_live_oops_size; - } -} - - -void PSParallelCompact::print_new_location_of_heap_address(HeapWord* q) { - if (!RecordMarkSweepCompaction) { - tty->print_cr("Requires RecordMarkSweepCompaction to be enabled"); - return; - } - - if (_last_gc_live_oops == NULL) { - tty->print_cr("No compaction information gathered yet"); - return; - } - - for (int i = 0; i < _last_gc_live_oops->length(); i++) { - HeapWord* old_oop = _last_gc_live_oops->at(i); - size_t sz = _last_gc_live_oops_size->at(i); - if (old_oop <= q && q < (old_oop + sz)) { - HeapWord* new_oop = _last_gc_live_oops_moved_to->at(i); - size_t offset = (q - old_oop); - tty->print_cr("Address " PTR_FORMAT, q); - tty->print_cr(" Was in oop " PTR_FORMAT ", size %d, at offset %d", old_oop, sz, offset); - tty->print_cr(" Now in oop " PTR_FORMAT ", actual address " PTR_FORMAT, new_oop, new_oop + offset); - return; - } - } - - tty->print_cr("Address " PTR_FORMAT " not found in live oop information from last GC", q); -} -#endif //VALIDATE_MARK_SWEEP - // Update interior oops in the ranges of regions [beg_region, end_region). void PSParallelCompact::update_and_deadwood_in_dense_prefix(ParCompactionManager* cm, diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -1006,34 +1006,6 @@ // Reset time since last full gc static void reset_millis_since_last_gc(); - protected: -#ifdef VALIDATE_MARK_SWEEP - static GrowableArray* _root_refs_stack; - static GrowableArray * _live_oops; - static GrowableArray * _live_oops_moved_to; - static GrowableArray* _live_oops_size; - static size_t _live_oops_index; - static size_t _live_oops_index_at_perm; - static GrowableArray* _other_refs_stack; - static GrowableArray* _adjusted_pointers; - static bool _pointer_tracking; - static bool _root_tracking; - - // The following arrays are saved since the time of the last GC and - // assist in tracking down problems where someone has done an errant - // store into the heap, usually to an oop that wasn't properly - // handleized across a GC. If we crash or otherwise fail before the - // next GC, we can query these arrays to find out the object we had - // intended to do the store to (assuming it is still alive) and the - // offset within that object. Covered under RecordMarkSweepCompaction. - static GrowableArray * _cur_gc_live_oops; - static GrowableArray * _cur_gc_live_oops_moved_to; - static GrowableArray* _cur_gc_live_oops_size; - static GrowableArray * _last_gc_live_oops; - static GrowableArray * _last_gc_live_oops_moved_to; - static GrowableArray* _last_gc_live_oops_size; -#endif - public: class MarkAndPushClosure: public OopClosure { private: @@ -1191,25 +1163,6 @@ // Time since last full gc (in milliseconds). static jlong millis_since_last_gc(); -#ifdef VALIDATE_MARK_SWEEP - static void track_adjusted_pointer(void* p, bool isroot); - static void check_adjust_pointer(void* p); - static void track_interior_pointers(oop obj); - static void check_interior_pointers(); - - static void reset_live_oop_tracking(); - static void register_live_oop(oop p, size_t size); - static void validate_live_oop(oop p, size_t size); - static void live_oop_moved_to(HeapWord* q, size_t size, HeapWord* compaction_top); - static void compaction_complete(); - - // Querying operation of RecordMarkSweepCompaction results. - // Finds and prints the current base oop and offset for a word - // within an oop that was live during the last GC. Helpful for - // tracking down heap stomps. - static void print_new_location_of_heap_address(HeapWord* q); -#endif // #ifdef VALIDATE_MARK_SWEEP - #ifndef PRODUCT // Debugging support. static const char* space_names[last_space_id]; @@ -1250,12 +1203,7 @@ inline void PSParallelCompact::follow_root(ParCompactionManager* cm, T* p) { assert(!Universe::heap()->is_in_reserved(p), "roots shouldn't be things within the heap"); -#ifdef VALIDATE_MARK_SWEEP - if (ValidateMarkSweep) { - guarantee(!_root_refs_stack->contains(p), "should only be in here once"); - _root_refs_stack->push(p); - } -#endif + T heap_oop = oopDesc::load_heap_oop(p); if (!oopDesc::is_null(heap_oop)) { oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); @@ -1294,20 +1242,10 @@ oopDesc::encode_store_heap_oop_not_null(p, new_obj); } } - VALIDATE_MARK_SWEEP_ONLY(track_adjusted_pointer(p, isroot)); } template inline void PSParallelCompact::KeepAliveClosure::do_oop_work(T* p) { -#ifdef VALIDATE_MARK_SWEEP - if (ValidateMarkSweep) { - if (!Universe::heap()->is_in_reserved(p)) { - _root_refs_stack->push(p); - } else { - _other_refs_stack->push(p); - } - } -#endif mark_and_push(_compaction_manager, p); } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -808,8 +808,9 @@ st->print(" to "); to_space()->print_on(st); } +// Note that a space is not printed before the [NAME: void PSYoungGen::print_used_change(size_t prev_used) const { - gclog_or_tty->print(" [%s:", name()); + gclog_or_tty->print("[%s:", name()); gclog_or_tty->print(" " SIZE_FORMAT "K" "->" SIZE_FORMAT "K" "(" SIZE_FORMAT "K)", diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/shared/markSweep.cpp --- a/src/share/vm/gc_implementation/shared/markSweep.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/shared/markSweep.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -42,26 +42,6 @@ PreservedMark* MarkSweep::_preserved_marks = NULL; ReferenceProcessor* MarkSweep::_ref_processor = NULL; -#ifdef VALIDATE_MARK_SWEEP -GrowableArray* MarkSweep::_root_refs_stack = NULL; -GrowableArray * MarkSweep::_live_oops = NULL; -GrowableArray * MarkSweep::_live_oops_moved_to = NULL; -GrowableArray* MarkSweep::_live_oops_size = NULL; -size_t MarkSweep::_live_oops_index = 0; -size_t MarkSweep::_live_oops_index_at_perm = 0; -GrowableArray* MarkSweep::_other_refs_stack = NULL; -GrowableArray* MarkSweep::_adjusted_pointers = NULL; -bool MarkSweep::_pointer_tracking = false; -bool MarkSweep::_root_tracking = true; - -GrowableArray* MarkSweep::_cur_gc_live_oops = NULL; -GrowableArray* MarkSweep::_cur_gc_live_oops_moved_to = NULL; -GrowableArray * MarkSweep::_cur_gc_live_oops_size = NULL; -GrowableArray* MarkSweep::_last_gc_live_oops = NULL; -GrowableArray* MarkSweep::_last_gc_live_oops_moved_to = NULL; -GrowableArray * MarkSweep::_last_gc_live_oops_size = NULL; -#endif - MarkSweep::FollowRootClosure MarkSweep::follow_root_closure; CodeBlobToOopClosure MarkSweep::follow_code_root_closure(&MarkSweep::follow_root_closure, /*do_marking=*/ true); @@ -185,142 +165,6 @@ } } -#ifdef VALIDATE_MARK_SWEEP - -void MarkSweep::track_adjusted_pointer(void* p, bool isroot) { - if (!ValidateMarkSweep) - return; - - if (!isroot) { - if (_pointer_tracking) { - guarantee(_adjusted_pointers->contains(p), "should have seen this pointer"); - _adjusted_pointers->remove(p); - } - } else { - ptrdiff_t index = _root_refs_stack->find(p); - if (index != -1) { - int l = _root_refs_stack->length(); - if (l > 0 && l - 1 != index) { - void* last = _root_refs_stack->pop(); - assert(last != p, "should be different"); - _root_refs_stack->at_put(index, last); - } else { - _root_refs_stack->remove(p); - } - } - } -} - -void MarkSweep::check_adjust_pointer(void* p) { - _adjusted_pointers->push(p); -} - -class AdjusterTracker: public OopClosure { - public: - AdjusterTracker() {} - void do_oop(oop* o) { MarkSweep::check_adjust_pointer(o); } - void do_oop(narrowOop* o) { MarkSweep::check_adjust_pointer(o); } -}; - -void MarkSweep::track_interior_pointers(oop obj) { - if (ValidateMarkSweep) { - _adjusted_pointers->clear(); - _pointer_tracking = true; - - AdjusterTracker checker; - obj->oop_iterate_no_header(&checker); - } -} - -void MarkSweep::check_interior_pointers() { - if (ValidateMarkSweep) { - _pointer_tracking = false; - guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers"); - } -} - -void MarkSweep::reset_live_oop_tracking() { - if (ValidateMarkSweep) { - guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops"); - _live_oops_index = 0; - } -} - -void MarkSweep::register_live_oop(oop p, size_t size) { - if (ValidateMarkSweep) { - _live_oops->push(p); - _live_oops_size->push(size); - _live_oops_index++; - } -} - -void MarkSweep::validate_live_oop(oop p, size_t size) { - if (ValidateMarkSweep) { - oop obj = _live_oops->at((int)_live_oops_index); - guarantee(obj == p, "should be the same object"); - guarantee(_live_oops_size->at((int)_live_oops_index) == size, "should be the same size"); - _live_oops_index++; - } -} - -void MarkSweep::live_oop_moved_to(HeapWord* q, size_t size, - HeapWord* compaction_top) { - assert(oop(q)->forwardee() == NULL || oop(q)->forwardee() == oop(compaction_top), - "should be moved to forwarded location"); - if (ValidateMarkSweep) { - MarkSweep::validate_live_oop(oop(q), size); - _live_oops_moved_to->push(oop(compaction_top)); - } - if (RecordMarkSweepCompaction) { - _cur_gc_live_oops->push(q); - _cur_gc_live_oops_moved_to->push(compaction_top); - _cur_gc_live_oops_size->push(size); - } -} - -void MarkSweep::compaction_complete() { - if (RecordMarkSweepCompaction) { - GrowableArray* _tmp_live_oops = _cur_gc_live_oops; - GrowableArray* _tmp_live_oops_moved_to = _cur_gc_live_oops_moved_to; - GrowableArray * _tmp_live_oops_size = _cur_gc_live_oops_size; - - _cur_gc_live_oops = _last_gc_live_oops; - _cur_gc_live_oops_moved_to = _last_gc_live_oops_moved_to; - _cur_gc_live_oops_size = _last_gc_live_oops_size; - _last_gc_live_oops = _tmp_live_oops; - _last_gc_live_oops_moved_to = _tmp_live_oops_moved_to; - _last_gc_live_oops_size = _tmp_live_oops_size; - } -} - -void MarkSweep::print_new_location_of_heap_address(HeapWord* q) { - if (!RecordMarkSweepCompaction) { - tty->print_cr("Requires RecordMarkSweepCompaction to be enabled"); - return; - } - - if (_last_gc_live_oops == NULL) { - tty->print_cr("No compaction information gathered yet"); - return; - } - - for (int i = 0; i < _last_gc_live_oops->length(); i++) { - HeapWord* old_oop = _last_gc_live_oops->at(i); - size_t sz = _last_gc_live_oops_size->at(i); - if (old_oop <= q && q < (old_oop + sz)) { - HeapWord* new_oop = _last_gc_live_oops_moved_to->at(i); - size_t offset = (q - old_oop); - tty->print_cr("Address " PTR_FORMAT, q); - tty->print_cr(" Was in oop " PTR_FORMAT ", size " SIZE_FORMAT ", at offset " SIZE_FORMAT, old_oop, sz, offset); - tty->print_cr(" Now in oop " PTR_FORMAT ", actual address " PTR_FORMAT, new_oop, new_oop + offset); - return; - } - } - - tty->print_cr("Address " PTR_FORMAT " not found in live oop information from last GC", q); -} -#endif //VALIDATE_MARK_SWEEP - MarkSweep::IsAliveClosure MarkSweep::is_alive; void MarkSweep::IsAliveClosure::do_object(oop p) { ShouldNotReachHere(); } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/shared/markSweep.hpp --- a/src/share/vm/gc_implementation/shared/markSweep.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/shared/markSweep.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -44,21 +44,6 @@ // // Class unloading will only occur when a full gc is invoked. -// If VALIDATE_MARK_SWEEP is defined, the -XX:+ValidateMarkSweep flag will -// be operational, and will provide slow but comprehensive self-checks within -// the GC. This is not enabled by default in product or release builds, -// since the extra call to track_adjusted_pointer() in _adjust_pointer() -// would be too much overhead, and would disturb performance measurement. -// However, debug builds are sometimes way too slow to run GC tests! -#ifdef ASSERT -#define VALIDATE_MARK_SWEEP 1 -#endif -#ifdef VALIDATE_MARK_SWEEP -#define VALIDATE_MARK_SWEEP_ONLY(code) code -#else -#define VALIDATE_MARK_SWEEP_ONLY(code) -#endif - // declared at end class PreservedMark; @@ -147,33 +132,6 @@ // Reference processing (used in ...follow_contents) static ReferenceProcessor* _ref_processor; -#ifdef VALIDATE_MARK_SWEEP - static GrowableArray* _root_refs_stack; - static GrowableArray * _live_oops; - static GrowableArray * _live_oops_moved_to; - static GrowableArray* _live_oops_size; - static size_t _live_oops_index; - static size_t _live_oops_index_at_perm; - static GrowableArray* _other_refs_stack; - static GrowableArray* _adjusted_pointers; - static bool _pointer_tracking; - static bool _root_tracking; - - // The following arrays are saved since the time of the last GC and - // assist in tracking down problems where someone has done an errant - // store into the heap, usually to an oop that wasn't properly - // handleized across a GC. If we crash or otherwise fail before the - // next GC, we can query these arrays to find out the object we had - // intended to do the store to (assuming it is still alive) and the - // offset within that object. Covered under RecordMarkSweepCompaction. - static GrowableArray * _cur_gc_live_oops; - static GrowableArray * _cur_gc_live_oops_moved_to; - static GrowableArray* _cur_gc_live_oops_size; - static GrowableArray * _last_gc_live_oops; - static GrowableArray * _last_gc_live_oops_moved_to; - static GrowableArray* _last_gc_live_oops_size; -#endif - // Non public closures static KeepAliveClosure keep_alive; @@ -227,24 +185,6 @@ static void adjust_pointer(oop* p) { adjust_pointer(p, false); } static void adjust_pointer(narrowOop* p) { adjust_pointer(p, false); } -#ifdef VALIDATE_MARK_SWEEP - static void track_adjusted_pointer(void* p, bool isroot); - static void check_adjust_pointer(void* p); - static void track_interior_pointers(oop obj); - static void check_interior_pointers(); - - static void reset_live_oop_tracking(); - static void register_live_oop(oop p, size_t size); - static void validate_live_oop(oop p, size_t size); - static void live_oop_moved_to(HeapWord* q, size_t size, HeapWord* compaction_top); - static void compaction_complete(); - - // Querying operation of RecordMarkSweepCompaction results. - // Finds and prints the current base oop and offset for a word - // within an oop that was live during the last GC. Helpful for - // tracking down heap stomps. - static void print_new_location_of_heap_address(HeapWord* q); -#endif }; class PreservedMark VALUE_OBJ_CLASS_SPEC { diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_implementation/shared/markSweep.inline.hpp --- a/src/share/vm/gc_implementation/shared/markSweep.inline.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_implementation/shared/markSweep.inline.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -46,12 +46,6 @@ template inline void MarkSweep::follow_root(T* p) { assert(!Universe::heap()->is_in_reserved(p), "roots shouldn't be things within the heap"); -#ifdef VALIDATE_MARK_SWEEP - if (ValidateMarkSweep) { - guarantee(!_root_refs_stack->contains(p), "should only be in here once"); - _root_refs_stack->push(p); - } -#endif T heap_oop = oopDesc::load_heap_oop(p); if (!oopDesc::is_null(heap_oop)) { oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); @@ -97,19 +91,9 @@ oopDesc::encode_store_heap_oop_not_null(p, new_obj); } } - VALIDATE_MARK_SWEEP_ONLY(track_adjusted_pointer(p, isroot)); } template inline void MarkSweep::KeepAliveClosure::do_oop_work(T* p) { -#ifdef VALIDATE_MARK_SWEEP - if (ValidateMarkSweep) { - if (!Universe::heap()->is_in_reserved(p)) { - _root_refs_stack->push(p); - } else { - _other_refs_stack->push(p); - } - } -#endif mark_and_push(p); } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/gc_interface/gcCause.hpp --- a/src/share/vm/gc_interface/gcCause.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/gc_interface/gcCause.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -99,9 +99,9 @@ public: GCCauseString(const char* prefix, GCCause::Cause cause) { if (PrintGCCause) { - _position = jio_snprintf(_buffer, _length, "%s (%s)", prefix, GCCause::to_string(cause)); + _position = jio_snprintf(_buffer, _length, "%s (%s) ", prefix, GCCause::to_string(cause)); } else { - _position = jio_snprintf(_buffer, _length, "%s", prefix); + _position = jio_snprintf(_buffer, _length, "%s ", prefix); } assert(_position >= 0 && _position <= _length, err_msg("Need to increase the buffer size in GCCauseString? %d", _position)); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/interpreter/interpreterRuntime.cpp --- a/src/share/vm/interpreter/interpreterRuntime.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -417,7 +417,7 @@ // exception handler lookup KlassHandle h_klass(THREAD, h_exception->klass()); - handler_bci = h_method->fast_exception_handler_bci_for(h_klass, current_bci, THREAD); + handler_bci = Method::fast_exception_handler_bci_for(h_method, h_klass, current_bci, THREAD); if (HAS_PENDING_EXCEPTION) { // We threw an exception while trying to find the exception handler. // Transfer the new exception to the exception handle which will diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/memory/binaryTreeDictionary.cpp --- a/src/share/vm/memory/binaryTreeDictionary.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/memory/binaryTreeDictionary.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -67,7 +67,8 @@ } template class FreeList_t> -TreeList::TreeList() {} +TreeList::TreeList() : _parent(NULL), + _left(NULL), _right(NULL) {} template class FreeList_t> TreeList* @@ -82,7 +83,7 @@ tl->link_head(tc); tl->link_tail(tc); tl->set_count(1); - + assert(tl->parent() == NULL, "Should be clear"); return tl; } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/memory/collectorPolicy.cpp --- a/src/share/vm/memory/collectorPolicy.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/memory/collectorPolicy.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -777,6 +777,15 @@ full_gc_count, GCCause::_metadata_GC_threshold); VMThread::execute(&op); + + // If GC was locked out, try again. Check + // before checking success because the prologue + // could have succeeded and the GC still have + // been locked out. + if (op.gc_locked()) { + continue; + } + if (op.prologue_succeeded()) { return op.result(); } @@ -818,7 +827,7 @@ if (_generations == NULL) vm_exit_during_initialization("Unable to allocate gen spec"); - if (UseParNewGC && ParallelGCThreads > 0) { + if (UseParNewGC) { _generations[0] = new GenerationSpec(Generation::ParNew, _initial_gen0_size, _max_gen0_size); } else { _generations[0] = new GenerationSpec(Generation::DefNew, _initial_gen0_size, _max_gen0_size); @@ -831,10 +840,9 @@ void MarkSweepPolicy::initialize_gc_policy_counters() { // initialize the policy counters - 2 collectors, 3 generations - if (UseParNewGC && ParallelGCThreads > 0) { + if (UseParNewGC) { _gc_policy_counters = new GCPolicyCounters("ParNew:MSC", 2, 3); - } - else { + } else { _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 3); } } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/memory/defNewGeneration.cpp --- a/src/share/vm/memory/defNewGeneration.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/memory/defNewGeneration.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -550,6 +550,11 @@ return allocate(size, is_tlab); } +void DefNewGeneration::adjust_desired_tenuring_threshold() { + // Set the desired survivor size to half the real survivor space + _tenuring_threshold = + age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize); +} void DefNewGeneration::collect(bool full, bool clear_all_soft_refs, @@ -649,9 +654,7 @@ assert(to()->is_empty(), "to space should be empty now"); - // Set the desired survivor size to half the real survivor space - _tenuring_threshold = - age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize); + adjust_desired_tenuring_threshold(); // A successful scavenge should restart the GC time limit count which is // for full GC's. diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/memory/defNewGeneration.hpp --- a/src/share/vm/memory/defNewGeneration.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/memory/defNewGeneration.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -124,7 +124,9 @@ _should_allocate_from_space = true; } - protected: + // Tenuring + void adjust_desired_tenuring_threshold(); + // Spaces EdenSpace* _eden_space; ContiguousSpace* _from_space; diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/memory/genMarkSweep.cpp --- a/src/share/vm/memory/genMarkSweep.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/memory/genMarkSweep.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -100,21 +100,8 @@ mark_sweep_phase3(level); - VALIDATE_MARK_SWEEP_ONLY( - if (ValidateMarkSweep) { - guarantee(_root_refs_stack->length() == 0, "should be empty by now"); - } - ) - mark_sweep_phase4(); - VALIDATE_MARK_SWEEP_ONLY( - if (ValidateMarkSweep) { - guarantee(_live_oops->length() == _live_oops_moved_to->length(), - "should be the same size"); - } - ) - restore_marks(); // Set saved marks for allocation profiler (and other things? -- dld) @@ -187,31 +174,6 @@ _preserved_marks = (PreservedMark*)scratch; _preserved_count = 0; - -#ifdef VALIDATE_MARK_SWEEP - if (ValidateMarkSweep) { - _root_refs_stack = new (ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _other_refs_stack = new (ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _adjusted_pointers = new (ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _live_oops = new (ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _live_oops_moved_to = new (ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _live_oops_size = new (ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - } - if (RecordMarkSweepCompaction) { - if (_cur_gc_live_oops == NULL) { - _cur_gc_live_oops = new(ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _cur_gc_live_oops_moved_to = new(ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _cur_gc_live_oops_size = new(ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _last_gc_live_oops = new(ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _last_gc_live_oops_moved_to = new(ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _last_gc_live_oops_size = new(ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - } else { - _cur_gc_live_oops->clear(); - _cur_gc_live_oops_moved_to->clear(); - _cur_gc_live_oops_size->clear(); - } - } -#endif } @@ -225,19 +187,6 @@ _preserved_oop_stack.clear(true); _marking_stack.clear(); _objarray_stack.clear(true); - -#ifdef VALIDATE_MARK_SWEEP - if (ValidateMarkSweep) { - delete _root_refs_stack; - delete _other_refs_stack; - delete _adjusted_pointers; - delete _live_oops; - delete _live_oops_size; - delete _live_oops_moved_to; - _live_oops_index = 0; - _live_oops_index_at_perm = 0; - } -#endif } void GenMarkSweep::mark_sweep_phase1(int level, @@ -246,8 +195,6 @@ TraceTime tm("phase 1", PrintGC && Verbose, true, gclog_or_tty); trace(" 1"); - VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking()); - GenCollectedHeap* gch = GenCollectedHeap::heap(); // Because follow_root_closure is created statically, cannot @@ -315,8 +262,6 @@ TraceTime tm("phase 2", PrintGC && Verbose, true, gclog_or_tty); trace("2"); - VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking()); - gch->prepare_for_compaction(); } @@ -337,8 +282,6 @@ // Need new claim bits for the pointer adjustment tracing. ClassLoaderDataGraph::clear_claimed_marks(); - VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking()); - // Because the two closures below are created statically, cannot // use OopsInGenClosure constructor which takes a generation, // as the Universe has not been created when the static constructors @@ -393,10 +336,6 @@ TraceTime tm("phase 4", PrintGC && Verbose, true, gclog_or_tty); trace("4"); - VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking()); - GenCompactClosure blk; gch->generation_iterate(&blk, true); - - VALIDATE_MARK_SWEEP_ONLY(compaction_complete()); } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/memory/metachunk.cpp --- a/src/share/vm/memory/metachunk.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/memory/metachunk.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -56,6 +56,7 @@ assert(chunk_end > chunk_bottom, "Chunk must be too small"); chunk->set_end(chunk_end); chunk->set_next(NULL); + chunk->set_prev(NULL); chunk->set_word_size(word_size); #ifdef ASSERT size_t data_word_size = pointer_delta(chunk_end, chunk_bottom, sizeof(MetaWord)); @@ -76,15 +77,15 @@ } // _bottom points to the start of the chunk including the overhead. -size_t Metachunk::used_word_size() { +size_t Metachunk::used_word_size() const { return pointer_delta(_top, _bottom, sizeof(MetaWord)); } -size_t Metachunk::free_word_size() { +size_t Metachunk::free_word_size() const { return pointer_delta(_end, _top, sizeof(MetaWord)); } -size_t Metachunk::capacity_word_size() { +size_t Metachunk::capacity_word_size() const { return pointer_delta(_end, _bottom, sizeof(MetaWord)); } @@ -93,6 +94,10 @@ " bottom " PTR_FORMAT " top " PTR_FORMAT " end " PTR_FORMAT " size " SIZE_FORMAT, bottom(), top(), end(), word_size()); + if (Verbose) { + st->print_cr(" used " SIZE_FORMAT " free " SIZE_FORMAT, + used_word_size(), free_word_size()); + } } #ifndef PRODUCT diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/memory/metachunk.hpp --- a/src/share/vm/memory/metachunk.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/memory/metachunk.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -67,9 +67,11 @@ void set_word_size(size_t v) { _word_size = v; } public: #ifdef ASSERT - Metachunk() : _bottom(NULL), _end(NULL), _top(NULL), _is_free(false) {} + Metachunk() : _bottom(NULL), _end(NULL), _top(NULL), _is_free(false), + _next(NULL), _prev(NULL) {} #else - Metachunk() : _bottom(NULL), _end(NULL), _top(NULL) {} + Metachunk() : _bottom(NULL), _end(NULL), _top(NULL), + _next(NULL), _prev(NULL) {} #endif // Used to add a Metachunk to a list of Metachunks @@ -102,15 +104,15 @@ } // Reset top to bottom so chunk can be reused. - void reset_empty() { _top = (_bottom + _overhead); } + void reset_empty() { _top = (_bottom + _overhead); _next = NULL; _prev = NULL; } bool is_empty() { return _top == (_bottom + _overhead); } // used (has been allocated) // free (available for future allocations) // capacity (total size of chunk) - size_t used_word_size(); - size_t free_word_size(); - size_t capacity_word_size(); + size_t used_word_size() const; + size_t free_word_size() const; + size_t capacity_word_size()const; // Debug support #ifdef ASSERT diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/memory/metadataFactory.hpp --- a/src/share/vm/memory/metadataFactory.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/memory/metadataFactory.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -66,7 +66,11 @@ if (data != NULL) { assert(loader_data != NULL, "shouldn't pass null"); int size = data->size(); - loader_data->metaspace_non_null()->deallocate((MetaWord*)data, size, false); + if (DumpSharedSpaces) { + loader_data->ro_metaspace()->deallocate((MetaWord*)data, size, false); + } else { + loader_data->metaspace_non_null()->deallocate((MetaWord*)data, size, false); + } } } @@ -77,6 +81,7 @@ assert(loader_data != NULL, "shouldn't pass null"); int size = md->size(); // Call metadata's deallocate function which will call deallocate fields + assert(!DumpSharedSpaces, "cannot deallocate metadata when dumping CDS archive"); assert(!md->on_stack(), "can't deallocate things on stack"); md->deallocate_contents(loader_data); loader_data->metaspace_non_null()->deallocate((MetaWord*)md, size, md->is_klass()); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/memory/metaspace.cpp --- a/src/share/vm/memory/metaspace.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/memory/metaspace.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -58,11 +58,23 @@ // Used in declarations in SpaceManager and ChunkManager enum ChunkIndex { - SmallIndex = 0, - MediumIndex = 1, - HumongousIndex = 2, - NumberOfFreeLists = 2, - NumberOfInUseLists = 3 + ZeroIndex = 0, + SpecializedIndex = ZeroIndex, + SmallIndex = SpecializedIndex + 1, + MediumIndex = SmallIndex + 1, + HumongousIndex = MediumIndex + 1, + NumberOfFreeLists = 3, + NumberOfInUseLists = 4 +}; + +enum ChunkSizes { // in words. + ClassSpecializedChunk = 128, + SpecializedChunk = 128, + ClassSmallChunk = 256, + SmallChunk = 512, + ClassMediumChunk = 1 * K, + MediumChunk = 8 * K, + HumongousChunkGranularity = 8 }; static ChunkIndex next_chunk_index(ChunkIndex i) { @@ -126,6 +138,7 @@ // HumongousChunk ChunkList _free_chunks[NumberOfFreeLists]; + // HumongousChunk ChunkTreeDictionary _humongous_dictionary; @@ -169,6 +182,10 @@ Metachunk* chunk_freelist_allocate(size_t word_size); void chunk_freelist_deallocate(Metachunk* chunk); + // Map a size to a list index assuming that there are lists + // for special, small, medium, and humongous chunks. + static ChunkIndex list_index(size_t size); + // Total of the space in the free chunks list size_t free_chunks_total(); size_t free_chunks_total_in_bytes(); @@ -180,8 +197,6 @@ Atomic::add_ptr(count, &_free_chunks_count); Atomic::add_ptr(v, &_free_chunks_total); } - ChunkList* free_medium_chunks() { return &_free_chunks[1]; } - ChunkList* free_small_chunks() { return &_free_chunks[0]; } ChunkTreeDictionary* humongous_dictionary() { return &_humongous_dictionary; } @@ -400,7 +415,14 @@ VirtualSpaceList(size_t word_size); VirtualSpaceList(ReservedSpace rs); - Metachunk* get_new_chunk(size_t word_size, size_t grow_chunks_by_words); + Metachunk* get_new_chunk(size_t word_size, + size_t grow_chunks_by_words, + size_t medium_chunk_bunch); + + // Get the first chunk for a Metaspace. Used for + // special cases such as the boot class loader, reflection + // class loader and anonymous class loader. + Metachunk* get_initialization_chunk(size_t word_size, size_t chunk_bunch); VirtualSpaceNode* current_virtual_space() { return _current_virtual_space; @@ -501,9 +523,13 @@ friend class Metadebug; private: + // protects allocations and contains. Mutex* const _lock; + // Chunk related size + size_t _medium_chunk_bunch; + // List of chunks in use by this SpaceManager. Allocations // are done from the current chunk. The list is used for deallocating // chunks when the SpaceManager is freed. @@ -532,6 +558,7 @@ static const int _expand_lock_rank; static Mutex* const _expand_lock; + private: // Accessors Metachunk* chunks_in_use(ChunkIndex index) const { return _chunks_in_use[index]; } void set_chunks_in_use(ChunkIndex index, Metachunk* v) { _chunks_in_use[index] = v; } @@ -554,23 +581,37 @@ Mutex* lock() const { return _lock; } + const char* chunk_size_name(ChunkIndex index) const; + + protected: + void initialize(); + public: - SpaceManager(Mutex* lock, VirtualSpaceList* vs_list); + SpaceManager(Mutex* lock, + VirtualSpaceList* vs_list); ~SpaceManager(); - enum ChunkSizes { // in words. - SmallChunk = 512, - MediumChunk = 8 * K, - MediumChunkBunch = 4 * MediumChunk + enum ChunkMultiples { + MediumChunkMultiple = 4 }; // Accessors + size_t specialized_chunk_size() { return SpecializedChunk; } + size_t small_chunk_size() { return (size_t) vs_list()->is_class() ? ClassSmallChunk : SmallChunk; } + size_t medium_chunk_size() { return (size_t) vs_list()->is_class() ? ClassMediumChunk : MediumChunk; } + size_t medium_chunk_bunch() { return medium_chunk_size() * MediumChunkMultiple; } + size_t allocation_total() const { return _allocation_total; } void inc_allocation_total(size_t v) { Atomic::add_ptr(v, &_allocation_total); } - static bool is_humongous(size_t word_size) { return word_size > MediumChunk; } + bool is_humongous(size_t word_size) { return word_size > medium_chunk_size(); } static Mutex* expand_lock() { return _expand_lock; } + // Set the sizes for the initial chunks. + void get_initial_chunk_sizes(Metaspace::MetaspaceType type, + size_t* chunk_word_size, + size_t* class_chunk_word_size); + size_t sum_capacity_in_chunks_in_use() const; size_t sum_used_in_chunks_in_use() const; size_t sum_free_in_chunks_in_use() const; @@ -580,6 +621,8 @@ size_t sum_count_in_chunks_in_use(); size_t sum_count_in_chunks_in_use(ChunkIndex i); + Metachunk* get_new_chunk(size_t word_size, size_t grow_chunks_by_words); + // Block allocation and deallocation. // Allocates a block from the current chunk MetaWord* allocate(size_t word_size); @@ -772,8 +815,10 @@ return false; } - // Commit only 1 page instead of the whole reserved space _rs.size() - size_t committed_byte_size = os::vm_page_size(); + // An allocation out of this Virtualspace that is larger + // than an initial commit size can waste that initial committed + // space. + size_t committed_byte_size = 0; bool result = virtual_space()->initialize(_rs, committed_byte_size); if (result) { set_top((MetaWord*)virtual_space()->low()); @@ -799,7 +844,8 @@ st->print_cr(" space @ " PTR_FORMAT " " SIZE_FORMAT "K, %3d%% used " "[" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ")", - vs, capacity / K, used * 100 / capacity, + vs, capacity / K, + capacity == 0 ? 0 : used * 100 / capacity, bottom(), top(), end(), vs->high_boundary()); } @@ -922,7 +968,8 @@ } Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, - size_t grow_chunks_by_words) { + size_t grow_chunks_by_words, + size_t medium_chunk_bunch) { // Get a chunk from the chunk freelist Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words); @@ -935,8 +982,8 @@ if (next == NULL) { // Not enough room in current virtual space. Try to commit // more space. - size_t expand_vs_by_words = MAX2((size_t)SpaceManager::MediumChunkBunch, - grow_chunks_by_words); + size_t expand_vs_by_words = MAX2(medium_chunk_bunch, + grow_chunks_by_words); size_t page_size_words = os::vm_page_size() / BytesPerWord; size_t aligned_expand_vs_by_words = align_size_up(expand_vs_by_words, page_size_words); @@ -954,12 +1001,6 @@ // Got it. It's on the list now. Get a chunk from it. next = current_virtual_space()->get_chunk_vs_with_expand(grow_chunks_by_words); } - if (TraceMetadataHumongousAllocation && SpaceManager::is_humongous(word_size)) { - gclog_or_tty->print_cr(" aligned_expand_vs_by_words " PTR_FORMAT, - aligned_expand_vs_by_words); - gclog_or_tty->print_cr(" grow_vs_words " PTR_FORMAT, - grow_vs_words); - } } else { // Allocation will fail and induce a GC if (TraceMetadataChunkAllocation && Verbose) { @@ -974,9 +1015,20 @@ } } + assert(next == NULL || (next->next() == NULL && next->prev() == NULL), + "New chunk is still on some list"); return next; } +Metachunk* VirtualSpaceList::get_initialization_chunk(size_t chunk_word_size, + size_t chunk_bunch) { + // Get a chunk from the chunk freelist + Metachunk* new_chunk = get_new_chunk(chunk_word_size, + chunk_word_size, + chunk_bunch); + return new_chunk; +} + void VirtualSpaceList::print_on(outputStream* st) const { if (TraceMetadataChunkAllocation && Verbose) { VirtualSpaceListIterator iter(virtual_space_list()); @@ -1373,16 +1425,17 @@ void ChunkList::add_at_head(Metachunk* head, Metachunk* tail) { assert_lock_strong(SpaceManager::expand_lock()); - assert(tail->next() == NULL, "Not the tail"); + assert(head == tail || tail->next() == NULL, + "Not the tail or the head has already been added to a list"); if (TraceMetadataChunkAllocation && Verbose) { - tty->print("ChunkList::add_at_head: "); + gclog_or_tty->print("ChunkList::add_at_head(head, tail): "); Metachunk* cur = head; while (cur != NULL) { - tty->print(PTR_FORMAT " (" SIZE_FORMAT ") ", cur, cur->word_size()); + gclog_or_tty->print(PTR_FORMAT " (" SIZE_FORMAT ") ", cur, cur->word_size()); cur = cur->next(); } - tty->print_cr(""); + gclog_or_tty->print_cr(""); } if (tail != NULL) { @@ -1486,13 +1539,13 @@ void ChunkManager::locked_print_free_chunks(outputStream* st) { assert_lock_strong(SpaceManager::expand_lock()); - st->print_cr("Free chunk total 0x%x count 0x%x", + st->print_cr("Free chunk total " SIZE_FORMAT " count " SIZE_FORMAT, _free_chunks_total, _free_chunks_count); } void ChunkManager::locked_print_sum_free_chunks(outputStream* st) { assert_lock_strong(SpaceManager::expand_lock()); - st->print_cr("Sum free chunk total 0x%x count 0x%x", + st->print_cr("Sum free chunk total " SIZE_FORMAT " count " SIZE_FORMAT, sum_free_chunks(), sum_free_chunks_count()); } ChunkList* ChunkManager::free_chunks(ChunkIndex index) { @@ -1504,7 +1557,7 @@ size_t ChunkManager::sum_free_chunks() { assert_lock_strong(SpaceManager::expand_lock()); size_t result = 0; - for (ChunkIndex i = SmallIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { + for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { ChunkList* list = free_chunks(i); if (list == NULL) { @@ -1520,7 +1573,7 @@ size_t ChunkManager::sum_free_chunks_count() { assert_lock_strong(SpaceManager::expand_lock()); size_t count = 0; - for (ChunkIndex i = SmallIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { + for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { ChunkList* list = free_chunks(i); if (list == NULL) { continue; @@ -1532,15 +1585,9 @@ } ChunkList* ChunkManager::find_free_chunks_list(size_t word_size) { - switch (word_size) { - case SpaceManager::SmallChunk : - return &_free_chunks[0]; - case SpaceManager::MediumChunk : - return &_free_chunks[1]; - default: - assert(word_size > SpaceManager::MediumChunk, "List inconsistency"); - return &_free_chunks[2]; - } + ChunkIndex index = list_index(word_size); + assert(index < HumongousIndex, "No humongous list"); + return free_chunks(index); } void ChunkManager::free_chunks_put(Metachunk* chunk) { @@ -1574,7 +1621,7 @@ slow_locked_verify(); Metachunk* chunk = NULL; - if (!SpaceManager::is_humongous(word_size)) { + if (list_index(word_size) != HumongousIndex) { ChunkList* free_list = find_free_chunks_list(word_size); assert(free_list != NULL, "Sanity check"); @@ -1587,8 +1634,8 @@ // Remove the chunk as the head of the list. free_list->set_head(chunk->next()); - chunk->set_next(NULL); - // Chunk has been removed from the chunks free list. + + // Chunk is being removed from the chunks free list. dec_free_chunks_total(chunk->capacity_word_size()); if (TraceMetadataChunkAllocation && Verbose) { @@ -1614,8 +1661,14 @@ #ifdef ASSERT chunk->set_is_free(false); #endif + } else { + return NULL; } } + + // Remove it from the links to this freelist + chunk->set_next(NULL); + chunk->set_prev(NULL); slow_locked_verify(); return chunk; } @@ -1630,13 +1683,20 @@ return NULL; } - assert(word_size <= chunk->word_size() || - SpaceManager::is_humongous(chunk->word_size()), - "Non-humongous variable sized chunk"); + assert((word_size <= chunk->word_size()) || + list_index(chunk->word_size() == HumongousIndex), + "Non-humongous variable sized chunk"); if (TraceMetadataChunkAllocation) { - tty->print("ChunkManager::chunk_freelist_allocate: chunk " - PTR_FORMAT " size " SIZE_FORMAT " ", - chunk, chunk->word_size()); + size_t list_count; + if (list_index(word_size) < HumongousIndex) { + ChunkList* list = find_free_chunks_list(word_size); + list_count = list->sum_list_count(); + } else { + list_count = humongous_dictionary()->total_count(); + } + tty->print("ChunkManager::chunk_freelist_allocate: " PTR_FORMAT " chunk " + PTR_FORMAT " size " SIZE_FORMAT " count " SIZE_FORMAT " ", + this, chunk, chunk->word_size(), list_count); locked_print_free_chunks(tty); } @@ -1651,10 +1711,42 @@ // SpaceManager methods +void SpaceManager::get_initial_chunk_sizes(Metaspace::MetaspaceType type, + size_t* chunk_word_size, + size_t* class_chunk_word_size) { + switch (type) { + case Metaspace::BootMetaspaceType: + *chunk_word_size = Metaspace::first_chunk_word_size(); + *class_chunk_word_size = Metaspace::first_class_chunk_word_size(); + break; + case Metaspace::ROMetaspaceType: + *chunk_word_size = SharedReadOnlySize / wordSize; + *class_chunk_word_size = ClassSpecializedChunk; + break; + case Metaspace::ReadWriteMetaspaceType: + *chunk_word_size = SharedReadWriteSize / wordSize; + *class_chunk_word_size = ClassSpecializedChunk; + break; + case Metaspace::AnonymousMetaspaceType: + case Metaspace::ReflectionMetaspaceType: + *chunk_word_size = SpecializedChunk; + *class_chunk_word_size = ClassSpecializedChunk; + break; + default: + *chunk_word_size = SmallChunk; + *class_chunk_word_size = ClassSmallChunk; + break; + } + assert(chunk_word_size != 0 && class_chunk_word_size != 0, + err_msg("Initial chunks sizes bad: data " SIZE_FORMAT + " class " SIZE_FORMAT, + chunk_word_size, class_chunk_word_size)); +} + size_t SpaceManager::sum_free_in_chunks_in_use() const { MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); size_t free = 0; - for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { Metachunk* chunk = chunks_in_use(i); while (chunk != NULL) { free += chunk->free_word_size(); @@ -1667,9 +1759,7 @@ size_t SpaceManager::sum_waste_in_chunks_in_use() const { MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); size_t result = 0; - for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { - - + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { result += sum_waste_in_chunks_in_use(i); } @@ -1678,7 +1768,6 @@ size_t SpaceManager::sum_waste_in_chunks_in_use(ChunkIndex index) const { size_t result = 0; - size_t count = 0; Metachunk* chunk = chunks_in_use(index); // Count the free space in all the chunk but not the // current chunk from which allocations are still being done. @@ -1688,7 +1777,6 @@ result += chunk->free_word_size(); prev = chunk; chunk = chunk->next(); - count++; } } return result; @@ -1697,7 +1785,7 @@ size_t SpaceManager::sum_capacity_in_chunks_in_use() const { MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); size_t sum = 0; - for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { Metachunk* chunk = chunks_in_use(i); while (chunk != NULL) { // Just changed this sum += chunk->capacity_word_size(); @@ -1711,7 +1799,7 @@ size_t SpaceManager::sum_count_in_chunks_in_use() { size_t count = 0; - for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { count = count + sum_count_in_chunks_in_use(i); } @@ -1732,7 +1820,7 @@ size_t SpaceManager::sum_used_in_chunks_in_use() const { MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); size_t used = 0; - for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { Metachunk* chunk = chunks_in_use(i); while (chunk != NULL) { used += chunk->used_word_size(); @@ -1744,19 +1832,17 @@ void SpaceManager::locked_print_chunks_in_use_on(outputStream* st) const { - Metachunk* small_chunk = chunks_in_use(SmallIndex); - st->print_cr("SpaceManager: small chunk " PTR_FORMAT - " free " SIZE_FORMAT, - small_chunk, - small_chunk->free_word_size()); - - Metachunk* medium_chunk = chunks_in_use(MediumIndex); - st->print("medium chunk " PTR_FORMAT, medium_chunk); - Metachunk* tail = current_chunk(); - st->print_cr(" current chunk " PTR_FORMAT, tail); - - Metachunk* head = chunks_in_use(HumongousIndex); - st->print_cr("humongous chunk " PTR_FORMAT, head); + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + Metachunk* chunk = chunks_in_use(i); + st->print("SpaceManager: %s " PTR_FORMAT, + chunk_size_name(i), chunk); + if (chunk != NULL) { + st->print_cr(" free " SIZE_FORMAT, + chunk->free_word_size()); + } else { + st->print_cr(""); + } + } vs_list()->chunk_manager()->locked_print_free_chunks(st); vs_list()->chunk_manager()->locked_print_sum_free_chunks(st); @@ -1772,18 +1858,28 @@ if (chunks_in_use(MediumIndex) == NULL && (!has_small_chunk_limit() || sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit)) { - chunk_word_size = (size_t) SpaceManager::SmallChunk; - if (word_size + Metachunk::overhead() > SpaceManager::SmallChunk) { - chunk_word_size = MediumChunk; + chunk_word_size = (size_t) small_chunk_size(); + if (word_size + Metachunk::overhead() > small_chunk_size()) { + chunk_word_size = medium_chunk_size(); } } else { - chunk_word_size = MediumChunk; + chunk_word_size = medium_chunk_size(); } - // Might still need a humongous chunk + // Might still need a humongous chunk. Enforce an + // eight word granularity to facilitate reuse (some + // wastage but better chance of reuse). + size_t if_humongous_sized_chunk = + align_size_up(word_size + Metachunk::overhead(), + HumongousChunkGranularity); chunk_word_size = - MAX2((size_t) chunk_word_size, word_size + Metachunk::overhead()); - + MAX2((size_t) chunk_word_size, if_humongous_sized_chunk); + + assert(!SpaceManager::is_humongous(word_size) || + chunk_word_size == if_humongous_sized_chunk, + err_msg("Size calculation is wrong, word_size " SIZE_FORMAT + " chunk_word_size " SIZE_FORMAT, + word_size, chunk_word_size)); if (TraceMetadataHumongousAllocation && SpaceManager::is_humongous(word_size)) { gclog_or_tty->print_cr("Metadata humongous allocation:"); @@ -1805,15 +1901,21 @@ MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); if (TraceMetadataChunkAllocation && Verbose) { + size_t words_left = 0; + size_t words_used = 0; + if (current_chunk() != NULL) { + words_left = current_chunk()->free_word_size(); + words_used = current_chunk()->used_word_size(); + } gclog_or_tty->print_cr("SpaceManager::grow_and_allocate for " SIZE_FORMAT - " words " SIZE_FORMAT " space left", - word_size, current_chunk() != NULL ? - current_chunk()->free_word_size() : 0); + " words " SIZE_FORMAT " words used " SIZE_FORMAT + " words left", + word_size, words_used, words_left); } // Get another chunk out of the virtual space size_t grow_chunks_by_words = calc_chunk_size(word_size); - Metachunk* next = vs_list()->get_new_chunk(word_size, grow_chunks_by_words); + Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words); // If a chunk was available, add it to the in-use chunk list // and do an allocation from it. @@ -1828,7 +1930,7 @@ void SpaceManager::print_on(outputStream* st) const { - for (ChunkIndex i = SmallIndex; + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists ; i = next_chunk_index(i) ) { st->print_cr(" chunks_in_use " PTR_FORMAT " chunk size " PTR_FORMAT, @@ -1847,12 +1949,18 @@ } } -SpaceManager::SpaceManager(Mutex* lock, VirtualSpaceList* vs_list) : +SpaceManager::SpaceManager(Mutex* lock, + VirtualSpaceList* vs_list) : _vs_list(vs_list), _allocation_total(0), - _lock(lock) { + _lock(lock) +{ + initialize(); +} + +void SpaceManager::initialize() { Metadebug::init_allocation_fail_alot_count(); - for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { _chunks_in_use[i] = NULL; } _current_chunk = NULL; @@ -1885,30 +1993,37 @@ // Add all the chunks in use by this space manager // to the global list of free chunks. - // Small chunks. There is one _current_chunk for each - // Metaspace. It could point to a small or medium chunk. - // Rather than determine which it is, follow the list of - // small chunks to add them to the free list - Metachunk* small_chunk = chunks_in_use(SmallIndex); - chunk_manager->free_small_chunks()->add_at_head(small_chunk); - set_chunks_in_use(SmallIndex, NULL); - - // After the small chunk are the medium chunks - Metachunk* medium_chunk = chunks_in_use(MediumIndex); - assert(medium_chunk == NULL || - medium_chunk->word_size() == MediumChunk, - "Chunk is on the wrong list"); - - if (medium_chunk != NULL) { - Metachunk* head = medium_chunk; - // If there is a medium chunk then the _current_chunk can only - // point to the last medium chunk. - Metachunk* tail = current_chunk(); - chunk_manager->free_medium_chunks()->add_at_head(head, tail); - set_chunks_in_use(MediumIndex, NULL); + // Follow each list of chunks-in-use and add them to the + // free lists. Each list is NULL terminated. + + for (ChunkIndex i = ZeroIndex; i < HumongousIndex; i = next_chunk_index(i)) { + if (TraceMetadataChunkAllocation && Verbose) { + gclog_or_tty->print_cr("returned %d %s chunks to freelist", + sum_count_in_chunks_in_use(i), + chunk_size_name(i)); + } + Metachunk* chunks = chunks_in_use(i); + chunk_manager->free_chunks(i)->add_at_head(chunks); + set_chunks_in_use(i, NULL); + if (TraceMetadataChunkAllocation && Verbose) { + gclog_or_tty->print_cr("updated freelist count %d %s", + chunk_manager->free_chunks(i)->sum_list_count(), + chunk_size_name(i)); + } + assert(i != HumongousIndex, "Humongous chunks are handled explicitly later"); } + // The medium chunk case may be optimized by passing the head and + // tail of the medium chunk list to add_at_head(). The tail is often + // the current chunk but there are probably exceptions. + // Humongous chunks + if (TraceMetadataChunkAllocation && Verbose) { + gclog_or_tty->print_cr("returned %d %s humongous chunks to dictionary", + sum_count_in_chunks_in_use(HumongousIndex), + chunk_size_name(HumongousIndex)); + gclog_or_tty->print("Humongous chunk dictionary: "); + } // Humongous chunks are never the current chunk. Metachunk* humongous_chunks = chunks_in_use(HumongousIndex); @@ -1916,14 +2031,65 @@ #ifdef ASSERT humongous_chunks->set_is_free(true); #endif + if (TraceMetadataChunkAllocation && Verbose) { + gclog_or_tty->print(PTR_FORMAT " (" SIZE_FORMAT ") ", + humongous_chunks, + humongous_chunks->word_size()); + } + assert(humongous_chunks->word_size() == (size_t) + align_size_up(humongous_chunks->word_size(), + HumongousChunkGranularity), + err_msg("Humongous chunk size is wrong: word size " SIZE_FORMAT + " granularity " SIZE_FORMAT, + humongous_chunks->word_size(), HumongousChunkGranularity)); Metachunk* next_humongous_chunks = humongous_chunks->next(); chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks); humongous_chunks = next_humongous_chunks; } + if (TraceMetadataChunkAllocation && Verbose) { + gclog_or_tty->print_cr(""); + gclog_or_tty->print_cr("updated dictionary count %d %s", + chunk_manager->humongous_dictionary()->total_count(), + chunk_size_name(HumongousIndex)); + } set_chunks_in_use(HumongousIndex, NULL); chunk_manager->slow_locked_verify(); } +const char* SpaceManager::chunk_size_name(ChunkIndex index) const { + switch (index) { + case SpecializedIndex: + return "Specialized"; + case SmallIndex: + return "Small"; + case MediumIndex: + return "Medium"; + case HumongousIndex: + return "Humongous"; + default: + return NULL; + } +} + +ChunkIndex ChunkManager::list_index(size_t size) { + switch (size) { + case SpecializedChunk: + assert(SpecializedChunk == ClassSpecializedChunk, + "Need branch for ClassSpecializedChunk"); + return SpecializedIndex; + case SmallChunk: + case ClassSmallChunk: + return SmallIndex; + case MediumChunk: + case ClassMediumChunk: + return MediumIndex; + default: + assert(size > MediumChunk || size > ClassMediumChunk, + "Not a humongous chunk"); + return HumongousIndex; + } +} + void SpaceManager::deallocate(MetaWord* p, size_t word_size) { assert_lock_strong(_lock); size_t min_size = TreeChunk::min_size(); @@ -1942,52 +2108,13 @@ // Find the correct list and and set the current // chunk for that list. - switch (new_chunk->word_size()) { - case SpaceManager::SmallChunk : - if (chunks_in_use(SmallIndex) == NULL) { - // First chunk to add to the list - set_chunks_in_use(SmallIndex, new_chunk); - } else { - assert(current_chunk()->word_size() == SpaceManager::SmallChunk, - err_msg( "Incorrect mix of sizes in chunk list " - SIZE_FORMAT " new chunk " SIZE_FORMAT, - current_chunk()->word_size(), new_chunk->word_size())); - current_chunk()->set_next(new_chunk); - } - // Make current chunk + ChunkIndex index = ChunkManager::list_index(new_chunk->word_size()); + + if (index != HumongousIndex) { set_current_chunk(new_chunk); - break; - case SpaceManager::MediumChunk : - if (chunks_in_use(MediumIndex) == NULL) { - // About to add the first medium chunk so teminate the - // small chunk list. In general once medium chunks are - // being added, we're past the need for small chunks. - if (current_chunk() != NULL) { - // Only a small chunk or the initial chunk could be - // the current chunk if this is the first medium chunk. - assert(current_chunk()->word_size() == SpaceManager::SmallChunk || - chunks_in_use(SmallIndex) == NULL, - err_msg("Should be a small chunk or initial chunk, current chunk " - SIZE_FORMAT " new chunk " SIZE_FORMAT, - current_chunk()->word_size(), new_chunk->word_size())); - current_chunk()->set_next(NULL); - } - // First chunk to add to the list - set_chunks_in_use(MediumIndex, new_chunk); - - } else { - // As a minimum the first medium chunk added would - // have become the _current_chunk - // so the _current_chunk has to be non-NULL here - // (although not necessarily still the first medium chunk). - assert(current_chunk()->word_size() == SpaceManager::MediumChunk, - "A medium chunk should the current chunk"); - current_chunk()->set_next(new_chunk); - } - // Make current chunk - set_current_chunk(new_chunk); - break; - default: { + new_chunk->set_next(chunks_in_use(index)); + set_chunks_in_use(index, new_chunk); + } else { // For null class loader data and DumpSharedSpaces, the first chunk isn't // small, so small will be null. Link this first chunk as the current // chunk. @@ -2002,8 +2129,7 @@ new_chunk->set_next(chunks_in_use(HumongousIndex)); set_chunks_in_use(HumongousIndex, new_chunk); - assert(new_chunk->word_size() > MediumChunk, "List inconsistency"); - } + assert(new_chunk->word_size() > medium_chunk_size(), "List inconsistency"); } assert(new_chunk->is_empty(), "Not ready for reuse"); @@ -2015,6 +2141,22 @@ } } +Metachunk* SpaceManager::get_new_chunk(size_t word_size, + size_t grow_chunks_by_words) { + + Metachunk* next = vs_list()->get_new_chunk(word_size, + grow_chunks_by_words, + medium_chunk_bunch()); + + if (TraceMetadataHumongousAllocation && + SpaceManager::is_humongous(next->word_size())) { + gclog_or_tty->print_cr(" new humongous chunk word size " PTR_FORMAT, + next->word_size()); + } + + return next; +} + MetaWord* SpaceManager::allocate(size_t word_size) { MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); @@ -2090,12 +2232,7 @@ // verfication of chunks does not work since // being in the dictionary alters a chunk. if (block_freelists()->total_size() == 0) { - // Skip the small chunks because their next link points to - // medium chunks. This is because the small chunk is the - // current chunk (for allocations) until it is full and the - // the addition of the next chunk does not NULL the next - // like of the small chunk. - for (ChunkIndex i = MediumIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { Metachunk* curr = chunks_in_use(i); while (curr != NULL) { curr->verify(); @@ -2108,15 +2245,15 @@ void SpaceManager::verify_chunk_size(Metachunk* chunk) { assert(is_humongous(chunk->word_size()) || - chunk->word_size() == MediumChunk || - chunk->word_size() == SmallChunk, + chunk->word_size() == medium_chunk_size() || + chunk->word_size() == small_chunk_size() || + chunk->word_size() == specialized_chunk_size(), "Chunk size is wrong"); return; } #ifdef ASSERT void SpaceManager::verify_allocation_total() { -#if 0 // Verification is only guaranteed at a safepoint. if (SafepointSynchronize::is_at_safepoint()) { gclog_or_tty->print_cr("Chunk " PTR_FORMAT " allocation_total " SIZE_FORMAT @@ -2129,7 +2266,6 @@ assert(allocation_total() == sum_used_in_chunks_in_use(), err_msg("allocation total is not consistent %d vs %d", allocation_total(), sum_used_in_chunks_in_use())); -#endif } #endif @@ -2142,7 +2278,7 @@ size_t capacity = 0; // Add up statistics for all chunks in this SpaceManager. - for (ChunkIndex index = SmallIndex; + for (ChunkIndex index = ZeroIndex; index < NumberOfInUseLists; index = next_chunk_index(index)) { for (Metachunk* curr = chunks_in_use(index); @@ -2160,7 +2296,7 @@ } } - size_t free = current_chunk()->free_word_size(); + size_t free = current_chunk() == NULL ? 0 : current_chunk()->free_word_size(); // Free space isn't wasted. waste -= free; @@ -2171,25 +2307,18 @@ #ifndef PRODUCT void SpaceManager::mangle_freed_chunks() { - for (ChunkIndex index = SmallIndex; + for (ChunkIndex index = ZeroIndex; index < NumberOfInUseLists; index = next_chunk_index(index)) { for (Metachunk* curr = chunks_in_use(index); curr != NULL; curr = curr->next()) { - // Try to detect incorrectly terminated small chunk - // list. - assert(index == MediumIndex || curr != chunks_in_use(MediumIndex), - err_msg("Mangling medium chunks in small chunks? " - "curr " PTR_FORMAT " medium list " PTR_FORMAT, - curr, chunks_in_use(MediumIndex))); curr->mangle(); } } } #endif // PRODUCT - // MetaspaceAux size_t MetaspaceAux::used_in_bytes(Metaspace::MetadataType mdtype) { @@ -2236,7 +2365,7 @@ return reserved * BytesPerWord; } -size_t MetaspaceAux::min_chunk_size() { return SpaceManager::MediumChunk; } +size_t MetaspaceAux::min_chunk_size() { return Metaspace::first_chunk_word_size(); } size_t MetaspaceAux::free_chunks_total(Metaspace::MetadataType mdtype) { ChunkManager* chunk = (mdtype == Metaspace::ClassType) ? @@ -2316,26 +2445,44 @@ // Print total fragmentation for class and data metaspaces separately void MetaspaceAux::print_waste(outputStream* out) { - size_t small_waste = 0, medium_waste = 0, large_waste = 0; - size_t cls_small_waste = 0, cls_medium_waste = 0, cls_large_waste = 0; + size_t specialized_waste = 0, small_waste = 0, medium_waste = 0, large_waste = 0; + size_t specialized_count = 0, small_count = 0, medium_count = 0, large_count = 0; + size_t cls_specialized_waste = 0, cls_small_waste = 0, cls_medium_waste = 0, cls_large_waste = 0; + size_t cls_specialized_count = 0, cls_small_count = 0, cls_medium_count = 0, cls_large_count = 0; ClassLoaderDataGraphMetaspaceIterator iter; while (iter.repeat()) { Metaspace* msp = iter.get_next(); if (msp != NULL) { + specialized_waste += msp->vsm()->sum_waste_in_chunks_in_use(SpecializedIndex); + specialized_count += msp->vsm()->sum_count_in_chunks_in_use(SpecializedIndex); small_waste += msp->vsm()->sum_waste_in_chunks_in_use(SmallIndex); + small_count += msp->vsm()->sum_count_in_chunks_in_use(SmallIndex); medium_waste += msp->vsm()->sum_waste_in_chunks_in_use(MediumIndex); + medium_count += msp->vsm()->sum_count_in_chunks_in_use(MediumIndex); large_waste += msp->vsm()->sum_waste_in_chunks_in_use(HumongousIndex); - + large_count += msp->vsm()->sum_count_in_chunks_in_use(HumongousIndex); + + cls_specialized_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SpecializedIndex); + cls_specialized_count += msp->class_vsm()->sum_count_in_chunks_in_use(SpecializedIndex); cls_small_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SmallIndex); + cls_small_count += msp->class_vsm()->sum_count_in_chunks_in_use(SmallIndex); cls_medium_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(MediumIndex); + cls_medium_count += msp->class_vsm()->sum_count_in_chunks_in_use(MediumIndex); cls_large_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(HumongousIndex); + cls_large_count += msp->class_vsm()->sum_count_in_chunks_in_use(HumongousIndex); } } out->print_cr("Total fragmentation waste (words) doesn't count free space"); - out->print(" data: small " SIZE_FORMAT " medium " SIZE_FORMAT, - small_waste, medium_waste); - out->print_cr(" class: small " SIZE_FORMAT, cls_small_waste); + out->print_cr(" data: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", " + SIZE_FORMAT " small(s) " SIZE_FORMAT ", " + SIZE_FORMAT " medium(s) " SIZE_FORMAT, + specialized_count, specialized_waste, small_count, + small_waste, medium_count, medium_waste); + out->print_cr(" class: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", " + SIZE_FORMAT " small(s) " SIZE_FORMAT, + cls_specialized_count, cls_specialized_waste, + cls_small_count, cls_small_waste); } // Dump global metaspace things from the end of ClassLoaderDataGraph @@ -2354,13 +2501,10 @@ // Metaspace methods size_t Metaspace::_first_chunk_word_size = 0; - -Metaspace::Metaspace(Mutex* lock, size_t word_size) { - initialize(lock, word_size); -} - -Metaspace::Metaspace(Mutex* lock) { - initialize(lock); +size_t Metaspace::_first_class_chunk_word_size = 0; + +Metaspace::Metaspace(Mutex* lock, MetaspaceType type) { + initialize(lock, type); } Metaspace::~Metaspace() { @@ -2412,11 +2556,18 @@ } } - // Initialize this before initializing the VirtualSpaceList + // Initialize these before initializing the VirtualSpaceList _first_chunk_word_size = InitialBootClassLoaderMetaspaceSize / BytesPerWord; + _first_chunk_word_size = align_word_size_up(_first_chunk_word_size); + // Make the first class chunk bigger than a medium chunk so it's not put + // on the medium chunk list. The next chunk will be small and progress + // from there. This size calculated by -version. + _first_class_chunk_word_size = MIN2((size_t)MediumChunk*6, + (ClassMetaspaceSize/BytesPerWord)*2); + _first_class_chunk_word_size = align_word_size_up(_first_class_chunk_word_size); // Arbitrarily set the initial virtual space to a multiple // of the boot class loader size. - size_t word_size = VIRTUALSPACEMULTIPLIER * Metaspace::first_chunk_word_size(); + size_t word_size = VIRTUALSPACEMULTIPLIER * first_chunk_word_size(); // Initialize the list of virtual spaces. _space_list = new VirtualSpaceList(word_size); } @@ -2431,23 +2582,8 @@ _class_space_list = new VirtualSpaceList(rs); } - -void Metaspace::initialize(Mutex* lock, size_t initial_size) { - // Use SmallChunk size if not specified. If specified, use this size for - // the data metaspace. - size_t word_size; - size_t class_word_size; - if (initial_size == 0) { - word_size = (size_t) SpaceManager::SmallChunk; - class_word_size = (size_t) SpaceManager::SmallChunk; - } else { - word_size = initial_size; - // Make the first class chunk bigger than a medium chunk so it's not put - // on the medium chunk list. The next chunk will be small and progress - // from there. This size calculated by -version. - class_word_size = MIN2((size_t)SpaceManager::MediumChunk*5, - (ClassMetaspaceSize/BytesPerWord)*2); - } +void Metaspace::initialize(Mutex* lock, + MetaspaceType type) { assert(space_list() != NULL, "Metadata VirtualSpaceList has not been initialized"); @@ -2456,6 +2592,11 @@ if (_vsm == NULL) { return; } + size_t word_size; + size_t class_word_size; + vsm()->get_initial_chunk_sizes(type, + &word_size, + &class_word_size); assert(class_space_list() != NULL, "Class VirtualSpaceList has not been initialized"); @@ -2470,7 +2611,8 @@ // Allocate chunk for metadata objects Metachunk* new_chunk = - space_list()->current_virtual_space()->get_chunk_vs_with_expand(word_size); + space_list()->get_initialization_chunk(word_size, + vsm()->medium_chunk_bunch()); assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks"); if (new_chunk != NULL) { // Add to this manager's list of chunks in use and current_chunk(). @@ -2479,12 +2621,18 @@ // Allocate chunk for class metadata objects Metachunk* class_chunk = - class_space_list()->current_virtual_space()->get_chunk_vs_with_expand(class_word_size); + class_space_list()->get_initialization_chunk(class_word_size, + class_vsm()->medium_chunk_bunch()); if (class_chunk != NULL) { class_vsm()->add_chunk(class_chunk, true); } } +size_t Metaspace::align_word_size_up(size_t word_size) { + size_t byte_size = word_size * wordSize; + return ReservedSpace::allocation_align_size_up(byte_size) / wordSize; +} + MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) { // DumpSharedSpaces doesn't use class metadata area (yet) if (mdtype == ClassType && !DumpSharedSpaces) { @@ -2610,6 +2758,12 @@ // If result is still null, we are out of memory. if (result == NULL) { + if (Verbose && TraceMetadataChunkAllocation) { + gclog_or_tty->print_cr("Metaspace allocation failed for size " + SIZE_FORMAT, word_size); + if (loader_data->metaspace_or_null() != NULL) loader_data->metaspace_or_null()->dump(gclog_or_tty); + MetaspaceAux::dump(gclog_or_tty); + } // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support report_java_out_of_memory("Metadata space"); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/memory/metaspace.hpp --- a/src/share/vm/memory/metaspace.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/memory/metaspace.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -87,11 +87,23 @@ public: enum MetadataType {ClassType, NonClassType}; + enum MetaspaceType { + StandardMetaspaceType, + BootMetaspaceType, + ROMetaspaceType, + ReadWriteMetaspaceType, + AnonymousMetaspaceType, + ReflectionMetaspaceType + }; private: - void initialize(Mutex* lock, size_t initial_size = 0); + void initialize(Mutex* lock, MetaspaceType type); + + // Align up the word size to the allocation word size + static size_t align_word_size_up(size_t); static size_t _first_chunk_word_size; + static size_t _first_class_chunk_word_size; SpaceManager* _vsm; SpaceManager* vsm() const { return _vsm; } @@ -110,8 +122,7 @@ public: - Metaspace(Mutex* lock, size_t initial_size); - Metaspace(Mutex* lock); + Metaspace(Mutex* lock, MetaspaceType type); ~Metaspace(); // Initialize globals for Metaspace @@ -119,6 +130,7 @@ static void initialize_class_space(ReservedSpace rs); static size_t first_chunk_word_size() { return _first_chunk_word_size; } + static size_t first_class_chunk_word_size() { return _first_class_chunk_word_size; } char* bottom() const; size_t used_words(MetadataType mdtype) const; diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/memory/metaspaceCounters.cpp --- a/src/share/vm/memory/metaspaceCounters.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/memory/metaspaceCounters.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/memory/metaspaceCounters.hpp --- a/src/share/vm/memory/metaspaceCounters.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/memory/metaspaceCounters.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/memory/space.cpp --- a/src/share/vm/memory/space.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/memory/space.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -411,7 +411,6 @@ assert(q->forwardee() == NULL, "should be forwarded to NULL"); } - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(q, size)); compact_top += size; // we need to update the offset table so that the beginnings of objects can be @@ -470,13 +469,10 @@ if (oop(q)->is_gc_marked()) { // q is alive - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q))); // point all the oops to the new location size_t size = oop(q)->adjust_pointers(); - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers()); debug_only(prev_q = q); - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size)); q += size; } else { diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/memory/space.hpp --- a/src/share/vm/memory/space.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/memory/space.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -655,16 +655,10 @@ assert(block_is_obj(q), \ "should be at block boundaries, and should be looking at objs"); \ \ - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q))); \ - \ /* point all the oops to the new location */ \ size_t size = oop(q)->adjust_pointers(); \ size = adjust_obj_size(size); \ \ - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers()); \ - \ - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size)); \ - \ q += size; \ } \ \ @@ -685,12 +679,9 @@ Prefetch::write(q, interval); \ if (oop(q)->is_gc_marked()) { \ /* q is alive */ \ - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q))); \ /* point all the oops to the new location */ \ size_t size = oop(q)->adjust_pointers(); \ size = adjust_obj_size(size); \ - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers()); \ - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size)); \ debug_only(prev_q = q); \ q += size; \ } else { \ @@ -725,7 +716,6 @@ size_t size = obj_size(q); \ assert(!oop(q)->is_gc_marked(), \ "should be unmarked (special dense prefix handling)"); \ - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, q)); \ debug_only(prev_q = q); \ q += size; \ } \ @@ -759,8 +749,6 @@ Prefetch::write(compaction_top, copy_interval); \ \ /* copy object and reinit its mark */ \ - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, \ - compaction_top)); \ assert(q != compaction_top, "everything in this pass should be moving"); \ Copy::aligned_conjoint_words(q, compaction_top, size); \ oop(compaction_top)->init_mark(); \ diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/memory/tenuredGeneration.cpp --- a/src/share/vm/memory/tenuredGeneration.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/memory/tenuredGeneration.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -62,7 +62,7 @@ _virtual_space.reserved_size(), _the_space, _gen_counters); #ifndef SERIALGC - if (UseParNewGC && ParallelGCThreads > 0) { + if (UseParNewGC) { typedef ParGCAllocBufferWithBOT* ParGCAllocBufferWithBOTPtr; _alloc_buffers = NEW_C_HEAP_ARRAY(ParGCAllocBufferWithBOTPtr, ParallelGCThreads, mtGC); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/oops/instanceKlass.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -2890,11 +2890,7 @@ st->print(BULLET"fake entry for mirror: "); mirrored_klass->print_value_on_maybe_null(st); st->cr(); - st->print(BULLET"fake entry resolved_constructor: "); - Method* ctor = java_lang_Class::resolved_constructor(obj); - ctor->print_value_on_maybe_null(st); Klass* array_klass = java_lang_Class::array_klass(obj); - st->cr(); st->print(BULLET"fake entry for array: "); array_klass->print_value_on_maybe_null(st); st->cr(); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/oops/instanceKlass.hpp --- a/src/share/vm/oops/instanceKlass.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/oops/instanceKlass.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -225,13 +225,17 @@ u2 _java_fields_count; // The number of declared Java fields int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks + // _is_marked_dependent can be set concurrently, thus cannot be part of the + // _misc_flags. bool _is_marked_dependent; // used for marking during flushing and deoptimization + enum { _misc_rewritten = 1 << 0, // methods rewritten. _misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops _misc_should_verify_class = 1 << 2, // allow caching of preverification _misc_is_anonymous = 1 << 3, // has embedded _inner_classes field - _misc_is_contended = 1 << 4 // marked with contended annotation + _misc_is_contended = 1 << 4, // marked with contended annotation + _misc_has_default_methods = 1 << 5 // class/superclass/implemented interfaces has default methods }; u2 _misc_flags; u2 _minor_version; // minor version number of class file @@ -254,10 +258,6 @@ jint _cached_class_file_len; // JVMTI: length of above JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration - // true if class, superclass, or implemented interfaces have default methods - bool _has_default_methods; - - volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change // Method array. Array* _methods; // Interface (Klass*s) this class declares locally to implement. @@ -281,6 +281,8 @@ // ... Array* _fields; + volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change + // Class states are defined as ClassState (see above). // Place the _init_state here to utilize the unused 2-byte after // _idnum_allocated_count. @@ -628,8 +630,16 @@ return _jvmti_cached_class_field_map; } - bool has_default_methods() const { return _has_default_methods; } - void set_has_default_methods(bool b) { _has_default_methods = b; } + bool has_default_methods() const { + return (_misc_flags & _misc_has_default_methods) != 0; + } + void set_has_default_methods(bool b) { + if (b) { + _misc_flags |= _misc_has_default_methods; + } else { + _misc_flags &= ~_misc_has_default_methods; + } + } // for adding methods, ConstMethod::UNSET_IDNUM means no more ids available inline u2 next_method_idnum(); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/oops/method.cpp --- a/src/share/vm/oops/method.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/oops/method.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -194,16 +194,16 @@ return buf; } -int Method::fast_exception_handler_bci_for(KlassHandle ex_klass, int throw_bci, TRAPS) { +int Method::fast_exception_handler_bci_for(methodHandle mh, KlassHandle ex_klass, int throw_bci, TRAPS) { // exception table holds quadruple entries of the form (beg_bci, end_bci, handler_bci, klass_index) // access exception table - ExceptionTable table(this); + ExceptionTable table(mh()); int length = table.length(); // iterate through all entries sequentially - constantPoolHandle pool(THREAD, constants()); + constantPoolHandle pool(THREAD, mh->constants()); for (int i = 0; i < length; i ++) { //reacquire the table in case a GC happened - ExceptionTable table(this); + ExceptionTable table(mh()); int beg_bci = table.start_pc(i); int end_bci = table.end_pc(i); assert(beg_bci <= end_bci, "inconsistent exception table"); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/oops/method.hpp --- a/src/share/vm/oops/method.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/oops/method.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -351,7 +351,7 @@ // exception handler which caused the exception to be thrown, which // is needed for proper retries. See, for example, // InterpreterRuntime::exception_handler_for_exception. - int fast_exception_handler_bci_for(KlassHandle ex_klass, int throw_bci, TRAPS); + static int fast_exception_handler_bci_for(methodHandle mh, KlassHandle ex_klass, int throw_bci, TRAPS); // method data access MethodData* method_data() const { diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/bytecodeInfo.cpp --- a/src/share/vm/opto/bytecodeInfo.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/bytecodeInfo.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -46,7 +46,8 @@ _method(callee), _site_invoke_ratio(site_invoke_ratio), _max_inline_level(max_inline_level), - _count_inline_bcs(method()->code_size_for_inlining()) + _count_inline_bcs(method()->code_size_for_inlining()), + _subtrees(c->comp_arena(), 2, 0, NULL) { NOT_PRODUCT(_count_inlines = 0;) if (_caller_jvms != NULL) { @@ -209,16 +210,18 @@ if ( callee_method->dont_inline()) return "don't inline by annotation"; if ( callee_method->has_unloaded_classes_in_signature()) return "unloaded signature classes"; - if (callee_method->force_inline() || callee_method->should_inline()) { + if (callee_method->should_inline()) { // ignore heuristic controls on inlining return NULL; } // Now perform checks which are heuristic - if (callee_method->has_compiled_code() && - callee_method->instructions_size() > InlineSmallCode) { + if (!callee_method->force_inline()) { + if (callee_method->has_compiled_code() && + callee_method->instructions_size() > InlineSmallCode) { return "already compiled into a big method"; + } } // don't inline exception code unless the top method belongs to an @@ -277,12 +280,15 @@ //-----------------------------try_to_inline----------------------------------- // return NULL if ok, reason for not inlining otherwise // Relocated from "InliningClosure::try_to_inline" -const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) { - +const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result, bool& should_delay) { // Old algorithm had funny accumulating BC-size counters if (UseOldInlining && ClipInlining && (int)count_inline_bcs() >= DesiredMethodLimit) { - return "size > DesiredMethodLimit"; + if (!callee_method->force_inline() || !IncrementalInline) { + return "size > DesiredMethodLimit"; + } else if (!C->inlining_incrementally()) { + should_delay = true; + } } const char *msg = NULL; @@ -303,8 +309,13 @@ if (callee_method->code_size() > MaxTrivialSize) { // don't inline into giant methods - if (C->unique() > (uint)NodeCountInliningCutoff) { - return "NodeCountInliningCutoff"; + if (C->over_inlining_cutoff()) { + if ((!callee_method->force_inline() && !caller_method->is_compiled_lambda_form()) + || !IncrementalInline) { + return "NodeCountInliningCutoff"; + } else { + should_delay = true; + } } if ((!UseInterpreter || CompileTheWorld) && @@ -323,7 +334,11 @@ return "not an accessor"; } if (inline_level() > _max_inline_level) { - return "inlining too deep"; + if (!callee_method->force_inline() || !IncrementalInline) { + return "inlining too deep"; + } else if (!C->inlining_incrementally()) { + should_delay = true; + } } // detect direct and indirect recursive inlining @@ -348,7 +363,11 @@ if (UseOldInlining && ClipInlining && (int)count_inline_bcs() + size >= DesiredMethodLimit) { - return "size > DesiredMethodLimit"; + if (!callee_method->force_inline() || !IncrementalInline) { + return "size > DesiredMethodLimit"; + } else if (!C->inlining_incrementally()) { + should_delay = true; + } } // ok, inline this method @@ -413,8 +432,9 @@ } //------------------------------ok_to_inline----------------------------------- -WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, ciCallProfile& profile, WarmCallInfo* initial_wci) { +WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, ciCallProfile& profile, WarmCallInfo* initial_wci, bool& should_delay) { assert(callee_method != NULL, "caller checks for optimized virtual!"); + assert(!should_delay, "should be initialized to false"); #ifdef ASSERT // Make sure the incoming jvms has the same information content as me. // This means that we can eventually make this whole class AllStatic. @@ -444,7 +464,7 @@ // Check if inlining policy says no. WarmCallInfo wci = *(initial_wci); - failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, &wci); + failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, &wci, should_delay); if (failure_msg != NULL && C->log() != NULL) { C->log()->inline_fail(failure_msg); } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/c2_globals.hpp --- a/src/share/vm/opto/c2_globals.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/c2_globals.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -606,6 +606,16 @@ \ develop(bool, VerifyAliases, false, \ "perform extra checks on the results of alias analysis") \ + \ + product(bool, IncrementalInline, true, \ + "do post parse inlining") \ + \ + develop(bool, AlwaysIncrementalInline, false, \ + "do all inlining incrementally") \ + \ + product(intx, LiveNodeCountInliningCutoff, 20000, \ + "max number of live nodes in a method") \ + C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG) diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/callGenerator.cpp --- a/src/share/vm/opto/callGenerator.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/callGenerator.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -262,8 +262,11 @@ // Allow inlining decisions to be delayed class LateInlineCallGenerator : public DirectCallGenerator { + protected: CallGenerator* _inline_cg; + virtual bool do_late_inline_check(JVMState* jvms) { return true; } + public: LateInlineCallGenerator(ciMethod* method, CallGenerator* inline_cg) : DirectCallGenerator(method, true), _inline_cg(inline_cg) {} @@ -279,7 +282,9 @@ // Record that this call site should be revisited once the main // parse is finished. - Compile::current()->add_late_inline(this); + if (!is_mh_late_inline()) { + C->add_late_inline(this); + } // Emit the CallStaticJava and request separate projections so // that the late inlining logic can distinguish between fall @@ -287,15 +292,34 @@ // as is done for allocations and macro expansion. return DirectCallGenerator::generate(jvms); } + + virtual void print_inlining_late(const char* msg) { + CallNode* call = call_node(); + Compile* C = Compile::current(); + C->print_inlining_insert(this); + C->print_inlining(method(), call->jvms()->depth()-1, call->jvms()->bci(), msg); + } + }; - void LateInlineCallGenerator::do_late_inline() { // Can't inline it if (call_node() == NULL || call_node()->outcnt() == 0 || call_node()->in(0) == NULL || call_node()->in(0)->is_top()) return; + for (int i1 = 0; i1 < method()->arg_size(); i1++) { + if (call_node()->in(TypeFunc::Parms + i1)->is_top()) { + assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing"); + return; + } + } + + if (call_node()->in(TypeFunc::Memory)->is_top()) { + assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing"); + return; + } + CallStaticJavaNode* call = call_node(); // Make a clone of the JVMState that appropriate to use for driving a parse @@ -324,6 +348,11 @@ } } + if (!do_late_inline_check(jvms)) { + map->disconnect_inputs(NULL, C); + return; + } + C->print_inlining_insert(this); CompileLog* log = C->log(); @@ -360,6 +389,10 @@ result = (result_size == 1) ? kit.pop() : kit.pop_pair(); } + C->set_has_loops(C->has_loops() || _inline_cg->method()->has_loops()); + C->env()->notice_inlined_method(_inline_cg->method()); + C->set_inlining_progress(true); + kit.replace_call(call, result); } @@ -368,6 +401,83 @@ return new LateInlineCallGenerator(method, inline_cg); } +class LateInlineMHCallGenerator : public LateInlineCallGenerator { + ciMethod* _caller; + int _attempt; + bool _input_not_const; + + virtual bool do_late_inline_check(JVMState* jvms); + virtual bool already_attempted() const { return _attempt > 0; } + + public: + LateInlineMHCallGenerator(ciMethod* caller, ciMethod* callee, bool input_not_const) : + LateInlineCallGenerator(callee, NULL), _caller(caller), _attempt(0), _input_not_const(input_not_const) {} + + virtual bool is_mh_late_inline() const { return true; } + + virtual JVMState* generate(JVMState* jvms) { + JVMState* new_jvms = LateInlineCallGenerator::generate(jvms); + if (_input_not_const) { + // inlining won't be possible so no need to enqueue right now. + call_node()->set_generator(this); + } else { + Compile::current()->add_late_inline(this); + } + return new_jvms; + } + + virtual void print_inlining_late(const char* msg) { + if (!_input_not_const) return; + LateInlineCallGenerator::print_inlining_late(msg); + } +}; + +bool LateInlineMHCallGenerator::do_late_inline_check(JVMState* jvms) { + + CallGenerator* cg = for_method_handle_inline(jvms, _caller, method(), _input_not_const); + + if (!_input_not_const) { + _attempt++; + } + + if (cg != NULL) { + assert(!cg->is_late_inline() && cg->is_inline(), "we're doing late inlining"); + _inline_cg = cg; + Compile::current()->dec_number_of_mh_late_inlines(); + return true; + } + + call_node()->set_generator(this); + return false; +} + +CallGenerator* CallGenerator::for_mh_late_inline(ciMethod* caller, ciMethod* callee, bool input_not_const) { + Compile::current()->inc_number_of_mh_late_inlines(); + CallGenerator* cg = new LateInlineMHCallGenerator(caller, callee, input_not_const); + return cg; +} + +class LateInlineStringCallGenerator : public LateInlineCallGenerator { + + public: + LateInlineStringCallGenerator(ciMethod* method, CallGenerator* inline_cg) : + LateInlineCallGenerator(method, inline_cg) {} + + virtual JVMState* generate(JVMState* jvms) { + Compile *C = Compile::current(); + C->print_inlining_skip(this); + + C->add_string_late_inline(this); + + JVMState* new_jvms = DirectCallGenerator::generate(jvms); + return new_jvms; + } +}; + +CallGenerator* CallGenerator::for_string_late_inline(ciMethod* method, CallGenerator* inline_cg) { + return new LateInlineStringCallGenerator(method, inline_cg); +} + //---------------------------WarmCallGenerator-------------------------------- // Internal class which handles initial deferral of inlining decisions. @@ -586,35 +696,53 @@ } -CallGenerator* CallGenerator::for_method_handle_call(JVMState* jvms, ciMethod* caller, ciMethod* callee) { +CallGenerator* CallGenerator::for_method_handle_call(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool delayed_forbidden) { assert(callee->is_method_handle_intrinsic() || callee->is_compiled_lambda_form(), "for_method_handle_call mismatch"); - CallGenerator* cg = CallGenerator::for_method_handle_inline(jvms, caller, callee); - if (cg != NULL) - return cg; - return CallGenerator::for_direct_call(callee); + bool input_not_const; + CallGenerator* cg = CallGenerator::for_method_handle_inline(jvms, caller, callee, input_not_const); + Compile* C = Compile::current(); + if (cg != NULL) { + if (!delayed_forbidden && AlwaysIncrementalInline) { + return CallGenerator::for_late_inline(callee, cg); + } else { + return cg; + } + } + int bci = jvms->bci(); + ciCallProfile profile = caller->call_profile_at_bci(bci); + int call_site_count = caller->scale_count(profile.count()); + + if (IncrementalInline && call_site_count > 0 && + (input_not_const || !C->inlining_incrementally() || C->over_inlining_cutoff())) { + return CallGenerator::for_mh_late_inline(caller, callee, input_not_const); + } else { + // Out-of-line call. + return CallGenerator::for_direct_call(callee); + } } -CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee) { +CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool& input_not_const) { GraphKit kit(jvms); PhaseGVN& gvn = kit.gvn(); Compile* C = kit.C; vmIntrinsics::ID iid = callee->intrinsic_id(); + input_not_const = true; switch (iid) { case vmIntrinsics::_invokeBasic: { // Get MethodHandle receiver: Node* receiver = kit.argument(0); if (receiver->Opcode() == Op_ConP) { + input_not_const = false; const TypeOopPtr* oop_ptr = receiver->bottom_type()->is_oopptr(); ciMethod* target = oop_ptr->const_oop()->as_method_handle()->get_vmtarget(); guarantee(!target->is_method_handle_intrinsic(), "should not happen"); // XXX remove const int vtable_index = Method::invalid_vtable_index; - CallGenerator* cg = C->call_generator(target, vtable_index, false, jvms, true, PROB_ALWAYS); + CallGenerator* cg = C->call_generator(target, vtable_index, false, jvms, true, PROB_ALWAYS, true, true); + assert(!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here"); if (cg != NULL && cg->is_inline()) return cg; - } else { - if (PrintInlining) C->print_inlining(callee, jvms->depth() - 1, jvms->bci(), "receiver not constant"); } } break; @@ -627,6 +755,7 @@ // Get MemberName argument: Node* member_name = kit.argument(callee->arg_size() - 1); if (member_name->Opcode() == Op_ConP) { + input_not_const = false; const TypeOopPtr* oop_ptr = member_name->bottom_type()->is_oopptr(); ciMethod* target = oop_ptr->const_oop()->as_member_name()->get_vmtarget(); @@ -659,9 +788,25 @@ } } } - const int vtable_index = Method::invalid_vtable_index; - const bool call_is_virtual = target->is_abstract(); // FIXME workaround - CallGenerator* cg = C->call_generator(target, vtable_index, call_is_virtual, jvms, true, PROB_ALWAYS); + + // Try to get the most accurate receiver type + const bool is_virtual = (iid == vmIntrinsics::_linkToVirtual); + const bool is_virtual_or_interface = (is_virtual || iid == vmIntrinsics::_linkToInterface); + int vtable_index = Method::invalid_vtable_index; + bool call_does_dispatch = false; + + if (is_virtual_or_interface) { + ciInstanceKlass* klass = target->holder(); + Node* receiver_node = kit.argument(0); + const TypeOopPtr* receiver_type = gvn.type(receiver_node)->isa_oopptr(); + // call_does_dispatch and vtable_index are out-parameters. They might be changed. + target = C->optimize_virtual_call(caller, jvms->bci(), klass, target, receiver_type, + is_virtual, + call_does_dispatch, vtable_index); // out-parameters + } + + CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms, true, PROB_ALWAYS, true, true); + assert(!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here"); if (cg != NULL && cg->is_inline()) return cg; } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/callGenerator.hpp --- a/src/share/vm/opto/callGenerator.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/callGenerator.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -68,6 +68,12 @@ // is_late_inline: supports conversion of call into an inline virtual bool is_late_inline() const { return false; } + // same but for method handle calls + virtual bool is_mh_late_inline() const { return false; } + + // for method handle calls: have we tried inlinining the call already? + virtual bool already_attempted() const { ShouldNotReachHere(); return false; } + // Replace the call with an inline version of the code virtual void do_late_inline() { ShouldNotReachHere(); } @@ -112,11 +118,13 @@ static CallGenerator* for_virtual_call(ciMethod* m, int vtable_index); // virtual, interface static CallGenerator* for_dynamic_call(ciMethod* m); // invokedynamic - static CallGenerator* for_method_handle_call( JVMState* jvms, ciMethod* caller, ciMethod* callee); - static CallGenerator* for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee); + static CallGenerator* for_method_handle_call( JVMState* jvms, ciMethod* caller, ciMethod* callee, bool delayed_forbidden); + static CallGenerator* for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool& input_not_const); // How to generate a replace a direct call with an inline version static CallGenerator* for_late_inline(ciMethod* m, CallGenerator* inline_cg); + static CallGenerator* for_mh_late_inline(ciMethod* caller, ciMethod* callee, bool input_not_const); + static CallGenerator* for_string_late_inline(ciMethod* m, CallGenerator* inline_cg); // How to make a call but defer the decision whether to inline or not. static CallGenerator* for_warm_call(WarmCallInfo* ci, @@ -147,6 +155,8 @@ CallGenerator* cg); virtual Node* generate_predicate(JVMState* jvms) { return NULL; }; + virtual void print_inlining_late(const char* msg) { ShouldNotReachHere(); } + static void print_inlining(Compile* C, ciMethod* callee, int inline_level, int bci, const char* msg) { if (PrintInlining) C->print_inlining(callee, inline_level, bci, msg); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/callnode.cpp --- a/src/share/vm/opto/callnode.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/callnode.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "ci/bcEscapeAnalyzer.hpp" #include "compiler/oopMap.hpp" +#include "opto/callGenerator.hpp" #include "opto/callnode.hpp" #include "opto/escape.hpp" #include "opto/locknode.hpp" @@ -775,16 +776,38 @@ // and the exception object may not exist if an exception handler // swallows the exception but all the other must exist and be found. assert(projs->fallthrough_proj != NULL, "must be found"); - assert(projs->fallthrough_catchproj != NULL, "must be found"); - assert(projs->fallthrough_memproj != NULL, "must be found"); - assert(projs->fallthrough_ioproj != NULL, "must be found"); - assert(projs->catchall_catchproj != NULL, "must be found"); + assert(Compile::current()->inlining_incrementally() || projs->fallthrough_catchproj != NULL, "must be found"); + assert(Compile::current()->inlining_incrementally() || projs->fallthrough_memproj != NULL, "must be found"); + assert(Compile::current()->inlining_incrementally() || projs->fallthrough_ioproj != NULL, "must be found"); + assert(Compile::current()->inlining_incrementally() || projs->catchall_catchproj != NULL, "must be found"); if (separate_io_proj) { - assert(projs->catchall_memproj != NULL, "must be found"); - assert(projs->catchall_ioproj != NULL, "must be found"); + assert(Compile::current()->inlining_incrementally() || projs->catchall_memproj != NULL, "must be found"); + assert(Compile::current()->inlining_incrementally() || projs->catchall_ioproj != NULL, "must be found"); } } +Node *CallNode::Ideal(PhaseGVN *phase, bool can_reshape) { + CallGenerator* cg = generator(); + if (can_reshape && cg != NULL && cg->is_mh_late_inline() && !cg->already_attempted()) { + // Check whether this MH handle call becomes a candidate for inlining + ciMethod* callee = cg->method(); + vmIntrinsics::ID iid = callee->intrinsic_id(); + if (iid == vmIntrinsics::_invokeBasic) { + if (in(TypeFunc::Parms)->Opcode() == Op_ConP) { + phase->C->prepend_late_inline(cg); + set_generator(NULL); + } + } else { + assert(callee->has_member_arg(), "wrong type of call?"); + if (in(TypeFunc::Parms + callee->arg_size() - 1)->Opcode() == Op_ConP) { + phase->C->prepend_late_inline(cg); + set_generator(NULL); + } + } + } + return SafePointNode::Ideal(phase, can_reshape); +} + //============================================================================= uint CallJavaNode::size_of() const { return sizeof(*this); } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/callnode.hpp --- a/src/share/vm/opto/callnode.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/callnode.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -507,6 +507,7 @@ Node* exobj; }; +class CallGenerator; //------------------------------CallNode--------------------------------------- // Call nodes now subsume the function of debug nodes at callsites, so they @@ -517,26 +518,31 @@ const TypeFunc *_tf; // Function type address _entry_point; // Address of method being called float _cnt; // Estimate of number of times called + CallGenerator* _generator; // corresponding CallGenerator for some late inline calls CallNode(const TypeFunc* tf, address addr, const TypePtr* adr_type) : SafePointNode(tf->domain()->cnt(), NULL, adr_type), _tf(tf), _entry_point(addr), - _cnt(COUNT_UNKNOWN) + _cnt(COUNT_UNKNOWN), + _generator(NULL) { init_class_id(Class_Call); } - const TypeFunc* tf() const { return _tf; } - const address entry_point() const { return _entry_point; } - const float cnt() const { return _cnt; } + const TypeFunc* tf() const { return _tf; } + const address entry_point() const { return _entry_point; } + const float cnt() const { return _cnt; } + CallGenerator* generator() const { return _generator; } - void set_tf(const TypeFunc* tf) { _tf = tf; } - void set_entry_point(address p) { _entry_point = p; } - void set_cnt(float c) { _cnt = c; } + void set_tf(const TypeFunc* tf) { _tf = tf; } + void set_entry_point(address p) { _entry_point = p; } + void set_cnt(float c) { _cnt = c; } + void set_generator(CallGenerator* cg) { _generator = cg; } virtual const Type *bottom_type() const; virtual const Type *Value( PhaseTransform *phase ) const; + virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); virtual Node *Identity( PhaseTransform *phase ) { return this; } virtual uint cmp( const Node &n ) const; virtual uint size_of() const = 0; diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/cfgnode.cpp --- a/src/share/vm/opto/cfgnode.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/cfgnode.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -363,6 +363,49 @@ return true; // The Region node is unreachable - it is dead. } +bool RegionNode::try_clean_mem_phi(PhaseGVN *phase) { + // Incremental inlining + PhaseStringOpts sometimes produce: + // + // cmpP with 1 top input + // | + // If + // / \ + // IfFalse IfTrue /- Some Node + // \ / / / + // Region / /-MergeMem + // \---Phi + // + // + // It's expected by PhaseStringOpts that the Region goes away and is + // replaced by If's control input but because there's still a Phi, + // the Region stays in the graph. The top input from the cmpP is + // propagated forward and a subgraph that is useful goes away. The + // code below replaces the Phi with the MergeMem so that the Region + // is simplified. + + PhiNode* phi = has_unique_phi(); + if (phi && phi->type() == Type::MEMORY && req() == 3 && phi->is_diamond_phi(true)) { + MergeMemNode* m = NULL; + assert(phi->req() == 3, "same as region"); + for (uint i = 1; i < 3; ++i) { + Node *mem = phi->in(i); + if (mem && mem->is_MergeMem() && in(i)->outcnt() == 1) { + // Nothing is control-dependent on path #i except the region itself. + m = mem->as_MergeMem(); + uint j = 3 - i; + Node* other = phi->in(j); + if (other && other == m->base_memory()) { + // m is a successor memory to other, and is not pinned inside the diamond, so push it out. + // This will allow the diamond to collapse completely. + phase->is_IterGVN()->replace_node(phi, m); + return true; + } + } + } + } + return false; +} + //------------------------------Ideal------------------------------------------ // Return a node which is more "ideal" than the current node. Must preserve // the CFG, but we can still strip out dead paths. @@ -375,6 +418,10 @@ bool has_phis = false; if (can_reshape) { // Need DU info to check for Phi users has_phis = (has_phi() != NULL); // Cache result + if (has_phis && try_clean_mem_phi(phase)) { + has_phis = false; + } + if (!has_phis) { // No Phi users? Nothing merging? for (uint i = 1; i < req()-1; i++) { Node *if1 = in(i); @@ -1005,7 +1052,9 @@ //------------------------------is_diamond_phi--------------------------------- // Does this Phi represent a simple well-shaped diamond merge? Return the // index of the true path or 0 otherwise. -int PhiNode::is_diamond_phi() const { +// If check_control_only is true, do not inspect the If node at the +// top, and return -1 (not an edge number) on success. +int PhiNode::is_diamond_phi(bool check_control_only) const { // Check for a 2-path merge Node *region = in(0); if( !region ) return 0; @@ -1018,6 +1067,7 @@ Node *iff = ifp1->in(0); if( !iff || !iff->is_If() ) return 0; if( iff != ifp2->in(0) ) return 0; + if (check_control_only) return -1; // Check for a proper bool/cmp const Node *b = iff->in(1); if( !b->is_Bool() ) return 0; diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/cfgnode.hpp --- a/src/share/vm/opto/cfgnode.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/cfgnode.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -95,6 +95,7 @@ virtual Node *Identity( PhaseTransform *phase ); virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); virtual const RegMask &out_RegMask() const; + bool try_clean_mem_phi(PhaseGVN *phase); }; //------------------------------JProjNode-------------------------------------- @@ -181,7 +182,7 @@ LoopSafety simple_data_loop_check(Node *in) const; // Is it unsafe data loop? It becomes a dead loop if this phi node removed. bool is_unsafe_data_reference(Node *in) const; - int is_diamond_phi() const; + int is_diamond_phi(bool check_control_only = false) const; virtual int Opcode() const; virtual bool pinned() const { return in(0) != 0; } virtual const TypePtr *adr_type() const { verify_adr_type(true); return _adr_type; } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/compile.cpp --- a/src/share/vm/opto/compile.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/compile.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -136,7 +136,7 @@ void Compile::register_intrinsic(CallGenerator* cg) { if (_intrinsics == NULL) { - _intrinsics = new GrowableArray(60); + _intrinsics = new (comp_arena())GrowableArray(comp_arena(), 60, 0, NULL); } // This code is stolen from ciObjectFactory::insert. // Really, GrowableArray should have methods for @@ -365,6 +365,21 @@ } } +void Compile::remove_useless_late_inlines(GrowableArray* inlines, Unique_Node_List &useful) { + int shift = 0; + for (int i = 0; i < inlines->length(); i++) { + CallGenerator* cg = inlines->at(i); + CallNode* call = cg->call_node(); + if (shift > 0) { + inlines->at_put(i-shift, cg); + } + if (!useful.member(call)) { + shift++; + } + } + inlines->trunc_to(inlines->length()-shift); +} + // Disconnect all useless nodes by disconnecting those at the boundary. void Compile::remove_useless_nodes(Unique_Node_List &useful) { uint next = 0; @@ -394,6 +409,9 @@ remove_macro_node(n); } } + // clean up the late inline lists + remove_useless_late_inlines(&_string_late_inlines, useful); + remove_useless_late_inlines(&_late_inlines, useful); debug_only(verify_graph_edges(true/*check for no_dead_code*/);) } @@ -611,6 +629,12 @@ _printer(IdealGraphPrinter::printer()), #endif _congraph(NULL), + _late_inlines(comp_arena(), 2, 0, NULL), + _string_late_inlines(comp_arena(), 2, 0, NULL), + _late_inlines_pos(0), + _number_of_mh_late_inlines(0), + _inlining_progress(false), + _inlining_incrementally(false), _print_inlining_list(NULL), _print_inlining(0) { C = this; @@ -668,7 +692,7 @@ PhaseGVN gvn(node_arena(), estimated_size); set_initial_gvn(&gvn); - if (PrintInlining) { + if (PrintInlining || PrintIntrinsics NOT_PRODUCT( || PrintOptoInlining)) { _print_inlining_list = new (comp_arena())GrowableArray(comp_arena(), 1, 1, PrintInliningBuffer()); } { // Scope for timing the parser @@ -737,29 +761,13 @@ rethrow_exceptions(kit.transfer_exceptions_into_jvms()); } - if (!failing() && has_stringbuilder()) { - { - // remove useless nodes to make the usage analysis simpler - ResourceMark rm; - PhaseRemoveUseless pru(initial_gvn(), &for_igvn); - } - - { - ResourceMark rm; - print_method("Before StringOpts", 3); - PhaseStringOpts pso(initial_gvn(), &for_igvn); - print_method("After StringOpts", 3); - } - - // now inline anything that we skipped the first time around - while (_late_inlines.length() > 0) { - CallGenerator* cg = _late_inlines.pop(); - cg->do_late_inline(); - if (failing()) return; - } + assert(IncrementalInline || (_late_inlines.length() == 0 && !has_mh_late_inlines()), "incremental inlining is off"); + + if (_late_inlines.length() == 0 && !has_mh_late_inlines() && !failing() && has_stringbuilder()) { + inline_string_calls(true); } - assert(_late_inlines.length() == 0, "should have been processed"); - dump_inlining(); + + if (failing()) return; print_method("Before RemoveUseless", 3); @@ -906,6 +914,9 @@ _dead_node_list(comp_arena()), _dead_node_count(0), _congraph(NULL), + _number_of_mh_late_inlines(0), + _inlining_progress(false), + _inlining_incrementally(false), _print_inlining_list(NULL), _print_inlining(0) { C = this; @@ -1760,6 +1771,124 @@ assert(predicate_count()==0, "should be clean!"); } +// StringOpts and late inlining of string methods +void Compile::inline_string_calls(bool parse_time) { + { + // remove useless nodes to make the usage analysis simpler + ResourceMark rm; + PhaseRemoveUseless pru(initial_gvn(), for_igvn()); + } + + { + ResourceMark rm; + print_method("Before StringOpts", 3); + PhaseStringOpts pso(initial_gvn(), for_igvn()); + print_method("After StringOpts", 3); + } + + // now inline anything that we skipped the first time around + if (!parse_time) { + _late_inlines_pos = _late_inlines.length(); + } + + while (_string_late_inlines.length() > 0) { + CallGenerator* cg = _string_late_inlines.pop(); + cg->do_late_inline(); + if (failing()) return; + } + _string_late_inlines.trunc_to(0); +} + +void Compile::inline_incrementally_one(PhaseIterGVN& igvn) { + assert(IncrementalInline, "incremental inlining should be on"); + PhaseGVN* gvn = initial_gvn(); + + set_inlining_progress(false); + for_igvn()->clear(); + gvn->replace_with(&igvn); + + int i = 0; + + for (; i <_late_inlines.length() && !inlining_progress(); i++) { + CallGenerator* cg = _late_inlines.at(i); + _late_inlines_pos = i+1; + cg->do_late_inline(); + if (failing()) return; + } + int j = 0; + for (; i < _late_inlines.length(); i++, j++) { + _late_inlines.at_put(j, _late_inlines.at(i)); + } + _late_inlines.trunc_to(j); + + { + ResourceMark rm; + PhaseRemoveUseless pru(C->initial_gvn(), C->for_igvn()); + } + + igvn = PhaseIterGVN(gvn); +} + +// Perform incremental inlining until bound on number of live nodes is reached +void Compile::inline_incrementally(PhaseIterGVN& igvn) { + PhaseGVN* gvn = initial_gvn(); + + set_inlining_incrementally(true); + set_inlining_progress(true); + uint low_live_nodes = 0; + + while(inlining_progress() && _late_inlines.length() > 0) { + + if (live_nodes() > (uint)LiveNodeCountInliningCutoff) { + if (low_live_nodes < (uint)LiveNodeCountInliningCutoff * 8 / 10) { + // PhaseIdealLoop is expensive so we only try it once we are + // out of loop and we only try it again if the previous helped + // got the number of nodes down significantly + PhaseIdealLoop ideal_loop( igvn, false, true ); + if (failing()) return; + low_live_nodes = live_nodes(); + _major_progress = true; + } + + if (live_nodes() > (uint)LiveNodeCountInliningCutoff) { + break; + } + } + + inline_incrementally_one(igvn); + + if (failing()) return; + + igvn.optimize(); + + if (failing()) return; + } + + assert( igvn._worklist.size() == 0, "should be done with igvn" ); + + if (_string_late_inlines.length() > 0) { + assert(has_stringbuilder(), "inconsistent"); + for_igvn()->clear(); + initial_gvn()->replace_with(&igvn); + + inline_string_calls(false); + + if (failing()) return; + + { + ResourceMark rm; + PhaseRemoveUseless pru(initial_gvn(), for_igvn()); + } + + igvn = PhaseIterGVN(gvn); + + igvn.optimize(); + } + + set_inlining_incrementally(false); +} + + //------------------------------Optimize--------------------------------------- // Given a graph, optimize it. void Compile::Optimize() { @@ -1792,6 +1921,12 @@ if (failing()) return; + inline_incrementally(igvn); + + print_method("Incremental Inline", 2); + + if (failing()) return; + // Perform escape analysis if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) { if (has_loops()) { @@ -1914,6 +2049,7 @@ } // (End scope of igvn; run destructor if necessary for asserts.) + dump_inlining(); // A method with only infinite loops has no edges entering loops from root { NOT_PRODUCT( TracePhase t2("graphReshape", &_t_graphReshaping, TimeCompiler); ) @@ -3361,7 +3497,29 @@ } void Compile::dump_inlining() { - if (PrintInlining) { + if (PrintInlining || PrintIntrinsics NOT_PRODUCT( || PrintOptoInlining)) { + // Print inlining message for candidates that we couldn't inline + // for lack of space or non constant receiver + for (int i = 0; i < _late_inlines.length(); i++) { + CallGenerator* cg = _late_inlines.at(i); + cg->print_inlining_late("live nodes > LiveNodeCountInliningCutoff"); + } + Unique_Node_List useful; + useful.push(root()); + for (uint next = 0; next < useful.size(); ++next) { + Node* n = useful.at(next); + if (n->is_Call() && n->as_Call()->generator() != NULL && n->as_Call()->generator()->call_node() == n) { + CallNode* call = n->as_Call(); + CallGenerator* cg = call->generator(); + cg->print_inlining_late("receiver not constant"); + } + uint max = n->len(); + for ( uint i = 0; i < max; ++i ) { + Node *m = n->in(i); + if ( m == NULL ) continue; + useful.push(m); + } + } for (int i = 0; i < _print_inlining_list->length(); i++) { tty->print(_print_inlining_list->at(i).ss()->as_string()); } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/compile.hpp --- a/src/share/vm/opto/compile.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/compile.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -72,6 +72,7 @@ class JVMState; class TypeData; class TypePtr; +class TypeOopPtr; class TypeFunc; class Unique_Node_List; class nmethod; @@ -280,6 +281,8 @@ int _orig_pc_slot_offset_in_bytes; int _major_progress; // Count of something big happening + bool _inlining_progress; // progress doing incremental inlining? + bool _inlining_incrementally;// Are we doing incremental inlining (post parse) bool _has_loops; // True if the method _may_ have some loops bool _has_split_ifs; // True if the method _may_ have some split-if bool _has_unsafe_access; // True if the method _may_ produce faults in unsafe loads or stores. @@ -367,8 +370,13 @@ Unique_Node_List* _for_igvn; // Initial work-list for next round of Iterative GVN WarmCallInfo* _warm_calls; // Sorted work-list for heat-based inlining. - GrowableArray _late_inlines; // List of CallGenerators to be revisited after - // main parsing has finished. + GrowableArray _late_inlines; // List of CallGenerators to be revisited after + // main parsing has finished. + GrowableArray _string_late_inlines; // same but for string operations + + int _late_inlines_pos; // Where in the queue should the next late inlining candidate go (emulate depth first inlining) + uint _number_of_mh_late_inlines; // number of method handle late inlining still pending + // Inlining may not happen in parse order which would make // PrintInlining output confusing. Keep track of PrintInlining @@ -491,6 +499,10 @@ int fixed_slots() const { assert(_fixed_slots >= 0, ""); return _fixed_slots; } void set_fixed_slots(int n) { _fixed_slots = n; } int major_progress() const { return _major_progress; } + void set_inlining_progress(bool z) { _inlining_progress = z; } + int inlining_progress() const { return _inlining_progress; } + void set_inlining_incrementally(bool z) { _inlining_incrementally = z; } + int inlining_incrementally() const { return _inlining_incrementally; } void set_major_progress() { _major_progress++; } void clear_major_progress() { _major_progress = 0; } int num_loop_opts() const { return _num_loop_opts; } @@ -729,9 +741,17 @@ // Decide how to build a call. // The profile factor is a discount to apply to this site's interp. profile. - CallGenerator* call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, float profile_factor, bool allow_intrinsics = true); + CallGenerator* call_generator(ciMethod* call_method, int vtable_index, bool call_does_dispatch, JVMState* jvms, bool allow_inline, float profile_factor, bool allow_intrinsics = true, bool delayed_forbidden = false); bool should_delay_inlining(ciMethod* call_method, JVMState* jvms); + // Helper functions to identify inlining potential at call-site + ciMethod* optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass, + ciMethod* callee, const TypeOopPtr* receiver_type, + bool is_virtual, + bool &call_does_dispatch, int &vtable_index); + ciMethod* optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass, + ciMethod* callee, const TypeOopPtr* receiver_type); + // Report if there were too many traps at a current method and bci. // Report if a trap was recorded, and/or PerMethodTrapLimit was exceeded. // If there is no MDO at all, report no trap unless told to assume it. @@ -765,10 +785,39 @@ WarmCallInfo* pop_warm_call(); // Record this CallGenerator for inlining at the end of parsing. - void add_late_inline(CallGenerator* cg) { _late_inlines.push(cg); } + void add_late_inline(CallGenerator* cg) { + _late_inlines.insert_before(_late_inlines_pos, cg); + _late_inlines_pos++; + } + + void prepend_late_inline(CallGenerator* cg) { + _late_inlines.insert_before(0, cg); + } + + void add_string_late_inline(CallGenerator* cg) { + _string_late_inlines.push(cg); + } + + void remove_useless_late_inlines(GrowableArray* inlines, Unique_Node_List &useful); void dump_inlining(); + bool over_inlining_cutoff() const { + if (!inlining_incrementally()) { + return unique() > (uint)NodeCountInliningCutoff; + } else { + return live_nodes() > (uint)LiveNodeCountInliningCutoff; + } + } + + void inc_number_of_mh_late_inlines() { _number_of_mh_late_inlines++; } + void dec_number_of_mh_late_inlines() { assert(_number_of_mh_late_inlines > 0, "_number_of_mh_late_inlines < 0 !"); _number_of_mh_late_inlines--; } + bool has_mh_late_inlines() const { return _number_of_mh_late_inlines > 0; } + + void inline_incrementally_one(PhaseIterGVN& igvn); + void inline_incrementally(PhaseIterGVN& igvn); + void inline_string_calls(bool parse_time); + // Matching, CFG layout, allocation, code generation PhaseCFG* cfg() { return _cfg; } bool select_24_bit_instr() const { return _select_24_bit_instr; } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/doCall.cpp --- a/src/share/vm/opto/doCall.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/doCall.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -61,9 +61,9 @@ } } -CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool call_is_virtual, +CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool call_does_dispatch, JVMState* jvms, bool allow_inline, - float prof_factor, bool allow_intrinsics) { + float prof_factor, bool allow_intrinsics, bool delayed_forbidden) { ciMethod* caller = jvms->method(); int bci = jvms->bci(); Bytecodes::Code bytecode = caller->java_code_at_bci(bci); @@ -82,7 +82,7 @@ // See how many times this site has been invoked. int site_count = profile.count(); int receiver_count = -1; - if (call_is_virtual && UseTypeProfile && profile.has_receiver(0)) { + if (call_does_dispatch && UseTypeProfile && profile.has_receiver(0)) { // Receivers in the profile structure are ordered by call counts // so that the most called (major) receiver is profile.receiver(0). receiver_count = profile.receiver_count(0); @@ -94,7 +94,7 @@ int r2id = (rid != -1 && profile.has_receiver(1))? log->identify(profile.receiver(1)):-1; log->begin_elem("call method='%d' count='%d' prof_factor='%g'", log->identify(callee), site_count, prof_factor); - if (call_is_virtual) log->print(" virtual='1'"); + if (call_does_dispatch) log->print(" virtual='1'"); if (allow_inline) log->print(" inline='1'"); if (receiver_count >= 0) { log->print(" receiver='%d' receiver_count='%d'", rid, receiver_count); @@ -111,12 +111,12 @@ // We do this before the strict f.p. check below because the // intrinsics handle strict f.p. correctly. if (allow_inline && allow_intrinsics) { - CallGenerator* cg = find_intrinsic(callee, call_is_virtual); + CallGenerator* cg = find_intrinsic(callee, call_does_dispatch); if (cg != NULL) { if (cg->is_predicted()) { // Code without intrinsic but, hopefully, inlined. CallGenerator* inline_cg = this->call_generator(callee, - vtable_index, call_is_virtual, jvms, allow_inline, prof_factor, false); + vtable_index, call_does_dispatch, jvms, allow_inline, prof_factor, false); if (inline_cg != NULL) { cg = CallGenerator::for_predicted_intrinsic(cg, inline_cg); } @@ -130,7 +130,9 @@ // MethodHandle.invoke* are native methods which obviously don't // have bytecodes and so normal inlining fails. if (callee->is_method_handle_intrinsic()) { - return CallGenerator::for_method_handle_call(jvms, caller, callee); + CallGenerator* cg = CallGenerator::for_method_handle_call(jvms, caller, callee, delayed_forbidden); + assert(cg == NULL || !delayed_forbidden || !cg->is_late_inline() || cg->is_mh_late_inline(), "unexpected CallGenerator"); + return cg; } // Do not inline strict fp into non-strict code, or the reverse @@ -147,7 +149,7 @@ float expected_uses = past_uses; // Try inlining a bytecoded method: - if (!call_is_virtual) { + if (!call_does_dispatch) { InlineTree* ilt; if (UseOldInlining) { ilt = InlineTree::find_subtree_from_root(this->ilt(), jvms->caller(), jvms->method()); @@ -161,32 +163,39 @@ WarmCallInfo scratch_ci; if (!UseOldInlining) scratch_ci.init(jvms, callee, profile, prof_factor); - WarmCallInfo* ci = ilt->ok_to_inline(callee, jvms, profile, &scratch_ci); + bool should_delay = false; + WarmCallInfo* ci = ilt->ok_to_inline(callee, jvms, profile, &scratch_ci, should_delay); assert(ci != &scratch_ci, "do not let this pointer escape"); bool allow_inline = (ci != NULL && !ci->is_cold()); bool require_inline = (allow_inline && ci->is_hot()); if (allow_inline) { CallGenerator* cg = CallGenerator::for_inline(callee, expected_uses); - if (require_inline && cg != NULL && should_delay_inlining(callee, jvms)) { + + if (require_inline && cg != NULL) { // Delay the inlining of this method to give us the // opportunity to perform some high level optimizations // first. - return CallGenerator::for_late_inline(callee, cg); + if (should_delay_inlining(callee, jvms)) { + assert(!delayed_forbidden, "strange"); + return CallGenerator::for_string_late_inline(callee, cg); + } else if ((should_delay || AlwaysIncrementalInline) && !delayed_forbidden) { + return CallGenerator::for_late_inline(callee, cg); + } } - if (cg == NULL) { + if (cg == NULL || should_delay) { // Fall through. } else if (require_inline || !InlineWarmCalls) { return cg; } else { - CallGenerator* cold_cg = call_generator(callee, vtable_index, call_is_virtual, jvms, false, prof_factor); + CallGenerator* cold_cg = call_generator(callee, vtable_index, call_does_dispatch, jvms, false, prof_factor); return CallGenerator::for_warm_call(ci, cold_cg, cg); } } } // Try using the type profile. - if (call_is_virtual && site_count > 0 && receiver_count > 0) { + if (call_does_dispatch && site_count > 0 && receiver_count > 0) { // The major receiver's count >= TypeProfileMajorReceiverPercent of site_count. bool have_major_receiver = (100.*profile.receiver_prob(0) >= (float)TypeProfileMajorReceiverPercent); ciMethod* receiver_method = NULL; @@ -200,7 +209,7 @@ if (receiver_method != NULL) { // The single majority receiver sufficiently outweighs the minority. CallGenerator* hit_cg = this->call_generator(receiver_method, - vtable_index, !call_is_virtual, jvms, allow_inline, prof_factor); + vtable_index, !call_does_dispatch, jvms, allow_inline, prof_factor); if (hit_cg != NULL) { // Look up second receiver. CallGenerator* next_hit_cg = NULL; @@ -210,7 +219,7 @@ profile.receiver(1)); if (next_receiver_method != NULL) { next_hit_cg = this->call_generator(next_receiver_method, - vtable_index, !call_is_virtual, jvms, + vtable_index, !call_does_dispatch, jvms, allow_inline, prof_factor); if (next_hit_cg != NULL && !next_hit_cg->is_inline() && have_major_receiver && UseOnlyInlinedBimorphic) { @@ -256,7 +265,7 @@ // There was no special inlining tactic, or it bailed out. // Use a more generic tactic, like a simple call. - if (call_is_virtual) { + if (call_does_dispatch) { return CallGenerator::for_virtual_call(callee, vtable_index); } else { // Class Hierarchy Analysis or Type Profile reveals a unique target, @@ -388,6 +397,7 @@ // orig_callee is the resolved callee which's signature includes the // appendix argument. const int nargs = orig_callee->arg_size(); + const bool is_signature_polymorphic = MethodHandles::is_signature_polymorphic(orig_callee->intrinsic_id()); // Push appendix argument (MethodType, CallSite, etc.), if one. if (iter().has_appendix()) { @@ -404,25 +414,18 @@ // Then we may introduce a run-time check and inline on the path where it succeeds. // The other path may uncommon_trap, check for another receiver, or do a v-call. - // Choose call strategy. - bool call_is_virtual = is_virtual_or_interface; - int vtable_index = Method::invalid_vtable_index; - ciMethod* callee = orig_callee; + // Try to get the most accurate receiver type + ciMethod* callee = orig_callee; + int vtable_index = Method::invalid_vtable_index; + bool call_does_dispatch = false; - // Try to get the most accurate receiver type if (is_virtual_or_interface) { Node* receiver_node = stack(sp() - nargs); const TypeOopPtr* receiver_type = _gvn.type(receiver_node)->isa_oopptr(); - ciMethod* optimized_virtual_method = optimize_inlining(method(), bci(), klass, orig_callee, receiver_type); - - // Have the call been sufficiently improved such that it is no longer a virtual? - if (optimized_virtual_method != NULL) { - callee = optimized_virtual_method; - call_is_virtual = false; - } else if (!UseInlineCaches && is_virtual && callee->is_loaded()) { - // We can make a vtable call at this site - vtable_index = callee->resolve_vtable_index(method()->holder(), klass); - } + // call_does_dispatch and vtable_index are out-parameters. They might be changed. + callee = C->optimize_virtual_call(method(), bci(), klass, orig_callee, receiver_type, + is_virtual, + call_does_dispatch, vtable_index); // out-parameters } // Note: It's OK to try to inline a virtual call. @@ -438,7 +441,7 @@ // Decide call tactic. // This call checks with CHA, the interpreter profile, intrinsics table, etc. // It decides whether inlining is desirable or not. - CallGenerator* cg = C->call_generator(callee, vtable_index, call_is_virtual, jvms, try_inline, prof_factor()); + CallGenerator* cg = C->call_generator(callee, vtable_index, call_does_dispatch, jvms, try_inline, prof_factor()); // NOTE: Don't use orig_callee and callee after this point! Use cg->method() instead. orig_callee = callee = NULL; @@ -478,7 +481,7 @@ // the call site, perhaps because it did not match a pattern the // intrinsic was expecting to optimize. Should always be possible to // get a normal java call that may inline in that case - cg = C->call_generator(cg->method(), vtable_index, call_is_virtual, jvms, try_inline, prof_factor(), /* allow_intrinsics= */ false); + cg = C->call_generator(cg->method(), vtable_index, call_does_dispatch, jvms, try_inline, prof_factor(), /* allow_intrinsics= */ false); if ((new_jvms = cg->generate(jvms)) == NULL) { guarantee(failing(), "call failed to generate: calls should work"); return; @@ -513,55 +516,50 @@ round_double_result(cg->method()); ciType* rtype = cg->method()->return_type(); - if (Bytecodes::has_optional_appendix(iter().cur_bc_raw())) { + ciType* ctype = declared_signature->return_type(); + + if (Bytecodes::has_optional_appendix(iter().cur_bc_raw()) || is_signature_polymorphic) { // Be careful here with return types. - ciType* ctype = declared_signature->return_type(); if (ctype != rtype) { BasicType rt = rtype->basic_type(); BasicType ct = ctype->basic_type(); - Node* retnode = peek(); if (ct == T_VOID) { // It's OK for a method to return a value that is discarded. // The discarding does not require any special action from the caller. // The Java code knows this, at VerifyType.isNullConversion. pop_node(rt); // whatever it was, pop it - retnode = top(); } else if (rt == T_INT || is_subword_type(rt)) { - // FIXME: This logic should be factored out. - if (ct == T_BOOLEAN) { - retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0x1)) ); - } else if (ct == T_CHAR) { - retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0xFFFF)) ); - } else if (ct == T_BYTE) { - retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(24)) ); - retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(24)) ); - } else if (ct == T_SHORT) { - retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(16)) ); - retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(16)) ); - } else { - assert(ct == T_INT, err_msg_res("rt=%s, ct=%s", type2name(rt), type2name(ct))); - } + // Nothing. These cases are handled in lambda form bytecode. + assert(ct == T_INT || is_subword_type(ct), err_msg_res("must match: rt=%s, ct=%s", type2name(rt), type2name(ct))); } else if (rt == T_OBJECT || rt == T_ARRAY) { assert(ct == T_OBJECT || ct == T_ARRAY, err_msg_res("rt=%s, ct=%s", type2name(rt), type2name(ct))); if (ctype->is_loaded()) { const TypeOopPtr* arg_type = TypeOopPtr::make_from_klass(rtype->as_klass()); const Type* sig_type = TypeOopPtr::make_from_klass(ctype->as_klass()); if (arg_type != NULL && !arg_type->higher_equal(sig_type)) { + Node* retnode = pop(); Node* cast_obj = _gvn.transform(new (C) CheckCastPPNode(control(), retnode, sig_type)); - pop(); push(cast_obj); } } } else { - assert(ct == rt, err_msg("unexpected mismatch rt=%d, ct=%d", rt, ct)); + assert(rt == ct, err_msg_res("unexpected mismatch: rt=%s, ct=%s", type2name(rt), type2name(ct))); // push a zero; it's better than getting an oop/int mismatch - retnode = pop_node(rt); - retnode = zerocon(ct); + pop_node(rt); + Node* retnode = zerocon(ct); push_node(ct, retnode); } // Now that the value is well-behaved, continue with the call-site type. rtype = ctype; } + } else { + // Symbolic resolution enforces the types to be the same. + // NOTE: We must relax the assert for unloaded types because two + // different ciType instances of the same unloaded class type + // can appear to be "loaded" by different loaders (depending on + // the accessing class). + assert(!rtype->is_loaded() || !ctype->is_loaded() || rtype == ctype, + err_msg_res("mismatched return types: rtype=%s, ctype=%s", rtype->name(), ctype->name())); } // If the return type of the method is not loaded, assert that the @@ -879,17 +877,39 @@ #endif //PRODUCT +ciMethod* Compile::optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass, + ciMethod* callee, const TypeOopPtr* receiver_type, + bool is_virtual, + bool& call_does_dispatch, int& vtable_index) { + // Set default values for out-parameters. + call_does_dispatch = true; + vtable_index = Method::invalid_vtable_index; + + // Choose call strategy. + ciMethod* optimized_virtual_method = optimize_inlining(caller, bci, klass, callee, receiver_type); + + // Have the call been sufficiently improved such that it is no longer a virtual? + if (optimized_virtual_method != NULL) { + callee = optimized_virtual_method; + call_does_dispatch = false; + } else if (!UseInlineCaches && is_virtual && callee->is_loaded()) { + // We can make a vtable call at this site + vtable_index = callee->resolve_vtable_index(caller->holder(), klass); + } + return callee; +} + // Identify possible target method and inlining style -ciMethod* Parse::optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass, - ciMethod *dest_method, const TypeOopPtr* receiver_type) { +ciMethod* Compile::optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass, + ciMethod* callee, const TypeOopPtr* receiver_type) { // only use for virtual or interface calls // If it is obviously final, do not bother to call find_monomorphic_target, // because the class hierarchy checks are not needed, and may fail due to // incompletely loaded classes. Since we do our own class loading checks // in this module, we may confidently bind to any method. - if (dest_method->can_be_statically_bound()) { - return dest_method; + if (callee->can_be_statically_bound()) { + return callee; } // Attempt to improve the receiver @@ -898,8 +918,8 @@ if (receiver_type != NULL) { // Array methods are all inherited from Object, and are monomorphic. if (receiver_type->isa_aryptr() && - dest_method->holder() == env()->Object_klass()) { - return dest_method; + callee->holder() == env()->Object_klass()) { + return callee; } // All other interesting cases are instance klasses. @@ -919,7 +939,7 @@ } ciInstanceKlass* calling_klass = caller->holder(); - ciMethod* cha_monomorphic_target = dest_method->find_monomorphic_target(calling_klass, klass, actual_receiver); + ciMethod* cha_monomorphic_target = callee->find_monomorphic_target(calling_klass, klass, actual_receiver); if (cha_monomorphic_target != NULL) { assert(!cha_monomorphic_target->is_abstract(), ""); // Look at the method-receiver type. Does it add "too much information"? @@ -937,10 +957,10 @@ cha_monomorphic_target->print(); tty->cr(); } - if (C->log() != NULL) { - C->log()->elem("missed_CHA_opportunity klass='%d' method='%d'", - C->log()->identify(klass), - C->log()->identify(cha_monomorphic_target)); + if (log() != NULL) { + log()->elem("missed_CHA_opportunity klass='%d' method='%d'", + log()->identify(klass), + log()->identify(cha_monomorphic_target)); } cha_monomorphic_target = NULL; } @@ -952,7 +972,7 @@ // by dynamic class loading. Be sure to test the "static" receiver // dest_method here, as opposed to the actual receiver, which may // falsely lead us to believe that the receiver is final or private. - C->dependencies()->assert_unique_concrete_method(actual_receiver, cha_monomorphic_target); + dependencies()->assert_unique_concrete_method(actual_receiver, cha_monomorphic_target); return cha_monomorphic_target; } @@ -961,7 +981,7 @@ if (actual_receiver_is_exact) { // In case of evolution, there is a dependence on every inlined method, since each // such method can be changed when its class is redefined. - ciMethod* exact_method = dest_method->resolve_invoke(calling_klass, actual_receiver); + ciMethod* exact_method = callee->resolve_invoke(calling_klass, actual_receiver); if (exact_method != NULL) { #ifndef PRODUCT if (PrintOpto) { diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/graphKit.cpp --- a/src/share/vm/opto/graphKit.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/graphKit.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -1794,10 +1794,15 @@ if (ejvms == NULL) { // No exception edges to simply kill off those paths - C->gvn_replace_by(callprojs.catchall_catchproj, C->top()); - C->gvn_replace_by(callprojs.catchall_memproj, C->top()); - C->gvn_replace_by(callprojs.catchall_ioproj, C->top()); - + if (callprojs.catchall_catchproj != NULL) { + C->gvn_replace_by(callprojs.catchall_catchproj, C->top()); + } + if (callprojs.catchall_memproj != NULL) { + C->gvn_replace_by(callprojs.catchall_memproj, C->top()); + } + if (callprojs.catchall_ioproj != NULL) { + C->gvn_replace_by(callprojs.catchall_ioproj, C->top()); + } // Replace the old exception object with top if (callprojs.exobj != NULL) { C->gvn_replace_by(callprojs.exobj, C->top()); @@ -1809,10 +1814,15 @@ SafePointNode* ex_map = ekit.combine_and_pop_all_exception_states(); Node* ex_oop = ekit.use_exception_state(ex_map); - - C->gvn_replace_by(callprojs.catchall_catchproj, ekit.control()); - C->gvn_replace_by(callprojs.catchall_memproj, ekit.reset_memory()); - C->gvn_replace_by(callprojs.catchall_ioproj, ekit.i_o()); + if (callprojs.catchall_catchproj != NULL) { + C->gvn_replace_by(callprojs.catchall_catchproj, ekit.control()); + } + if (callprojs.catchall_memproj != NULL) { + C->gvn_replace_by(callprojs.catchall_memproj, ekit.reset_memory()); + } + if (callprojs.catchall_ioproj != NULL) { + C->gvn_replace_by(callprojs.catchall_ioproj, ekit.i_o()); + } // Replace the old exception object with the newly created one if (callprojs.exobj != NULL) { diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/library_call.cpp --- a/src/share/vm/opto/library_call.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/library_call.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -3559,7 +3559,6 @@ // public static T[] java.util.Arrays.copyOf( U[] original, int newLength, Class newType); // public static T[] java.util.Arrays.copyOfRange(U[] original, int from, int to, Class newType); bool LibraryCallKit::inline_array_copyOf(bool is_copyOfRange) { - return false; if (too_many_traps(Deoptimization::Reason_intrinsic)) return false; // Get the arguments. diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/memnode.cpp --- a/src/share/vm/opto/memnode.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/memnode.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -2725,10 +2725,8 @@ zend = phase->transform( new(C) URShiftXNode(zend, shift) ); } + // Bulk clear double-words Node* zsize = phase->transform( new(C) SubXNode(zend, zbase) ); - Node* zinit = phase->zerocon((unit == BytesPerLong) ? T_LONG : T_INT); - - // Bulk clear double-words Node* adr = phase->transform( new(C) AddPNode(dest, dest, start_offset) ); mem = new (C) ClearArrayNode(ctl, mem, zsize, adr); return phase->transform(mem); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/parse.hpp --- a/src/share/vm/opto/parse.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/parse.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -70,7 +70,7 @@ InlineTree *build_inline_tree_for_callee(ciMethod* callee_method, JVMState* caller_jvms, int caller_bci); - const char* try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result); + const char* try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result, bool& should_delay); const char* should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const; const char* should_not_inline(ciMethod* callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const; void print_inlining(ciMethod *callee_method, int caller_bci, const char *failure_msg) const; @@ -107,7 +107,7 @@ // and may be accessed by find_subtree_from_root. // The call_method is the dest_method for a special or static invocation. // The call_method is an optimized virtual method candidate otherwise. - WarmCallInfo* ok_to_inline(ciMethod *call_method, JVMState* caller_jvms, ciCallProfile& profile, WarmCallInfo* wci); + WarmCallInfo* ok_to_inline(ciMethod *call_method, JVMState* caller_jvms, ciCallProfile& profile, WarmCallInfo* wci, bool& should_delay); // Information about inlined method JVMState* caller_jvms() const { return _caller_jvms; } @@ -469,10 +469,6 @@ // Helper function to uncommon-trap or bailout for non-compilable call-sites bool can_not_compile_call_site(ciMethod *dest_method, ciInstanceKlass *klass); - // Helper function to identify inlining potential at call-site - ciMethod* optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass, - ciMethod *dest_method, const TypeOopPtr* receiver_type); - // Helper function to setup for type-profile based inlining bool prepare_type_profile_inline(ciInstanceKlass* prof_klass, ciMethod* prof_method); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/parse1.cpp --- a/src/share/vm/opto/parse1.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/parse1.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -1404,7 +1404,8 @@ do_one_bytecode(); - assert(!have_se || stopped() || failing() || (sp() - pre_bc_sp) == depth, "correct depth prediction"); + assert(!have_se || stopped() || failing() || (sp() - pre_bc_sp) == depth, + err_msg_res("incorrect depth prediction: sp=%d, pre_bc_sp=%d, depth=%d", sp(), pre_bc_sp, depth)); do_exceptions(); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/phaseX.cpp --- a/src/share/vm/opto/phaseX.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/phaseX.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -75,6 +75,13 @@ // nh->_sentinel must be in the current node space } +void NodeHash::replace_with(NodeHash *nh) { + debug_only(_table = (Node**)badAddress); // interact correctly w/ operator= + // just copy in all the fields + *this = *nh; + // nh->_sentinel must be in the current node space +} + //------------------------------hash_find-------------------------------------- // Find in hash table Node *NodeHash::hash_find( const Node *n ) { diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/phaseX.hpp --- a/src/share/vm/opto/phaseX.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/phaseX.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -92,6 +92,7 @@ } void remove_useless_nodes(VectorSet &useful); // replace with sentinel + void replace_with(NodeHash* nh); Node *sentinel() { return _sentinel; } @@ -386,6 +387,11 @@ Node *transform( Node *n ); Node *transform_no_reclaim( Node *n ); + void replace_with(PhaseGVN* gvn) { + _table.replace_with(&gvn->_table); + _types = gvn->_types; + } + // Check for a simple dead loop when a data node references itself. DEBUG_ONLY(void dead_loop_check(Node *n);) }; diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/opto/stringopts.cpp --- a/src/share/vm/opto/stringopts.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/opto/stringopts.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -265,7 +265,8 @@ } else if (n->is_IfTrue()) { Compile* C = _stringopts->C; C->gvn_replace_by(n, n->in(0)->in(0)); - C->gvn_replace_by(n->in(0), C->top()); + // get rid of the other projection + C->gvn_replace_by(n->in(0)->as_If()->proj_out(false), C->top()); } } } @@ -439,7 +440,7 @@ } // Find the constructor call Node* result = alloc->result_cast(); - if (result == NULL || !result->is_CheckCastPP()) { + if (result == NULL || !result->is_CheckCastPP() || alloc->in(TypeFunc::Memory)->is_top()) { // strange looking allocation #ifndef PRODUCT if (PrintOptimizeStringConcat) { @@ -834,6 +835,9 @@ ptr->in(1)->in(0) != NULL && ptr->in(1)->in(0)->is_If()) { // Simple diamond. // XXX should check for possibly merging stores. simple data merges are ok. + // The IGVN will make this simple diamond go away when it + // transforms the Region. Make sure it sees it. + Compile::current()->record_for_igvn(ptr); ptr = ptr->in(1)->in(0)->in(0); continue; } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/prims/jvm.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -1582,8 +1582,11 @@ if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls)); if (k->oop_is_instance()) { - typeArrayOop a = Annotations::make_java_array(InstanceKlass::cast(k)->type_annotations()->class_annotations(), CHECK_NULL); - return (jbyteArray) JNIHandles::make_local(env, a); + Annotations* type_annotations = InstanceKlass::cast(k)->type_annotations(); + if (type_annotations != NULL) { + typeArrayOop a = Annotations::make_java_array(type_annotations->class_annotations(), CHECK_NULL); + return (jbyteArray) JNIHandles::make_local(env, a); + } } } return NULL; diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/prims/jvmtiExport.cpp --- a/src/share/vm/prims/jvmtiExport.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/prims/jvmtiExport.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -1305,15 +1305,21 @@ vframeStream st(thread); assert(!st.at_end(), "cannot be at end"); Method* current_method = NULL; + // A GC may occur during the Method::fast_exception_handler_bci_for() + // call below if it needs to load the constraint class. Using a + // methodHandle to keep the 'current_method' from being deallocated + // if GC happens. + methodHandle current_mh = methodHandle(thread, current_method); int current_bci = -1; do { current_method = st.method(); + current_mh = methodHandle(thread, current_method); current_bci = st.bci(); do { should_repeat = false; KlassHandle eh_klass(thread, exception_handle()->klass()); - current_bci = current_method->fast_exception_handler_bci_for( - eh_klass, current_bci, THREAD); + current_bci = Method::fast_exception_handler_bci_for( + current_mh, eh_klass, current_bci, THREAD); if (HAS_PENDING_EXCEPTION) { exception_handle = Handle(thread, PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; @@ -1328,8 +1334,7 @@ catch_jmethodID = 0; current_bci = 0; } else { - catch_jmethodID = jem.to_jmethodID( - methodHandle(thread, current_method)); + catch_jmethodID = jem.to_jmethodID(current_mh); } JvmtiJavaThreadEventTransition jet(thread); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/runtime/arguments.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -1083,10 +1083,6 @@ } } -// If the user has chosen ParallelGCThreads > 0, we set UseParNewGC -// if it's not explictly set or unset. If the user has chosen -// UseParNewGC and not explicitly set ParallelGCThreads we -// set it, unless this is a single cpu machine. void Arguments::set_parnew_gc_flags() { assert(!UseSerialGC && !UseParallelOldGC && !UseParallelGC && !UseG1GC, "control point invariant"); @@ -1095,42 +1091,41 @@ // Turn off AdaptiveSizePolicy for parnew until it is complete. disable_adaptive_size_policy("UseParNewGC"); - if (ParallelGCThreads == 0) { - FLAG_SET_DEFAULT(ParallelGCThreads, - Abstract_VM_Version::parallel_worker_threads()); - if (ParallelGCThreads == 1) { - FLAG_SET_DEFAULT(UseParNewGC, false); - FLAG_SET_DEFAULT(ParallelGCThreads, 0); - } + if (FLAG_IS_DEFAULT(ParallelGCThreads)) { + FLAG_SET_DEFAULT(ParallelGCThreads, Abstract_VM_Version::parallel_worker_threads()); + assert(ParallelGCThreads > 0, "We should always have at least one thread by default"); + } else if (ParallelGCThreads == 0) { + jio_fprintf(defaultStream::error_stream(), + "The ParNew GC can not be combined with -XX:ParallelGCThreads=0\n"); + vm_exit(1); + } + + // By default YoungPLABSize and OldPLABSize are set to 4096 and 1024 respectively, + // these settings are default for Parallel Scavenger. For ParNew+Tenured configuration + // we set them to 1024 and 1024. + // See CR 6362902. + if (FLAG_IS_DEFAULT(YoungPLABSize)) { + FLAG_SET_DEFAULT(YoungPLABSize, (intx)1024); } - if (UseParNewGC) { - // By default YoungPLABSize and OldPLABSize are set to 4096 and 1024 respectively, - // these settings are default for Parallel Scavenger. For ParNew+Tenured configuration - // we set them to 1024 and 1024. - // See CR 6362902. - if (FLAG_IS_DEFAULT(YoungPLABSize)) { - FLAG_SET_DEFAULT(YoungPLABSize, (intx)1024); + if (FLAG_IS_DEFAULT(OldPLABSize)) { + FLAG_SET_DEFAULT(OldPLABSize, (intx)1024); + } + + // AlwaysTenure flag should make ParNew promote all at first collection. + // See CR 6362902. + if (AlwaysTenure) { + FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, 0); + } + // When using compressed oops, we use local overflow stacks, + // rather than using a global overflow list chained through + // the klass word of the object's pre-image. + if (UseCompressedOops && !ParGCUseLocalOverflow) { + if (!FLAG_IS_DEFAULT(ParGCUseLocalOverflow)) { + warning("Forcing +ParGCUseLocalOverflow: needed if using compressed references"); } - if (FLAG_IS_DEFAULT(OldPLABSize)) { - FLAG_SET_DEFAULT(OldPLABSize, (intx)1024); - } - - // AlwaysTenure flag should make ParNew promote all at first collection. - // See CR 6362902. - if (AlwaysTenure) { - FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, 0); - } - // When using compressed oops, we use local overflow stacks, - // rather than using a global overflow list chained through - // the klass word of the object's pre-image. - if (UseCompressedOops && !ParGCUseLocalOverflow) { - if (!FLAG_IS_DEFAULT(ParGCUseLocalOverflow)) { - warning("Forcing +ParGCUseLocalOverflow: needed if using compressed references"); - } - FLAG_SET_DEFAULT(ParGCUseLocalOverflow, true); - } - assert(ParGCUseLocalOverflow || !UseCompressedOops, "Error"); + FLAG_SET_DEFAULT(ParGCUseLocalOverflow, true); } + assert(ParGCUseLocalOverflow || !UseCompressedOops, "Error"); } // Adjust some sizes to suit CMS and/or ParNew needs; these work well on @@ -1459,30 +1454,34 @@ // If no heap maximum was requested explicitly, use some reasonable fraction // of the physical memory, up to a maximum of 1GB. - if (UseParallelGC) { - FLAG_SET_DEFAULT(ParallelGCThreads, - Abstract_VM_Version::parallel_worker_threads()); - - // If InitialSurvivorRatio or MinSurvivorRatio were not specified, but the - // SurvivorRatio has been set, reset their default values to SurvivorRatio + - // 2. By doing this we make SurvivorRatio also work for Parallel Scavenger. - // See CR 6362902 for details. - if (!FLAG_IS_DEFAULT(SurvivorRatio)) { - if (FLAG_IS_DEFAULT(InitialSurvivorRatio)) { - FLAG_SET_DEFAULT(InitialSurvivorRatio, SurvivorRatio + 2); - } - if (FLAG_IS_DEFAULT(MinSurvivorRatio)) { - FLAG_SET_DEFAULT(MinSurvivorRatio, SurvivorRatio + 2); - } + FLAG_SET_DEFAULT(ParallelGCThreads, + Abstract_VM_Version::parallel_worker_threads()); + if (ParallelGCThreads == 0) { + jio_fprintf(defaultStream::error_stream(), + "The Parallel GC can not be combined with -XX:ParallelGCThreads=0\n"); + vm_exit(1); + } + + + // If InitialSurvivorRatio or MinSurvivorRatio were not specified, but the + // SurvivorRatio has been set, reset their default values to SurvivorRatio + + // 2. By doing this we make SurvivorRatio also work for Parallel Scavenger. + // See CR 6362902 for details. + if (!FLAG_IS_DEFAULT(SurvivorRatio)) { + if (FLAG_IS_DEFAULT(InitialSurvivorRatio)) { + FLAG_SET_DEFAULT(InitialSurvivorRatio, SurvivorRatio + 2); } - - if (UseParallelOldGC) { - // Par compact uses lower default values since they are treated as - // minimums. These are different defaults because of the different - // interpretation and are not ergonomically set. - if (FLAG_IS_DEFAULT(MarkSweepDeadRatio)) { - FLAG_SET_DEFAULT(MarkSweepDeadRatio, 1); - } + if (FLAG_IS_DEFAULT(MinSurvivorRatio)) { + FLAG_SET_DEFAULT(MinSurvivorRatio, SurvivorRatio + 2); + } + } + + if (UseParallelOldGC) { + // Par compact uses lower default values since they are treated as + // minimums. These are different defaults because of the different + // interpretation and are not ergonomically set. + if (FLAG_IS_DEFAULT(MarkSweepDeadRatio)) { + FLAG_SET_DEFAULT(MarkSweepDeadRatio, 1); } } } @@ -1783,6 +1782,24 @@ return status; } +void Arguments::check_deprecated_gcs() { + if (UseConcMarkSweepGC && !UseParNewGC) { + warning("Using the DefNew young collector with the CMS collector is deprecated " + "and will likely be removed in a future release"); + } + + if (UseParNewGC && !UseConcMarkSweepGC) { + // !UseConcMarkSweepGC means that we are using serial old gc. Unfortunately we don't + // set up UseSerialGC properly, so that can't be used in the check here. + warning("Using the ParNew young collector with the Serial old collector is deprecated " + "and will likely be removed in a future release"); + } + + if (CMSIncrementalMode) { + warning("Using incremental CMS is deprecated and will likely be removed in a future release"); + } +} + // Check stack pages settings bool Arguments::check_stack_pages() { @@ -3241,6 +3258,7 @@ } else if (UseG1GC) { set_g1_gc_flags(); } + check_deprecated_gcs(); #endif // INCLUDE_ALTERNATE_GCS #ifdef SERIALGC @@ -3285,6 +3303,18 @@ if (!EliminateLocks) { EliminateNestedLocks = false; } + if (!Inline) { + IncrementalInline = false; + } +#ifndef PRODUCT + if (!IncrementalInline) { + AlwaysIncrementalInline = false; + } +#endif + if (IncrementalInline && FLAG_IS_DEFAULT(MaxNodeLimit)) { + // incremental inlining: bump MaxNodeLimit + FLAG_SET_DEFAULT(MaxNodeLimit, (intx)75000); + } #endif if (PrintAssembly && FLAG_IS_DEFAULT(DebugNonSafepoints)) { diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/runtime/arguments.hpp --- a/src/share/vm/runtime/arguments.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/runtime/arguments.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -413,6 +413,7 @@ static jint adjust_after_os(); // Check for consistency in the selection of the garbage collector. static bool check_gc_consistency(); + static void check_deprecated_gcs(); // Check consistecy or otherwise of VM argument settings static bool check_vm_args_consistency(); // Check stack pages settings diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/runtime/globals.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -929,11 +929,14 @@ "Starts debugger when an implicit OS (e.g., NULL) " \ "exception happens") \ \ - notproduct(bool, PrintCodeCache, false, \ - "Print the compiled_code cache when exiting") \ + product(bool, PrintCodeCache, false, \ + "Print the code cache memory usage when exiting") \ \ develop(bool, PrintCodeCache2, false, \ - "Print detailed info on the compiled_code cache when exiting") \ + "Print detailed usage info on the code cache when exiting") \ + \ + product(bool, PrintCodeCacheOnCompilation, false, \ + "Print the code cache memory usage each time a method is compiled") \ \ diagnostic(bool, PrintStubCode, false, \ "Print generated stub code") \ @@ -969,18 +972,6 @@ notproduct(uintx, WarnOnStalledSpinLock, 0, \ "Prints warnings for stalled SpinLocks") \ \ - develop(bool, InitializeJavaLangSystem, true, \ - "Initialize java.lang.System - turn off for individual " \ - "method debugging") \ - \ - develop(bool, InitializeJavaLangString, true, \ - "Initialize java.lang.String - turn off for individual " \ - "method debugging") \ - \ - develop(bool, InitializeJavaLangExceptionsErrors, true, \ - "Initialize various error and exception classes - turn off for " \ - "individual method debugging") \ - \ product(bool, RegisterFinalizersAtInit, true, \ "Register finalizable objects at end of Object. or " \ "after allocation") \ @@ -1101,13 +1092,6 @@ product(bool, ReduceSignalUsage, false, \ "Reduce the use of OS signals in Java and/or the VM") \ \ - notproduct(bool, ValidateMarkSweep, false, \ - "Do extra validation during MarkSweep collection") \ - \ - notproduct(bool, RecordMarkSweepCompaction, false, \ - "Enable GC-to-GC recording and querying of compaction during " \ - "MarkSweep") \ - \ develop_pd(bool, ShareVtableStubs, \ "Share vtable stubs (smaller code but worse branch prediction") \ \ @@ -1618,7 +1602,7 @@ develop(bool, CMSTraceThreadState, false, \ "Trace the CMS thread state (enable the trace_state() method)") \ \ - product(bool, CMSClassUnloadingEnabled, false, \ + product(bool, CMSClassUnloadingEnabled, true, \ "Whether class unloading enabled when using CMS GC") \ \ product(uintx, CMSClassUnloadingMaxInterval, 0, \ @@ -2229,7 +2213,8 @@ develop(bool, TraceClassLoaderData, false, \ "Trace class loader loader_data lifetime") \ \ - product(uintx, InitialBootClassLoaderMetaspaceSize, 3*M, \ + product(uintx, InitialBootClassLoaderMetaspaceSize, \ + NOT_LP64(2200*K) LP64_ONLY(4*M), \ "Initial size of the boot class loader data metaspace") \ \ product(bool, TraceGen0Time, false, \ diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/runtime/java.cpp --- a/src/share/vm/runtime/java.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/runtime/java.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -368,6 +368,12 @@ if (CITime) { CompileBroker::print_times(); } + + if (PrintCodeCache) { + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + CodeCache::print(); + } + #ifdef COMPILER2 if (PrintPreciseBiasedLockingStatistics) { OptoRuntime::print_named_counters(); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/runtime/os_ext.hpp --- a/src/share/vm/runtime/os_ext.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/runtime/os_ext.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/runtime/sharedRuntime.cpp --- a/src/share/vm/runtime/sharedRuntime.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/runtime/sharedRuntime.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -643,7 +643,8 @@ bool skip_scope_increment = false; // exception handler lookup KlassHandle ek (THREAD, exception->klass()); - handler_bci = sd->method()->fast_exception_handler_bci_for(ek, bci, THREAD); + methodHandle mh(THREAD, sd->method()); + handler_bci = Method::fast_exception_handler_bci_for(mh, ek, bci, THREAD); if (HAS_PENDING_EXCEPTION) { recursive_exception = true; // We threw an exception while trying to find the exception handler. diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/runtime/thread.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -1716,7 +1716,6 @@ // cleanup_failed_attach_current_thread as well. void JavaThread::exit(bool destroy_vm, ExitType exit_type) { assert(this == JavaThread::current(), "thread consistency check"); - if (!InitializeJavaLangSystem) return; HandleMark hm(this); Handle uncaught_exception(this, this->pending_exception()); @@ -3469,11 +3468,7 @@ create_vm_init_libraries(); } - if (InitializeJavaLangString) { - initialize_class(vmSymbols::java_lang_String(), CHECK_0); - } else { - warning("java.lang.String not initialized"); - } + initialize_class(vmSymbols::java_lang_String(), CHECK_0); if (AggressiveOpts) { { @@ -3514,53 +3509,39 @@ } // Initialize java_lang.System (needed before creating the thread) - if (InitializeJavaLangSystem) { - initialize_class(vmSymbols::java_lang_System(), CHECK_0); - initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK_0); - Handle thread_group = create_initial_thread_group(CHECK_0); - Universe::set_main_thread_group(thread_group()); - initialize_class(vmSymbols::java_lang_Thread(), CHECK_0); - oop thread_object = create_initial_thread(thread_group, main_thread, CHECK_0); - main_thread->set_threadObj(thread_object); - // Set thread status to running since main thread has - // been started and running. - java_lang_Thread::set_thread_status(thread_object, - java_lang_Thread::RUNNABLE); - - // The VM creates & returns objects of this class. Make sure it's initialized. - initialize_class(vmSymbols::java_lang_Class(), CHECK_0); - - // The VM preresolves methods to these classes. Make sure that they get initialized - initialize_class(vmSymbols::java_lang_reflect_Method(), CHECK_0); - initialize_class(vmSymbols::java_lang_ref_Finalizer(), CHECK_0); - call_initializeSystemClass(CHECK_0); - - // get the Java runtime name after java.lang.System is initialized - JDK_Version::set_runtime_name(get_java_runtime_name(THREAD)); - JDK_Version::set_runtime_version(get_java_runtime_version(THREAD)); - } else { - warning("java.lang.System not initialized"); - } + initialize_class(vmSymbols::java_lang_System(), CHECK_0); + initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK_0); + Handle thread_group = create_initial_thread_group(CHECK_0); + Universe::set_main_thread_group(thread_group()); + initialize_class(vmSymbols::java_lang_Thread(), CHECK_0); + oop thread_object = create_initial_thread(thread_group, main_thread, CHECK_0); + main_thread->set_threadObj(thread_object); + // Set thread status to running since main thread has + // been started and running. + java_lang_Thread::set_thread_status(thread_object, + java_lang_Thread::RUNNABLE); + + // The VM creates & returns objects of this class. Make sure it's initialized. + initialize_class(vmSymbols::java_lang_Class(), CHECK_0); + + // The VM preresolves methods to these classes. Make sure that they get initialized + initialize_class(vmSymbols::java_lang_reflect_Method(), CHECK_0); + initialize_class(vmSymbols::java_lang_ref_Finalizer(), CHECK_0); + call_initializeSystemClass(CHECK_0); + + // get the Java runtime name after java.lang.System is initialized + JDK_Version::set_runtime_name(get_java_runtime_name(THREAD)); + JDK_Version::set_runtime_version(get_java_runtime_version(THREAD)); // an instance of OutOfMemory exception has been allocated earlier - if (InitializeJavaLangExceptionsErrors) { - initialize_class(vmSymbols::java_lang_OutOfMemoryError(), CHECK_0); - initialize_class(vmSymbols::java_lang_NullPointerException(), CHECK_0); - initialize_class(vmSymbols::java_lang_ClassCastException(), CHECK_0); - initialize_class(vmSymbols::java_lang_ArrayStoreException(), CHECK_0); - initialize_class(vmSymbols::java_lang_ArithmeticException(), CHECK_0); - initialize_class(vmSymbols::java_lang_StackOverflowError(), CHECK_0); - initialize_class(vmSymbols::java_lang_IllegalMonitorStateException(), CHECK_0); - initialize_class(vmSymbols::java_lang_IllegalArgumentException(), CHECK_0); - } else { - warning("java.lang.OutOfMemoryError has not been initialized"); - warning("java.lang.NullPointerException has not been initialized"); - warning("java.lang.ClassCastException has not been initialized"); - warning("java.lang.ArrayStoreException has not been initialized"); - warning("java.lang.ArithmeticException has not been initialized"); - warning("java.lang.StackOverflowError has not been initialized"); - warning("java.lang.IllegalArgumentException has not been initialized"); - } + initialize_class(vmSymbols::java_lang_OutOfMemoryError(), CHECK_0); + initialize_class(vmSymbols::java_lang_NullPointerException(), CHECK_0); + initialize_class(vmSymbols::java_lang_ClassCastException(), CHECK_0); + initialize_class(vmSymbols::java_lang_ArrayStoreException(), CHECK_0); + initialize_class(vmSymbols::java_lang_ArithmeticException(), CHECK_0); + initialize_class(vmSymbols::java_lang_StackOverflowError(), CHECK_0); + initialize_class(vmSymbols::java_lang_IllegalMonitorStateException(), CHECK_0); + initialize_class(vmSymbols::java_lang_IllegalArgumentException(), CHECK_0); } // See : bugid 4211085. diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/runtime/vmStructs.cpp --- a/src/share/vm/runtime/vmStructs.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/runtime/vmStructs.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -1198,7 +1198,6 @@ /*********************************/ \ \ static_field(java_lang_Class, _klass_offset, int) \ - static_field(java_lang_Class, _resolved_constructor_offset, int) \ static_field(java_lang_Class, _array_klass_offset, int) \ static_field(java_lang_Class, _oop_size_offset, int) \ static_field(java_lang_Class, _static_oop_field_count_offset, int) \ diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/services/diagnosticArgument.cpp --- a/src/share/vm/services/diagnosticArgument.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/services/diagnosticArgument.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/services/diagnosticCommand_ext.hpp --- a/src/share/vm/services/diagnosticCommand_ext.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/services/diagnosticCommand_ext.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -1,6 +1,6 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. DO - * NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * Copyright (c) 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 diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/services/memReporter.cpp --- a/src/share/vm/services/memReporter.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/services/memReporter.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/services/memReporter.hpp --- a/src/share/vm/services/memReporter.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/services/memReporter.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/shark/sharkBlock.cpp --- a/src/share/vm/shark/sharkBlock.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/shark/sharkBlock.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -1032,7 +1032,7 @@ check_null(value); object = value->generic_value(); } - if (is_get && field->is_constant()) { + if (is_get && field->is_constant() && field->is_static()) { SharkConstant *constant = SharkConstant::for_field(iter()); if (constant->is_loaded()) value = constant->value(builder()); @@ -1044,10 +1044,17 @@ BasicType basic_type = field->type()->basic_type(); Type *stack_type = SharkType::to_stackType(basic_type); Type *field_type = SharkType::to_arrayType(basic_type); - + Type *type = field_type; + if (field->is_volatile()) { + if (field_type == SharkType::jfloat_type()) { + type = SharkType::jint_type(); + } else if (field_type == SharkType::jdouble_type()) { + type = SharkType::jlong_type(); + } + } Value *addr = builder()->CreateAddressOfStructEntry( object, in_ByteSize(field->offset_in_bytes()), - PointerType::getUnqual(field_type), + PointerType::getUnqual(type), "addr"); // Do the access @@ -1055,6 +1062,7 @@ Value* field_value; if (field->is_volatile()) { field_value = builder()->CreateAtomicLoad(addr); + field_value = builder()->CreateBitCast(field_value, field_type); } else { field_value = builder()->CreateLoad(addr); } @@ -1074,6 +1082,7 @@ } if (field->is_volatile()) { + field_value = builder()->CreateBitCast(field_value, type); builder()->CreateAtomicStore(field_value, addr); } else { builder()->CreateStore(field_value, addr); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/shark/sharkCompiler.cpp --- a/src/share/vm/shark/sharkCompiler.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/shark/sharkCompiler.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -185,6 +185,9 @@ // Build the LLVM IR for the method Function *function = SharkFunction::build(env, &builder, flow, name); + if (env->failing()) { + return; + } // Generate native code. It's unpleasant that we have to drop into // the VM to do this -- it blocks safepoints -- but I can't see any diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/shark/sharkCompiler.hpp --- a/src/share/vm/shark/sharkCompiler.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/shark/sharkCompiler.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -46,6 +46,9 @@ // Missing feature tests bool supports_native() { return true; } bool supports_osr() { return true; } + bool can_compile_method(methodHandle method) { + return ! (method->is_method_handle_intrinsic() || method->is_compiled_lambda_form()); + } // Customization bool needs_adapters() { return false; } diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/shark/sharkConstant.cpp --- a/src/share/vm/shark/sharkConstant.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/shark/sharkConstant.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -37,7 +37,12 @@ ciType *type = NULL; if (constant.basic_type() == T_OBJECT) { ciEnv *env = ciEnv::current(); - assert(constant.as_object()->klass() == env->String_klass() || constant.as_object()->klass() == env->Class_klass(), "should be"); + + assert(constant.as_object()->klass() == env->String_klass() + || constant.as_object()->klass() == env->Class_klass() + || constant.as_object()->klass()->is_subtype_of(env->MethodType_klass()) + || constant.as_object()->klass()->is_subtype_of(env->MethodHandle_klass()), "should be"); + type = constant.as_object()->klass(); } return new SharkConstant(constant, type); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/shark/sharkFunction.cpp --- a/src/share/vm/shark/sharkFunction.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/shark/sharkFunction.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -77,6 +77,10 @@ // Walk the tree from the start block to determine which // blocks are entered and which blocks require phis SharkTopLevelBlock *start_block = block(flow()->start_block_num()); + if (is_osr() && start_block->stack_depth_at_entry() != 0) { + env()->record_method_not_compilable("can't compile OSR block with incoming stack-depth > 0"); + return; + } assert(start_block->start() == flow()->start_bci(), "blocks out of order"); start_block->enter(); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/shark/sharkInliner.cpp --- a/src/share/vm/shark/sharkInliner.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/shark/sharkInliner.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -725,7 +725,7 @@ // Push the result if necessary if (is_get) { bool result_pushed = false; - if (field->is_constant()) { + if (field->is_constant() && field->is_static()) { SharkConstant *sc = SharkConstant::for_field(iter()); if (sc->is_loaded()) { push(sc->is_nonzero()); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/shark/sharkInvariants.hpp --- a/src/share/vm/shark/sharkInvariants.hpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/shark/sharkInvariants.hpp Fri Jan 18 14:15:51 2013 +0100 @@ -68,7 +68,7 @@ // // Accessing this directly is kind of ugly, so it's private. Add // new accessors below if you need something from it. - private: + protected: ciEnv* env() const { assert(_env != NULL, "env not available"); return _env; @@ -99,12 +99,14 @@ DebugInformationRecorder* debug_info() const { return env()->debug_info(); } + SharkCodeBuffer* code_buffer() const { + return builder()->code_buffer(); + } + + public: Dependencies* dependencies() const { return env()->dependencies(); } - SharkCodeBuffer* code_buffer() const { - return builder()->code_buffer(); - } // Commonly used classes protected: diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/shark/sharkTopLevelBlock.cpp --- a/src/share/vm/shark/sharkTopLevelBlock.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/shark/sharkTopLevelBlock.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -113,7 +113,19 @@ ciSignature* sig; method = iter()->get_method(will_link, &sig); assert(will_link, "typeflow responsibility"); - + // We can't compile calls to method handle intrinsics, because we use + // the interpreter entry points and they expect the top frame to be an + // interpreter frame. We need to implement the intrinsics for Shark. + if (method->is_method_handle_intrinsic() || method->is_compiled_lambda_form()) { + if (SharkPerformanceWarnings) { + warning("JSR292 optimization not yet implemented in Shark"); + } + set_trap( + Deoptimization::make_trap_request( + Deoptimization::Reason_unhandled, + Deoptimization::Action_make_not_compilable), bci()); + return; + } if (!method->holder()->is_linked()) { set_trap( Deoptimization::make_trap_request( @@ -158,6 +170,16 @@ return; } break; + case Bytecodes::_invokedynamic: + case Bytecodes::_invokehandle: + if (SharkPerformanceWarnings) { + warning("JSR292 optimization not yet implemented in Shark"); + } + set_trap( + Deoptimization::make_trap_request( + Deoptimization::Reason_unhandled, + Deoptimization::Action_make_not_compilable), bci()); + return; } } @@ -1030,7 +1052,6 @@ dest_method->holder() == java_lang_Object_klass()) return dest_method; -#ifdef SHARK_CAN_DEOPTIMIZE_ANYWHERE // This code can replace a virtual call with a direct call if this // class is the only one in the entire set of loaded classes that // implements this method. This makes the compiled code dependent @@ -1064,6 +1085,8 @@ if (monomorphic_target != NULL) { assert(!monomorphic_target->is_abstract(), "shouldn't be"); + function()->dependencies()->assert_unique_concrete_method(actual_receiver, monomorphic_target); + // Opto has a bunch of type checking here that I don't // understand. It's to inhibit casting in one direction, // possibly because objects in Opto can have inexact @@ -1097,7 +1120,6 @@ // with non-monomorphic targets if the receiver has an exact // type. We don't mark types this way, so we can't do this. -#endif // SHARK_CAN_DEOPTIMIZE_ANYWHERE return NULL; } @@ -1298,8 +1320,9 @@ // Try to inline the call if (!call_is_virtual) { - if (SharkInliner::attempt_inline(call_method, current_state())) + if (SharkInliner::attempt_inline(call_method, current_state())) { return; + } } // Find the method we are calling diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/utilities/debug.cpp --- a/src/share/vm/utilities/debug.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/utilities/debug.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -612,21 +612,6 @@ Events::print(); } -// Given a heap address that was valid before the most recent GC, if -// the oop that used to contain it is still live, prints the new -// location of the oop and the address. Useful for tracking down -// certain kinds of naked oop and oop map bugs. -extern "C" void pnl(intptr_t old_heap_addr) { - // Print New Location of old heap address - Command c("pnl"); -#ifndef VALIDATE_MARK_SWEEP - tty->print_cr("Requires build with VALIDATE_MARK_SWEEP defined (debug build) and RecordMarkSweepCompaction enabled"); -#else - MarkSweep::print_new_location_of_heap_address((HeapWord*) old_heap_addr); -#endif -} - - extern "C" Method* findm(intptr_t pc) { Command c("findm"); nmethod* nm = CodeCache::find_nmethod((address)pc); diff -r e94ed1591b42 -r 557bda927cc2 src/share/vm/utilities/vmError.cpp --- a/src/share/vm/utilities/vmError.cpp Wed Jan 16 16:30:04 2013 +0100 +++ b/src/share/vm/utilities/vmError.cpp Fri Jan 18 14:15:51 2013 +0100 @@ -702,7 +702,7 @@ if (_verbose && Universe::is_fully_initialized()) { // print code cache information before vm abort - CodeCache::print_bounds(st); + CodeCache::print_summary(st); st->cr(); } diff -r e94ed1591b42 -r 557bda927cc2 test/compiler/7190310/Test7190310.java --- a/test/compiler/7190310/Test7190310.java Wed Jan 16 16:30:04 2013 +0100 +++ b/test/compiler/7190310/Test7190310.java Fri Jan 18 14:15:51 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -23,7 +23,16 @@ */ /* - * Manual test + * @test + * @bug 7190310 + * @summary Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops + * @run main/othervm/timeout=600 -Xbatch Test7190310 + */ + +/* + * Note bug exhibits as infinite loop, timeout is helpful. + * It should normally finish pretty quickly, but on some especially slow machines + * it may not. The companion _unsafe test lacks a timeout, but that is okay. */ import java.lang.ref.*; diff -r e94ed1591b42 -r 557bda927cc2 test/compiler/8005419/Test8005419.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/8005419/Test8005419.java Fri Jan 18 14:15:51 2013 +0100 @@ -0,0 +1,120 @@ +/* + * Copyright (c) 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. + * + * 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 8005419 + * @summary Improve intrinsics code performance on x86 by using AVX2 + * @run main/othervm -Xbatch -Xmx64m Test8005419 + * + */ + +public class Test8005419 { + public static int SIZE = 64; + + public static void main(String[] args) { + char[] a = new char[SIZE]; + char[] b = new char[SIZE]; + + for (int i = 16; i < SIZE; i++) { + a[i] = (char)i; + b[i] = (char)i; + } + String s1 = new String(a); + String s2 = new String(b); + + // Warm up + boolean failed = false; + int result = 0; + for (int i = 0; i < 10000; i++) { + result += test(s1, s2); + } + for (int i = 0; i < 10000; i++) { + result += test(s1, s2); + } + for (int i = 0; i < 10000; i++) { + result += test(s1, s2); + } + if (result != 0) failed = true; + + System.out.println("Start testing"); + // Compare same string + result = test(s1, s1); + if (result != 0) { + failed = true; + System.out.println("Failed same: result = " + result + ", expected 0"); + } + // Compare equal strings + for (int i = 1; i <= SIZE; i++) { + s1 = new String(a, 0, i); + s2 = new String(b, 0, i); + result = test(s1, s2); + if (result != 0) { + failed = true; + System.out.println("Failed equals s1[" + i + "], s2[" + i + "]: result = " + result + ", expected 0"); + } + } + // Compare equal strings but different sizes + for (int i = 1; i <= SIZE; i++) { + s1 = new String(a, 0, i); + for (int j = 1; j <= SIZE; j++) { + s2 = new String(b, 0, j); + result = test(s1, s2); + if (result != (i-j)) { + failed = true; + System.out.println("Failed diff size s1[" + i + "], s2[" + j + "]: result = " + result + ", expected " + (i-j)); + } + } + } + // Compare strings with one char different and different sizes + for (int i = 1; i <= SIZE; i++) { + s1 = new String(a, 0, i); + for (int j = 0; j < i; j++) { + b[j] -= 3; // change char + s2 = new String(b, 0, i); + result = test(s1, s2); + int chdiff = a[j] - b[j]; + if (result != chdiff) { + failed = true; + System.out.println("Failed diff char s1[" + i + "], s2[" + i + "]: result = " + result + ", expected " + chdiff); + } + result = test(s2, s1); + chdiff = b[j] - a[j]; + if (result != chdiff) { + failed = true; + System.out.println("Failed diff char s2[" + i + "], s1[" + i + "]: result = " + result + ", expected " + chdiff); + } + b[j] += 3; // restore + } + } + if (failed) { + System.out.println("FAILED"); + System.exit(97); + } + System.out.println("PASSED"); + } + + private static int test(String str1, String str2) { + return str1.compareTo(str2); + } +} diff -r e94ed1591b42 -r 557bda927cc2 test/runtime/7158804/Test7158804.sh --- a/test/runtime/7158804/Test7158804.sh Wed Jan 16 16:30:04 2013 +0100 +++ b/test/runtime/7158804/Test7158804.sh Fri Jan 18 14:15:51 2013 +0100 @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. #